summaryrefslogtreecommitdiff
path: root/contrib/python/pypodman/lib/actions
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/python/pypodman/lib/actions')
-rw-r--r--contrib/python/pypodman/lib/actions/__init__.py7
-rw-r--r--contrib/python/pypodman/lib/actions/images_action.py88
-rw-r--r--contrib/python/pypodman/lib/actions/ps_action.py76
-rw-r--r--contrib/python/pypodman/lib/actions/rm_action.py51
-rw-r--r--contrib/python/pypodman/lib/actions/rmi_action.py50
5 files changed, 272 insertions, 0 deletions
diff --git a/contrib/python/pypodman/lib/actions/__init__.py b/contrib/python/pypodman/lib/actions/__init__.py
new file mode 100644
index 000000000..cdc58b6ab
--- /dev/null
+++ b/contrib/python/pypodman/lib/actions/__init__.py
@@ -0,0 +1,7 @@
+"""Module to export all the podman subcommands."""
+from .images_action import Images
+from .ps_action import Ps
+from .rm_action import Rm
+from .rmi_action import Rmi
+
+__all__ = ['Images', 'Ps', 'Rm', 'Rmi']
diff --git a/contrib/python/pypodman/lib/actions/images_action.py b/contrib/python/pypodman/lib/actions/images_action.py
new file mode 100644
index 000000000..f6a7497e5
--- /dev/null
+++ b/contrib/python/pypodman/lib/actions/images_action.py
@@ -0,0 +1,88 @@
+"""Remote client commands dealing with images."""
+import operator
+from collections import OrderedDict
+
+import humanize
+import podman
+
+from .. import AbstractActionBase, Report, ReportColumn
+
+
+class Images(AbstractActionBase):
+ """Class for Image manipulation."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """Add Images commands to parent parser."""
+ parser = parent.add_parser('images', help='list images')
+ super().subparser(parser)
+ parser.add_argument(
+ '--sort',
+ choices=['created', 'id', 'repository', 'size', 'tag'],
+ default='created',
+ type=str.lower,
+ help=('Change sort ordered of displayed images.'
+ ' (default: %(default)s)'))
+
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument(
+ '--digests',
+ action='store_true',
+ help='Include digests with images. (default: %(default)s)')
+ parser.set_defaults(class_=cls, method='list')
+
+ def __init__(self, args):
+ """Construct Images class."""
+ super().__init__(args)
+
+ self.columns = OrderedDict({
+ 'name':
+ ReportColumn('name', 'REPOSITORY', 40),
+ 'tag':
+ ReportColumn('tag', 'TAG', 10),
+ 'id':
+ ReportColumn('id', 'IMAGE ID', 12),
+ 'created':
+ ReportColumn('created', 'CREATED', 12),
+ 'size':
+ ReportColumn('size', 'SIZE', 8),
+ 'repoDigests':
+ ReportColumn('repoDigests', 'DIGESTS', 35),
+ })
+
+ def list(self):
+ """List images."""
+ images = sorted(
+ self.client.images.list(),
+ key=operator.attrgetter(self._args.sort))
+ if len(images) == 0:
+ return 0
+
+ rows = list()
+ for image in images:
+ fields = dict(image)
+ fields.update({
+ 'created':
+ humanize.naturaldate(podman.datetime_parse(image.created)),
+ 'size':
+ humanize.naturalsize(int(image.size)),
+ 'repoDigests':
+ ' '.join(image.repoDigests),
+ })
+
+ for r in image.repoTags:
+ name, tag = r.split(':', 1)
+ fields.update({
+ 'name': name,
+ 'tag': tag,
+ })
+ rows.append(fields)
+
+ if not self._args.digests:
+ del self.columns['repoDigests']
+
+ with Report(self.columns, heading=self._args.heading) as report:
+ report.layout(
+ rows, self.columns.keys(), truncate=self._args.truncate)
+ for row in rows:
+ report.row(**row)
diff --git a/contrib/python/pypodman/lib/actions/ps_action.py b/contrib/python/pypodman/lib/actions/ps_action.py
new file mode 100644
index 000000000..4bbec5578
--- /dev/null
+++ b/contrib/python/pypodman/lib/actions/ps_action.py
@@ -0,0 +1,76 @@
+"""Remote client commands dealing with containers."""
+import operator
+from collections import OrderedDict
+
+import humanize
+import podman
+
+from .. import AbstractActionBase, Report, ReportColumn
+
+
+class Ps(AbstractActionBase):
+ """Class for Container manipulation."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """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',
+ 'status'
+ ],
+ default='createdat',
+ type=str.lower,
+ help=('Change sort ordered of displayed containers.'
+ ' (default: %(default)s)'))
+ parser.set_defaults(class_=cls, method='list')
+
+ def __init__(self, args):
+ """Construct Ps class."""
+ super().__init__(args)
+
+ self.columns = OrderedDict({
+ 'id':
+ ReportColumn('id', 'CONTAINER ID', 14),
+ 'image':
+ ReportColumn('image', 'IMAGE', 30),
+ 'command':
+ ReportColumn('column', 'COMMAND', 20),
+ 'createdat':
+ ReportColumn('createdat', 'CREATED', 12),
+ 'status':
+ ReportColumn('status', 'STATUS', 10),
+ 'ports':
+ ReportColumn('ports', 'PORTS', 28),
+ 'names':
+ ReportColumn('names', 'NAMES', 18)
+ })
+
+ def list(self):
+ """List containers."""
+ # TODO: Verify sorting on dates and size
+ ctnrs = sorted(
+ self.client.containers.list(),
+ key=operator.attrgetter(self._args.sort))
+ if len(ctnrs) == 0:
+ return 0
+
+ rows = list()
+ for ctnr in ctnrs:
+ fields = dict(ctnr)
+ fields.update({
+ 'command':
+ ' '.join(ctnr.command),
+ 'createdat':
+ humanize.naturaldate(podman.datetime_parse(ctnr.createdat)),
+ })
+ rows.append(fields)
+
+ with Report(self.columns, heading=self._args.heading) as report:
+ report.layout(
+ rows, self.columns.keys(), truncate=self._args.truncate)
+ for row in rows:
+ report.row(**row)
diff --git a/contrib/python/pypodman/lib/actions/rm_action.py b/contrib/python/pypodman/lib/actions/rm_action.py
new file mode 100644
index 000000000..bd8950bd6
--- /dev/null
+++ b/contrib/python/pypodman/lib/actions/rm_action.py
@@ -0,0 +1,51 @@
+"""Remote client command for deleting containers."""
+import sys
+
+import podman
+
+from .. import AbstractActionBase
+
+
+class Rm(AbstractActionBase):
+ """Class for removing containers from storage."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """Add Rm command to parent parser."""
+ parser = parent.add_parser('rm', help='delete container(s)')
+ parser.add_argument(
+ '-f',
+ '--force',
+ action='store_true',
+ help=('force delete of running container(s).'
+ ' (default: %(default)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)
+ if len(args.targets) < 1:
+ raise ValueError('You must supply at least one container id'
+ ' or name to be deleted.')
+
+ def remove(self):
+ """Remove container(s)."""
+ for id in self._args.targets:
+ try:
+ ctnr = self.client.containers.get(id)
+ ctnr.remove(self._args.force)
+ print(id)
+ except podman.ContainerNotFound as e:
+ sys.stdout.flush()
+ print(
+ 'Container {} not found.'.format(e.name),
+ file=sys.stderr,
+ flush=True)
+ except podman.ErrorOccurred as e:
+ sys.stdout.flush()
+ print(
+ '{}'.format(e.reason).capitalize(),
+ file=sys.stderr,
+ flush=True)
diff --git a/contrib/python/pypodman/lib/actions/rmi_action.py b/contrib/python/pypodman/lib/actions/rmi_action.py
new file mode 100644
index 000000000..91f0deeaf
--- /dev/null
+++ b/contrib/python/pypodman/lib/actions/rmi_action.py
@@ -0,0 +1,50 @@
+"""Remote client command for deleting images."""
+import sys
+
+import podman
+
+from .. import AbstractActionBase
+
+
+class Rmi(AbstractActionBase):
+ """Clas for removing images from storage."""
+
+ @classmethod
+ def subparser(cls, parent):
+ """Add Rmi command to parent parser."""
+ parser = parent.add_parser('rmi', help='delete image(s)')
+ parser.add_argument(
+ '-f',
+ '--force',
+ action='store_true',
+ help=('force delete of image(s) and associated containers.'
+ ' (default: %(default)s)'))
+ 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)
+ if len(args.targets) < 1:
+ raise ValueError('You must supply at least one image id'
+ ' or name to be deleted.')
+
+ def remove(self):
+ """Remove image(s)."""
+ for id in self._args.targets:
+ try:
+ img = self.client.images.get(id)
+ img.remove(self._args.force)
+ print(id)
+ except podman.ImageNotFound as e:
+ sys.stdout.flush()
+ print(
+ 'Image {} not found.'.format(e.name),
+ file=sys.stderr,
+ flush=True)
+ except podman.ErrorOccurred as e:
+ sys.stdout.flush()
+ print(
+ '{}'.format(e.reason).capitalize(),
+ file=sys.stderr,
+ flush=True)