mirror of
https://github.com/containers/podman.git
synced 2025-06-23 18:59:30 +08:00
Merge pull request #1893 from jwhonce/bug/1869
Refactor CLI booleans to be consistent and defined behavior
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
PYTHON ?= $(shell command -v python3 2>/dev/null || command -v python)
|
||||
DESTDIR ?= /
|
||||
PODMAN_VERSION ?= '0.0.4'
|
||||
PODMAN_VERSION ?= '0.11.1.1'
|
||||
|
||||
.PHONY: python-podman
|
||||
python-podman:
|
||||
@ -22,8 +22,8 @@ install:
|
||||
|
||||
.PHONY: upload
|
||||
upload:
|
||||
$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
|
||||
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
|
||||
PODMAN_VERSION=$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
|
||||
twine upload --verbose --repository-url https://test.pypi.org/legacy/ dist/*
|
||||
|
||||
.PHONY: clobber
|
||||
clobber: uninstall clean
|
||||
|
@ -1,6 +1,6 @@
|
||||
PYTHON ?= $(shell command -v python3 2>/dev/null || command -v python)
|
||||
DESTDIR := /
|
||||
PODMAN_VERSION ?= '0.0.4'
|
||||
PODMAN_VERSION ?= '0.11.1.1'
|
||||
|
||||
.PHONY: python-pypodman
|
||||
python-pypodman:
|
||||
@ -22,7 +22,7 @@ install:
|
||||
|
||||
.PHONY: upload
|
||||
upload:
|
||||
$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
|
||||
PODMAN_VERSION=$(PODMAN_VERSION) $(PYTHON) setup.py sdist bdist_wheel
|
||||
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
|
||||
|
||||
.PHONY: clobber
|
||||
|
@ -3,18 +3,17 @@ import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib.action_base import AbstractActionBase
|
||||
from pypodman.lib.parser_actions import (BooleanAction, BooleanValidate,
|
||||
ChangeAction, PathAction,
|
||||
PositiveIntAction, UnitAction)
|
||||
from pypodman.lib.parser_actions import (ChangeAction, PathAction,
|
||||
PositiveIntAction, SignalAction,
|
||||
UnitAction)
|
||||
from pypodman.lib.podman_parser import PodmanArgumentParser
|
||||
from pypodman.lib.report import Report, ReportColumn
|
||||
|
||||
# Silence pylint overlording...
|
||||
assert BooleanAction
|
||||
assert BooleanValidate
|
||||
assert ChangeAction
|
||||
assert PathAction
|
||||
assert PositiveIntAction
|
||||
assert SignalAction
|
||||
assert UnitAction
|
||||
|
||||
__all__ = [
|
||||
|
@ -17,29 +17,21 @@ class AbstractActionBase(abc.ABC):
|
||||
Use set_defaults() to set attributes "class_" and "method". These will
|
||||
be invoked as class_(parsed_args).method()
|
||||
"""
|
||||
parent.add_argument(
|
||||
parent.add_flag(
|
||||
'--all',
|
||||
action='store_true',
|
||||
help=('list all items.'
|
||||
' (default: no-op, included for compatibility.)'))
|
||||
parent.add_argument(
|
||||
'--no-trunc',
|
||||
'--notruncate',
|
||||
action='store_false',
|
||||
dest='truncate',
|
||||
help='list all items.')
|
||||
parent.add_flag(
|
||||
'--truncate',
|
||||
'--trunc',
|
||||
default=True,
|
||||
help='Display extended information. (default: False)')
|
||||
parent.add_argument(
|
||||
'--noheading',
|
||||
action='store_false',
|
||||
dest='heading',
|
||||
help="Truncate id's and other long fields.")
|
||||
parent.add_flag(
|
||||
'--heading',
|
||||
default=True,
|
||||
help=('Omit the table headings from the output.'
|
||||
' (default: False)'))
|
||||
parent.add_argument(
|
||||
help='Include table headings in the output.')
|
||||
parent.add_flag(
|
||||
'--quiet',
|
||||
action='store_true',
|
||||
help='List only the IDs. (default: %(default)s)')
|
||||
help='List only the IDs.')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct class."""
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Implement common create container arguments together."""
|
||||
|
||||
from pypodman.lib import BooleanAction, UnitAction
|
||||
from pypodman.lib import SignalAction, UnitAction
|
||||
|
||||
|
||||
class CreateArguments():
|
||||
@ -108,11 +108,9 @@ class CreateArguments():
|
||||
metavar='NODES',
|
||||
help=('Memory nodes (MEMs) in which to allow execution (0-3, 0,1).'
|
||||
' Only effective on NUMA systems'))
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--detach',
|
||||
'-d',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help='Detached mode: run the container in the background and'
|
||||
' print the new container ID. (default: False)')
|
||||
parser.add_argument(
|
||||
@ -218,7 +216,7 @@ class CreateArguments():
|
||||
|
||||
# only way for argparse to handle these options.
|
||||
vol_args = {
|
||||
'choices': ['bind', 'tmpfs', 'ignore'],
|
||||
'choices': ('bind', 'tmpfs', 'ignore'),
|
||||
'metavar': 'MODE',
|
||||
'type': str.lower,
|
||||
'help': 'Tells podman how to handle the builtin image volumes',
|
||||
@ -228,12 +226,10 @@ class CreateArguments():
|
||||
volume_group.add_argument('--image-volume', **vol_args)
|
||||
volume_group.add_argument('--builtin-volume', **vol_args)
|
||||
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--interactive',
|
||||
'-i',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help='Keep STDIN open even if not attached. (default: False)')
|
||||
help='Keep STDIN open even if not attached.')
|
||||
parser.add_argument('--ipc', help='Create namespace')
|
||||
parser.add_argument(
|
||||
'--kernel-memory', action=UnitAction, help='Kernel memory limit')
|
||||
@ -278,10 +274,9 @@ class CreateArguments():
|
||||
metavar='BRIDGE',
|
||||
help='Set the Network mode for the container.'
|
||||
' (format: bridge, host, container:UUID, ns:PATH, none)')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--oom-kill-disable',
|
||||
action=BooleanAction,
|
||||
help='Whether to disable OOM Killer for the container or not')
|
||||
help='Whether to disable OOM Killer for the container or not.')
|
||||
parser.add_argument(
|
||||
'--oom-score-adj',
|
||||
choices=range(-1000, 1000),
|
||||
@ -298,41 +293,33 @@ class CreateArguments():
|
||||
help=("Tune the container's pids limit."
|
||||
" Set -1 to have unlimited pids for the container."))
|
||||
parser.add_argument('--pod', help='Run container in an existing pod')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--privileged',
|
||||
action=BooleanAction,
|
||||
help='Give extended privileges to this container.')
|
||||
parser.add_argument(
|
||||
'--publish',
|
||||
'-p',
|
||||
metavar='RANGE',
|
||||
help="Publish a container's port, or range of ports, to the host")
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--publish-all',
|
||||
'-P',
|
||||
action=BooleanAction,
|
||||
help='Publish all exposed ports to random'
|
||||
' ports on the host interfaces'
|
||||
'(default: False)')
|
||||
parser.add_argument(
|
||||
' ports on the host interfaces.')
|
||||
parser.add_flag(
|
||||
'--quiet',
|
||||
'-q',
|
||||
action='store_true',
|
||||
help='Suppress output information when pulling images')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--read-only',
|
||||
action=BooleanAction,
|
||||
help="Mount the container's root filesystem as read only.")
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--rm',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help='Automatically remove the container when it exits.')
|
||||
parser.add_argument(
|
||||
'--rootfs',
|
||||
action='store_true',
|
||||
help=('If specified, the first argument refers to an'
|
||||
' exploded container on the file system of remote host.'))
|
||||
help='If specified, the first argument refers to an'
|
||||
' exploded container on the file system of remote host.')
|
||||
parser.add_argument(
|
||||
'--security-opt',
|
||||
action='append',
|
||||
@ -340,15 +327,14 @@ class CreateArguments():
|
||||
help='Set security options.')
|
||||
parser.add_argument(
|
||||
'--shm-size', action=UnitAction, help='Size of /dev/shm')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--sig-proxy',
|
||||
action=BooleanAction,
|
||||
default=True,
|
||||
help='Proxy signals sent to the podman run'
|
||||
' command to the container process')
|
||||
parser.add_argument(
|
||||
'--stop-signal',
|
||||
metavar='SIGTERM',
|
||||
action=SignalAction,
|
||||
default='TERM',
|
||||
help='Signal to stop a container')
|
||||
parser.add_argument(
|
||||
'--stop-timeout',
|
||||
@ -374,11 +360,9 @@ class CreateArguments():
|
||||
metavar='MOUNT',
|
||||
help='Create a tmpfs mount.'
|
||||
' (default: rw,noexec,nosuid,nodev,size=65536k.)')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--tty',
|
||||
'-t',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help='Allocate a pseudo-TTY for standard input of container.')
|
||||
parser.add_argument(
|
||||
'--uidmap',
|
||||
@ -394,15 +378,16 @@ class CreateArguments():
|
||||
parser.add_argument(
|
||||
'--user',
|
||||
'-u',
|
||||
help=('Sets the username or UID used and optionally'
|
||||
' the groupname or GID for the specified command.'))
|
||||
help='Sets the username or UID used and optionally'
|
||||
' the groupname or GID for the specified command.')
|
||||
parser.add_argument(
|
||||
'--userns',
|
||||
metavar='NAMESPACE',
|
||||
help='Set the user namespace mode for the container')
|
||||
parser.add_argument(
|
||||
'--uts',
|
||||
choices=['host', 'ns'],
|
||||
choices=('host', 'ns'),
|
||||
type=str.lower,
|
||||
help='Set the UTS mode for the container')
|
||||
parser.add_argument('--volume', '-v', help='Create a bind mount.')
|
||||
parser.add_argument(
|
||||
|
@ -2,7 +2,7 @@
|
||||
import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib import AbstractActionBase, BooleanAction, ChangeAction
|
||||
from pypodman.lib import AbstractActionBase, ChangeAction
|
||||
|
||||
|
||||
class Commit(AbstractActionBase):
|
||||
@ -44,17 +44,14 @@ class Commit(AbstractActionBase):
|
||||
help='Set commit message for committed image'
|
||||
' (Only on docker images.)',
|
||||
)
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--pause',
|
||||
'-p',
|
||||
action=BooleanAction,
|
||||
default=True,
|
||||
help='Pause the container when creating an image',
|
||||
)
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--quiet',
|
||||
'-q',
|
||||
action='store_true',
|
||||
help='Suppress output',
|
||||
)
|
||||
parser.add_argument(
|
||||
|
@ -5,8 +5,7 @@ from collections import OrderedDict
|
||||
import humanize
|
||||
|
||||
import podman
|
||||
from pypodman.lib import (AbstractActionBase, BooleanAction, Report,
|
||||
ReportColumn)
|
||||
from pypodman.lib import AbstractActionBase, Report, ReportColumn
|
||||
|
||||
|
||||
class History(AbstractActionBase):
|
||||
@ -17,13 +16,10 @@ class History(AbstractActionBase):
|
||||
"""Add History command to parent parser."""
|
||||
parser = parent.add_parser('history', help='report image history')
|
||||
super().subparser(parser)
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--human',
|
||||
'-H',
|
||||
action=BooleanAction,
|
||||
default='True',
|
||||
help='Display sizes and dates in human readable format.'
|
||||
' (default: %(default)s)')
|
||||
help='Display sizes and dates in human readable format.')
|
||||
parser.add_argument(
|
||||
'--format',
|
||||
choices=('json', 'table'),
|
||||
|
@ -24,11 +24,9 @@ class Images(AbstractActionBase):
|
||||
help=('Change sort ordered of displayed images.'
|
||||
' (default: %(default)s)'))
|
||||
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument(
|
||||
parser.add_flag(
|
||||
'--digests',
|
||||
action='store_true',
|
||||
help='Include digests with images. (default: %(default)s)')
|
||||
help='Include digests with images.')
|
||||
parser.set_defaults(class_=cls, method='list')
|
||||
|
||||
def __init__(self, args):
|
||||
|
@ -22,10 +22,6 @@ class Info(AbstractActionBase):
|
||||
" (default: yaml)")
|
||||
parser.set_defaults(class_=cls, method='info')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Info class."""
|
||||
super().__init__(args)
|
||||
|
||||
def info(self):
|
||||
"""Report on Podman Service."""
|
||||
try:
|
||||
|
@ -22,12 +22,9 @@ class Inspect(AbstractActionBase):
|
||||
type=str.lower,
|
||||
help='Type of object to inspect',
|
||||
)
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--size',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Display the total file size if the type is a container.'
|
||||
' Always True.')
|
||||
help='Display the total file size if the type is a container.')
|
||||
parser.add_argument(
|
||||
'objects',
|
||||
nargs='+',
|
||||
@ -35,10 +32,6 @@ class Inspect(AbstractActionBase):
|
||||
)
|
||||
parser.set_defaults(class_=cls, method='inspect')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Inspect class."""
|
||||
super().__init__(args)
|
||||
|
||||
def _get_container(self, ident):
|
||||
try:
|
||||
logging.debug("Getting container %s", ident)
|
||||
|
@ -1,9 +1,8 @@
|
||||
"""Remote client command for signaling podman containers."""
|
||||
import signal
|
||||
import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib import AbstractActionBase
|
||||
from pypodman.lib import AbstractActionBase, SignalAction
|
||||
|
||||
|
||||
class Kill(AbstractActionBase):
|
||||
@ -16,10 +15,9 @@ class Kill(AbstractActionBase):
|
||||
parser.add_argument(
|
||||
'--signal',
|
||||
'-s',
|
||||
choices=range(1, signal.NSIG),
|
||||
metavar='[1,{}]'.format(signal.NSIG),
|
||||
action=SignalAction,
|
||||
default=9,
|
||||
help='Signal to send to the container. (default: 9)')
|
||||
help='Signal to send to the container. (default: %(default)s)')
|
||||
parser.add_argument(
|
||||
'containers',
|
||||
nargs='+',
|
||||
@ -27,10 +25,6 @@ class Kill(AbstractActionBase):
|
||||
)
|
||||
parser.set_defaults(class_=cls, method='kill')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Kill class."""
|
||||
super().__init__(args)
|
||||
|
||||
def kill(self):
|
||||
"""Signal provided containers."""
|
||||
try:
|
||||
|
@ -19,10 +19,6 @@ class Pause(AbstractActionBase):
|
||||
)
|
||||
parser.set_defaults(class_=cls, method='pause')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Pause class."""
|
||||
super().__init__(args)
|
||||
|
||||
def pause(self):
|
||||
"""Pause provided containers."""
|
||||
try:
|
||||
|
@ -2,7 +2,7 @@
|
||||
import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib import AbstractActionBase, BooleanAction
|
||||
from pypodman.lib import AbstractActionBase
|
||||
|
||||
|
||||
class CreatePod(AbstractActionBase):
|
||||
@ -20,12 +20,9 @@ class CreatePod(AbstractActionBase):
|
||||
type=str,
|
||||
help='Path to cgroups under which the'
|
||||
' cgroup for the pod will be created.')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--infra',
|
||||
action=BooleanAction,
|
||||
default=True,
|
||||
help='Create an infra container and associate it with the pod'
|
||||
'(default: %(default)s)')
|
||||
help='Create an infra container and associate it with the pod.')
|
||||
parser.add_argument(
|
||||
'-l',
|
||||
'--label',
|
||||
|
@ -3,7 +3,7 @@ import signal
|
||||
import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib import AbstractActionBase
|
||||
from pypodman.lib import AbstractActionBase, SignalAction
|
||||
from pypodman.lib import query_model as query_pods
|
||||
|
||||
|
||||
@ -15,18 +15,16 @@ class KillPod(AbstractActionBase):
|
||||
"""Add Pod Kill command to parent parser."""
|
||||
parser = parent.add_parser('kill', help='signal containers in pod')
|
||||
|
||||
parser.add_argument(
|
||||
'-a',
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
action='store_true',
|
||||
help='Sends signal to all pods')
|
||||
'-a',
|
||||
help='Sends signal to all pods.')
|
||||
parser.add_argument(
|
||||
'-s',
|
||||
'--signal',
|
||||
choices=range(1, signal.NSIG),
|
||||
metavar='[1,{}]'.format(signal.NSIG),
|
||||
action=SignalAction,
|
||||
default=9,
|
||||
help='Signal to send to the pod. (default: 9)')
|
||||
help='Signal to send to the pod. (default: %(default)s)')
|
||||
parser.add_argument('pod', nargs='*', help='pod(s) to signal')
|
||||
parser.set_defaults(class_=cls, method='kill')
|
||||
|
||||
|
@ -13,8 +13,10 @@ class PausePod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Pause command to parent parser."""
|
||||
parser = parent.add_parser('pause', help='pause containers in pod')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Pause all pods')
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Pause all pods.')
|
||||
parser.add_argument('pod', nargs='*', help='pod(s) to pause.')
|
||||
parser.set_defaults(class_=cls, method='pause')
|
||||
|
||||
|
@ -14,18 +14,15 @@ class ProcessesPod(AbstractActionBase):
|
||||
parser = parent.add_parser('ps', help='list processes of pod')
|
||||
super().subparser(parser)
|
||||
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--ctr-names',
|
||||
action='store_true',
|
||||
help='Include container name in the info field')
|
||||
parser.add_argument(
|
||||
help='Include container name in the info field.')
|
||||
parser.add_flag(
|
||||
'--ctr-ids',
|
||||
action='store_true',
|
||||
help='Include container ID in the info field')
|
||||
parser.add_argument(
|
||||
help='Include container ID in the info field.')
|
||||
parser.add_flag(
|
||||
'--ctr-status',
|
||||
action='store_true',
|
||||
help='Include container status in the info field')
|
||||
help='Include container status in the info field.')
|
||||
parser.add_argument(
|
||||
'--format',
|
||||
choices=('json'),
|
||||
|
@ -13,13 +13,14 @@ class RemovePod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Rm command to parent parser."""
|
||||
parser = parent.add_parser('rm', help='Delete pod and container(s)')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Remove all pods')
|
||||
parser.add_argument(
|
||||
'-f',
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Remove all pods.')
|
||||
parser.add_flag(
|
||||
'--force',
|
||||
action='store_true',
|
||||
help='Stop and remove container(s) then delete pod')
|
||||
'-f',
|
||||
help='Stop and remove container(s) then delete pod.')
|
||||
parser.add_argument(
|
||||
'pod', nargs='*', help='Pod to remove. Or, use --all')
|
||||
parser.set_defaults(class_=cls, method='remove')
|
||||
|
@ -13,8 +13,10 @@ class RestartPod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Restart command to parent parser."""
|
||||
parser = parent.add_parser('restart', help='restart containers in pod')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Restart all pods')
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Restart all pods.')
|
||||
parser.add_argument(
|
||||
'pod', nargs='*', help='Pod to restart. Or, use --all')
|
||||
parser.set_defaults(class_=cls, method='restart')
|
||||
|
@ -14,8 +14,10 @@ class StartPod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Start command to parent parser."""
|
||||
parser = parent.add_parser('start', help='start pod')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Start all pods')
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Start all pods.')
|
||||
parser.add_argument(
|
||||
'pod', nargs='*', help='Pod to start. Or, use --all')
|
||||
parser.set_defaults(class_=cls, method='start')
|
||||
|
@ -13,8 +13,10 @@ class StopPod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Stop command to parent parser."""
|
||||
parser = parent.add_parser('stop', help='stop pod')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Stop all pods')
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Stop all pods.')
|
||||
parser.add_argument(
|
||||
'pod', nargs='*', help='Pod to stop. Or, use --all')
|
||||
parser.set_defaults(class_=cls, method='stop')
|
||||
|
@ -13,8 +13,10 @@ class UnpausePod(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Pod Unpause command to parent parser."""
|
||||
parser = parent.add_parser('unpause', help='unpause pod')
|
||||
parser.add_argument(
|
||||
'-a', '--all', action='store_true', help='Unpause all pods')
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
help='Unpause all pods.')
|
||||
parser.add_argument(
|
||||
'pod', nargs='*', help='Pod to unpause. Or, use --all')
|
||||
parser.set_defaults(class_=cls, method='unpause')
|
||||
|
@ -5,6 +5,8 @@ import sys
|
||||
|
||||
from pypodman.lib import AbstractActionBase
|
||||
|
||||
# pylint: disable=wildcard-import
|
||||
# pylint: disable=unused-wildcard-import
|
||||
from .pod import *
|
||||
|
||||
|
||||
|
@ -13,16 +13,13 @@ class Port(AbstractActionBase):
|
||||
"""Add Port command to parent parser."""
|
||||
parser = parent.add_parser(
|
||||
'port', help='retrieve ports from containers')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--all',
|
||||
'-a',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='List all known port mappings for running containers')
|
||||
parser.add_argument(
|
||||
'containers',
|
||||
nargs='*',
|
||||
default=None,
|
||||
help='containers to list ports',
|
||||
)
|
||||
parser.set_defaults(class_=cls, method='port')
|
||||
@ -61,3 +58,4 @@ class Port(AbstractActionBase):
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
return 1
|
||||
return 0
|
||||
|
@ -15,12 +15,10 @@ class Push(AbstractActionBase):
|
||||
'push',
|
||||
help='push image elsewhere',
|
||||
)
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--tlsverify',
|
||||
action='store_true',
|
||||
default=True,
|
||||
help='Require HTTPS and verify certificates when'
|
||||
' contacting registries (default: %(default)s)')
|
||||
' contacting registries.')
|
||||
parser.add_argument(
|
||||
'image', nargs=1, help='name or id of image to push')
|
||||
parser.add_argument(
|
||||
@ -30,10 +28,6 @@ class Push(AbstractActionBase):
|
||||
)
|
||||
parser.set_defaults(class_=cls, method='push')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Push class."""
|
||||
super().__init__(args)
|
||||
|
||||
def pull(self):
|
||||
"""Store image elsewhere."""
|
||||
try:
|
||||
|
@ -23,10 +23,6 @@ class Restart(AbstractActionBase):
|
||||
'targets', nargs='+', help='container id(s) to restart')
|
||||
parser.set_defaults(class_=cls, method='restart')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Restart class."""
|
||||
super().__init__(args)
|
||||
|
||||
def restart(self):
|
||||
"""Restart container(s)."""
|
||||
try:
|
||||
|
@ -12,20 +12,14 @@ class Rm(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Rm command to parent parser."""
|
||||
parser = parent.add_parser('rm', help='delete container(s)')
|
||||
parser.add_argument(
|
||||
'-f',
|
||||
parser.add_flag(
|
||||
'--force',
|
||||
action='store_true',
|
||||
help=('force delete of running container(s).'
|
||||
' (default: %(default)s)'))
|
||||
'-f',
|
||||
help='force delete of running container(s).')
|
||||
parser.add_argument(
|
||||
'targets', nargs='+', help='container id(s) to delete')
|
||||
parser.set_defaults(class_=cls, method='remove')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Rm class."""
|
||||
super().__init__(args)
|
||||
|
||||
def remove(self):
|
||||
"""Remove container(s)."""
|
||||
for ident in self._args.targets:
|
||||
|
@ -12,19 +12,13 @@ class Rmi(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Rmi command to parent parser."""
|
||||
parser = parent.add_parser('rmi', help='delete image(s)')
|
||||
parser.add_argument(
|
||||
'-f',
|
||||
parser.add_flag(
|
||||
'--force',
|
||||
action='store_true',
|
||||
help=('force delete of image(s) and associated containers.'
|
||||
' (default: %(default)s)'))
|
||||
'-f',
|
||||
help='force delete of image(s) and associated containers.')
|
||||
parser.add_argument('targets', nargs='+', help='image id(s) to delete')
|
||||
parser.set_defaults(class_=cls, method='remove')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Rmi class."""
|
||||
super().__init__(args)
|
||||
|
||||
def remove(self):
|
||||
"""Remove image(s)."""
|
||||
for ident in self._args.targets:
|
||||
|
@ -4,8 +4,8 @@ import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
import podman
|
||||
from pypodman.lib import (AbstractActionBase, BooleanValidate,
|
||||
PositiveIntAction, Report, ReportColumn)
|
||||
from pypodman.lib import (AbstractActionBase, PositiveIntAction, Report,
|
||||
ReportColumn)
|
||||
|
||||
|
||||
class FilterAction(argparse.Action):
|
||||
@ -58,16 +58,16 @@ class FilterAction(argparse.Action):
|
||||
if val < 0:
|
||||
parser.error(msg)
|
||||
elif opt == 'is-automated':
|
||||
try:
|
||||
val = BooleanValidate()(val)
|
||||
except ValueError:
|
||||
if val.capitalize() in ('True', 'False'):
|
||||
val = bool(val)
|
||||
else:
|
||||
msg = ('{} option "is-automated"'
|
||||
' must be True or False.'.format(self.dest))
|
||||
parser.error(msg)
|
||||
elif opt == 'is-official':
|
||||
try:
|
||||
val = BooleanValidate()(val)
|
||||
except ValueError:
|
||||
if val.capitalize() in ('True', 'False'):
|
||||
val = bool(val)
|
||||
else:
|
||||
msg = ('{} option "is-official"'
|
||||
' must be True or False.'.format(self.dest))
|
||||
parser.error(msg)
|
||||
|
@ -2,7 +2,7 @@
|
||||
import sys
|
||||
|
||||
import podman
|
||||
from pypodman.lib import AbstractActionBase, BooleanAction
|
||||
from pypodman.lib import AbstractActionBase
|
||||
|
||||
|
||||
class Start(AbstractActionBase):
|
||||
@ -12,12 +12,10 @@ class Start(AbstractActionBase):
|
||||
def subparser(cls, parent):
|
||||
"""Add Start command to parent parser."""
|
||||
parser = parent.add_parser('start', help='start container')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--attach',
|
||||
'-a',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help="Attach container's STDOUT and STDERR (default: %(default)s)")
|
||||
help="Attach container's STDOUT and STDERR.")
|
||||
parser.add_argument(
|
||||
'--detach-keys',
|
||||
metavar='KEY(s)',
|
||||
@ -25,18 +23,14 @@ class Start(AbstractActionBase):
|
||||
help='Override the key sequence for detaching a container.'
|
||||
' (format: a single character [a-Z] or ctrl-<value> where'
|
||||
' <value> is one of: a-z, @, ^, [, , or _) (default: ^D)')
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--interactive',
|
||||
'-i',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help="Attach container's STDIN (default: %(default)s)")
|
||||
help="Attach container's STDIN.")
|
||||
# TODO: Implement sig-proxy
|
||||
parser.add_argument(
|
||||
parser.add_flag(
|
||||
'--sig-proxy',
|
||||
action=BooleanAction,
|
||||
default=False,
|
||||
help="Proxy received signals to the process (default: %(default)s)"
|
||||
help="Proxy received signals to the process."
|
||||
)
|
||||
parser.add_argument(
|
||||
'containers',
|
||||
@ -74,3 +68,4 @@ class Start(AbstractActionBase):
|
||||
file=sys.stderr,
|
||||
flush=True)
|
||||
return 1
|
||||
return 0
|
||||
|
@ -1,9 +1,7 @@
|
||||
"""Remote client command for reporting on Podman service."""
|
||||
import json
|
||||
import sys
|
||||
|
||||
import podman
|
||||
import yaml
|
||||
from pypodman.lib import AbstractActionBase
|
||||
|
||||
|
||||
@ -17,10 +15,6 @@ class Version(AbstractActionBase):
|
||||
'version', help='report version on podman service')
|
||||
parser.set_defaults(class_=cls, method='version')
|
||||
|
||||
def __init__(self, args):
|
||||
"""Construct Version class."""
|
||||
super().__init__(args)
|
||||
|
||||
def version(self):
|
||||
"""Report on Podman Service."""
|
||||
try:
|
||||
|
@ -6,6 +6,7 @@ The constructors are very verbose but remain for IDE support.
|
||||
import argparse
|
||||
import copy
|
||||
import os
|
||||
import signal
|
||||
|
||||
# API defined by argparse.Action therefore shut up pylint
|
||||
# pragma pylint: disable=redefined-builtin
|
||||
@ -13,22 +14,8 @@ import os
|
||||
# pragma pylint: disable=too-many-arguments
|
||||
|
||||
|
||||
class BooleanValidate():
|
||||
"""Validate value is boolean string."""
|
||||
|
||||
def __call__(self, value):
|
||||
"""Return True, False or raise ValueError."""
|
||||
val = value.capitalize()
|
||||
if val == 'False':
|
||||
return False
|
||||
elif val == 'True':
|
||||
return True
|
||||
else:
|
||||
raise ValueError('"{}" is not True or False'.format(value))
|
||||
|
||||
|
||||
class BooleanAction(argparse.Action):
|
||||
"""Convert and validate bool argument."""
|
||||
class ChangeAction(argparse.Action):
|
||||
"""Convert and validate change argument."""
|
||||
|
||||
def __init__(self,
|
||||
option_strings,
|
||||
@ -40,47 +27,12 @@ class BooleanAction(argparse.Action):
|
||||
choices=None,
|
||||
required=False,
|
||||
help=None,
|
||||
metavar='{True,False}'):
|
||||
"""Create BooleanAction object."""
|
||||
super().__init__(
|
||||
option_strings=option_strings,
|
||||
dest=dest,
|
||||
nargs=nargs,
|
||||
const=const,
|
||||
default=default,
|
||||
type=type,
|
||||
choices=choices,
|
||||
required=required,
|
||||
help=help,
|
||||
metavar=metavar)
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
"""Convert and Validate input."""
|
||||
try:
|
||||
val = BooleanValidate()(values)
|
||||
except ValueError:
|
||||
parser.error('"{}" must be True or False.'.format(option_string))
|
||||
else:
|
||||
setattr(namespace, self.dest, val)
|
||||
|
||||
|
||||
class ChangeAction(argparse.Action):
|
||||
"""Convert and validate change argument."""
|
||||
|
||||
def __init__(self,
|
||||
option_strings,
|
||||
dest,
|
||||
nargs=None,
|
||||
const=None,
|
||||
default=[],
|
||||
type=None,
|
||||
choices=None,
|
||||
required=False,
|
||||
help=None,
|
||||
metavar='OPT=VALUE'):
|
||||
"""Create ChangeAction object."""
|
||||
help = (help or '') + ('Apply change(s) to the new image.'
|
||||
' May be given multiple times.')
|
||||
if default is None:
|
||||
default = []
|
||||
|
||||
super().__init__(
|
||||
option_strings=option_strings,
|
||||
@ -102,7 +54,7 @@ class ChangeAction(argparse.Action):
|
||||
choices = ('CMD', 'ENTRYPOINT', 'ENV', 'EXPOSE', 'LABEL', 'ONBUILD',
|
||||
'STOPSIGNAL', 'USER', 'VOLUME', 'WORKDIR')
|
||||
|
||||
opt, val = values.split('=', 1)
|
||||
opt, _ = values.split('=', 1)
|
||||
if opt not in choices:
|
||||
parser.error('Option "{}" is not supported by argument "{}",'
|
||||
' valid options are: {}'.format(
|
||||
@ -111,6 +63,70 @@ class ChangeAction(argparse.Action):
|
||||
setattr(namespace, self.dest, items)
|
||||
|
||||
|
||||
class SignalAction(argparse.Action):
|
||||
"""Validate input as a signal."""
|
||||
|
||||
def __init__(self,
|
||||
option_strings,
|
||||
dest,
|
||||
nargs=None,
|
||||
const=None,
|
||||
default=None,
|
||||
type=str,
|
||||
choices=None,
|
||||
required=False,
|
||||
help='The signal to send.'
|
||||
' It may be given as a name or a number.',
|
||||
metavar='SIGNAL'):
|
||||
"""Create SignalAction object."""
|
||||
super().__init__(
|
||||
option_strings=option_strings,
|
||||
dest=dest,
|
||||
nargs=nargs,
|
||||
const=const,
|
||||
default=default,
|
||||
type=type,
|
||||
choices=choices,
|
||||
required=required,
|
||||
help=help,
|
||||
metavar=metavar)
|
||||
|
||||
if hasattr(signal, "Signals"):
|
||||
|
||||
def _signal_number(signame):
|
||||
cooked = 'SIG{}'.format(signame)
|
||||
try:
|
||||
return signal.Signals[cooked].value
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
|
||||
def _signal_number(signame):
|
||||
cooked = 'SIG{}'.format(signame)
|
||||
for n, v in sorted(signal.__dict__.items()):
|
||||
if n != cooked:
|
||||
continue
|
||||
if n.startswith("SIG") and not n.startswith("SIG_"):
|
||||
return v
|
||||
|
||||
self._signal_number = _signal_number
|
||||
|
||||
def __call__(self, parser, namespace, values, option_string=None):
|
||||
"""Validate input is a signal for platform."""
|
||||
if values.isdigit():
|
||||
signum = int(values)
|
||||
if signal.SIGRTMIN <= signum >= signal.SIGRTMAX:
|
||||
raise ValueError('"{}" is not a valid signal. {}-{}'.format(
|
||||
values, signal.SIGRTMIN, signal.SIGRTMAX))
|
||||
else:
|
||||
signum = self._signal_number(values)
|
||||
if signum is None:
|
||||
parser.error(
|
||||
'"{}" is not a valid signal,'
|
||||
' see your platform documentation.'.format(values))
|
||||
setattr(namespace, self.dest, signum)
|
||||
|
||||
|
||||
class UnitAction(argparse.Action):
|
||||
"""Validate number given is positive integer, with optional suffix."""
|
||||
|
||||
|
@ -48,6 +48,18 @@ class PodmanArgumentParser(argparse.ArgumentParser):
|
||||
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def add_flag(self, *args, **kwargs):
|
||||
"""Add flag to parser."""
|
||||
flags = [a for a in args if a[0] in self.prefix_chars]
|
||||
dest = flags[0].lstrip(self.prefix_chars)
|
||||
no_flag = '{0}{0}no-{1}'.format(self.prefix_chars, dest)
|
||||
|
||||
group = self.add_mutually_exclusive_group(required=False)
|
||||
group.add_argument(*flags, action='store_true', dest=dest, **kwargs)
|
||||
group.add_argument(no_flag, action='store_false', dest=dest, **kwargs)
|
||||
default = kwargs.get('default', False)
|
||||
self.set_defaults(**{dest: default})
|
||||
|
||||
def initialize_parser(self):
|
||||
"""Initialize parser without causing recursion meltdown."""
|
||||
self.add_argument(
|
||||
|
Reference in New Issue
Block a user