mirror of
https://github.com/CumulusNetworks/ifupdown2.git
synced 2024-05-06 15:54:50 +00:00
267 lines
8.3 KiB
Python
267 lines
8.3 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# Copyright 2013. Cumulus Networks, Inc.
|
|
# Author: Roopa Prabhu, roopa@cumulusnetworks.com
|
|
#
|
|
# stateManager --
|
|
# interface state manager
|
|
#
|
|
import cPickle
|
|
from collections import OrderedDict
|
|
from exceptions import *
|
|
import logging
|
|
import pprint
|
|
import os
|
|
from iface import *
|
|
|
|
class pickling():
|
|
|
|
@classmethod
|
|
def save(cls, filename, list_of_objects):
|
|
try:
|
|
with open(filename, 'w') as f:
|
|
for obj in list_of_objects:
|
|
cPickle.dump(obj, f)
|
|
except:
|
|
raise
|
|
|
|
@classmethod
|
|
def save_obj(cls, f, obj):
|
|
try:
|
|
cPickle.dump(obj, f)
|
|
except:
|
|
raise
|
|
|
|
|
|
@classmethod
|
|
def load(cls, filename):
|
|
with open(filename, 'r') as f:
|
|
while True:
|
|
try: yield cPickle.load(f)
|
|
except EOFError: break
|
|
except: raise
|
|
|
|
|
|
|
|
class stateManager():
|
|
|
|
state_file = '/run/network/ifstatenew'
|
|
|
|
|
|
def __init__(self):
|
|
self.ifaceobjdict = OrderedDict()
|
|
self.logger = logging.getLogger('ifupdown.' +
|
|
self.__class__.__name__)
|
|
|
|
def save_ifaceobj(self, ifaceobj):
|
|
if self.ifaceobjdict.get(ifaceobj.get_name()) is None:
|
|
self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
|
|
else:
|
|
self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
|
|
|
|
def read_saved_state(self, filename=None):
|
|
pickle_filename = filename
|
|
if pickle_filename == None:
|
|
pickle_filename = self.state_file
|
|
|
|
if not os.path.exists(pickle_filename):
|
|
return
|
|
|
|
# Read all ifaces from file
|
|
for ifaceobj in pickling.load(pickle_filename):
|
|
self.save_ifaceobj(ifaceobj)
|
|
#ifaceobj.set_refcnt(0)
|
|
#ifaceobj.set_dependents(None)
|
|
|
|
return 0
|
|
|
|
def get_ifaceobjdict(self):
|
|
return self.ifaceobjdict
|
|
|
|
def save_state(self, ifaceobjs, filename=None):
|
|
pickle_filename = filename
|
|
if pickle_filename == None:
|
|
pickle_filename = self.state_file
|
|
|
|
pickling.save(pickle_filename, ifaceobjs)
|
|
|
|
|
|
def compare_iface_state(ifaceobj1, ifaceobj2):
|
|
ifaceobj1_state = ifaceobj1.get_state()
|
|
ifaceobj2_state = ifaceobj2.get_state()
|
|
|
|
if ifaceobj1_state < ifaceobj2_state:
|
|
return -1
|
|
elif ifaceobj1_state > ifaceobj2_state:
|
|
return 1
|
|
elif ifaceobj1_state == ifaceobj2_state:
|
|
return 0
|
|
|
|
def compare_iface_with_old(self, ifaceobj):
|
|
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
|
|
if old_ifaceobj == None:
|
|
raise ifacenotfound(ifaceobj.get_name())
|
|
|
|
if ifaceobj.get_addr_family() != old_ifaceobj.get_addr_family():
|
|
return -1
|
|
|
|
if ifaceobj.get_method() != old_ifaceobj.get_method():
|
|
return -1
|
|
|
|
# compare config items
|
|
unmatched_item = set(ifaceobj.items()) ^ set(old_ifaceobj.items())
|
|
if len(unmatched_item) != 0:
|
|
return -1
|
|
|
|
return 0
|
|
|
|
def get_iface_state_old(self, ifaceobj):
|
|
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
|
|
if old_ifaceobj == None:
|
|
raise ifacenotfound(ifaceobj.get_name())
|
|
|
|
return old_ifaceobj.get_state()
|
|
|
|
def get_iface_status_old(self, ifaceobj):
|
|
old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
|
|
if old_ifaceobj == None:
|
|
raise ifacenotfound(ifaceobj.get_name())
|
|
|
|
return old_ifaceobj.get_status()
|
|
|
|
def cmp_old_new_state(self, ifacename, operation):
|
|
""" compares current operation with old state """
|
|
|
|
state_arg = ifaceState.from_str(operation)
|
|
if state_arg == ifaceState.UP:
|
|
old_ifaceobj = self.ifaceobjdict.get(ifacename)
|
|
if old_ifaceobj != None:
|
|
# found old state for iface
|
|
# Check its state
|
|
if (old_ifaceobj.get_state() == state_arg and
|
|
old_ifaceobj.get_status() == ifaceStatus.SUCCESS):
|
|
self.statemsg = 'iface already up'
|
|
return 0
|
|
elif state_arg == ifaceState.DOWN:
|
|
old_ifaceobj = self.ifaceobjdict.get(ifname)
|
|
if old_ifaceobj != None:
|
|
# found old state for iface
|
|
# Check its state
|
|
if (old_ifaceobj.get_state() == state_arg and
|
|
old_ifaceobj.get_status() == ifaceStatus.SUCCESS):
|
|
self.statemsg = 'iface already down'
|
|
return 0
|
|
|
|
return 1
|
|
|
|
def iface_obj_compare(self, ifaceobj_a, ifaceobj_b):
|
|
if ifaceobj_a.get_name() != ifaceobj_b.get_name():
|
|
return False
|
|
|
|
if (ifaceobj_a.get_addr_family() is None and
|
|
ifaceobj_b.get_addr_family() is not None):
|
|
return False
|
|
|
|
if (ifaceobj_a.get_addr_family() is not None and
|
|
ifaceobj_b.get_addr_family() is None):
|
|
return False
|
|
|
|
if (ifaceobj_a.get_addr_family() is None and
|
|
ifaceobj_b.get_addr_family() is None):
|
|
return True
|
|
|
|
if ifaceobj_a.get_addr_family() != ifaceobj_b.get_addr_family():
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
def update_iface_state(self, ifaceobj):
|
|
old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
|
|
if old_ifaceobjs is None:
|
|
self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
|
|
else:
|
|
for oi in old_ifaceobjs:
|
|
if self.iface_obj_compare(ifaceobj, oi) == True:
|
|
oi.set_state(ifaceobj.get_state())
|
|
oi.set_status(ifaceobj.get_status())
|
|
return
|
|
|
|
self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
|
|
|
|
def flush_state(self, ifaceobjdict=None):
|
|
if ifaceobjdict is None:
|
|
ifaceobjdict = self.ifaceobjdict
|
|
|
|
try:
|
|
with open(self.state_file, 'w') as f:
|
|
for ifaceobjs in ifaceobjdict.values():
|
|
for i in ifaceobjs:
|
|
pickling.save_obj(f, i)
|
|
except:
|
|
raise
|
|
|
|
|
|
def is_valid_state_transition(self, ifaceobj, tobe_state):
|
|
if self.ifaceobjdict is None:
|
|
return True
|
|
|
|
if tobe_state == 'up':
|
|
max_tobe_state = ifaceState.POST_UP
|
|
elif tobe_state == 'down':
|
|
max_tobe_state = ifaceState.POST_DOWN
|
|
else:
|
|
return True
|
|
|
|
old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
|
|
if old_ifaceobjs is not None:
|
|
for oi in old_ifaceobjs:
|
|
if self.iface_obj_compare(ifaceobj, oi) == True:
|
|
if (oi.get_state() == max_tobe_state and
|
|
oi.get_status() == ifaceStatus.SUCCESS):
|
|
# if old state is greater than or equal to
|
|
# tobe_state
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
return True
|
|
else:
|
|
return True
|
|
|
|
def print_state(self, ifaceobj, prefix, indent):
|
|
print (indent + '%s' %prefix +
|
|
'%s' %ifaceobj.get_state_str() +
|
|
', %s' %ifaceobj.get_status_str())
|
|
|
|
def print_state_pretty(self, ifacenames, logger):
|
|
for ifacename in ifacenames:
|
|
old_ifaceobjs = self.ifaceobjdict.get(ifacename)
|
|
if old_ifaceobjs is not None:
|
|
firstifaceobj = old_ifaceobjs[0]
|
|
self.print_state(firstifaceobj,
|
|
'%s: ' %firstifaceobj.get_name(), '')
|
|
|
|
def print_state_detailed_pretty(self, ifacenames, logger):
|
|
indent = '\t'
|
|
for ifacename in ifacenames:
|
|
old_ifaceobjs = self.ifaceobjdict.get(ifacename)
|
|
if old_ifaceobjs is not None:
|
|
for i in old_ifaceobjs:
|
|
i.dump_pretty(logger)
|
|
self.print_state(i, '', indent)
|
|
print '\n'
|
|
|
|
def dump(self, ifacenames=None):
|
|
print 'iface state:'
|
|
if ifacenames is not None and len(ifacenames) > 0:
|
|
for i in ifacenames:
|
|
ifaceobj = self.ifaces.get(i)
|
|
if ifaceobj is None:
|
|
raise ifaceNotFoundError('ifname %s'
|
|
%i + ' not found')
|
|
ifaceobj.dump(self.logger)
|
|
else:
|
|
for ifacename, ifaceobj in self.ifaceobjdict.items():
|
|
ifaceobj.dump(self.logger)
|