]> git.proxmox.com Git - mirror_ifupdown2.git/blame - pkg/statemanager.py
Doc updates + cleanup
[mirror_ifupdown2.git] / pkg / statemanager.py
CommitLineData
a6f80f0e 1#!/usr/bin/python
3e8ee54f 2#
3# Copyright 2013. Cumulus Networks, Inc.
4# Author: Roopa Prabhu, roopa@cumulusnetworks.com
5#
6# stateManager --
7# interface state manager
8#
a6f80f0e 9import cPickle
10from collections import OrderedDict
a6f80f0e 11import logging
a6f80f0e 12import os
13from iface import *
14
15class pickling():
53b00224 16 """ class with helper methods for pickling/unpickling iface objects """
a6f80f0e 17
18 @classmethod
19 def save(cls, filename, list_of_objects):
2c0ad8b3 20 """ pickle a list of iface objects """
a6f80f0e 21 try:
22 with open(filename, 'w') as f:
23 for obj in list_of_objects:
5c721925 24 cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
a6f80f0e 25 except:
26 raise
27
28 @classmethod
29 def save_obj(cls, f, obj):
2c0ad8b3 30 """ pickle iface object """
a6f80f0e 31 try:
5c721925 32 cPickle.dump(obj, f, cPickle.HIGHEST_PROTOCOL)
a6f80f0e 33 except:
34 raise
35
a6f80f0e 36 @classmethod
37 def load(cls, filename):
2c0ad8b3 38 """ load picked iface object """
a6f80f0e 39 with open(filename, 'r') as f:
40 while True:
41 try: yield cPickle.load(f)
42 except EOFError: break
43 except: raise
44
a6f80f0e 45class stateManager():
2c0ad8b3
RP
46 """ state manager for managing ifupdown iface obj state
47
48 ifupdown2 has to maitain old objects for down operation on
49 interfaces. ie to down or delete old configuration.
50
51 This class uses pickle to store iface objects.
52
53 """
a6f80f0e 54
a690dfae 55 state_dir = '/var/tmp/network/'
2c0ad8b3
RP
56 """directory where the state file is stored """
57
a690dfae 58 state_filename = 'ifstatenew'
2c0ad8b3 59 """name of the satefile """
a6f80f0e 60
61 def __init__(self):
2c0ad8b3
RP
62 """ Initializes statemanager internal state
63
64 which includes a dictionary of last pickled iface objects
65 """
a6f80f0e 66 self.ifaceobjdict = OrderedDict()
67 self.logger = logging.getLogger('ifupdown.' +
68 self.__class__.__name__)
a690dfae 69 if not os.path.exists(self.state_dir):
70 os.mkdir(self.state_dir)
71 self.state_file = self.state_dir + self.state_filename
a6f80f0e 72
73 def save_ifaceobj(self, ifaceobj):
62ddec8b 74 self.ifaceobjdict.setdefault(ifaceobj.name,
5c721925 75 []).append(ifaceobj)
a6f80f0e 76
77 def read_saved_state(self, filename=None):
2c0ad8b3
RP
78 """This member function reads saved iface objects
79
80 Kwargs:
81 filename (str): name of the state file
82 """
83
a6f80f0e 84 pickle_filename = filename
fe0a57d3 85 if not pickle_filename:
a6f80f0e 86 pickle_filename = self.state_file
a6f80f0e 87 if not os.path.exists(pickle_filename):
88 return
a6f80f0e 89 for ifaceobj in pickling.load(pickle_filename):
90 self.save_ifaceobj(ifaceobj)
a6f80f0e 91
5c721925 92 def get_ifaceobjs(self, ifacename):
93 return self.ifaceobjdict.get(ifacename)
94
cb7cc592 95 def ifaceobj_sync(self, ifaceobj, op):
2c0ad8b3
RP
96 """This member function sync's new obj state to old statemanager state
97
98 Args:
99 ifaceobj (object): new iface object
100 op (str): ifupdown operation
101 """
102
53b00224 103 self.logger.debug('%s: statemanager sync state' %ifaceobj.name)
104 old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.name)
cb7cc592 105 if 'up' in op:
106 if not old_ifaceobjs:
53b00224 107 self.ifaceobjdict[ifaceobj.name] = [ifaceobj]
31a5f4c3 108 else:
cb7cc592 109 # If it matches any of the object, return
110 if any(o.compare(ifaceobj) for o in old_ifaceobjs):
111 return
112 # If it does not match any of the objects, and if
113 # all objs in the list came from the pickled file,
114 # then reset the list and add this object as a fresh one,
115 # else append to the list
116 if old_ifaceobjs[0].flags & iface._PICKLED:
117 del self.ifaceobjdict[ifaceobj.name]
118 self.ifaceobjdict[ifaceobj.name] = [ifaceobj]
119 else:
120 self.ifaceobjdict[ifaceobj.name].append(ifaceobj)
121 elif 'down' in op:
122 # If down of object successfull, delete object from state manager
123 if not old_ifaceobjs:
124 return
125 if ifaceobj.status != ifaceStatus.SUCCESS:
126 return
127 # If it matches any of the object, return
128 oidx = 0
129 for o in old_ifaceobjs:
130 if o.compare(ifaceobj):
131 old_ifaceobjs.pop(oidx)
132 if not len(old_ifaceobjs):
133 del self.ifaceobjdict[ifaceobj.name]
134 return
135 oidx += 1
a6f80f0e 136
31a5f4c3 137 def save_state(self):
2c0ad8b3
RP
138 """ saves state (ifaceobjects) to persistent state file """
139
a6f80f0e 140 try:
141 with open(self.state_file, 'w') as f:
cb7cc592 142 if not len(self.ifaceobjdict):
525f0a30 143 f.truncate(0)
cb7cc592 144 return
525f0a30 145 self.logger.debug('saving state ..')
31a5f4c3 146 for ifaceobjs in self.ifaceobjdict.values():
53b00224 147 [pickling.save_obj(f, i) for i in ifaceobjs]
a6f80f0e 148 except:
149 raise
150
5c721925 151 def dump_pretty(self, ifacenames, format='native'):
152 if not ifacenames:
153 ifacenames = self.ifaceobjdict.keys()
154 for i in ifacenames:
155 ifaceobjs = self.get_ifaceobjs(i)
156 if not ifaceobjs:
157 continue
158 for ifaceobj in ifaceobjs:
159 if format == 'json':
160 ifaceobj.dump_json()
161 else:
162 ifaceobj.dump_pretty()
a6f80f0e 163
164 def dump(self, ifacenames=None):
31a5f4c3 165 self.logger.debug('statemanager iface state:')
fe0a57d3 166 if ifacenames:
a6f80f0e 167 for i in ifacenames:
168 ifaceobj = self.ifaces.get(i)
169 if ifaceobj is None:
170 raise ifaceNotFoundError('ifname %s'
171 %i + ' not found')
172 ifaceobj.dump(self.logger)
173 else:
31a5f4c3 174 for ifacename, ifaceobjs in self.ifaceobjdict.items():
175 [i.dump(self.logger) for i in ifaceobjs]