Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement interfaces selection like ifupdown1 #265

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
82 changes: 61 additions & 21 deletions ifupdown2/ifupdown/argv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#

import sys
from functools import reduce
import argparse

try:
Expand Down Expand Up @@ -90,20 +91,23 @@ def __init__(self, argv):
raise

def validate(self):
if self.op == 'query' and (self.args.syntaxhelp or self.args.list):
return True
# Implicit -a/--all for all query operations
if self.op == 'query' and not self.args.iflist:
self.args.all = True

# Implicit -a/--all for reload currentlyup option
if self.op == 'reload':
if not self.args.all and not self.args.currentlyup and not self.args.CLASS:
raise ArgvParseError("'-a' or '-c' or '-allow' option is required")
elif not self.args.iflist and not self.args.all and not self.args.CLASS:
raise ArgvParseError("'-a' option or interface list are required")
if self.args.iflist:
raise ArgvParseError("Unsupported IFLIST for reload operation")
elif not self.args.all and not self.args.currentlyup:
raise ArgvParseError("-a/--all or -c/--currently-up option is required")
# Early return to prevent interfaces_selection_post_validate to add [auto] in --allow
if self.args.currentlyup:
self.args.all = True
return True

if self.args.iflist and self.args.all:
raise ArgvParseError("'-a' option and interface list are mutually exclusive")
self.argparser_interfaces_selection_post_validate()

if self.op != 'reload' and self.args.CLASS and self.args.all:
raise ArgvParseError("'--allow' option is mutually exclusive with '-a'")
return True

def get_op(self):
Expand All @@ -118,17 +122,55 @@ def get_op(self):
def get_args(self):
return self.args

def argparser_interfaces_selection(self, argparser):
"""
Manage interfaces selection like ifupdown1 does
* -a/--all and iflist options target a list of interfaces
* --allow filter this interfaces list with the specified scope
* --allow default value is [auto] when -a/--all option is used
Some commands have an implicit -a/--all (ifquery, ifreload)
"""

class ExpandItfListAction(argparse.Action):
def __call__(self, _parser, namespace, values, option_string=None):
expanded = (utils.expand_iface_range(itf) or [itf] for itf in values)
flattened = reduce(lambda xs, x: xs + x, expanded, [])
uniq_itfs = reduce(lambda xs, x: xs if x in xs else xs + [x], flattened, [])
setattr(namespace, self.dest, uniq_itfs)

argparser.add_argument('iflist', metavar='IFACE', nargs='*', action=ExpandItfListAction,
help='interface list separated by spaces. ')
argparser.add_argument('-a', '--all', action='store_true',
help='process all interfaces (limited by --allow= filter)')
allow_group = argparser.add_mutually_exclusive_group(required=False)
allow_group.add_argument('--allow', dest='CLASS', action='append',
help='ignore non-"allow-CLASS" interfaces (default is [auto] when -a/--all else [])')
# For ifupdown compatibility, '--all' implies '--allow auto'. '--allow-all' parameter offers
# a way to have all interfaces without implicit filter.
allow_group.add_argument('--allow-all', action='store_true',
help='ensure non-"allow-CLASS" is set to []')

def argparser_interfaces_selection_post_validate(self):
""" Set and validate interfaces selection options """

if self.args.allow_all:
self.args.CLASS = []
elif self.args.all and not self.args.CLASS:
# Default filter scope is auto/allow-auto when -a/--all option is set
self.args.CLASS = ['auto']

if self.args.iflist and self.args.all:
raise ArgvParseError("IFACE list is mutually exclusive with -a/--all option")
elif not self.args.iflist and not self.args.all:
raise ArgvParseError("no interface(s) specified. IFACE list or -a/--all option is required")

def update_argparser(self, 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.')
self.argparser_interfaces_selection(argparser)

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', action='append', 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. "
Expand Down Expand Up @@ -204,14 +246,12 @@ def update_ifquery_argparser(self, argparser):

def update_ifreload_argparser(self, argparser):
""" parser for ifreload """
group = argparser.add_mutually_exclusive_group(required=True)
group.add_argument('-a', '--all', action='store_true', help='process all interfaces marked "auto"')
group.add_argument('-c', '--currently-up', dest='currentlyup', action='store_true',
self.argparser_interfaces_selection(argparser)

argparser.add_argument('-c', '--currently-up', dest='currentlyup', action='store_true',
help='Reload the configuration for all interfaces which are '
'currently up regardless of whether an interface has '
'"auto <interface>" configuration within the /etc/network/interfaces file.')
group.add_argument('--allow', dest='CLASS', action='append', help='ignore non-"allow-CLASS" interfaces')
argparser.add_argument('iflist', metavar='IFACE', nargs='*', help=argparse.SUPPRESS)
argparser.add_argument('-n', '--no-act', dest='noact', action='store_true',
help='print out what would happen, but don\'t do it')
argparser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='verbose')
Expand Down