Source code for dhcpcanon.clientscript

# -*- coding: utf-8 -*-
# vim:ts=4:sw=4:expandtab 2
# Copyright 2016, 2017 juga (juga at riseup dot net), MIT license.
"""Class to Initialize and call external script."""
from __future__ import absolute_import, unicode_literals

import logging
import os
import subprocess

import attr

from .constants import (ENV_OPTIONS_REQ, LEASEATTRS2ENVKEYS,
                        LEASEATTRS_SAMEAS_ENVKEYS, SCRIPT_ENV_KEYS,
                        SCRIPT_PATH, STATES2REASONS)

logger = logging.getLogger('dhcpcanon')


[docs] @attr.s class ClientScript(object): """Simulates the behaviour of the isc-dhcp client-script or nm-dhcp-helper. `client-script <https://anonscm.debian.org/cgit/pkg-dhcp/isc-dhcp.git/tree/client/scripts/linux>`_ or `nm-dhcp-helper <https://github.com/NetworkManager/NetworkManager/tree/master/src/dhcp>`_. """ scriptname = attr.ib(default=None) env = attr.ib(default=attr.Factory(dict)) def __attrs_post_init__(self, scriptfile=None, env=None): """.""" logger.debug('Modifying ClientScript obj after creating it.') self.scriptname = self.scriptname or scriptfile or SCRIPT_PATH if env is None: self.env = dict.fromkeys(SCRIPT_ENV_KEYS, str('')) else: self.env = env self.env['medium'] = str() self.env['pid'] = str(os.getpid())
[docs] def script_init(self, lease, state, prefix='', medium=''): """Initialize environment to pass to the external script.""" logger.debug('self.scriptname %s', self.scriptname) if self.scriptname is not None: logger.debug('Modifying ClientScript obj, setting env.') if isinstance(state, int): reason = STATES2REASONS[state] else: reason = state self.env['reason'] = str(reason) self.env['medium'] = self.env.get('medium') or str(medium) self.env['client'] = str('dhcpcanon') self.env['pid'] = str(os.getpid()) for k in LEASEATTRS_SAMEAS_ENVKEYS: self.env[k] = str(lease.__getattribute__(k)) for k, v in LEASEATTRS2ENVKEYS.items(): self.env[v] = str(lease.__getattribute__(k)) self.env.update(ENV_OPTIONS_REQ) else: logger.debug('There is not script path.')
[docs] def script_go(self, scriptname=None, env=None): """Run the external script.""" scriptname = self.scriptname or scriptname if scriptname is not None: env = self.env or env logger.info('Calling script %s', scriptname) logger.info('with env %s', env) proc = subprocess.Popen([scriptname], env=env, stderr=subprocess.STDOUT) try: (stdout, stderr) = proc.communicate() return True except TypeError as e: logger.error(e) return False