summaryrefslogtreecommitdiff
path: root/contrib/python/pypodman
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/python/pypodman')
-rw-r--r--contrib/python/pypodman/Makefile6
-rw-r--r--contrib/python/pypodman/docs/man1/pypodman.12
-rw-r--r--contrib/python/pypodman/pypodman/lib/__init__.py9
-rw-r--r--contrib/python/pypodman/pypodman/lib/action_base.py30
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/__init__.py4
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/_create_args.py61
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/commit_action.py27
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/create_action.py2
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/history_action.py10
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/images_action.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/info_action.py4
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/inspect_action.py23
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/kill_action.py12
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pause_action.py4
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py9
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py14
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py15
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py13
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/pod_action.py2
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/port_action.py6
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/ps_action.py19
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/push_action.py10
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/restart_action.py4
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/rm_action.py12
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/rmi_action.py12
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/run_action.py2
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/search_action.py16
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/start_action.py71
-rw-r--r--contrib/python/pypodman/pypodman/lib/actions/version_action.py35
-rw-r--r--contrib/python/pypodman/pypodman/lib/parser_actions.py133
-rw-r--r--contrib/python/pypodman/pypodman/lib/podman_parser.py29
36 files changed, 359 insertions, 273 deletions
diff --git a/contrib/python/pypodman/Makefile b/contrib/python/pypodman/Makefile
index cd0fcf1de..230eee44d 100644
--- a/contrib/python/pypodman/Makefile
+++ b/contrib/python/pypodman/Makefile
@@ -1,9 +1,10 @@
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:
+ PODMAN_VERSION=$(PODMAN_VERSION) \
$(PYTHON) setup.py sdist bdist
.PHONY: lint
@@ -16,11 +17,12 @@ integration:
.PHONY: install
install:
+ PODMAN_VERSION=$(PODMAN_VERSION) \
$(PYTHON) setup.py install --root ${DESTDIR}
.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
diff --git a/contrib/python/pypodman/docs/man1/pypodman.1 b/contrib/python/pypodman/docs/man1/pypodman.1
index 09acb205b..45472dab0 100644
--- a/contrib/python/pypodman/docs/man1/pypodman.1
+++ b/contrib/python/pypodman/docs/man1/pypodman.1
@@ -85,7 +85,7 @@ overwriting earlier. Any missing items are ignored.
.IP \[bu] 2
From \f[C]\-\-config\-home\f[] command line option + \f[C]pypodman/pypodman.conf\f[]
.IP \[bu] 2
-From environment variable, for example: RUN_DIR
+From environment variable prefixed with PODMAN_, for example: PODMAN_RUN_DIR
.IP \[bu] 2
From command line option, for example: \[en]run\-dir
.PP
diff --git a/contrib/python/pypodman/pypodman/lib/__init__.py b/contrib/python/pypodman/pypodman/lib/__init__.py
index be1b5f467..d9a434254 100644
--- a/contrib/python/pypodman/pypodman/lib/__init__.py
+++ b/contrib/python/pypodman/pypodman/lib/__init__.py
@@ -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__ = [
diff --git a/contrib/python/pypodman/pypodman/lib/action_base.py b/contrib/python/pypodman/pypodman/lib/action_base.py
index a950c362b..5cba7ac5c 100644
--- a/contrib/python/pypodman/pypodman/lib/action_base.py
+++ b/contrib/python/pypodman/pypodman/lib/action_base.py
@@ -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."""
diff --git a/contrib/python/pypodman/pypodman/lib/actions/__init__.py b/contrib/python/pypodman/pypodman/lib/actions/__init__.py
index 2668cd8ff..c0d77ddb1 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/__init__.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/__init__.py
@@ -22,6 +22,8 @@ from pypodman.lib.actions.rm_action import Rm
from pypodman.lib.actions.rmi_action import Rmi
from pypodman.lib.actions.run_action import Run
from pypodman.lib.actions.search_action import Search
+from pypodman.lib.actions.start_action import Start
+from pypodman.lib.actions.version_action import Version
__all__ = [
'Attach',
@@ -47,4 +49,6 @@ __all__ = [
'Rmi',
'Run',
'Search',
+ 'Start',
+ 'Version',
]
diff --git a/contrib/python/pypodman/pypodman/lib/actions/_create_args.py b/contrib/python/pypodman/pypodman/lib/actions/_create_args.py
index 207f52796..8ab4292e8 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/_create_args.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/_create_args.py
@@ -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(
diff --git a/contrib/python/pypodman/pypodman/lib/actions/commit_action.py b/contrib/python/pypodman/pypodman/lib/actions/commit_action.py
index 21665ad0b..c166e1aff 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/commit_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/commit_action.py
@@ -2,7 +2,7 @@
import sys
import podman
-from pypodman.lib import AbstractActionBase, BooleanAction, ChangeAction
+from pypodman.lib import AbstractActionBase, ChangeAction
class Commit(AbstractActionBase):
@@ -30,7 +30,8 @@ class Commit(AbstractActionBase):
choices=('oci', 'docker'),
default='oci',
type=str.lower,
- help='Set the format of the image manifest and metadata',
+ help='Set the format of the image manifest and metadata.'
+ ' (Ignored.)',
)
parser.add_argument(
'--iidfile',
@@ -40,19 +41,17 @@ class Commit(AbstractActionBase):
parser.add_argument(
'--message',
'-m',
- help='Set commit message for committed image',
+ 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(
@@ -80,8 +79,16 @@ class Commit(AbstractActionBase):
flush=True)
return 1
else:
- ident = ctnr.commit(self.opts['image'][0], **self.opts)
- print(ident)
+ ident = ctnr.commit(
+ self.opts['image'][0],
+ change=self.opts.get('change', None),
+ message=self.opts.get('message', None),
+ pause=self.opts['pause'],
+ author=self.opts.get('author', None),
+ )
+
+ if not self.opts['quiet']:
+ print(ident)
except podman.ErrorOccurred as e:
sys.stdout.flush()
print(
diff --git a/contrib/python/pypodman/pypodman/lib/actions/create_action.py b/contrib/python/pypodman/pypodman/lib/actions/create_action.py
index d9631763a..26a312bb1 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/create_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/create_action.py
@@ -21,7 +21,7 @@ class Create(AbstractActionBase):
parser.add_argument('image', nargs=1, help='source image id')
parser.add_argument(
'command',
- nargs='*',
+ nargs=parent.REMAINDER,
help='command and args to run.',
)
parser.set_defaults(class_=cls, method='create')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/history_action.py b/contrib/python/pypodman/pypodman/lib/actions/history_action.py
index f9aaa54f6..76c3ad756 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/history_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/history_action.py
@@ -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'),
diff --git a/contrib/python/pypodman/pypodman/lib/actions/images_action.py b/contrib/python/pypodman/pypodman/lib/actions/images_action.py
index 29bf90dd2..21376eeeb 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/images_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/images_action.py
@@ -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):
diff --git a/contrib/python/pypodman/pypodman/lib/actions/info_action.py b/contrib/python/pypodman/pypodman/lib/actions/info_action.py
index 988284541..3c854a358 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/info_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/info_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py b/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py
index 514b4702a..ca5ad2215 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/inspect_action.py
@@ -22,12 +22,9 @@ class Inspect(AbstractActionBase):
type=str.lower,
help='Type of object to inspect',
)
- parser.add_argument(
- 'size',
- action='store_true',
- default=True,
- help='Display the total file size if the type is a container.'
- ' Always True.')
+ parser.add_flag(
+ '--size',
+ 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)
@@ -59,7 +52,7 @@ class Inspect(AbstractActionBase):
def inspect(self):
"""Inspect provided podman objects."""
- output = {}
+ output = []
try:
for ident in self._args.objects:
obj = None
@@ -78,7 +71,13 @@ class Inspect(AbstractActionBase):
msg = 'Object "{}" not found'.format(ident)
print(msg, file=sys.stderr, flush=True)
else:
- output.update(obj._asdict())
+ fields = obj._asdict()
+ if not self._args.size:
+ try:
+ del fields['sizerootfs']
+ except KeyError:
+ pass
+ output.append(fields)
except podman.ErrorOccurred as e:
sys.stdout.flush()
print(
diff --git a/contrib/python/pypodman/pypodman/lib/actions/kill_action.py b/contrib/python/pypodman/pypodman/lib/actions/kill_action.py
index cb3d3f035..e8fb4e74d 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/kill_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/kill_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pause_action.py b/contrib/python/pypodman/pypodman/lib/actions/pause_action.py
index ab64d8b81..7dc02f7fe 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pause_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pause_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py
index 46c1e3e51..4e0bde777 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/create_parser.py
@@ -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',
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py
index 430ec34e0..9b6229939 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/kill_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py
index daae028d4..c751314ca 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/pause_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py
index ecfcb883a..855e313c7 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/processes_parser.py
@@ -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'),
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py
index 40eeb7203..289325d14 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/remove_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py
index af489ad28..53f45b6de 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/restart_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py
index 0ddc336bf..ff62b839e 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/start_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py
index 7054fd38a..cbf2bf1e7 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/stop_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py b/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py
index 90e1ddbe2..5186cf9cc 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod/unpause_parser.py
@@ -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')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/pod_action.py b/contrib/python/pypodman/pypodman/lib/actions/pod_action.py
index 046af34bb..4b8997a05 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/pod_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/pod_action.py
@@ -5,6 +5,8 @@ import sys
from pypodman.lib import AbstractActionBase
+# pylint: disable=wildcard-import
+# pylint: disable=unused-wildcard-import
from .pod import *
diff --git a/contrib/python/pypodman/pypodman/lib/actions/port_action.py b/contrib/python/pypodman/pypodman/lib/actions/port_action.py
index d2a8ded46..6913f3813 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/port_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/port_action.py
@@ -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
diff --git a/contrib/python/pypodman/pypodman/lib/actions/ps_action.py b/contrib/python/pypodman/pypodman/lib/actions/ps_action.py
index cd7a7947d..62ceb2e67 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/ps_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/ps_action.py
@@ -16,6 +16,7 @@ class Ps(AbstractActionBase):
"""Add Images command to parent parser."""
parser = parent.add_parser('ps', help='list containers')
super().subparser(parser)
+
parser.add_argument(
'--sort',
choices=('createdat', 'id', 'image', 'names', 'runningfor', 'size',
@@ -32,9 +33,9 @@ class Ps(AbstractActionBase):
self.columns = OrderedDict({
'id':
- ReportColumn('id', 'CONTAINER ID', 14),
+ ReportColumn('id', 'CONTAINER ID', 12),
'image':
- ReportColumn('image', 'IMAGE', 30),
+ ReportColumn('image', 'IMAGE', 31),
'command':
ReportColumn('column', 'COMMAND', 20),
'createdat':
@@ -49,10 +50,15 @@ class Ps(AbstractActionBase):
def list(self):
"""List containers."""
+ if self._args.all:
+ ictnrs = self.client.containers.list()
+ else:
+ ictnrs = filter(
+ lambda c: podman.FoldedString(c['status']) == 'running',
+ self.client.containers.list())
+
# TODO: Verify sorting on dates and size
- ctnrs = sorted(
- self.client.containers.list(),
- key=operator.attrgetter(self._args.sort))
+ ctnrs = sorted(ictnrs, key=operator.attrgetter(self._args.sort))
if not ctnrs:
return
@@ -65,9 +71,6 @@ class Ps(AbstractActionBase):
'createdat':
humanize.naturaldate(podman.datetime_parse(ctnr.createdat)),
})
-
- if self._args.truncate:
- fields.update({'image': ctnr.image[-30:]})
rows.append(fields)
with Report(self.columns, heading=self._args.heading) as report:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/push_action.py b/contrib/python/pypodman/pypodman/lib/actions/push_action.py
index 0030cb5b9..8e86ca335 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/push_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/push_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/restart_action.py b/contrib/python/pypodman/pypodman/lib/actions/restart_action.py
index d99d1ad65..415594920 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/restart_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/restart_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/rm_action.py b/contrib/python/pypodman/pypodman/lib/actions/rm_action.py
index e8074ef4e..99ff6c460 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/rm_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/rm_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py b/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py
index c6ba835cb..7c3d0bd79 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/rmi_action.py
@@ -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:
diff --git a/contrib/python/pypodman/pypodman/lib/actions/run_action.py b/contrib/python/pypodman/pypodman/lib/actions/run_action.py
index a63eb7917..6a6b3cb2c 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/run_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/run_action.py
@@ -21,7 +21,7 @@ class Run(AbstractActionBase):
parser.add_argument('image', nargs=1, help='source image id.')
parser.add_argument(
'command',
- nargs='*',
+ nargs=parent.REMAINDER,
help='command and args to run.',
)
parser.set_defaults(class_=cls, method='run')
diff --git a/contrib/python/pypodman/pypodman/lib/actions/search_action.py b/contrib/python/pypodman/pypodman/lib/actions/search_action.py
index d2a585d92..b7b8b465d 100644
--- a/contrib/python/pypodman/pypodman/lib/actions/search_action.py
+++ b/contrib/python/pypodman/pypodman/lib/actions/search_action.py
@@ -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)
diff --git a/contrib/python/pypodman/pypodman/lib/actions/start_action.py b/contrib/python/pypodman/pypodman/lib/actions/start_action.py
new file mode 100644
index 000000000..5f88731dc
--- /dev/null
+++ b/contrib/python/pypodman/pypodman/lib/actions/start_action.py
@@ -0,0 +1,71 @@
+"""Remote client command for starting containers."""
+import sys
+
+import podman
+from pypodman.lib import AbstractActionBase
+
+
+class Start(AbstractActionBase):
+ """Class for starting container."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """Add Start command to parent parser."""
+ parser = parent.add_parser('start', help='start container')
+ parser.add_flag(
+ '--attach',
+ '-a',
+ help="Attach container's STDOUT and STDERR.")
+ parser.add_argument(
+ '--detach-keys',
+ metavar='KEY(s)',
+ default=4,
+ 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_flag(
+ '--interactive',
+ '-i',
+ help="Attach container's STDIN.")
+ # TODO: Implement sig-proxy
+ parser.add_flag(
+ '--sig-proxy',
+ help="Proxy received signals to the process."
+ )
+ parser.add_argument(
+ 'containers',
+ nargs='+',
+ help='containers to start',
+ )
+ parser.set_defaults(class_=cls, method='start')
+
+ def start(self):
+ """Start provided containers."""
+ stdin = sys.stdin if self.opts['interactive'] else None
+ stdout = sys.stdout if self.opts['attach'] else None
+
+ try:
+ for ident in self._args.containers:
+ try:
+ ctnr = self.client.containers.get(ident)
+ ctnr.attach(
+ eot=self.opts['detach_keys'],
+ stdin=stdin,
+ stdout=stdout)
+ ctnr.start()
+ except podman.ContainerNotFound as e:
+ sys.stdout.flush()
+ print(
+ 'Container "{}" not found'.format(e.name),
+ file=sys.stderr,
+ flush=True)
+ else:
+ print(ident)
+ except podman.ErrorOccurred as e:
+ sys.stdout.flush()
+ print(
+ '{}'.format(e.reason).capitalize(),
+ file=sys.stderr,
+ flush=True)
+ return 1
+ return 0
diff --git a/contrib/python/pypodman/pypodman/lib/actions/version_action.py b/contrib/python/pypodman/pypodman/lib/actions/version_action.py
new file mode 100644
index 000000000..29a0cabe4
--- /dev/null
+++ b/contrib/python/pypodman/pypodman/lib/actions/version_action.py
@@ -0,0 +1,35 @@
+"""Remote client command for reporting on Podman service."""
+import sys
+
+import podman
+from pypodman.lib import AbstractActionBase
+
+
+class Version(AbstractActionBase):
+ """Class for reporting on Podman Service."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """Add Version command to parent parser."""
+ parser = parent.add_parser(
+ 'version', help='report version on podman service')
+ parser.set_defaults(class_=cls, method='version')
+
+ def version(self):
+ """Report on Podman Service."""
+ try:
+ info = self.client.system.info()
+ except podman.ErrorOccurred as e:
+ sys.stdout.flush()
+ print(
+ '{}'.format(e.reason).capitalize(),
+ file=sys.stderr,
+ flush=True)
+ return 1
+ else:
+ version = info._asdict()['podman']
+ host = info._asdict()['host']
+ print("Version {}".format(version['podman_version']))
+ print("Go Version {}".format(version['go_version']))
+ print("Git Commit {}".format(version['git_commit']))
+ print("OS/Arch {}/{}".format(host["os"], host["arch"]))
diff --git a/contrib/python/pypodman/pypodman/lib/parser_actions.py b/contrib/python/pypodman/pypodman/lib/parser_actions.py
index c10b85495..3ff12cab8 100644
--- a/contrib/python/pypodman/pypodman/lib/parser_actions.py
+++ b/contrib/python/pypodman/pypodman/lib/parser_actions.py
@@ -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,
@@ -37,11 +24,16 @@ class BooleanAction(argparse.Action):
const=None,
default=None,
type=None,
- choices=('True', 'False'),
+ choices=None,
required=False,
help=None,
- metavar='{True,False}'):
- """Create BooleanAction object."""
+ 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,
dest=dest,
@@ -56,32 +48,37 @@ class BooleanAction(argparse.Action):
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(self.dest))
- else:
- setattr(namespace, self.dest, val)
+ items = getattr(namespace, self.dest, None) or []
+ items = copy.copy(items)
+ choices = ('CMD', 'ENTRYPOINT', 'ENV', 'EXPOSE', 'LABEL', 'ONBUILD',
+ 'STOPSIGNAL', 'USER', 'VOLUME', 'WORKDIR')
-class ChangeAction(argparse.Action):
- """Convert and validate change argument."""
+ opt, _ = values.split('=', 1)
+ if opt not in choices:
+ parser.error('Option "{}" is not supported by argument "{}",'
+ ' valid options are: {}'.format(
+ opt, option_string, ', '.join(choices)))
+ items.append(values)
+ 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=[],
- type=None,
+ default=None,
+ type=str,
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.')
-
+ 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,
@@ -94,22 +91,40 @@ class ChangeAction(argparse.Action):
help=help,
metavar=metavar)
- def __call__(self, parser, namespace, values, option_string=None):
- """Convert and Validate input."""
- print(self.dest)
- items = getattr(namespace, self.dest, None) or []
- items = copy.copy(items)
+ if hasattr(signal, "Signals"):
- choices = ('CMD', 'ENTRYPOINT', 'ENV', 'EXPOSE', 'LABEL', 'ONBUILD',
- 'STOPSIGNAL', 'USER', 'VOLUME', 'WORKDIR')
+ def _signal_number(signame):
+ cooked = 'SIG{}'.format(signame)
+ try:
+ return signal.Signals[cooked].value
+ except ValueError:
+ pass
+ else:
- opt, val = values.split('=', 1)
- if opt not in choices:
- parser.error('{} is not a supported "--change" option,'
- ' valid options are: {}'.format(
- opt, ', '.join(choices)))
- items.append(values)
- setattr(namespace, self.dest, items)
+ 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):
@@ -127,8 +142,8 @@ class UnitAction(argparse.Action):
help=None,
metavar='UNIT'):
"""Create UnitAction object."""
- help = (help or metavar or dest
- ) + ' (format: <number>[<unit>], where unit = b, k, m or g)'
+ help = (help or metavar or dest)\
+ + ' (format: <number>[<unit>], where unit = b, k, m or g)'
super().__init__(
option_strings=option_strings,
dest=dest,
@@ -148,15 +163,15 @@ class UnitAction(argparse.Action):
except ValueError:
if not values[:-1].isdigit():
msg = ('{} must be a positive integer,'
- ' with optional suffix').format(self.dest)
+ ' with optional suffix').format(option_string)
parser.error(msg)
if not values[-1] in ('b', 'k', 'm', 'g'):
msg = '{} only supports suffices of: b, k, m, g'.format(
- self.dest)
+ option_string)
parser.error(msg)
else:
if val <= 0:
- msg = '{} must be a positive integer'.format(self.dest)
+ msg = '{} must be a positive integer'.format(option_string)
parser.error(msg)
setattr(namespace, self.dest, values)
@@ -174,19 +189,16 @@ class PositiveIntAction(argparse.Action):
type=int,
choices=None,
required=False,
- help=None,
+ help='Must be a positive integer.',
metavar=None):
"""Create PositiveIntAction object."""
- self.message = '{} must be a positive integer'.format(dest)
- help = help or self.message
-
super().__init__(
option_strings=option_strings,
dest=dest,
nargs=nargs,
const=const,
default=default,
- type=int,
+ type=type,
choices=choices,
required=required,
help=help,
@@ -198,7 +210,8 @@ class PositiveIntAction(argparse.Action):
setattr(namespace, self.dest, values)
return
- parser.error(self.message)
+ msg = '{} must be a positive integer'.format(option_string)
+ parser.error(msg)
class PathAction(argparse.Action):
diff --git a/contrib/python/pypodman/pypodman/lib/podman_parser.py b/contrib/python/pypodman/pypodman/lib/podman_parser.py
index d3c84224f..913546a91 100644
--- a/contrib/python/pypodman/pypodman/lib/podman_parser.py
+++ b/contrib/python/pypodman/pypodman/lib/podman_parser.py
@@ -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(
@@ -97,6 +109,8 @@ class PodmanArgumentParser(argparse.ArgumentParser):
actions_parser = self.add_subparsers(
dest='subparser_name', help='commands')
+ # For create/exec/run: don't process options intended for subcommand
+ actions_parser.REMAINDER = argparse.REMAINDER
# import buried here to prevent import loops
import pypodman.lib.actions # pylint: disable=cyclic-import
@@ -152,7 +166,7 @@ class PodmanArgumentParser(argparse.ArgumentParser):
reqattr(
'run_dir',
getattr(args, 'run_dir')
- or os.environ.get('RUN_DIR')
+ or os.environ.get('PODMAN_RUN_DIR')
or config['default'].get('run_dir')
or str(Path(args.xdg_runtime_dir, 'pypodman'))
) # yapf: disable
@@ -161,23 +175,24 @@ class PodmanArgumentParser(argparse.ArgumentParser):
args,
'host',
getattr(args, 'host')
- or os.environ.get('HOST')
+ or os.environ.get('PODMAN_HOST')
or config['default'].get('host')
) # yapf:disable
reqattr(
'username',
getattr(args, 'username')
+ or os.environ.get('PODMAN_USER')
+ or config['default'].get('username')
or os.environ.get('USER')
or os.environ.get('LOGNAME')
- or config['default'].get('username')
or getpass.getuser()
) # yapf:disable
reqattr(
'port',
getattr(args, 'port')
- or os.environ.get('PORT')
+ or os.environ.get('PODMAN_PORT')
or config['default'].get('port', None)
or 22
) # yapf:disable
@@ -185,7 +200,7 @@ class PodmanArgumentParser(argparse.ArgumentParser):
reqattr(
'remote_socket_path',
getattr(args, 'remote_socket_path')
- or os.environ.get('REMOTE_SOCKET_PATH')
+ or os.environ.get('PODMAN_REMOTE_SOCKET_PATH')
or config['default'].get('remote_socket_path')
or '/run/podman/io.podman'
) # yapf:disable
@@ -193,7 +208,7 @@ class PodmanArgumentParser(argparse.ArgumentParser):
reqattr(
'log_level',
getattr(args, 'log_level')
- or os.environ.get('LOG_LEVEL')
+ or os.environ.get('PODMAN_LOG_LEVEL')
or config['default'].get('log_level')
or logging.WARNING
) # yapf:disable
@@ -202,7 +217,7 @@ class PodmanArgumentParser(argparse.ArgumentParser):
args,
'identity_file',
getattr(args, 'identity_file')
- or os.environ.get('IDENTITY_FILE')
+ or os.environ.get('PODMAN_IDENTITY_FILE')
or config['default'].get('identity_file')
or os.path.expanduser('~{}/.ssh/id_dsa'.format(args.username))
) # yapf:disable