mirror of
				https://github.com/CumulusNetworks/ifupdown2.git
				synced 2024-05-06 15:54:50 +00:00 
			
		
		
		
	example fixes Ticket: CM-2911 Reviewed By: CCR-1637 Testing Done: tested ifupdown2 sanity and bash completion The python argcomplete module that i use for ifupdown2 has a limitation that it does not work with sudo when used in the global mode. But there is a workaround for it online (long story short...instead of enabling the global argparse complete ...the author recommends registering argparse complete bash completion individually for your script). This patch does just that. This patch also moves the udev overrides to their respective packages. Two of them are owned by ifupdown2. Conflicts: rootconf/default/home/cumulus/sysroot-complete
		
			
				
	
	
		
			414 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/python
 | 
						|
 | 
						|
import sys
 | 
						|
import os
 | 
						|
import argcomplete
 | 
						|
import argparse
 | 
						|
import ConfigParser
 | 
						|
import StringIO
 | 
						|
import logging
 | 
						|
from ifupdown.ifupdownmain import *
 | 
						|
from ifupdown.utils import *
 | 
						|
 | 
						|
lockfile="/run/network/.lock"
 | 
						|
configfile="/etc/network/ifupdown2/ifupdown2.conf"
 | 
						|
configmap_g=None
 | 
						|
logger = None
 | 
						|
interfacesfileiobuf=None
 | 
						|
ENVPATH = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
 | 
						|
 | 
						|
def run_up(args):
 | 
						|
    logger.debug('args = %s' %str(args))
 | 
						|
 | 
						|
    try:
 | 
						|
        iflist = args.iflist
 | 
						|
        if len(args.iflist) == 0:
 | 
						|
            iflist = None
 | 
						|
        logger.debug('creating ifupdown object ..')
 | 
						|
        cachearg=(False if (iflist or args.nocache or
 | 
						|
                            args.perfmode or args.noact)
 | 
						|
                            else True)
 | 
						|
        ifupdown_handle = ifupdownMain(config=configmap_g,
 | 
						|
                                       force=args.force,
 | 
						|
                                       withdepends=args.withdepends,
 | 
						|
                                       perfmode=args.perfmode,
 | 
						|
                                       dryrun=args.noact,
 | 
						|
                                       cache=cachearg,
 | 
						|
                                       addons_enable=not args.noaddons,
 | 
						|
                                       statemanager_enable=not args.noaddons,
 | 
						|
                                       interfacesfile=args.interfacesfile,
 | 
						|
                                       interfacesfileiobuf=interfacesfileiobuf,
 | 
						|
                                       interfacesfileformat=args.interfacesfileformat)
 | 
						|
        if args.noaddons:
 | 
						|
            ifupdown_handle.up(['up'], args.all, args.CLASS, iflist,
 | 
						|
                               excludepats=args.excludepats,
 | 
						|
                               printdependency=args.printdependency,
 | 
						|
                               syntaxcheck=args.syntaxcheck)
 | 
						|
        else:
 | 
						|
            ifupdown_handle.up(['pre-up', 'up', 'post-up'],
 | 
						|
                               args.all, args.CLASS, iflist,
 | 
						|
                               excludepats=args.excludepats,
 | 
						|
                               printdependency=args.printdependency,
 | 
						|
                               syntaxcheck=args.syntaxcheck)
 | 
						|
    except:
 | 
						|
        raise
 | 
						|
 | 
						|
def run_down(args):
 | 
						|
    logger.debug('args = %s' %str(args))
 | 
						|
 | 
						|
    try:
 | 
						|
        iflist = args.iflist
 | 
						|
        logger.debug('creating ifupdown object ..')
 | 
						|
        ifupdown_handle = ifupdownMain(config=configmap_g, force=args.force,
 | 
						|
                                       withdepends=args.withdepends,
 | 
						|
                                       perfmode=args.perfmode,
 | 
						|
                                       dryrun=args.noact,
 | 
						|
                                       addons_enable=not args.noaddons,
 | 
						|
                                       statemanager_enable=not args.noaddons,
 | 
						|
                                       interfacesfile=args.interfacesfile,
 | 
						|
                                       interfacesfileiobuf=interfacesfileiobuf,
 | 
						|
                                       interfacesfileformat=args.interfacesfileformat)
 | 
						|
 | 
						|
        ifupdown_handle.down(['pre-down', 'down', 'post-down'],
 | 
						|
                             args.all, args.CLASS, iflist,
 | 
						|
                             excludepats=args.excludepats,
 | 
						|
                             printdependency=args.printdependency,
 | 
						|
                             usecurrentconfig=args.usecurrentconfig)
 | 
						|
    except:
 | 
						|
        raise
 | 
						|
 | 
						|
def run_query(args):
 | 
						|
    logger.debug('args = %s' %str(args))
 | 
						|
 | 
						|
    try:
 | 
						|
        iflist = args.iflist
 | 
						|
        if args.checkcurr:
 | 
						|
            qop='query-checkcurr'
 | 
						|
        elif args.running:
 | 
						|
            qop='query-running'
 | 
						|
        elif args.raw:
 | 
						|
            qop='query-raw'
 | 
						|
        elif args.syntaxhelp:
 | 
						|
            qop = 'query-syntax'
 | 
						|
        elif args.printdependency:
 | 
						|
            qop = 'query-dependency'
 | 
						|
        elif args.printsavedstate:
 | 
						|
            qop = 'query-savedstate'
 | 
						|
        else:
 | 
						|
            qop='query'
 | 
						|
        cachearg=(False if (iflist or args.nocache or
 | 
						|
                            args.perfmode or args.syntaxhelp or
 | 
						|
                            (qop != 'query-checkcurr' and
 | 
						|
                            qop != 'query-running')) else True)
 | 
						|
        if not iflist and qop == 'query-running':
 | 
						|
            iflist = [i for i in os.listdir('/sys/class/net/')
 | 
						|
                        if os.path.isdir('/sys/class/net/%s' %i)]
 | 
						|
        logger.debug('creating ifupdown object ..')
 | 
						|
        ifupdown_handle = ifupdownMain(config=configmap_g,
 | 
						|
                                       withdepends=args.withdepends,
 | 
						|
                                       perfmode=args.perfmode,
 | 
						|
                                       cache=cachearg,
 | 
						|
                                       interfacesfile=args.interfacesfile,
 | 
						|
                                       interfacesfileiobuf=interfacesfileiobuf,
 | 
						|
                                       interfacesfileformat=args.interfacesfileformat)
 | 
						|
 | 
						|
        ifupdown_handle.query([qop], args.all, args.CLASS, iflist,
 | 
						|
                              excludepats=args.excludepats,
 | 
						|
                              printdependency=args.printdependency,
 | 
						|
                              format=args.format)
 | 
						|
    except:
 | 
						|
        raise
 | 
						|
 | 
						|
def run_reload(args):
 | 
						|
    logger.debug('args = %s' %str(args))
 | 
						|
 | 
						|
    try:
 | 
						|
        logger.debug('creating ifupdown object ..')
 | 
						|
        ifupdown_handle = ifupdownMain(config=configmap_g,
 | 
						|
                                       withdepends=args.withdepends,
 | 
						|
                                       perfmode=args.perfmode)
 | 
						|
        ifupdown_handle.reload(['pre-up', 'up', 'post-up'],
 | 
						|
                               ['pre-down', 'down', 'post-down'],
 | 
						|
                               args.all, None, None,
 | 
						|
                               excludepats=args.excludepats,
 | 
						|
                               usecurrentconfig=args.usecurrentconfig)
 | 
						|
    except:
 | 
						|
        raise
 | 
						|
 | 
						|
def init(args):
 | 
						|
    global logger
 | 
						|
    global interfacesfileiobuf
 | 
						|
 | 
						|
    log_level = logging.WARNING
 | 
						|
    if args.verbose:
 | 
						|
        log_level = logging.INFO
 | 
						|
    if args.debug:
 | 
						|
        log_level = logging.DEBUG
 | 
						|
 | 
						|
    try:
 | 
						|
        logging.basicConfig(level=log_level,
 | 
						|
            format='%(levelname)s: %(message)s')
 | 
						|
        logging.addLevelName(logging.ERROR, 'error')
 | 
						|
        logging.addLevelName(logging.WARNING, 'warning')
 | 
						|
        logging.addLevelName(logging.DEBUG, 'debug')
 | 
						|
        logging.addLevelName(logging.INFO, 'info')
 | 
						|
        logger = logging.getLogger('ifupdown')
 | 
						|
    except:
 | 
						|
        raise
 | 
						|
 | 
						|
    # If interfaces file is stdin, read
 | 
						|
    if hasattr(args, 'interfacesfile') and args.interfacesfile == '-':
 | 
						|
        interfacesfileiobuf = sys.stdin.read()
 | 
						|
 | 
						|
def deinit():
 | 
						|
    {}
 | 
						|
 | 
						|
def update_argparser(argparser):
 | 
						|
    """ base parser, common to all commands """
 | 
						|
 | 
						|
    argparser.add_argument('-a', '--all', action='store_true', required=False,
 | 
						|
                help='process all interfaces marked \"auto\"')
 | 
						|
    argparser.add_argument('iflist', metavar='IFACE',
 | 
						|
                nargs='*', help='interface list separated by spaces. ' +
 | 
						|
                'IFACE list is mutually exclusive with -a option.')
 | 
						|
    argparser.add_argument('-v', '--verbose', dest='verbose',
 | 
						|
                action='store_true', help='verbose')
 | 
						|
    argparser.add_argument('-d', '--debug', dest='debug',
 | 
						|
                action='store_true',
 | 
						|
                help='output debug info')
 | 
						|
    argparser.add_argument('-q', '--quiet', dest='quiet',
 | 
						|
                action='store_true',
 | 
						|
                help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('--allow', dest='CLASS', 
 | 
						|
                help='ignore non-\"allow-CLASS\" interfaces')
 | 
						|
    argparser.add_argument('-w', '--with-depends', dest='withdepends',
 | 
						|
                action='store_true', help='run with all dependent interfaces.'+
 | 
						|
                ' This option is redundant when \'-a\' is specified. With ' +
 | 
						|
                '\'-a\' interfaces are always executed in dependency order')
 | 
						|
    argparser.add_argument('--perfmode', dest='perfmode',
 | 
						|
                action='store_true', help=argparse.SUPPRESS)
 | 
						|
    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
 | 
						|
    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('--nocache', dest='nocache', action='store_true',
 | 
						|
                help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('-X', '--exclude', dest='excludepats',
 | 
						|
                action='append',
 | 
						|
                help='Exclude interfaces from the list of interfaces' +
 | 
						|
                ' to operate on. Can be specified multiple times.')
 | 
						|
    argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
 | 
						|
                default='/etc/network/interfaces',
 | 
						|
                help='use interfaces file instead of default ' +
 | 
						|
                '/etc/network/interfaces')
 | 
						|
    argparser.add_argument('-t', '--interfaces-format',
 | 
						|
                dest='interfacesfileformat',
 | 
						|
                default='native',
 | 
						|
                choices=['native', 'json'],
 | 
						|
                help='interfaces file format')
 | 
						|
 | 
						|
def update_ifupdown_argparser(argparser):
 | 
						|
    """ common arg parser for ifup and ifdown """
 | 
						|
    argparser.add_argument('-f', '--force', dest='force',
 | 
						|
                action='store_true',
 | 
						|
                help='force run all operations')
 | 
						|
    group = argparser.add_mutually_exclusive_group(required=False)
 | 
						|
    group.add_argument('-n', '--no-act', dest='noact',
 | 
						|
                action='store_true', help='print out what would happen,' +
 | 
						|
                'but don\'t do it')
 | 
						|
    group.add_argument('-p', '--print-dependency',
 | 
						|
                dest='printdependency', choices=['list', 'dot'],
 | 
						|
                help='print iface dependency')
 | 
						|
    group.add_argument('--no-scripts', '--admin-state',
 | 
						|
                dest='noaddons',  action='store_true',
 | 
						|
                help='dont run any addon modules/scripts. Only bring the ' +
 | 
						|
                    'interface administratively up/down')
 | 
						|
 | 
						|
def update_ifup_argparser(argparser):
 | 
						|
    argparser.add_argument('-s', '--syntax-check', dest='syntaxcheck',
 | 
						|
                action='store_true',
 | 
						|
                help='Only run the interfaces file parser')
 | 
						|
    update_ifupdown_argparser(argparser)
 | 
						|
 | 
						|
def update_ifdown_argparser(argparser):
 | 
						|
    update_ifupdown_argparser(argparser)
 | 
						|
    argparser.add_argument('-u', '--use-current-config',
 | 
						|
                dest='usecurrentconfig',  action='store_true',
 | 
						|
                help='By default ifdown looks at the saved state for ' +
 | 
						|
                'interfaces to bring down. This option allows ifdown to ' +
 | 
						|
                'look at the current interfaces file. Useful when your ' +
 | 
						|
                'state file is corrupted or you want down to use the latest '
 | 
						|
                'from the interfaces file')
 | 
						|
 | 
						|
def update_ifquery_argparser(argparser):
 | 
						|
    """ arg parser for ifquery options """
 | 
						|
 | 
						|
    # -l is same as '-a', only here for backward compatibility
 | 
						|
    argparser.add_argument('-l', '--list', action='store_true', dest='all',
 | 
						|
                help=argparse.SUPPRESS)
 | 
						|
    group = argparser.add_mutually_exclusive_group(required=False)
 | 
						|
    group.add_argument('-r', '--running', dest='running',
 | 
						|
                       action='store_true',
 | 
						|
                       help='query running state of an interface')
 | 
						|
    group.add_argument('-c', '--check', dest='checkcurr',
 | 
						|
                       action='store_true',
 | 
						|
                       help='check interface file contents against ' +
 | 
						|
                       'running state of an interface')
 | 
						|
    group.add_argument(-x', '--raw', action='store_true', dest='raw',
 | 
						|
                       help='print raw config file entries')
 | 
						|
    group.add_argument('--print-savedstate', action='store_true',
 | 
						|
                       dest='printsavedstate',
 | 
						|
                       help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('-o', '--format', dest='format', default='native',
 | 
						|
                           choices=['native', 'json'],
 | 
						|
                           help='interface display format')
 | 
						|
    argparser.add_argument('-p', '--print-dependency',
 | 
						|
                           dest='printdependency', choices=['list', 'dot'],
 | 
						|
                           help='print interface dependency')
 | 
						|
    argparser.add_argument('-s', '--syntax-help', action='store_true',
 | 
						|
                           dest='syntaxhelp',
 | 
						|
                           help='print supported interface config syntax')
 | 
						|
 | 
						|
def update_ifreload_argparser(argparser):
 | 
						|
    """ parser for ifreload """
 | 
						|
    argparser.add_argument('-a', '--all', action='store_true', required=True,
 | 
						|
                help='process all interfaces marked \"auto\"')
 | 
						|
    argparser.add_argument('iflist', metavar='IFACE',
 | 
						|
                nargs='*', help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('-n', '--no-act', dest='noact',
 | 
						|
                action='store_true', help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('-v', '--verbose', dest='verbose',
 | 
						|
                action='store_true', help='verbose')
 | 
						|
    argparser.add_argument('-d', '--debug', dest='debug',
 | 
						|
                action='store_true',
 | 
						|
                help='output debug info')
 | 
						|
    argparser.add_argument('-w', '--with-depends', dest='withdepends',
 | 
						|
                action='store_true', help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('--perfmode', dest='perfmode',
 | 
						|
                action='store_true', help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('--nocache', dest='nocache', action='store_true',
 | 
						|
                help=argparse.SUPPRESS)
 | 
						|
    argparser.add_argument('-X', '--exclude', dest='excludepats',
 | 
						|
                action='append',
 | 
						|
                help=argparse.SUPPRESS)
 | 
						|
    #argparser.add_argument('-j', '--jobs', dest='jobs', type=int,
 | 
						|
    #            default=-1, choices=range(1,12), help=argparse.SUPPRESS)
 | 
						|
    #argparser.add_argument('-i', '--interfaces', dest='interfacesfile',
 | 
						|
    #            default='/etc/network/interfaces',
 | 
						|
    #            help='use interfaces file instead of default ' +
 | 
						|
    #            '/etc/network/interfaces')
 | 
						|
    argparser.add_argument('-u', '--use-current-config',
 | 
						|
                dest='usecurrentconfig',  action='store_true',
 | 
						|
                help='By default ifreload looks at saved state for ' +
 | 
						|
                'interfaces to bring down. With this option ifreload will'
 | 
						|
                ' only look at the current interfaces file. Useful when your ' +
 | 
						|
                'state file is corrupted or you want down to use the latest '
 | 
						|
                'from the interfaces file')
 | 
						|
 | 
						|
def parse_args(argsv, op):
 | 
						|
    if op == 'query':
 | 
						|
        descr = 'query interfaces (all or interface list)'
 | 
						|
    elif op == 'reload':
 | 
						|
        descr = 'reload interface configuration.'
 | 
						|
    else:
 | 
						|
        descr = 'interface management'
 | 
						|
    argparser = argparse.ArgumentParser(description=descr)
 | 
						|
    if op == 'reload':
 | 
						|
        update_ifreload_argparser(argparser)
 | 
						|
    else:
 | 
						|
        update_argparser(argparser)
 | 
						|
        if op == 'up':
 | 
						|
            update_ifup_argparser(argparser)
 | 
						|
        elif op == 'down':
 | 
						|
            update_ifdown_argparser(argparser)
 | 
						|
        elif op == 'query':
 | 
						|
            update_ifquery_argparser(argparser)
 | 
						|
        elif op == 'reload':
 | 
						|
            update_ifreload_argparser(argparser)
 | 
						|
    argcomplete.autocomplete(argparser)
 | 
						|
    return argparser.parse_args(argsv)
 | 
						|
 | 
						|
handlers = {'up' : run_up,
 | 
						|
            'down' : run_down,
 | 
						|
            'query' : run_query,
 | 
						|
            'reload' : run_reload }
 | 
						|
 | 
						|
def validate_args(op, args):
 | 
						|
    #if op == 'up' and args.syntaxcheck:
 | 
						|
    #    if args.iflist or args.all:
 | 
						|
    #        print 'ignoring interface options ..'
 | 
						|
    #    return True
 | 
						|
    if op == 'query' and args.syntaxhelp:
 | 
						|
        return True
 | 
						|
    if not args.iflist and not args.all:
 | 
						|
        print '\'-a\' option or interface list are required'
 | 
						|
        return False
 | 
						|
    if args.iflist and args.all:
 | 
						|
        print '\'-a\' option and interface list are mutually exclusive'
 | 
						|
        return False
 | 
						|
    return True
 | 
						|
 | 
						|
def read_config():
 | 
						|
    global configmap_g
 | 
						|
 | 
						|
    config = open(configfile, 'r').read()
 | 
						|
    configStr = '[ifupdown2]\n' + config
 | 
						|
    configFP =  StringIO.StringIO(configStr)
 | 
						|
    parser = ConfigParser.RawConfigParser()
 | 
						|
    parser.readfp(configFP)
 | 
						|
    configmap_g = dict(parser.items('ifupdown2'))
 | 
						|
 | 
						|
def main(argv):
 | 
						|
    """ main function """
 | 
						|
    args = None
 | 
						|
    try:
 | 
						|
        op = None
 | 
						|
        if argv[0].endswith('ifup'):
 | 
						|
            op = 'up'
 | 
						|
        elif argv[0].endswith('ifdown'):
 | 
						|
            op = 'down'
 | 
						|
        elif argv[0].endswith('ifquery'):
 | 
						|
            op = 'query'
 | 
						|
        elif argv[0].endswith('ifreload'):
 | 
						|
            op = 'reload'
 | 
						|
        else:
 | 
						|
            print ('Unexpected executable.' +
 | 
						|
                   ' Should be \'ifup\' or \'ifdown\' or \'ifquery\'')
 | 
						|
            exit(1)
 | 
						|
        # Command line arg parser
 | 
						|
        args = parse_args(argv[1:], op)
 | 
						|
        if not validate_args(op, args):
 | 
						|
            exit(1)
 | 
						|
 | 
						|
        if not sys.argv[0].endswith('ifquery') and not os.geteuid() == 0:
 | 
						|
            print 'error: must be root to run this command'
 | 
						|
            exit(1)
 | 
						|
 | 
						|
        if not sys.argv[0].endswith('ifquery') and not utils.lockFile(lockfile):
 | 
						|
            print 'Another instance of this program is already running.'
 | 
						|
            exit(0)
 | 
						|
 | 
						|
        read_config()
 | 
						|
        init(args)
 | 
						|
        handlers.get(op)(args)
 | 
						|
    except Exception, e:
 | 
						|
        if not str(e):
 | 
						|
            exit(1)
 | 
						|
        if args and args.debug:
 | 
						|
            raise
 | 
						|
        else:
 | 
						|
            if logger:
 | 
						|
                logger.error(str(e))
 | 
						|
            else:
 | 
						|
                print str(e)
 | 
						|
            #if args and not args.debug:
 | 
						|
            #    print '\nrerun the command with \'-d\' for a detailed errormsg'
 | 
						|
        exit(1)
 | 
						|
    finally:
 | 
						|
        deinit()
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
 | 
						|
 | 
						|
    # required during boot
 | 
						|
    os.putenv('PATH', ENVPATH)
 | 
						|
    main(sys.argv)
 |