]> git.proxmox.com Git - mirror_ifupdown2.git/blame - sbin/ifupdown
execute 'up' on upper devices if ifup is called with --with-depends
[mirror_ifupdown2.git] / sbin / ifupdown
CommitLineData
a6f80f0e 1#!/usr/bin/python
e6c9d007 2# PYTHON_ARGCOMPLETE_OK
a6f80f0e 3
4import sys
5import os
e6c9d007 6import argcomplete
a6f80f0e 7import argparse
3e8ee54f 8from ifupdown.ifupdownmain import *
a6f80f0e 9
10import logging
11
12lockfile="/run/network/.lock"
13logger = None
14
f802fe3c 15def run_up(args):
a6f80f0e 16 logger.debug('args = %s' %str(args))
17
18 try:
739f665b 19 iflist = args.iflist
20 if len(args.iflist) == 0:
21 iflist = None
a6f80f0e 22 logger.debug('creating ifupdown object ..')
f802fe3c 23 cachearg=(False if (iflist or args.nocache or
d08d5f54 24 args.perfmode or args.noact)
25 else True)
f802fe3c 26 ifupdown_handle = ifupdownMain(force=args.force,
27 withdepends=args.withdepends,
28 perfmode=args.perfmode,
29 njobs=args.jobs,
30 dryrun=args.noact,
20dd6242 31 cache=cachearg,
32 addons_enable=not args.noaddons,
33 statemanager_enable=not args.noaddons)
a6f80f0e 34
20dd6242 35 if args.noaddons:
36 ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
37 excludepats=args.excludepats,
38 printdependency=args.printdependency)
39 else:
40 ifupdown_handle.up(['pre-up', 'up', 'post-up'],
d08d5f54 41 args.all, args.CLASS, iflist,
739f665b 42 excludepats=args.excludepats,
43 printdependency=args.printdependency)
f802fe3c 44 except:
45 raise
739f665b 46
f802fe3c 47def run_down(args):
48 logger.debug('args = %s' %str(args))
49
50 try:
51 iflist = args.iflist
f802fe3c 52 logger.debug('creating ifupdown object ..')
53 cachearg=(False if (iflist or args.nocache or
54 args.perfmode or args.noact)
55 else True)
56 ifupdown_handle = ifupdownMain(force=args.force,
57 withdepends=args.withdepends,
58 perfmode=args.perfmode,
59 njobs=args.jobs,
60 dryrun=args.noact,
20dd6242 61 cache=cachearg,
62 addons_enable=not args.noaddons,
63 statemanager_enable=not args.noaddons)
f802fe3c 64
65 ifupdown_handle.down(['pre-down', 'down', 'post-down'],
66 args.all, args.CLASS, iflist,
67 excludepats=args.excludepats,
5c721925 68 printdependency=args.printdependency,
69 usecurrentconfig=args.usecurrentconfig)
f802fe3c 70 except:
71 raise
72
73def run_query(args):
74 logger.debug('args = %s' %str(args))
75
76 try:
77 iflist = args.iflist
f802fe3c 78 if args.checkcurr:
79 qop='query-checkcurr'
80 elif args.running:
f802fe3c 81 qop='query-running'
82 elif args.raw:
83 qop='query-raw'
84 elif args.syntaxhelp:
85 qop = 'query-syntax'
86 elif args.printdependency:
87 qop = 'query-dependency'
5c721925 88 elif args.printsavedstate:
89 qop = 'query-savedstate'
f802fe3c 90 else:
91 qop='query'
83c1f241 92 cachearg=(False if (iflist or args.nocache or
93 args.perfmode or args.syntaxhelp or
94 (qop != 'query-checkcurr' and
95 qop != 'query-running')) else True)
c798b0f4 96 if not iflist and qop == 'query-running':
97 iflist = [i for i in os.listdir('/sys/class/net/')
98 if os.path.isdir('/sys/class/net/%s' %i)]
83c1f241 99 logger.debug('creating ifupdown object ..')
100 ifupdown_handle = ifupdownMain(withdepends=args.withdepends,
101 perfmode=args.perfmode,
102 njobs=args.jobs,
103 cache=cachearg)
104
f802fe3c 105 ifupdown_handle.query([qop], args.all, args.CLASS, iflist,
106 excludepats=args.excludepats,
107 printdependency=args.printdependency,
108 format=args.format)
109 except:
110 raise
111
f802fe3c 112def run_reload(args):
113 logger.debug('args = %s' %str(args))
114
115 try:
116 logger.debug('creating ifupdown object ..')
117 cachearg=(False if (args.nocache or
118 args.perfmode or args.noact) else True)
119 ifupdown_handle = ifupdownMain(withdepends=args.withdepends,
120 perfmode=args.perfmode,
121 njobs=args.jobs,
122 cache=cachearg)
20dd6242 123 ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
124 ['pre-down', 'down', 'post-down'],
125 args.all, None, None,
f802fe3c 126 excludepats=args.excludepats,
127 downchangediface=args.downchangediface)
a6f80f0e 128 except:
129 raise
130
a6f80f0e 131def init(args):
132 global logger
133
134 log_level = logging.WARNING
fe0a57d3 135 if args.verbose:
a6f80f0e 136 log_level = logging.INFO
fe0a57d3 137 if args.debug:
a6f80f0e 138 log_level = logging.DEBUG
139
140 try:
141 logging.basicConfig(level=log_level,
eab25b7c 142 format='%(levelname)s: %(message)s')
a6f80f0e 143 logger = logging.getLogger('ifupdown')
144 except:
145 raise
146
147
148def deinit():
eab25b7c 149 {}
a6f80f0e 150
151def update_argparser(argparser):
cca03c30 152 """ base parser, common to all commands """
37c0543d 153
154 argparser.add_argument('-a', '--all', action='store_true', required=False,
cca03c30 155 help='process all interfaces marked \"auto\"')
a6f80f0e 156 argparser.add_argument('iflist', metavar='IFACE',
f802fe3c 157 nargs='*', help='interface list separated by spaces. ' +
158 'IFACE list is mutually exclusive with -a option.')
a6f80f0e 159 argparser.add_argument('-v', '--verbose', dest='verbose',
160 action='store_true', help='verbose')
161 argparser.add_argument('-d', '--debug', dest='debug',
162 action='store_true',
163 help='output debug info')
164 argparser.add_argument('-q', '--quiet', dest='quiet',
165 action='store_true',
166 help=argparse.SUPPRESS)
eab25b7c 167 argparser.add_argument('--allow', dest='CLASS',
168 help='ignore non-\"allow-CLASS\" interfaces')
cca03c30 169 argparser.add_argument('--with-depends', dest='withdepends',
f802fe3c 170 action='store_true', help='run with all dependent interfaces.'+
171 ' This option is redundant when \'-a\' is specified. With ' +
172 '\'-a\' interfaces are always executed in dependency order')
3e8ee54f 173 argparser.add_argument('--perfmode', dest='perfmode',
eab25b7c 174 action='store_true', help=argparse.SUPPRESS)
3e8ee54f 175 argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
176 default=-1, choices=range(1,12), help=argparse.SUPPRESS)
739f665b 177 argparser.add_argument('--nocache', dest='nocache', action='store_true',
178 help=argparse.SUPPRESS)
3e8ee54f 179 argparser.add_argument('-X', '--exclude', dest='excludepats',
37c0543d 180 action='append',
181 help='Exclude interfaces from the list of interfaces' +
f802fe3c 182 ' to operate on. Can be specified multiple times.')
a6f80f0e 183
184def update_ifupdown_argparser(argparser):
cca03c30 185 """ common arg parser for ifup and ifdown """
a6f80f0e 186 argparser.add_argument('-f', '--force', dest='force',
187 action='store_true',
188 help='force run all operations')
5c721925 189 group = argparser.add_mutually_exclusive_group(required=False)
190 group.add_argument('-n', '--no-act', dest='noact',
3e8ee54f 191 action='store_true', help='print out what would happen,' +
192 'but don\'t do it')
5c721925 193 group.add_argument('--print-dependency',
cca03c30 194 dest='printdependency', choices=['list', 'dot'],
195 help='print iface dependency')
5c721925 196 group.add_argument('--no-scripts', '--no-addons',
20dd6242 197 dest='noaddons', action='store_true',
198 help='dont run any addon modules or scripts. Runs only link ' +
199 'up/down')
a6f80f0e 200
201def update_ifup_argparser(argparser):
202 update_ifupdown_argparser(argparser)
203
204def update_ifdown_argparser(argparser):
205 update_ifupdown_argparser(argparser)
5c721925 206 argparser.add_argument('--use-current-config',
207 dest='usecurrentconfig', action='store_true',
208 help=argparse.SUPPRESS)
209 #help='By default ifdown looks at the saved state for ' +
210 #'interfaces to bring down. This option allows ifdown to ' +
211 #'look at the current interfaces file. Useful when your ' +
212 #'state file is corrupted or you want down to use the latest '
213 #'from the interfaces file')
a6f80f0e 214
215def update_ifquery_argparser(argparser):
cca03c30 216 """ arg parser for ifquery options """
217
37c0543d 218 # -l is same as '-a', only here for backward compatibility
3e8ee54f 219 argparser.add_argument('-l', '--list', action='store_true', dest='all',
cca03c30 220 help=argparse.SUPPRESS)
a6f80f0e 221 group = argparser.add_mutually_exclusive_group(required=False)
360d5f8e 222 group.add_argument('-r', '--running', dest='running',
eab25b7c 223 action='store_true',
224 help='query running state of an interface')
360d5f8e 225 group.add_argument('-c', '--check', dest='checkcurr',
739f665b 226 action='store_true',
360d5f8e 227 help='check interface file contents against ' +
228 'running state of an interface')
d08d5f54 229 group.add_argument('--raw', action='store_true', dest='raw',
230 help='print raw config file entries')
5c721925 231 group.add_argument('--print-savedstate', action='store_true',
232 dest='printsavedstate',
233 help=argparse.SUPPRESS)
d08d5f54 234 argparser.add_argument('--format', dest='format', default='native',
235 choices=['native', 'json'], help=argparse.SUPPRESS)
37c0543d 236 argparser.add_argument('--print-dependency',
d08d5f54 237 dest='printdependency', choices=['list', 'dot'],
238 help='print interface dependency')
239 argparser.add_argument('--syntax-help', action='store_true',
240 dest='syntaxhelp',
241 help='print supported interface config syntax')
37c0543d 242
739f665b 243def update_ifreload_argparser(argparser):
f802fe3c 244 """ parser for ifreload """
245 argparser.add_argument('-a', '--all', action='store_true', required=True,
246 help='process all interfaces marked \"auto\"')
247 argparser.add_argument('iflist', metavar='IFACE',
248 nargs='*', help=argparse.SUPPRESS)
249 argparser.add_argument('-n', '--no-act', dest='noact',
250 action='store_true', help=argparse.SUPPRESS)
251 argparser.add_argument('-v', '--verbose', dest='verbose',
252 action='store_true', help='verbose')
253 argparser.add_argument('-d', '--debug', dest='debug',
37c0543d 254 action='store_true',
f802fe3c 255 help='output debug info')
256 argparser.add_argument('--with-depends', dest='withdepends',
257 action='store_true', help=argparse.SUPPRESS)
258 argparser.add_argument('--perfmode', dest='perfmode',
259 action='store_true', help=argparse.SUPPRESS)
260 argparser.add_argument('--nocache', dest='nocache', action='store_true',
261 help=argparse.SUPPRESS)
262 argparser.add_argument('-X', '--exclude', dest='excludepats',
263 action='append',
264 help=argparse.SUPPRESS)
265 argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
266 default=-1, choices=range(1,12), help=argparse.SUPPRESS)
267 argparser.add_argument('--down-changediface', dest='downchangediface',
268 action='store_true', help='down interfaces whose ' +
269 'config have changed before bringing them up. By' +
270 ' default all interfaces are brought up')
37c0543d 271
a6f80f0e 272def parse_args(argsv, op):
cca03c30 273 if op == 'query':
37c0543d 274 descr = 'query interfaces (all or interface list)'
cca03c30 275 else:
276 descr = 'interface management'
a6f80f0e 277 argparser = argparse.ArgumentParser(description=descr)
f802fe3c 278 if op == 'reload':
739f665b 279 update_ifreload_argparser(argparser)
f802fe3c 280 else:
281 update_argparser(argparser)
282 if op == 'up':
283 update_ifup_argparser(argparser)
284 elif op == 'down':
285 update_ifdown_argparser(argparser)
286 elif op == 'query':
287 update_ifquery_argparser(argparser)
288 elif op == 'reload':
289 update_ifreload_argparser(argparser)
e6c9d007 290
291 argcomplete.autocomplete(argparser)
292
a6f80f0e 293 return argparser.parse_args(argsv)
294
f802fe3c 295handlers = {'up' : run_up,
296 'down' : run_down,
297 'query' : run_query,
298 'reload' : run_reload }
299
a6f80f0e 300def main(argv):
301 """ main function """
f802fe3c 302 args = None
a6f80f0e 303 try:
304 op = None
fe0a57d3 305 if argv[0].endswith('ifup'):
a6f80f0e 306 op = 'up'
fe0a57d3 307 elif argv[0].endswith('ifdown'):
a6f80f0e 308 op = 'down'
fe0a57d3 309 elif argv[0].endswith('ifquery'):
a6f80f0e 310 op = 'query'
fe0a57d3 311 elif argv[0].endswith('ifreload'):
739f665b 312 op = 'reload'
a6f80f0e 313 else:
314 print ('Unexpected executable.' +
315 ' Should be \'ifup\' or \'ifdown\' or \'ifquery\'')
316 exit(1)
a6f80f0e 317 # Command line arg parser
318 args = parse_args(argv[1:], op)
fe0a57d3 319 if not args.iflist and not args.all:
f802fe3c 320 if op != 'query' or not args.syntaxhelp:
321 print '\'-a\' option or interface list are required'
322 exit(1)
323
fe0a57d3 324 if args.iflist and args.all:
37c0543d 325 print '\'-a\' option and interface list are mutually exclusive'
a6f80f0e 326 exit(1)
a6f80f0e 327 init(args)
f802fe3c 328 handlers.get(op)(args)
a6f80f0e 329 except Exception, e:
fe0a57d3 330 if not str(e):
eab25b7c 331 exit(1)
f802fe3c 332 if args and args.debug:
a6f80f0e 333 raise
334 else:
f802fe3c 335 if logger:
336 logger.error(str(e))
337 else:
338 print str(e)
339 if args and not args.debug:
d08d5f54 340 print '\nRerun the command with \'-d\' for a detailed errormsg'
eab25b7c 341 exit(1)
a6f80f0e 342 finally:
343 deinit()
344
a6f80f0e 345if __name__ == "__main__":
346
347 if not os.geteuid() == 0:
348 print 'Error: Must be root to run this command'
349 exit(1)
350
351 """
eab25b7c 352 XXX: Cannot use this. A spawned dhclient process can hold the lock
a6f80f0e 353 if not utilities.lockFile(lockfile):
354 print 'Another instance of this program is already running.'
355 exit(0)
356 """
357
358 main(sys.argv)