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