]>
git.proxmox.com Git - mirror_ifupdown2.git/blob - ifupdown2/ifupdownaddons/modulebase.py
3 # Copyright 2014 Cumulus Networks, Inc. All rights reserved.
4 # Author: Roopa Prabhu, roopa@cumulusnetworks.com
13 from ifupdown
.iface
import *
14 #from ifupdownaddons.iproute2 import *
15 #from ifupdownaddons.dhclient import *
16 #from ifupdownaddons.bridgeutils import *
17 #from ifupdownaddons.mstpctlutil import *
18 #from ifupdownaddons.ifenslaveutil import *
20 class moduleBase(object):
21 """ Base class for ifupdown addon modules
23 Provides common infrastructure methods for all addon modules """
25 def __init__(self
, *args
, **kargs
):
26 modulename
= self
.__class
__.__name
__
27 self
.logger
= logging
.getLogger('ifupdown.' + modulename
)
28 self
.FORCE
= kargs
.get('force', False)
29 """force interface configuration"""
30 self
.DRYRUN
= kargs
.get('dryrun', False)
31 """only predend you are applying configuration, dont really do it"""
32 self
.NOWAIT
= kargs
.get('nowait', False)
33 self
.PERFMODE
= kargs
.get('perfmode', False)
34 self
.CACHE
= kargs
.get('cache', False)
35 self
.CACHE_FLAGS
= kargs
.get('cacheflags', 0x0)
37 def log_warn(self
, str):
38 """ log a warning if err str is not one of which we should ignore """
39 if not self
.ignore_error(str):
40 if self
.logger
.getEffectiveLevel() == logging
.DEBUG
:
41 traceback
.print_stack()
45 def log_error(self
, str):
46 """ log an err if err str is not one of which we should ignore and raise an exception """
47 if not self
.ignore_error(str):
48 if self
.logger
.getEffectiveLevel() == logging
.DEBUG
:
49 traceback
.print_stack()
54 def is_process_running(self
, procName
):
56 self
.exec_command('/bin/pidof -x %s' % procName
)
62 def exec_command(self
, cmd
, cmdenv
=None):
63 """ execute command passed as argument.
66 cmd (str): command to execute
69 cmdenv (dict): environment variable name value pairs
75 self
.logger
.info('Executing ' + cmd
)
78 ch
= subprocess
.Popen(cmd
.split(),
79 stdout
=subprocess
.PIPE
,
80 shell
=False, env
=cmdenv
,
81 stderr
=subprocess
.STDOUT
,
83 cmdout
= ch
.communicate()[0]
84 cmd_returncode
= ch
.wait()
86 raise Exception('could not execute ' + cmd
+
88 if cmd_returncode
!= 0:
89 raise Exception('error executing cmd \'%s\'' %cmd
+
90 '(' + cmdout
.strip('\n ') + ')')
93 def exec_command_talk_stdin(self
, cmd
, stdinbuf
):
94 """ execute command passed as argument and write contents of stdinbuf
98 cmd (str): command to execute
99 stdinbuf (str): string to write to stdin of the cmd process
105 self
.logger
.info('Executing %s (stdin=%s)' %(cmd
, stdinbuf
))
108 ch
= subprocess
.Popen(cmd
.split(),
109 stdout
=subprocess
.PIPE
,
110 stdin
=subprocess
.PIPE
,
111 shell
=False, env
=cmdenv
,
112 stderr
=subprocess
.STDOUT
,
114 cmdout
= ch
.communicate(input=stdinbuf
)[0]
115 cmd_returncode
= ch
.wait()
117 raise Exception('could not execute ' + cmd
+
119 if cmd_returncode
!= 0:
120 raise Exception('error executing cmd \'%s (%s)\''
121 %(cmd
, stdinbuf
) + '(' + cmdout
.strip('\n ') + ')')
124 def get_ifaces_from_proc(self
):
126 with
open('/proc/net/dev') as f
:
128 lines
= f
.readlines()
130 ifacenames
.append(line
.split()[0].strip(': '))
135 def parse_regex(self
, expr
, ifacenames
=None):
137 proc_ifacenames
= self
.get_ifaces_from_proc()
139 self
.logger
.warn('error reading ifaces from proc')
140 for proc_ifacename
in proc_ifacenames
:
141 if re
.search(expr
+ '$', proc_ifacename
):
145 for ifacename
in ifacenames
:
146 if re
.search(expr
+ '$', ifacename
):
149 def parse_glob(self
, expr
):
150 errmsg
= ('error parsing glob expression \'%s\'' %expr
+
151 ' (supported glob syntax: swp1-10 or swp[1-10])')
155 regexs
= [re
.compile(r
"([A-Za-z0-9\-]+[A-Za-z])(\d+)\-(\d+)(.*)"),
156 re
.compile(r
"([A-Za-z0-9\-]+)\[(\d+)\-(\d+)\](.*)")]
163 raise Exception(errmsg
+ '(unexpected len)')
166 start_index
= int(mlist
[1])
167 end_index
= int(mlist
[2])
169 self
.logger
.warn(errmsg
)
171 if not start_index
and not end_index
:
172 self
.logger
.warn(errmsg
)
175 for i
in range(start_index
, end_index
+ 1):
176 yield prefix
+ '%d' %i + suffix
178 def parse_port_list(self
, port_expr
, ifacenames
=None):
179 """ parse port list containing glob and regex
182 port_expr (str): expression
183 ifacenames (list): list of interface names. This needs to be specified if the expression has a regular expression
191 for expr
in re
.split(r
'[\s\t]\s*', port_expr
):
192 if expr
== 'noregex':
194 elif expr
== 'noglob':
196 elif expr
== 'regex':
201 for port
in self
.parse_regex(expr
, ifacenames
):
202 if port
not in portlist
:
203 portlist
.append(port
)
206 for port
in self
.parse_glob(expr
):
207 portlist
.append(port
)
210 portlist
.append(expr
)
215 def ignore_error(self
, errmsg
):
216 if (self
.FORCE
or re
.search(r
'exists', errmsg
,
217 re
.IGNORECASE | re
.MULTILINE
)):
221 def write_file(self
, filename
, strexpr
):
222 """ writes string to a file """
224 self
.logger
.info('writing \'%s\'' %strexpr
+
225 ' to file %s' %filename
)
228 with
open(filename
, 'w') as f
:
231 self
.logger
.warn('error writing to file %s'
232 %filename
+ '(' + str(e
) + ')')
236 def read_file(self
, filename
):
237 """ read file and return lines from the file """
239 self
.logger
.info('reading \'%s\'' %filename
)
240 with
open(filename
, 'r') as f
:
246 def read_file_oneline(self
, filename
):
247 """ reads and returns first line from the file """
249 self
.logger
.info('reading \'%s\'' %filename
)
250 with
open(filename
, 'r') as f
:
251 return f
.readline().strip('\n')
256 def sysctl_set(self
, variable
, value
):
257 """ set sysctl variable to value passed as argument """
258 self
.exec_command('sysctl %s=' %variable
+ '%s' %value
)
260 def sysctl_get(self
, variable
):
261 """ get value of sysctl variable """
262 return self
.exec_command('sysctl %s' %variable
).split('=')[1].strip()
264 def set_iface_attr(self
, ifaceobj
, attr_name
, attr_valsetfunc
,
265 prehook
=None, prehookargs
=None):
266 ifacename
= ifaceobj
.name
267 attrvalue
= ifaceobj
.get_attr_value_first(attr_name
)
274 attr_valsetfunc(ifacename
, attrvalue
)
276 def query_n_update_ifaceobjcurr_attr(self
, ifaceobj
, ifaceobjcurr
,
277 attr_name
, attr_valgetfunc
,
278 attr_valgetextraarg
=None):
279 attrvalue
= ifaceobj
.get_attr_value_first(attr_name
)
282 if attr_valgetextraarg
:
283 runningattrvalue
= attr_valgetfunc(ifaceobj
.name
,
286 runningattrvalue
= attr_valgetfunc(ifaceobj
.name
)
287 if (not runningattrvalue
or
288 (runningattrvalue
!= attrvalue
)):
289 ifaceobjcurr
.update_config_with_status(attr_name
,
292 ifaceobjcurr
.update_config_with_status(attr_name
,
295 def dict_key_subset(self
, a
, b
):
296 """ returns a list of differing keys """
297 return [x
for x
in a
if x
in b
]
299 def get_mod_attrs(self
):
300 """ returns list of all module attrs defined in the module _modinfo dict"""
302 return self
._modinfo
.get('attrs').keys()
306 def get_mod_attr(self
, attrname
):
307 """ returns module attr info """
309 return self
._modinfo
.get('attrs', {}).get(attrname
)
313 def get_mod_subattr(self
, attrname
, subattrname
):
314 """ returns module attrs defined in the module _modinfo dict"""
316 return reduce(lambda d
, k
: d
[k
], ['attrs', attrname
, subattrname
],
321 def get_modinfo(self
):
322 """ return module info """
329 return dict(force
=self
.FORCE
, dryrun
=self
.DRYRUN
, nowait
=self
.NOWAIT
,
330 perfmode
=self
.PERFMODE
, cache
=self
.CACHE
,
331 cacheflags
=self
.CACHE_FLAGS
)
333 def _get_reserved_vlan_range(self
):
335 get_resvvlan
= '/usr/share/python-ifupdown2/get_reserved_vlan_range.sh'
336 if not os
.path
.exists(get_resvvlan
):
339 (s
, e
) = self
.exec_command(get_resvvlan
).strip('\n').split('-')
343 self
.logger
.debug('%s failed (%s)' %(get_resvvlan
, str(e
)))
348 def _handle_reserved_vlan(self
, vlanid
, logprefix
=''):
349 """ Helper function to check and warn if the vlanid falls in the
350 reserved vlan range """
351 if vlanid
in range(self
._resv
_vlan
_range
[0],
352 self
._resv
_vlan
_range
[1]):
353 self
.logger
.error('%s: reserved vlan %d being used'
354 %(logprefix
, vlanid
) + ' (reserved vlan range %d-%d)'
355 %(self
._resv
_vlan
_range
[0], self
._resv
_vlan
_range
[1]))
359 def _valid_ethaddr(self
, ethaddr
):
360 """ Check if address is 00:00:00:00:00:00 """
361 if not ethaddr
or re
.match('00:00:00:00:00:00', ethaddr
):