]> git.proxmox.com Git - mirror_ifupdown2.git/blob - pkg/statemanager.py
More fixes and cleanup
[mirror_ifupdown2.git] / pkg / statemanager.py
1 #!/usr/bin/python
2 #
3 # Copyright 2013. Cumulus Networks, Inc.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
5 #
6 # stateManager --
7 # interface state manager
8 #
9 import cPickle
10 from collections import OrderedDict
11 from exceptions import *
12 import logging
13 import pprint
14 import os
15 from iface import *
16
17 class pickling():
18
19 @classmethod
20 def save(cls, filename, list_of_objects):
21 try:
22 with open(filename, 'w') as f:
23 for obj in list_of_objects:
24 cPickle.dump(obj, f)
25 except:
26 raise
27
28 @classmethod
29 def save_obj(cls, f, obj):
30 try:
31 cPickle.dump(obj, f)
32 except:
33 raise
34
35
36 @classmethod
37 def load(cls, filename):
38 with open(filename, 'r') as f:
39 while True:
40 try: yield cPickle.load(f)
41 except EOFError: break
42 except: raise
43
44
45
46 class stateManager():
47
48 state_file = '/run/network/ifstatenew'
49
50
51 def __init__(self):
52 self.ifaceobjdict = OrderedDict()
53 self.logger = logging.getLogger('ifupdown.' +
54 self.__class__.__name__)
55
56 def save_ifaceobj(self, ifaceobj):
57 if self.ifaceobjdict.get(ifaceobj.get_name()) is None:
58 self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
59 else:
60 self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
61
62 def read_saved_state(self, filename=None):
63 pickle_filename = filename
64 if pickle_filename == None:
65 pickle_filename = self.state_file
66
67 if not os.path.exists(pickle_filename):
68 return
69
70 # Read all ifaces from file
71 for ifaceobj in pickling.load(pickle_filename):
72 self.save_ifaceobj(ifaceobj)
73 #ifaceobj.set_refcnt(0)
74 #ifaceobj.set_dependents(None)
75
76 return 0
77
78 def get_ifaceobjdict(self):
79 return self.ifaceobjdict
80
81 def save_state(self, ifaceobjs, filename=None):
82 pickle_filename = filename
83 if pickle_filename == None:
84 pickle_filename = self.state_file
85
86 pickling.save(pickle_filename, ifaceobjs)
87
88
89 def compare_iface_state(ifaceobj1, ifaceobj2):
90 ifaceobj1_state = ifaceobj1.get_state()
91 ifaceobj2_state = ifaceobj2.get_state()
92
93 if ifaceobj1_state < ifaceobj2_state:
94 return -1
95 elif ifaceobj1_state > ifaceobj2_state:
96 return 1
97 elif ifaceobj1_state == ifaceobj2_state:
98 return 0
99
100 def compare_iface_with_old(self, ifaceobj):
101 old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
102 if old_ifaceobj == None:
103 raise ifacenotfound(ifaceobj.get_name())
104
105 if ifaceobj.get_addr_family() != old_ifaceobj.get_addr_family():
106 return -1
107
108 if ifaceobj.get_method() != old_ifaceobj.get_method():
109 return -1
110
111 # compare config items
112 unmatched_item = set(ifaceobj.items()) ^ set(old_ifaceobj.items())
113 if len(unmatched_item) != 0:
114 return -1
115
116 return 0
117
118 def get_iface_state_old(self, ifaceobj):
119 old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
120 if old_ifaceobj == None:
121 raise ifacenotfound(ifaceobj.get_name())
122
123 return old_ifaceobj.get_state()
124
125 def get_iface_status_old(self, ifaceobj):
126 old_ifaceobj = self.ifaceobjdict.get(ifaceobj.get_name())
127 if old_ifaceobj == None:
128 raise ifacenotfound(ifaceobj.get_name())
129
130 return old_ifaceobj.get_status()
131
132 def cmp_old_new_state(self, ifacename, operation):
133 """ compares current operation with old state """
134
135 state_arg = ifaceState.from_str(operation)
136 if state_arg == ifaceState.UP:
137 old_ifaceobj = self.ifaceobjdict.get(ifacename)
138 if old_ifaceobj != None:
139 # found old state for iface
140 # Check its state
141 if (old_ifaceobj.get_state() == state_arg and
142 old_ifaceobj.get_status() == ifaceStatus.SUCCESS):
143 self.statemsg = 'iface already up'
144 return 0
145 elif state_arg == ifaceState.DOWN:
146 old_ifaceobj = self.ifaceobjdict.get(ifname)
147 if old_ifaceobj != None:
148 # found old state for iface
149 # Check its state
150 if (old_ifaceobj.get_state() == state_arg and
151 old_ifaceobj.get_status() == ifaceStatus.SUCCESS):
152 self.statemsg = 'iface already down'
153 return 0
154
155 return 1
156
157 def iface_obj_compare(self, ifaceobj_a, ifaceobj_b):
158 if ifaceobj_a.get_name() != ifaceobj_b.get_name():
159 return False
160
161 if (ifaceobj_a.get_addr_family() is None and
162 ifaceobj_b.get_addr_family() is not None):
163 return False
164
165 if (ifaceobj_a.get_addr_family() is not None and
166 ifaceobj_b.get_addr_family() is None):
167 return False
168
169 if (ifaceobj_a.get_addr_family() is None and
170 ifaceobj_b.get_addr_family() is None):
171 return True
172
173 if ifaceobj_a.get_addr_family() != ifaceobj_b.get_addr_family():
174 return False
175
176 return True
177
178
179 def update_iface_state(self, ifaceobj):
180 old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
181 if old_ifaceobjs is None:
182 self.ifaceobjdict[ifaceobj.get_name()] = [ifaceobj]
183 else:
184 for oi in old_ifaceobjs:
185 if self.iface_obj_compare(ifaceobj, oi) == True:
186 oi.set_state(ifaceobj.get_state())
187 oi.set_status(ifaceobj.get_status())
188 return
189
190 self.ifaceobjdict[ifaceobj.get_name()].append(ifaceobj)
191
192 def flush_state(self, ifaceobjdict=None):
193 if ifaceobjdict is None:
194 ifaceobjdict = self.ifaceobjdict
195
196 try:
197 with open(self.state_file, 'w') as f:
198 for ifaceobjs in ifaceobjdict.values():
199 for i in ifaceobjs:
200 pickling.save_obj(f, i)
201 except:
202 raise
203
204
205 def is_valid_state_transition(self, ifaceobj, tobe_state):
206 if self.ifaceobjdict is None:
207 return True
208
209 if tobe_state == 'up':
210 max_tobe_state = ifaceState.POST_UP
211 elif tobe_state == 'down':
212 max_tobe_state = ifaceState.POST_DOWN
213 else:
214 return True
215
216 old_ifaceobjs = self.ifaceobjdict.get(ifaceobj.get_name())
217 if old_ifaceobjs is not None:
218 for oi in old_ifaceobjs:
219 if self.iface_obj_compare(ifaceobj, oi) == True:
220 if (oi.get_state() == max_tobe_state and
221 oi.get_status() == ifaceStatus.SUCCESS):
222 # if old state is greater than or equal to
223 # tobe_state
224 return False
225 else:
226 return True
227
228 return True
229 else:
230 return True
231
232 def print_state(self, ifaceobj, prefix, indent):
233 print (indent + '%s' %prefix +
234 '%s' %ifaceobj.get_state_str() +
235 ', %s' %ifaceobj.get_status_str())
236
237 def print_state_pretty(self, ifacenames, logger):
238 for ifacename in ifacenames:
239 old_ifaceobjs = self.ifaceobjdict.get(ifacename)
240 if old_ifaceobjs is not None:
241 firstifaceobj = old_ifaceobjs[0]
242 self.print_state(firstifaceobj,
243 '%s: ' %firstifaceobj.get_name(), '')
244
245 def print_state_detailed_pretty(self, ifacenames, logger):
246 indent = '\t'
247 for ifacename in ifacenames:
248 old_ifaceobjs = self.ifaceobjdict.get(ifacename)
249 if old_ifaceobjs is not None:
250 for i in old_ifaceobjs:
251 i.dump_pretty(logger)
252 self.print_state(i, '', indent)
253 print '\n'
254
255 def dump(self, ifacenames=None):
256 print 'iface state:'
257 if ifacenames is not None and len(ifacenames) > 0:
258 for i in ifacenames:
259 ifaceobj = self.ifaces.get(i)
260 if ifaceobj is None:
261 raise ifaceNotFoundError('ifname %s'
262 %i + ' not found')
263 ifaceobj.dump(self.logger)
264 else:
265 for ifacename, ifaceobj in self.ifaceobjdict.items():
266 ifaceobj.dump(self.logger)