]>
Commit | Line | Data |
---|---|---|
d486dd0d JF |
1 | #!/usr/bin/python |
2 | # | |
3 | # Copyright 2014-2017 Cumulus Networks, Inc. All rights reserved. | |
4 | # Authors: | |
5 | # Roopa Prabhu, roopa@cumulusnetworks.com | |
6 | # Julien Fortin, julien@cumulusnetworks.com | |
7 | # ifupdown2 -- | |
8 | # tool to configure network interfaces | |
9 | # | |
10 | ||
11 | import os | |
12 | import sys | |
13 | import signal | |
14 | import StringIO | |
15 | import ConfigParser | |
16 | ||
17 | try: | |
18 | from ifupdown2.ifupdown.log import log | |
19 | from ifupdown2.ifupdown.argv import Parse | |
20 | from ifupdown2.ifupdown.config import IFUPDOWN2_CONF_PATH | |
21 | from ifupdown2.ifupdown.ifupdownmain import ifupdownMain | |
22 | except ImportError: | |
23 | from ifupdown.log import log | |
24 | from ifupdown.argv import Parse | |
25 | from ifupdown.config import IFUPDOWN2_CONF_PATH | |
26 | from ifupdown.ifupdownmain import ifupdownMain | |
27 | ||
28 | ||
29 | _SIGINT = signal.getsignal(signal.SIGINT) | |
30 | _SIGTERM = signal.getsignal(signal.SIGTERM) | |
31 | _SIGQUIT = signal.getsignal(signal.SIGQUIT) | |
32 | ||
33 | configmap_g = None | |
34 | ||
35 | ||
36 | class Ifupdown2: | |
37 | def __init__(self, daemon, uid): | |
38 | self.daemon = daemon | |
39 | self.uid = uid | |
40 | self.args = None | |
41 | self.op = None | |
42 | ||
43 | self.interfaces_filename = None | |
44 | self.interfaces_file_iobuf = None | |
45 | ||
46 | self.handlers = { | |
47 | 'up': self.run_up, | |
48 | 'down': self.run_down, | |
49 | 'query': self.run_query, | |
50 | 'reload': self.run_reload | |
51 | } | |
52 | ||
53 | def parse_argv(self, argv): | |
54 | args_parse = Parse(argv) | |
55 | args_parse.validate() | |
56 | ||
57 | self.args = args_parse.get_args() | |
58 | self.op = args_parse.get_op() | |
59 | ||
60 | def update_logger(self, socket=None): | |
61 | syslog = self.args.syslog if hasattr(self.args, 'syslog') else False | |
62 | log.update_current_logger(syslog=syslog, | |
63 | verbose=self.args.verbose, | |
64 | debug=self.args.debug) | |
65 | if socket: | |
66 | log.set_socket(socket) | |
67 | ||
68 | def main(self, stdin_buffer=None): | |
69 | if self.op != 'query' and self.uid != 0: | |
70 | raise Exception('must be root to run this command') | |
71 | ||
72 | try: | |
73 | self.read_config() | |
74 | self.init(stdin_buffer) | |
75 | self.handlers.get(self.op)(self.args) | |
76 | except Exception, e: | |
77 | if not str(e): | |
78 | return 1 | |
79 | # if args and args.debug: | |
80 | raise | |
81 | # else: | |
82 | if log: | |
83 | log.error(str(e)) | |
84 | else: | |
85 | print str(e) | |
86 | # if args and not args.debug: | |
87 | # print '\nrerun the command with \'-d\' for a detailed errormsg' | |
88 | return 1 | |
89 | return 0 | |
90 | ||
91 | def init(self, stdin_buffer): | |
92 | if hasattr(self.args, 'interfacesfile') and self.args.interfacesfile != None: | |
93 | # Check to see if -i option is allowed by config file | |
94 | # But for ifquery, we will not check this | |
95 | if (not self.op == 'query' and | |
96 | configmap_g.get('disable_cli_interfacesfile', '0') == '1'): | |
97 | log.error('disable_cli_interfacesfile is set so users ' | |
98 | 'not allowed to specify interfaces file on cli.') | |
99 | raise Exception("") | |
100 | if self.args.interfacesfile == '-': | |
101 | # If interfaces file is stdin, read | |
102 | if self.daemon: | |
103 | self.interfaces_file_iobuf = stdin_buffer | |
104 | else: | |
105 | self.interfaces_file_iobuf = sys.stdin.read() | |
106 | else: | |
107 | self.interfaces_filename = self.args.interfacesfile | |
108 | else: | |
109 | # if the ifupdown2 config file does not have it, default to standard | |
110 | self.interfaces_filename = configmap_g.get('default_interfaces_configfile', | |
111 | '/etc/network/interfaces') | |
112 | ||
113 | def read_config(self): | |
114 | global configmap_g | |
115 | ||
116 | with open(IFUPDOWN2_CONF_PATH, 'r') as f: | |
117 | config = f.read() | |
118 | configStr = '[ifupdown2]\n' + config | |
119 | configFP = StringIO.StringIO(configStr) | |
120 | parser = ConfigParser.RawConfigParser() | |
121 | parser.readfp(configFP) | |
122 | configmap_g = dict(parser.items('ifupdown2')) | |
123 | ||
124 | # Preprocess config map | |
125 | configval = configmap_g.get('multiple_vlan_aware_bridge_support', '0') | |
126 | if configval == '0': | |
127 | # if multiple bridges not allowed, set the bridge-vlan-aware | |
128 | # attribute in the 'no_repeats' config, so that the ifupdownmain | |
129 | # module can catch it appropriately | |
130 | configmap_g['no_repeats'] = {'bridge-vlan-aware': 'yes'} | |
131 | ||
132 | configval = configmap_g.get('link_master_slave', '0') | |
133 | if configval == '1': | |
134 | # link_master_slave is only valid when all is set | |
135 | if hasattr(self.args, 'all') and not self.args.all: | |
136 | configmap_g['link_master_slave'] = '0' | |
137 | ||
138 | configval = configmap_g.get('delay_admin_state_change', '0') | |
139 | if configval == '1': | |
140 | # reset link_master_slave if delay_admin_state_change is on | |
141 | configmap_g['link_master_slave'] = '0' | |
142 | ||
143 | def run_up(self, args): | |
144 | log.debug('args = %s' % str(args)) | |
145 | ||
146 | try: | |
147 | iflist = args.iflist | |
148 | if len(args.iflist) == 0: | |
149 | iflist = None | |
150 | log.debug('creating ifupdown object ..') | |
151 | cachearg = (False if (iflist or args.nocache or args.noact) | |
152 | else True) | |
153 | ifupdown_handle = ifupdownMain(daemon=self.daemon, | |
154 | config=configmap_g, | |
155 | force=args.force, | |
156 | withdepends=args.withdepends, | |
157 | perfmode=args.perfmode, | |
158 | dryrun=args.noact, | |
159 | cache=cachearg, | |
160 | addons_enable=not args.noaddons, | |
161 | statemanager_enable=not args.noaddons, | |
162 | interfacesfile=self.interfaces_filename, | |
163 | interfacesfileiobuf=self.interfaces_file_iobuf, | |
164 | interfacesfileformat=args.interfacesfileformat) | |
165 | if args.noaddons: | |
166 | ifupdown_handle.up(['up'], args.all, args.CLASS, iflist, | |
167 | excludepats=args.excludepats, | |
168 | printdependency=args.printdependency, | |
169 | syntaxcheck=args.syntaxcheck, type=args.type, | |
170 | skipupperifaces=args.skipupperifaces) | |
171 | else: | |
172 | ifupdown_handle.up(['pre-up', 'up', 'post-up'], | |
173 | args.all, args.CLASS, iflist, | |
174 | excludepats=args.excludepats, | |
175 | printdependency=args.printdependency, | |
176 | syntaxcheck=args.syntaxcheck, type=args.type, | |
177 | skipupperifaces=args.skipupperifaces) | |
178 | except: | |
179 | raise | |
180 | ||
181 | def run_down(self, args): | |
182 | log.debug('args = %s' % str(args)) | |
183 | ||
184 | try: | |
185 | iflist = args.iflist | |
186 | log.debug('creating ifupdown object ..') | |
187 | ifupdown_handle = ifupdownMain(daemon=self.daemon, | |
188 | config=configmap_g, force=args.force, | |
189 | withdepends=args.withdepends, | |
190 | perfmode=args.perfmode, | |
191 | dryrun=args.noact, | |
192 | addons_enable=not args.noaddons, | |
193 | statemanager_enable=not args.noaddons, | |
194 | interfacesfile=self.interfaces_filename, | |
195 | interfacesfileiobuf=self.interfaces_file_iobuf, | |
196 | interfacesfileformat=args.interfacesfileformat) | |
197 | ||
198 | ifupdown_handle.down(['pre-down', 'down', 'post-down'], | |
199 | args.all, args.CLASS, iflist, | |
200 | excludepats=args.excludepats, | |
201 | printdependency=args.printdependency, | |
202 | usecurrentconfig=args.usecurrentconfig, | |
203 | type=args.type) | |
204 | except: | |
205 | raise | |
206 | ||
207 | def run_query(self, args): | |
208 | log.debug('args = %s' % str(args)) | |
209 | ||
210 | try: | |
211 | iflist = args.iflist | |
212 | if args.checkcurr: | |
213 | qop = 'query-checkcurr' | |
214 | elif args.running: | |
215 | qop = 'query-running' | |
216 | elif args.raw: | |
217 | qop = 'query-raw' | |
218 | elif args.syntaxhelp: | |
219 | qop = 'query-syntax' | |
220 | elif args.printdependency: | |
221 | qop = 'query-dependency' | |
222 | elif args.printsavedstate: | |
223 | qop = 'query-savedstate' | |
224 | else: | |
225 | qop = 'query' | |
226 | cachearg = (False if (iflist or args.nocache or args.syntaxhelp or | |
227 | (qop != 'query-checkcurr' and | |
228 | qop != 'query-running')) else True) | |
229 | if not iflist and qop == 'query-running': | |
230 | iflist = [i for i in os.listdir('/sys/class/net/') | |
231 | if os.path.isdir('/sys/class/net/%s' % i)] | |
232 | log.debug('creating ifupdown object ..') | |
233 | ifupdown_handle = ifupdownMain(daemon=self.daemon, | |
234 | config=configmap_g, | |
235 | withdepends=args.withdepends, | |
236 | perfmode=args.perfmode, | |
237 | cache=cachearg, | |
238 | interfacesfile=self.interfaces_filename, | |
239 | interfacesfileiobuf=self.interfaces_file_iobuf, | |
240 | interfacesfileformat=args.interfacesfileformat, | |
241 | withdefaults=args.withdefaults) | |
242 | # list implies all auto interfaces (this is how ifupdown behaves) | |
243 | if args.list: | |
244 | args.all = True | |
245 | ifupdown_handle.query([qop], args.all, args.list, args.CLASS, iflist, | |
246 | excludepats=args.excludepats, | |
247 | printdependency=args.printdependency, | |
248 | format=args.format, type=args.type) | |
249 | except: | |
250 | raise | |
251 | ||
252 | def run_reload(self, args): | |
253 | log.debug('args = %s' % str(args)) | |
254 | ||
255 | try: | |
256 | log.debug('creating ifupdown object ..') | |
257 | ifupdown_handle = ifupdownMain(daemon=self.daemon, | |
258 | config=configmap_g, | |
259 | interfacesfile=self.interfaces_filename, | |
260 | withdepends=args.withdepends, | |
261 | perfmode=args.perfmode, | |
262 | dryrun=args.noact) | |
263 | ifupdown_handle.reload(['pre-up', 'up', 'post-up'], | |
264 | ['pre-down', 'down', 'post-down'], | |
265 | auto=args.all, allow=args.CLASS, ifacenames=None, | |
266 | excludepats=args.excludepats, | |
267 | usecurrentconfig=args.usecurrentconfig, | |
268 | syntaxcheck=args.syntaxcheck, | |
269 | currentlyup=args.currentlyup) | |
270 | except: | |
271 | raise | |
272 | ||
273 | @staticmethod | |
274 | def set_signal_handlers(): | |
275 | signal.signal(signal.SIGQUIT, _SIGQUIT) | |
276 | signal.signal(signal.SIGTERM, _SIGTERM) | |
277 | signal.signal(signal.SIGINT, _SIGINT) |