def set_bridge_attr(self, bridgename, attrname, attrvalue, check=True): if check: if attrname == 'treeprio': attrvalue_curr = self.get_bridge_attr(bridgename, attrname) else: attrvalue_curr = self.get_bridge_attr( bridgename, self._bridge_jsonAttr_map[attrname]) if attrvalue_curr and attrvalue_curr == attrvalue: return if attrname == 'treeprio': utils.exec_commandl([ utils.mstpctl_cmd, 'set%s' % attrname, '%s' % bridgename, '0', '%s' % attrvalue ], stderr=None) self.update_bridge_cache(bridgename, attrname, str(attrvalue)) else: utils.exec_commandl([ utils.mstpctl_cmd, 'set%s' % attrname, '%s' % bridgename, '%s' % attrvalue ], stderr=None) self.update_bridge_cache(bridgename, self._bridge_jsonAttr_map[attrname], str(attrvalue))
def _get_bridge_and_port_attrs_from_cache(self, bridgename): attrs = MSTPAttrsCache.get(bridgename, None) if attrs is not None: return attrs mstpctl_bridgeport_attrs_dict = {} try: cmd = [utils.mstpctl_cmd, 'showportdetail', bridgename, 'json'] output = utils.exec_commandl(cmd) if not output: MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict) return mstpctl_bridgeport_attrs_dict except Exception as e: self.logger.info(str(e)) return mstpctl_bridgeport_attrs_dict portname = bridgename # assigning portname to avoid an exception, in the exception handler try: mstpctl_bridge_cache = json.loads(output.strip("\n")) for portname in list(mstpctl_bridge_cache.keys()): for portid in list(mstpctl_bridge_cache[portname].keys()): mstpctl_bridgeport_attrs_dict[portname] = {} mstpctl_bridgeport_attrs_dict[portname][ 'treeportprio'] = self._extract_bridge_port_prio( portid) for jsonAttr in list( mstpctl_bridge_cache[portname][portid].keys()): jsonVal = mstpctl_bridge_cache[portname][portid][ jsonAttr] mstpctl_bridgeport_attrs_dict[portname][ jsonAttr] = str(jsonVal) MSTPAttrsCache.set(bridgename, mstpctl_bridgeport_attrs_dict) except Exception as e: self.logger.info( '%s: cannot fetch mstpctl bridge port attributes: %s' % (portname, str(e))) mstpctl_bridge_attrs_dict = {} try: cmd = [utils.mstpctl_cmd, 'showbridge', 'json', bridgename] output = utils.exec_commandl(cmd) if not output: return mstpctl_bridge_attrs_dict except Exception as e: self.logger.info(str(e)) return mstpctl_bridge_attrs_dict try: mstpctl_bridge_cache = json.loads(output.strip('\n')) for jsonAttr in list(mstpctl_bridge_cache[bridgename].keys()): mstpctl_bridge_attrs_dict[jsonAttr] = (str( mstpctl_bridge_cache[bridgename][jsonAttr])) mstpctl_bridge_attrs_dict['treeprio'] = '%d' % (int( mstpctl_bridge_attrs_dict.get('bridgeId', '').split('.')[0], base=16) * 4096) del mstpctl_bridge_attrs_dict['bridgeId'] MSTPAttrsCache.bridges[bridgename].update( mstpctl_bridge_attrs_dict) except Exception as e: self.logger.info('%s: cannot fetch mstpctl bridge attributes: %s' % (bridgename, str(e))) return MSTPAttrsCache.get(bridgename)
def check_service_status(cls, servicename=None): if not servicename: return False try: utils.exec_commandl([utils.service_cmd, servicename, 'status']) except Exception: # XXX: check for subprocess errors vs os error return False return True
def _up(self, ifaceobj): """ Up the PPP connection """ provider = ifaceobj.get_attr_value_first('provider') old_config = None old_provider = None try: ppp_file = os.path.join('/etc/ppp/peers', provider) if not os.path.isfile(ppp_file): self.log_warn('Invalid ppp provider file does not exist') return # Load state data saved_ifaceobjs = statemanager.statemanager_api.get_ifaceobjs( ifaceobj.name) if saved_ifaceobjs: old_provider = saved_ifaceobjs[0].get_attr_value_first( 'provider') old_config = saved_ifaceobjs[0].get_attr_value_first( 'provider_file') config = hashlib.sha256(open(ppp_file, 'rb').read()).hexdigest() # Always save the current config files hash ifaceobj.update_config('provider_file', config) if not self.cache.link_exists(ifaceobj.name): try: # This fails if not running utils.exec_user_command( '/bin/ps ax | /bin/grep pppd | /bin/grep -v grep | /bin/grep ' + provider) except Exception: utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) if old_config and old_config != config: # Restart on config change utils.exec_commandl(['/usr/bin/poff', provider], stdout=None, stderr=None) utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) elif old_provider and old_provider != provider: # Restart on provider change utils.exec_commandl(['/usr/bin/poff', old_provider], stdout=None, stderr=None) utils.exec_commandl(['/usr/bin/pon', provider], stdout=None, stderr=None) except Exception as e: self.log_warn(str(e))
def _run_dhclient_cmd(self, cmd, cmd_prefix=None): if not cmd_prefix: cmd_aslist = [] else: cmd_aslist = cmd_prefix.split() if cmd_aslist: cmd_aslist.extend(cmd) else: cmd_aslist = cmd utils.exec_commandl(cmd_aslist, stdout=None, stderr=None)
def set_bridge_treeprio(self, bridgename, attrvalue, check=True): if check: attrvalue_curr = self.get_bridge_treeprio(bridgename) if attrvalue_curr and attrvalue_curr == attrvalue: return utils.exec_commandl([ utils.mstpctl_cmd, 'settreeprio', bridgename, '0', str(attrvalue) ]) self.update_bridge_cache(bridgename, 'treeprio', str(attrvalue))
def _run_dhclient_cmd(self, cmd, cmd_prefix=None): if not cmd_prefix: cmd_aslist = [] else: cmd_aslist = cmd_prefix.split() if cmd_aslist: cmd_aslist.extend(cmd) else: cmd_aslist = cmd utils.exec_commandl(cmd_aslist, stdout=None, stderr=None)
def check_service_status(cls, servicename=None): if not servicename: return False try: utils.exec_commandl([utils.service_cmd, servicename, 'status']) except Exception: # XXX: check for subprocess errors vs os error return False return True
def _batctl_if (self, bat_iface, mesh_iface, op): if op not in [ 'add', 'del' ]: raise Exception ("_batctl_if() called with invalid \"op\" value: %s" % op) try: self.logger.debug ("Running batctl -m %s if %s %s" % (bat_iface, op, mesh_iface)) utils.exec_commandl(["batctl", "-m", bat_iface, "if", op, mesh_iface]) except subprocess.CalledProcessError as c: raise Exception ("Command \"batctl -m %s if %s %s\" failed: %s" % (bat_iface, op, mesh_iface, c.output)) except Exception as e: raise Exception ("_batctl_if: %s" % e)
def _batctl_if (self, bat_iface, mesh_iface, op): if op not in [ 'add', 'del' ]: raise Exception ("_batctl_if() called with invalid \"op\" value: %s" % op) try: self.logger.debug ("Running batctl -m %s if %s %s" % (bat_iface, op, mesh_iface)) utils.exec_commandl(["batctl", "-m", bat_iface, "if", op, mesh_iface]) except subprocess.CalledProcessError as c: raise Exception ("Command \"batctl -m %s if %s %s\" failed: %s" % (bat_iface, op, mesh_iface, c.output)) except Exception as e: raise Exception ("_batctl_if: %s" % e)
def _down(self, ifaceobj): """ Down the PPP connection """ try: provider = ifaceobj.get_attr_value_first('provider') # This fails if not running utils.exec_user_command( '/bin/ps ax | /bin/grep pppd | /bin/grep -v grep | /bin/grep ' + provider) utils.exec_commandl(['/usr/bin/poff', provider], stdout=None, stderr=None) except Exception as e: self.log_warn(str(e))
def _check_if_process_is_running(self, cmdname, cmdline): targetpids = [] pidstr = '' try: cmdl = [utils.pidof_cmd, cmdname] pidstr = utils.exec_commandl(cmdl, stderr=None).strip('\n') except: pass if not pidstr: return [] pids = pidstr.split() if not pids: return targetpids for pid in pids: tmpcmdline = cmdline.replace(' ', '') try: pcmdline = self.read_file_oneline('/proc/%s/cmdline' % pid) pcmdline = re.sub(r'\\(.)', r'\1', pcmdline) self.logger.info('(%s)' % (pcmdline)) self.logger.info('(%s)' % (tmpcmdline)) self.logger.info('(%d) (%d)' % (len(pcmdline), len(tmpcmdline))) if pcmdline and pcmdline == tmpcmdline: targetpids.append(pid) except: pass return targetpids
def __call__(self, parser, namespace, values, option_string=None): try: dpkg = utils.exec_commandl([utils.dpkg_cmd, '-l', 'ifupdown2']) if not dpkg: raise Exception('dpkg -l ifupdown2 returns without output') dpkg = dpkg.split('\n') if not dpkg: raise Exception('dpkg -l ifupdown2 returns without output') for line in dpkg: if 'ifupdown2' in line: info = line.split() sys.stdout.write('ifupdown2:%s\n' % (info[2])) sys.exit(0) raise Exception('ifupdown2 package not found using dpkg -l') except Exception as e: sys.stderr.write( 'error: cannot get current version using dpkg: %s\n' % str(e)) sys.exit(1)
def _check_if_process_is_running(self, cmdname, cmdline): targetpids = [] pidstr = '' try: cmdl = [utils.pidof_cmd, cmdname] pidstr = utils.exec_commandl(cmdl, stderr=None).strip('\n') except: pass if not pidstr: return [] pids = pidstr.split() if not pids: return targetpids for pid in pids: tmpcmdline = cmdline.replace(' ', '') try: pcmdline = self.read_file_oneline('/proc/%s/cmdline' %pid) pcmdline = re.sub(r'\\(.)', r'\1', pcmdline) self.logger.info('(%s)' %(pcmdline)) self.logger.info('(%s)' %(tmpcmdline)) self.logger.info('(%d) (%d)' %(len(pcmdline), len(tmpcmdline))) if pcmdline and pcmdline == tmpcmdline: targetpids.append(pid) except: pass return targetpids
def __call__(self, parser, namespace, values, option_string=None): try: dpkg = utils.exec_commandl([utils.dpkg_cmd, '-l', 'ifupdown2']) if not dpkg: raise Exception('dpkg -l ifupdown2 returns without output') dpkg = dpkg.split('\n') if not dpkg: raise Exception('dpkg -l ifupdown2 returns without output') for line in dpkg: if 'ifupdown2' in line: info = line.split() sys.stdout.write('ifupdown2:%s\n' % (info[2])) sys.exit(0) raise Exception('ifupdown2 package not found using dpkg -l') except Exception as e: sys.stderr.write('error: cannot get current version using dpkg: %s\n' % str(e)) sys.exit(1)
def get_running_attr(self,attr='',ifaceobj=None): if not ifaceobj or not attr: return running_attr = None try: if attr == 'autoneg': output = utils.exec_commandl([utils.ethtool_cmd, ifaceobj.name]) running_attr = self.get_autoneg(ethtool_output=output) elif attr == 'fec': output = utils.exec_command('%s --show-fec %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_fec_encoding(ethtool_output=output) elif attr == 'gro': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='generic-receive-offload') elif attr == 'lro': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='large-receive-offload') elif attr == 'gso': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='generic-segmentation-offload') elif attr == 'tso': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='tcp-segmentation-offload') elif attr == 'ufo': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='udp-fragmentation-offload') elif attr == 'rx': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='rx-checksumming') elif attr == 'tx': if not self.feature_cache: self.feature_cache = utils.exec_command('%s --show-features %s'% (utils.ethtool_cmd, ifaceobj.name)) running_attr = self.get_offload_setting(ethtool_output=self.feature_cache, setting='tx-checksumming') else: running_attr = self.io.read_file_oneline('/sys/class/net/%s/%s' % \ (ifaceobj.name, attr)) except Exception as e: if not self.ethtool_ignore_errors: # for nonexistent interfaces, we get an error (rc = 256 or 19200) self.logger.debug('ethtool: problems calling ethtool or reading' ' /sys/class on iface %s for attr %s: %s' % (ifaceobj.name, attr, str(e))) return running_attr
def set_bridge_port_attr(self, bridgename, portname, attrname, value, json_attr=None): cache_value = self.get_bridge_port_attr(bridgename, portname, json_attr) if cache_value and cache_value == value: return if attrname == 'treeportcost' or attrname == 'treeportprio': utils.exec_commandl([ utils.mstpctl_cmd, 'set%s' % attrname, bridgename, portname, '0', value ]) else: utils.exec_commandl([ utils.mstpctl_cmd, 'set%s' % attrname, bridgename, portname, value ]) if json_attr: self.update_bridge_port_cache(bridgename, portname, json_attr, value)
def get_current_ip_configured(self, ifname, family): ips = set() try: a = utils.exec_commandl(["ip", "-o", "addr", "show", ifname]).split("\n") for entry in a: family_index = entry.find(family) if family_index < 0: continue tmp = entry[entry.find(family) + len(family) + 1:] ip = tmp[:tmp.find(" ")] if ip: ips.add(ip) except Exception: pass return ips
def link_add_xfrm(self, ifname, xfrm_name, xfrm_id): utils.exec_commandl([ 'ip', 'link', 'add', xfrm_name, 'type', 'xfrm', 'dev', ifname, 'if_id', xfrm_id ]) self.__update_cache_after_link_creation(xfrm_name, "xfrm")
def _kill_ssh_connections(self, ifacename): try: runningaddrsdict = self.ipcmd.get_running_addrs(None, ifacename) if not runningaddrsdict: return iplist = [i.split('/', 1)[0] for i in runningaddrsdict.keys()] if not iplist: return proc=[] #Example output: #ESTAB 0 0 10.0.1.84:ssh 10.0.1.228:45186 #users:(("sshd",pid=2528,fd=3)) cmdl = [utils.ss_cmd, '-t', '-p'] for line in utils.exec_commandl(cmdl).splitlines(): citems = line.split() addr = None if '%' in citems[3]: addr = citems[3].split('%')[0] elif ':ssh' in citems[3]: addr = citems[3].split(':')[0] if not addr: continue if addr in iplist: if len(citems) == 6: proc.append(citems[5].split(',')[1].split('=')[1]) if not proc: return pid = None # outpt of '/usr/bin/pstree -Aps <pid>': # 'systemd(1)---sshd(990)---sshd(16112)---sshd(16126)---bash(16127)---sudo(16756)---ifreload(16761)---pstree(16842)\n' # get the above output to following format # ['systemd(1)', 'sshd(990)', 'sshd(16112)', 'sshd(16126)', 'bash(16127)', 'sudo(16756)', 'ifreload(16761)', 'pstree(16850)'] pstree = list(reversed(utils.exec_command('%s -Aps %s' % (utils.pstree_cmd, os.getpid())).strip().split('---'))) for index, process in enumerate(pstree): # check the parent of SSH process to make sure # we don't kill SSH server or systemd process if 'sshd' in process and 'sshd' in pstree[index + 1]: pid = filter(lambda x: x.isdigit(), process) break self.logger.info("%s: killing active ssh sessions: %s" %(ifacename, str(proc))) if ifupdownflags.flags.DRYRUN: return for id in proc: if id != pid: try: os.kill(int(id), signal.SIGINT) except OSError as e: continue # Kill current SSH client if pid in proc: try: forkret = os.fork() except OSError, e: self.logger.info("fork error : %s [%d]" % (e.strerror, e.errno)) if (forkret == 0): # The first child. try: os.setsid() self.logger.info("%s: ifreload continuing in the background" %ifacename) except OSError, (err_no, err_message): self.logger.info("os.setsid failed: errno=%d: %s" % (err_no, err_message)) self.logger.info("pid=%d pgid=%d" % (os.getpid(), os.getpgid(0))) try: self.logger.info("%s: killing our session: %s" %(ifacename, str(proc))) os.kill(int(pid), signal.SIGINT) return except OSError as e: return
def _kill_ssh_connections(self, ifacename, ifaceobj): try: iplist = [str(ip.ip) for ip in self.cache.get_managed_ip_addresses( ifname=ifacename, ifaceobj_list=[ifaceobj], )] if not iplist: return proc=[] #Example output: #ESTAB 0 0 10.0.1.84:ssh 10.0.1.228:45186 #users:(("sshd",pid=2528,fd=3)) cmdl = [utils.ss_cmd, '-t', '-p'] for line in utils.exec_commandl(cmdl).splitlines(): citems = line.split() addr = None if '%' in citems[3]: addr = citems[3].split('%')[0] elif ':ssh' in citems[3]: addr = citems[3].split(':')[0] if not addr: continue if addr in iplist: if len(citems) == 6: proc.append(citems[5].split(',')[1].split('=')[1]) if not proc: return pid = None # outpt of '/usr/bin/pstree -Aps <pid>': # 'systemd(1)---sshd(990)---sshd(16112)---sshd(16126)---bash(16127)---sudo(16756)---ifreload(16761)---pstree(16842)\n' # get the above output to following format # ['systemd(1)', 'sshd(990)', 'sshd(16112)', 'sshd(16126)', 'bash(16127)', 'sudo(16756)', 'ifreload(16761)', 'pstree(16850)'] pstree = list(reversed(utils.exec_command('%s -Aps %s' % (utils.pstree_cmd, os.getpid())).strip().split('---'))) for index, process in enumerate(pstree): # check the parent of SSH process to make sure # we don't kill SSH server or systemd process if 'sshd' in process and 'sshd' in pstree[index + 1]: pid = [x for x in process if x.isdigit()] break self.logger.info("%s: killing active ssh sessions: %s" %(ifacename, str(proc))) if ifupdownflags.flags.DRYRUN: return for id in proc: if id != pid: try: os.kill(int(id), signal.SIGINT) except OSError as e: continue # Kill current SSH client if pid in proc: try: forkret = os.fork() except OSError as e: self.logger.info("fork error : %s [%d]" % (e.strerror, e.errno)) if (forkret == 0): # The first child. try: os.setsid() self.logger.info("%s: ifreload continuing in the background" %ifacename) except OSError as xxx_todo_changeme: (err_no, err_message) = xxx_todo_changeme.args self.logger.info("os.setsid failed: errno=%d: %s" % (err_no, err_message)) self.logger.info("pid=%d pgid=%d" % (os.getpid(), os.getpgid(0))) try: self.logger.info("%s: killing our session: %s" %(ifacename, str(proc))) os.kill(int(pid), signal.SIGINT) return except OSError as e: return except Exception as e: self.logger.info('%s: %s' %(ifacename, str(e)))