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