X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=pkg%2Fiface.py;h=3ea64894eb4eed5162c5bccfedccacd3497f9770;hb=c798b0f4aa66736f9c260886c0bf4181dc755211;hp=d137b6acdcf596fc535115c8140718eb650c37c5;hpb=cca03c30c5c718caf5800a238331825eed9b2015;p=mirror_ifupdown2.git diff --git a/pkg/iface.py b/pkg/iface.py index d137b6a..3ea6489 100644 --- a/pkg/iface.py +++ b/pkg/iface.py @@ -6,18 +6,19 @@ # iface -- # interface object # - from collections import OrderedDict -import logging +#from json import * import json +import logging -class ifaceFlags(): +tickmark = ' (' + u'\u2713'.encode('utf8') + ')' +crossmark = ' (' + u'\u2717'.encode('utf8') + ')' +class ifaceFlags(): NONE = 0x1 FOLLOW_DEPENDENTS = 0x2 class ifaceStatus(): - """iface status """ UNKNOWN = 0x1 SUCCESS = 0x2 @@ -33,7 +34,7 @@ class ifaceStatus(): elif state == cls.ERROR: return 'error' elif state == cls.NOTFOUND: - return 'not found' + return 'notfound' @classmethod def from_str(cls, state_str): @@ -56,6 +57,10 @@ class ifaceState(): DOWN = 0x7 POST_DOWN = 0x8 + # Pseudo states + QUERY_CHECKCURR = 0x9 + QUERY_RUNNING = 0xa + @classmethod def to_str(cls, state): if state == cls.UNKNOWN: @@ -70,8 +75,14 @@ class ifaceState(): return 'post-up' elif state == cls.PRE_DOWN: return 'pre-down' + elif state == cls.DOWN: + return 'down' elif state == cls.POST_DOWN: return 'post-down' + elif state == cls.QUERY_CHECKCURR: + return 'query-checkcurr' + elif state == cls.QUERY_RUNNING: + return 'query-running' @classmethod def from_str(cls, state_str): @@ -87,36 +98,54 @@ class ifaceState(): return cls.POST_UP elif state_str == 'pre-down': return cls.PRE_DOWN + elif state_str == 'down': + return cls.DOWN elif state_str == 'post-down': return cls.POST_DOWN - + elif state_str == 'query-checkcurr': + return cls.QUERY_CHECKCURR + elif state_str == 'query-running': + return cls.QUERY_RUNNING + +class ifaceJsonEncoder(json.JSONEncoder): + def default(self, o): + retconfig = {} + if o.config: + for k, v in o.config.items(): + if len(v) == 1: + retconfig[k] = v[0] + else: + retconfig[k] = v + + return OrderedDict({'name' : o.name, + 'addr_method' : o.addr_method, + 'addr_family' : o.addr_family, + 'auto' : o.auto, + 'config' : retconfig}) class iface(): - """ config flags """ - AUTO = 0x1 - HOT_PLUG = 0x2 + """ flags """ + # flag to indicate that the object was created from pickled state + PICKLED = 0x1 + + version = '0.1' - def __init__(self): self.name = None self.addr_family = None self.addr_method = None self.config = OrderedDict() - self.children = [] + self.config_status = {} self.state = ifaceState.NEW self.status = ifaceStatus.UNKNOWN self.flags = 0x0 + self.priv_flags = 0x0 self.refcnt = 0 - # dependents that are listed as in the - # config file - self.dependents = None - # All dependents (includes dependents that - # are not listed in the config file) - self.realdev_dependents = None + self.lowerifaces = None + self.upperifaces = None self.auto = False self.classes = [] self.env = None - self.config_current = {} self.raw_lines = [] self.linkstate = None @@ -157,16 +186,15 @@ class iface(): return self.config def is_config_present(self): - if self.config is None: + addr_method = self.get_addr_method() + if addr_method: + if (addr_method.find('dhcp') != -1 or + addr_method.find('dhcp6') != -1): + return True + if not self.config: return False - - return (len(self.config) != 0) - - def set_config_current(self, config_current): - self.config_current = config_current - - def get_config_current(self): - return self.config_current + else: + return True def get_auto(self): return self.auto @@ -191,11 +219,13 @@ class iface(): def belongs_to_class(self, intfclass): if intfclass in self.classes: return True - return False - def add_child(self, child_iface_obj): - self.children.append(child_iface_obj) + def set_priv_flags(self, priv_flags): + self.priv_flags = priv_flags + + def get_priv_flags(self): + return self.priv_flags def get_state(self): return self.state @@ -215,6 +245,10 @@ class iface(): def set_status(self, status): self.status = status + def set_state_n_status(self, state, status): + self.state = state + self.status = status + def state_str_to_hex(self, state_str): return self.state_str_map.get(state_str) @@ -224,17 +258,24 @@ class iface(): def clear_flag(self, flag): self.flags &= ~flag - def set_dependents(self, dlist): - self.dependents = dlist + def set_lowerifaces(self, dlist): + self.lowerifaces = dlist + + def get_lowerifaces(self): + return self.lowerifaces - def get_dependents(self): - return self.dependents + def set_upperifaces(self, dlist): + self.upperifaces = dlist - def set_realdev_dependents(self, dlist): - self.realdev_dependents = dlist + def add_to_upperifaces(self, upperifacename): + if self.upperifaces: + if upperifacename not in self.upperifaces: + self.upperifaces.append(upperifacename) + else: + self.upperifaces = [upperifacename] - def get_realdev_dependents(self): - return self.realdev_dependents + def get_upperifaces(self): + return self.upperifaces def set_linkstate(self, l): self.linkstate = l @@ -249,27 +290,24 @@ class iface(): def get_attr_value_first(self, attr_name): config = self.get_config() - attr_value_list = config.get(attr_name) - if attr_value_list is not None: + if attr_value_list: return attr_value_list[0] - return None def get_attr_value_n(self, attr_name, attr_index): config = self.get_config() attr_value_list = config.get(attr_name) - if attr_value_list is not None: + if attr_value_list: try: return attr_value_list[attr_index] except: return None - return None def get_env(self): - if self.env is None or len(self.env) == 0: + if not self.env: self.generate_env() return self.env @@ -284,11 +322,11 @@ class iface(): attr_env_name = 'IF_%s' %attr.upper() env[attr_env_name] = attr_value[0] - if len(env) > 0: + if env: self.set_env(env) def update_config(self, attr_name, attr_value): - if self.config.get(attr_name) is None: + if not self.config.get(attr_name): self.config[attr_name] = [attr_value] else: self.config[attr_name].append(attr_value) @@ -297,29 +335,78 @@ class iface(): self.config.update(attrdict) def update_config_with_status(self, attr_name, attr_value, attr_status=0): - if attr_value is None: + if not attr_value: attr_value = '' - if attr_status != 0: - self.set_status(ifaceStatus.ERROR) - else: - if self.get_status() != ifaceStatus.ERROR: - self.set_status(ifaceStatus.SUCCESS) - if self.config.get(attr_name) is not None: + if self.config.get(attr_name): self.config[attr_name].append(attr_value) + self.config_status[attr_name].append(attr_status) else: self.config[attr_name] = [attr_value] + self.config_status[attr_name] = [attr_status] + + # set global iface state + if attr_status: + self.set_status(ifaceStatus.ERROR) + elif self.get_status() != ifaceStatus.ERROR: + # Not already error, mark success + self.set_status(ifaceStatus.SUCCESS) + + def get_config_attr_status(self, attr_name, idx=0): + self.config_status.get(attr_name, [])[idx] + + def get_config_attr_status_str(self, attr_name, idx=0): + ret = self.config_status.get(attr_name, [])[idx] + if ret: + return crossmark + else: + return tickmark + + def is_different(self, dstiface): + if self.name != dstiface.name: return True + if self.addr_family != dstiface.addr_family: return True + if self.addr_method != dstiface.addr_method: return True + if self.auto != dstiface.auto: return True + if self.classes != dstiface.classes: return True + + if any(True for k in self.config if k not in dstiface.config): + return True + + if any(True for k,v in self.config.items() + if v != dstiface.config.get(k)): return True - """ XXX: If status needs to be encoded in the query string - if attr_status == 0: - self.set_status(attr - attr_status_str = '' - elif attr_status == 0: - attr_status_str = ' (success)' - elif attr_status != 0: - attr_status_str = ' (error)' - self.config[attr_name] = attr_value + attr_status_str """ + return False + def __getstate__(self): + odict = self.__dict__.copy() + del odict['state'] + del odict['status'] + del odict['lowerifaces'] + del odict['upperifaces'] + del odict['refcnt'] + del odict['config_status'] + del odict['flags'] + del odict['priv_flags'] + del odict['raw_lines'] + del odict['linkstate'] + del odict['env'] + return odict + + def __setstate__(self, dict): + self.__dict__.update(dict) + self.config_status = {} + self.state = ifaceState.NEW + self.status = ifaceStatus.UNKNOWN + self.refcnt = 0 + self.flags = 0 + self.lowerifaces = None + self.upperifaces = None + self.linkstate = None + self.env = None + self.priv_flags = 0 + self.raw_lines = [] + self.flags |= self.PICKLED + def dump_raw(self, logger): indent = ' ' print (self.raw_lines[0]) @@ -331,50 +418,48 @@ class iface(): logger.info(self.get_name() + ' : {') logger.info(indent + 'family: %s' %self.get_addr_family()) logger.info(indent + 'method: %s' %self.get_addr_method()) + logger.info(indent + 'flags: %x' %self.flags) logger.info(indent + 'state: %s' %ifaceState.to_str(self.get_state())) logger.info(indent + 'status: %s' %ifaceStatus.to_str(self.get_status())) logger.info(indent + 'refcnt: %d' %self.get_refcnt()) - d = self.get_dependents() - if d is not None: - logger.info(indent + 'dependents: %s' %str(d)) + d = self.get_lowerifaces() + if d: + logger.info(indent + 'lowerdevs: %s' %str(d)) else: - logger.info(indent + 'dependents: None') - - logger.info(indent + 'realdev dependents: %s' - %str(self.get_realdev_dependents())) + logger.info(indent + 'lowerdevs: None') logger.info(indent + 'config: ') config = self.get_config() - if config is not None: + if config: logger.info(indent + indent + str(config)) logger.info('}') - def dump_pretty(self, logger): + def dump_pretty(self, with_status=False): indent = '\t' outbuf = '' if self.get_auto(): outbuf += 'auto %s\n' %self.get_name() outbuf += 'iface %s' %self.get_name() - if self.get_addr_family() is not None: + if self.get_addr_family(): outbuf += ' %s' %self.get_addr_family() - - if self.get_addr_method() is not None: + if self.get_addr_method(): outbuf += ' %s' %self.get_addr_method() - outbuf += '\n' - config = self.get_config() - if config is not None: + if config: for cname, cvaluelist in config.items(): + idx = 0 for cv in cvaluelist: - outbuf += indent + '%s' %cname + ' %s\n' %cv - - #outbuf += ('%s' %indent + '%s' %self.get_state_str() + - # ' %s' %self.get_status_str()) + if with_status: + outbuf += indent + '%s %s %s\n' %(cname, cv, + self.get_config_attr_status_str(cname, idx)) + else: + outbuf += indent + '%s %s\n' %(cname, cv) + idx += 1 print outbuf - def dump_json(self, logger): - json.dumps(self) + def dump_json(self, with_status=False): + print json.dumps(self, cls=ifaceJsonEncoder, indent=4)