]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/ifupdown/statemanager.py
3 # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
7 # interface state manager
15 from ifupdown2
.ifupdown
.iface
import *
17 import ifupdown2
.ifupdown
.exceptions
as exceptions
18 import ifupdown2
.ifupdown
.ifupdownconfig
as ifupdownConfig
20 from ifupdown
.iface
import *
22 import ifupdown
.exceptions
as exceptions
23 import ifupdown
.ifupdownconfig
as ifupdownConfig
27 """ class with helper methods for pickling/unpickling iface objects """
30 def save(cls
, filename
, list_of_objects
):
31 """ pickle a list of iface objects """
33 with
open(filename
, 'w') as f
:
34 for obj
in list_of_objects
:
35 cPickle
.dump(obj
, f
, cPickle
.HIGHEST_PROTOCOL
)
40 def save_obj(cls
, f
, obj
):
41 """ pickle iface object """
43 cPickle
.dump(obj
, f
, cPickle
.HIGHEST_PROTOCOL
)
48 def load(cls
, filename
):
49 """ load picked iface object """
50 with
open(filename
, 'r') as f
:
52 try: yield cPickle
.load(f
)
53 except EOFError: break
57 """ state manager for managing ifupdown iface obj state
59 ifupdown2 has to maitain old objects for down operation on
60 interfaces. ie to down or delete old configuration.
62 This class uses pickle to store iface objects.
66 __DEFAULT_STATE_DIR
= "/run/network/"
68 state_filename
= 'ifstatenew'
69 """name of the satefile """
71 state_rundir
= '/run/network/'
72 """name of the state run dir """
74 state_runlockfile
= 'ifstatelock'
75 """name of the state run lock file """
78 """ Initializes statemanager internal state
80 which includes a dictionary of last pickled iface objects
83 self
.state_file
= None
84 self
.ifaceobjdict
= OrderedDict()
85 self
.logger
= logging
.getLogger('ifupdown.' +
86 self
.__class
__.__name
__)
89 self
.state_dir
= ifupdownConfig
.config
.get("state_dir")
92 if not self
.state_dir
:
93 self
.logger
.debug("statemanager: state_dir not defined in config file, using default: %s" % self
.__DEFAULT
_STATE
_DIR
)
94 self
.state_dir
= self
.__DEFAULT
_STATE
_DIR
98 self
._init
_makedirs
_state
_dir
()
99 except Exception as e
:
101 # if the default path was used but still throws an exception...
103 self
.logger
.info("statemanager: %s: using default directory: %s" % (e
, self
.__DEFAULT
_STATE
_DIR
))
104 self
.state_dir
= self
.__DEFAULT
_STATE
_DIR
106 self
._init
_makedirs
_state
_dir
()
107 except Exception as e
:
108 raise Exception("statemanager: unable to create required directory: %s" % str(e
))
110 if not os
.path
.exists(self
.state_rundir
):
111 os
.makedirs(self
.state_rundir
)
113 self
.state_file
= "%s/%s" % (self
.state_dir
, self
.state_filename
)
115 def _init_makedirs_state_dir(self
):
116 if not os
.path
.exists(self
.state_dir
):
117 os
.makedirs(self
.state_dir
)
120 def save_ifaceobj(self
, ifaceobj
):
121 self
.ifaceobjdict
.setdefault(ifaceobj
.name
,
124 def read_saved_state(self
, filename
=None):
125 """This member function reads saved iface objects
128 filename (str): name of the state file
131 pickle_filename
= filename
132 if not pickle_filename
:
133 pickle_filename
= self
.state_file
134 if not os
.path
.exists(pickle_filename
):
136 for ifaceobj
in pickling
.load(pickle_filename
):
137 self
.save_ifaceobj(ifaceobj
)
139 def get_ifaceobjs(self
, ifacename
):
140 return self
.ifaceobjdict
.get(ifacename
)
142 def ifaceobj_sync(self
, ifaceobj
, op
):
143 """This member function sync's new obj state to old statemanager state
146 ifaceobj (object): new iface object
147 op (str): ifupdown operation
150 self
.logger
.debug('%s: statemanager sync state %s'
151 %(ifaceobj
.name
, op
))
152 old_ifaceobjs
= self
.ifaceobjdict
.get(ifaceobj
.name
)
154 if not old_ifaceobjs
:
155 self
.ifaceobjdict
[ifaceobj
.name
] = [ifaceobj
]
157 # If it matches any of the object, return
158 if any(o
.compare(ifaceobj
) for o
in old_ifaceobjs
):
160 # If it does not match any of the objects, and if
161 # all objs in the list came from the pickled file,
162 # then reset the list and add this object as a fresh one,
163 # else append to the list
164 if old_ifaceobjs
[0].flags
& iface
._PICKLED
:
165 del self
.ifaceobjdict
[ifaceobj
.name
]
166 self
.ifaceobjdict
[ifaceobj
.name
] = [ifaceobj
]
168 self
.ifaceobjdict
[ifaceobj
.name
].append(ifaceobj
)
170 # If down of object successfull, delete object from state manager
171 if not old_ifaceobjs
:
173 if ifaceobj
.status
!= ifaceStatus
.SUCCESS
:
175 # If it matches any of the object, return
177 for o
in old_ifaceobjs
:
178 if o
.compare(ifaceobj
):
179 old_ifaceobjs
.pop(oidx
)
180 if not len(old_ifaceobjs
):
181 del self
.ifaceobjdict
[ifaceobj
.name
]
185 def save_state(self
):
186 """ saves state (ifaceobjects) to persistent state file """
189 with
open(self
.state_file
, 'w') as f
:
190 if not len(self
.ifaceobjdict
):
193 self
.logger
.debug('saving state ..')
194 for ifaceobjs
in self
.ifaceobjdict
.values():
195 [pickling
.save_obj(f
, i
) for i
in ifaceobjs
]
196 open('%s/%s' %(self
.state_rundir
, self
.state_runlockfile
), 'w').close()
200 def dump_pretty(self
, ifacenames
, format
='native'):
202 ifacenames
= self
.ifaceobjdict
.keys()
204 ifaceobjs
= self
.get_ifaceobjs(i
)
207 for ifaceobj
in ifaceobjs
:
211 ifaceobj
.dump_pretty()
213 def dump(self
, ifacenames
=None):
214 self
.logger
.debug('statemanager iface state:')
217 ifaceobj
= self
.ifaces
.get(i
)
219 raise exceptions
.ifaceNotFoundError('ifname %s'
221 ifaceobj
.dump(self
.logger
)
223 for ifacename
, ifaceobjs
in self
.ifaceobjdict
.items():
224 [i
.dump(self
.logger
) for i
in ifaceobjs
]
226 statemanager_api
= stateManager()
229 global statemanager_api
230 statemanager_api
= stateManager()