Merge "Check restart and auto_remove are setted for per container"
This commit is contained in:
commit
c36a9f7a00
@ -18,6 +18,7 @@
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import getpass
|
||||
import inspect
|
||||
import os
|
||||
@ -90,6 +91,15 @@ def arg(*args, **kwargs):
|
||||
return _decorator
|
||||
|
||||
|
||||
def exclusive_arg(group_name, *args, **kwargs):
|
||||
"""Decorator for CLI mutually exclusive args."""
|
||||
def _decorator(func):
|
||||
required = kwargs.pop('required', None)
|
||||
add_exclusive_arg(func, group_name, required, *args, **kwargs)
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def env(*args, **kwargs):
|
||||
"""Returns the first environment variable set.
|
||||
|
||||
@ -116,6 +126,24 @@ def add_arg(func, *args, **kwargs):
|
||||
func.arguments.insert(0, (args, kwargs))
|
||||
|
||||
|
||||
def add_exclusive_arg(func, group_name, required, *args, **kwargs):
|
||||
"""Bind CLI mutally exclusive arguments to a shell.py `do_foo` function."""
|
||||
|
||||
if not hasattr(func, 'exclusive_args'):
|
||||
func.exclusive_args = collections.defaultdict(list)
|
||||
# Default required to False
|
||||
func.exclusive_args['__required__'] = collections.defaultdict(bool)
|
||||
|
||||
# NOTE(sirp): avoid dups that can occur when the module is shared across
|
||||
# tests.
|
||||
if (args, kwargs) not in func.exclusive_args[group_name]:
|
||||
# Because of the semantics of decorator composition if we just append
|
||||
# to the options list positional options will appear to be backwards.
|
||||
func.exclusive_args[group_name].insert(0, (args, kwargs))
|
||||
if required is not None:
|
||||
func.exclusive_args['__required__'][group_name] = required
|
||||
|
||||
|
||||
def unauthenticated(func):
|
||||
"""Adds 'unauthenticated' attribute to decorated function.
|
||||
|
||||
|
@ -87,11 +87,18 @@ class CreateContainer(command.ShowOne):
|
||||
'already exist on the node. '
|
||||
'"always": Always pull the image from repository.'
|
||||
'"never": never pull the image')
|
||||
parser.add_argument(
|
||||
restart_auto_remove_args = parser.add_mutually_exclusive_group()
|
||||
restart_auto_remove_args.add_argument(
|
||||
'--restart',
|
||||
metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
restart_auto_remove_args.add_argument(
|
||||
'--auto-remove',
|
||||
dest='auto_remove',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Automatically remove the container when it exits')
|
||||
parser.add_argument(
|
||||
'--image-driver',
|
||||
metavar='<image_driver>',
|
||||
@ -142,12 +149,6 @@ class CreateContainer(command.ShowOne):
|
||||
metavar='<mount>',
|
||||
help='A dictionary to configure volumes mounted inside the '
|
||||
'container.')
|
||||
parser.add_argument(
|
||||
'--auto-remove',
|
||||
dest='auto_remove',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Automatically remove the container when it exits')
|
||||
parser.add_argument(
|
||||
'--runtime',
|
||||
metavar='<runtime>',
|
||||
@ -705,11 +706,18 @@ class RunContainer(command.ShowOne):
|
||||
'already exist on the node. '
|
||||
'"always": Always pull the image from repository.'
|
||||
'"never": never pull the image')
|
||||
parser.add_argument(
|
||||
restart_auto_remove_args = parser.add_mutually_exclusive_group()
|
||||
restart_auto_remove_args.add_argument(
|
||||
'--restart',
|
||||
metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
restart_auto_remove_args.add_argument(
|
||||
'--auto-remove',
|
||||
dest='auto_remove',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Automatically remove the container when it exits')
|
||||
parser.add_argument(
|
||||
'--image-driver',
|
||||
metavar='<image_driver>',
|
||||
@ -760,12 +768,6 @@ class RunContainer(command.ShowOne):
|
||||
metavar='<mount>',
|
||||
help='A dictionary to configure volumes mounted inside the '
|
||||
'container.')
|
||||
parser.add_argument(
|
||||
'--auto-remove',
|
||||
dest='auto_remove',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Automatically remove the container when it exits')
|
||||
parser.add_argument(
|
||||
'--runtime',
|
||||
metavar='<runtime>',
|
||||
|
@ -429,6 +429,7 @@ class OpenStackZunShell(object):
|
||||
continue
|
||||
|
||||
action_help = desc.strip()
|
||||
exclusive_args = getattr(callback, 'exclusive_args', {})
|
||||
arguments = getattr(callback, 'arguments', [])
|
||||
|
||||
subparser = (
|
||||
@ -443,29 +444,46 @@ class OpenStackZunShell(object):
|
||||
help=argparse.SUPPRESS,)
|
||||
self.subcommands[command] = subparser
|
||||
|
||||
for (args, kwargs) in arguments:
|
||||
start_version = kwargs.get("start_version", None)
|
||||
if start_version:
|
||||
start_version = api_versions.APIVersion(start_version)
|
||||
end_version = kwargs.get("end_version", None)
|
||||
if end_version:
|
||||
end_version = api_versions.APIVersion(end_version)
|
||||
else:
|
||||
end_version = api_versions.APIVersion(
|
||||
"%s.latest" % start_version.ver_major)
|
||||
if do_help:
|
||||
kwargs["help"] = kwargs.get("help", "") + (msg % {
|
||||
"start": start_version.get_string(),
|
||||
"end": end_version.get_string()})
|
||||
else:
|
||||
if not version.matches(start_version, end_version):
|
||||
continue
|
||||
kw = kwargs.copy()
|
||||
kw.pop("start_version", None)
|
||||
kw.pop("end_version", None)
|
||||
subparser.add_argument(*args, **kwargs)
|
||||
self._add_subparser_args(subparser, arguments, version, do_help,
|
||||
msg)
|
||||
self._add_subparser_exclusive_args(subparser, exclusive_args,
|
||||
version, do_help, msg)
|
||||
subparser.set_defaults(func=callback)
|
||||
|
||||
def _add_subparser_exclusive_args(self, subparser, exclusive_args,
|
||||
version, do_help, msg):
|
||||
for group_name, arguments in exclusive_args.items():
|
||||
if group_name == '__required__':
|
||||
continue
|
||||
required = exclusive_args['__required__'][group_name]
|
||||
exclusive_group = subparser.add_mutually_exclusive_group(
|
||||
required=required)
|
||||
self._add_subparser_args(exclusive_group, arguments,
|
||||
version, do_help, msg)
|
||||
|
||||
def _add_subparser_args(self, subparser, arguments, version, do_help, msg):
|
||||
for (args, kwargs) in arguments:
|
||||
start_version = kwargs.get("start_version", None)
|
||||
if start_version:
|
||||
start_version = api_versions.APIVersion(start_version)
|
||||
end_version = kwargs.get("end_version", None)
|
||||
if end_version:
|
||||
end_version = api_versions.APIVersion(end_version)
|
||||
else:
|
||||
end_version = api_versions.APIVersion(
|
||||
"%s.latest" % start_version.ver_major)
|
||||
if do_help:
|
||||
kwargs["help"] = kwargs.get("help", "") + (msg % {
|
||||
"start": start_version.get_string(),
|
||||
"end": end_version.get_string()})
|
||||
else:
|
||||
if not version.matches(start_version, end_version):
|
||||
continue
|
||||
kw = kwargs.copy()
|
||||
kw.pop("start_version", None)
|
||||
kw.pop("end_version", None)
|
||||
subparser.add_argument(*args, **kwargs)
|
||||
|
||||
def setup_debugging(self, debug):
|
||||
if debug:
|
||||
streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
||||
|
@ -39,6 +39,17 @@ def _show_container(container):
|
||||
utils.print_dict(container._info)
|
||||
|
||||
|
||||
@utils.exclusive_arg(
|
||||
'restart_auto_remove',
|
||||
'--auto-remove',
|
||||
required=False, action='store_true',
|
||||
help='Automatically remove the container when it exits')
|
||||
@utils.exclusive_arg(
|
||||
'restart_auto_remove',
|
||||
'--restart',
|
||||
required=False, metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
@utils.arg('-n', '--name',
|
||||
metavar='<name>',
|
||||
help='name of the container')
|
||||
@ -55,9 +66,6 @@ def _show_container(container):
|
||||
@utils.arg('--workdir',
|
||||
metavar='<workdir>',
|
||||
help='The working directory for commands to run in')
|
||||
@utils.arg('--auto-remove',
|
||||
action='store_true',
|
||||
help='Automatically remove the container when it exits')
|
||||
@utils.arg('--label',
|
||||
metavar='<KEY=VALUE>',
|
||||
action='append', default=[],
|
||||
@ -75,10 +83,6 @@ def _show_container(container):
|
||||
'"always": Always pull the image from repository.'
|
||||
'"never": never pull the image')
|
||||
@utils.arg('image', metavar='<image>', help='name or ID of the image')
|
||||
@utils.arg('--restart',
|
||||
metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
@utils.arg('-i', '--interactive',
|
||||
dest='interactive',
|
||||
action='store_true',
|
||||
@ -523,6 +527,17 @@ def do_kill(cs, args):
|
||||
{'container': container, 'e': e})
|
||||
|
||||
|
||||
@utils.exclusive_arg(
|
||||
'restart_auto_remove',
|
||||
'--auto-remove',
|
||||
required=False, action='store_true',
|
||||
help='Automatically remove the container when it exits')
|
||||
@utils.exclusive_arg(
|
||||
'restart_auto_remove',
|
||||
'--restart',
|
||||
required=False, metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
@utils.arg('-n', '--name',
|
||||
metavar='<name>',
|
||||
help='name of the container')
|
||||
@ -539,9 +554,6 @@ def do_kill(cs, args):
|
||||
@utils.arg('--workdir',
|
||||
metavar='<workdir>',
|
||||
help='The working directory for commands to run in')
|
||||
@utils.arg('--auto-remove',
|
||||
action='store_true',
|
||||
help='Automatically remove the container when it exits')
|
||||
@utils.arg('--label',
|
||||
metavar='<KEY=VALUE>',
|
||||
action='append', default=[],
|
||||
@ -559,10 +571,6 @@ def do_kill(cs, args):
|
||||
'"always": Always pull the image from repository.'
|
||||
'"never": never pull the image')
|
||||
@utils.arg('image', metavar='<image>', help='name or ID of the image')
|
||||
@utils.arg('--restart',
|
||||
metavar='<restart>',
|
||||
help='Restart policy to apply when a container exits'
|
||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
||||
@utils.arg('-i', '--interactive',
|
||||
dest='interactive',
|
||||
action='store_true',
|
||||
|
Loading…
x
Reference in New Issue
Block a user