Merge "Check restart and auto_remove are setted for per container"
This commit is contained in:
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import collections
|
||||||
import getpass
|
import getpass
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
@@ -90,6 +91,15 @@ def arg(*args, **kwargs):
|
|||||||
return _decorator
|
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):
|
def env(*args, **kwargs):
|
||||||
"""Returns the first environment variable set.
|
"""Returns the first environment variable set.
|
||||||
|
|
||||||
@@ -116,6 +126,24 @@ def add_arg(func, *args, **kwargs):
|
|||||||
func.arguments.insert(0, (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):
|
def unauthenticated(func):
|
||||||
"""Adds 'unauthenticated' attribute to decorated function.
|
"""Adds 'unauthenticated' attribute to decorated function.
|
||||||
|
|
||||||
|
@@ -87,11 +87,18 @@ class CreateContainer(command.ShowOne):
|
|||||||
'already exist on the node. '
|
'already exist on the node. '
|
||||||
'"always": Always pull the image from repository.'
|
'"always": Always pull the image from repository.'
|
||||||
'"never": never pull the image')
|
'"never": never pull the image')
|
||||||
parser.add_argument(
|
restart_auto_remove_args = parser.add_mutually_exclusive_group()
|
||||||
|
restart_auto_remove_args.add_argument(
|
||||||
'--restart',
|
'--restart',
|
||||||
metavar='<restart>',
|
metavar='<restart>',
|
||||||
help='Restart policy to apply when a container exits'
|
help='Restart policy to apply when a container exits'
|
||||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
'(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(
|
parser.add_argument(
|
||||||
'--image-driver',
|
'--image-driver',
|
||||||
metavar='<image_driver>',
|
metavar='<image_driver>',
|
||||||
@@ -142,12 +149,6 @@ class CreateContainer(command.ShowOne):
|
|||||||
metavar='<mount>',
|
metavar='<mount>',
|
||||||
help='A dictionary to configure volumes mounted inside the '
|
help='A dictionary to configure volumes mounted inside the '
|
||||||
'container.')
|
'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(
|
parser.add_argument(
|
||||||
'--runtime',
|
'--runtime',
|
||||||
metavar='<runtime>',
|
metavar='<runtime>',
|
||||||
@@ -705,11 +706,18 @@ class RunContainer(command.ShowOne):
|
|||||||
'already exist on the node. '
|
'already exist on the node. '
|
||||||
'"always": Always pull the image from repository.'
|
'"always": Always pull the image from repository.'
|
||||||
'"never": never pull the image')
|
'"never": never pull the image')
|
||||||
parser.add_argument(
|
restart_auto_remove_args = parser.add_mutually_exclusive_group()
|
||||||
|
restart_auto_remove_args.add_argument(
|
||||||
'--restart',
|
'--restart',
|
||||||
metavar='<restart>',
|
metavar='<restart>',
|
||||||
help='Restart policy to apply when a container exits'
|
help='Restart policy to apply when a container exits'
|
||||||
'(no, on-failure[:max-retry], always, unless-stopped)')
|
'(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(
|
parser.add_argument(
|
||||||
'--image-driver',
|
'--image-driver',
|
||||||
metavar='<image_driver>',
|
metavar='<image_driver>',
|
||||||
@@ -760,12 +768,6 @@ class RunContainer(command.ShowOne):
|
|||||||
metavar='<mount>',
|
metavar='<mount>',
|
||||||
help='A dictionary to configure volumes mounted inside the '
|
help='A dictionary to configure volumes mounted inside the '
|
||||||
'container.')
|
'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(
|
parser.add_argument(
|
||||||
'--runtime',
|
'--runtime',
|
||||||
metavar='<runtime>',
|
metavar='<runtime>',
|
||||||
|
@@ -429,6 +429,7 @@ class OpenStackZunShell(object):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
action_help = desc.strip()
|
action_help = desc.strip()
|
||||||
|
exclusive_args = getattr(callback, 'exclusive_args', {})
|
||||||
arguments = getattr(callback, 'arguments', [])
|
arguments = getattr(callback, 'arguments', [])
|
||||||
|
|
||||||
subparser = (
|
subparser = (
|
||||||
@@ -443,29 +444,46 @@ class OpenStackZunShell(object):
|
|||||||
help=argparse.SUPPRESS,)
|
help=argparse.SUPPRESS,)
|
||||||
self.subcommands[command] = subparser
|
self.subcommands[command] = subparser
|
||||||
|
|
||||||
for (args, kwargs) in arguments:
|
self._add_subparser_args(subparser, arguments, version, do_help,
|
||||||
start_version = kwargs.get("start_version", None)
|
msg)
|
||||||
if start_version:
|
self._add_subparser_exclusive_args(subparser, exclusive_args,
|
||||||
start_version = api_versions.APIVersion(start_version)
|
version, do_help, msg)
|
||||||
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)
|
|
||||||
subparser.set_defaults(func=callback)
|
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):
|
def setup_debugging(self, debug):
|
||||||
if debug:
|
if debug:
|
||||||
streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
|
||||||
|
@@ -39,6 +39,17 @@ def _show_container(container):
|
|||||||
utils.print_dict(container._info)
|
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',
|
@utils.arg('-n', '--name',
|
||||||
metavar='<name>',
|
metavar='<name>',
|
||||||
help='name of the container')
|
help='name of the container')
|
||||||
@@ -55,9 +66,6 @@ def _show_container(container):
|
|||||||
@utils.arg('--workdir',
|
@utils.arg('--workdir',
|
||||||
metavar='<workdir>',
|
metavar='<workdir>',
|
||||||
help='The working directory for commands to run in')
|
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',
|
@utils.arg('--label',
|
||||||
metavar='<KEY=VALUE>',
|
metavar='<KEY=VALUE>',
|
||||||
action='append', default=[],
|
action='append', default=[],
|
||||||
@@ -75,10 +83,6 @@ def _show_container(container):
|
|||||||
'"always": Always pull the image from repository.'
|
'"always": Always pull the image from repository.'
|
||||||
'"never": never pull the image')
|
'"never": never pull the image')
|
||||||
@utils.arg('image', metavar='<image>', help='name or ID of 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',
|
@utils.arg('-i', '--interactive',
|
||||||
dest='interactive',
|
dest='interactive',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
@@ -523,6 +527,17 @@ def do_kill(cs, args):
|
|||||||
{'container': container, 'e': e})
|
{'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',
|
@utils.arg('-n', '--name',
|
||||||
metavar='<name>',
|
metavar='<name>',
|
||||||
help='name of the container')
|
help='name of the container')
|
||||||
@@ -539,9 +554,6 @@ def do_kill(cs, args):
|
|||||||
@utils.arg('--workdir',
|
@utils.arg('--workdir',
|
||||||
metavar='<workdir>',
|
metavar='<workdir>',
|
||||||
help='The working directory for commands to run in')
|
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',
|
@utils.arg('--label',
|
||||||
metavar='<KEY=VALUE>',
|
metavar='<KEY=VALUE>',
|
||||||
action='append', default=[],
|
action='append', default=[],
|
||||||
@@ -559,10 +571,6 @@ def do_kill(cs, args):
|
|||||||
'"always": Always pull the image from repository.'
|
'"always": Always pull the image from repository.'
|
||||||
'"never": never pull the image')
|
'"never": never pull the image')
|
||||||
@utils.arg('image', metavar='<image>', help='name or ID of 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',
|
@utils.arg('-i', '--interactive',
|
||||||
dest='interactive',
|
dest='interactive',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
Reference in New Issue
Block a user