diff options
Diffstat (limited to 'contrib/python/cmd/lib')
-rw-r--r-- | contrib/python/cmd/lib/__init__.py | 5 | ||||
-rw-r--r-- | contrib/python/cmd/lib/action_base.py | 80 | ||||
-rw-r--r-- | contrib/python/cmd/lib/actions/__init__.py | 7 | ||||
-rw-r--r-- | contrib/python/cmd/lib/actions/images_action.py | 88 | ||||
-rw-r--r-- | contrib/python/cmd/lib/actions/ps_action.py | 76 | ||||
-rw-r--r-- | contrib/python/cmd/lib/actions/rm_action.py | 51 | ||||
-rw-r--r-- | contrib/python/cmd/lib/actions/rmi_action.py | 50 | ||||
-rw-r--r-- | contrib/python/cmd/lib/future_abstract.py | 29 | ||||
-rw-r--r-- | contrib/python/cmd/lib/report.py | 67 |
9 files changed, 0 insertions, 453 deletions
diff --git a/contrib/python/cmd/lib/__init__.py b/contrib/python/cmd/lib/__init__.py deleted file mode 100644 index db0f640b1..000000000 --- a/contrib/python/cmd/lib/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Remote podman client support library.""" -from .action_base import AbstractActionBase -from .report import Report, ReportColumn - -__all__ = ['AbstractActionBase', 'Report', 'ReportColumn'] diff --git a/contrib/python/cmd/lib/action_base.py b/contrib/python/cmd/lib/action_base.py deleted file mode 100644 index bafddea03..000000000 --- a/contrib/python/cmd/lib/action_base.py +++ /dev/null @@ -1,80 +0,0 @@ -"""Base class for all actions of remote client.""" -import abc -from functools import lru_cache - -import podman - - -class AbstractActionBase(abc.ABC): - """Base class for all actions of remote client.""" - - @classmethod - @abc.abstractmethod - def subparser(cls, parser): - """Define parser for this action. Subclasses must implement. - - API: - Use set_defaults() to set attributes "klass" and "method". These will - be invoked as klass(parsed_args).method() - """ - parser.add_argument( - '--all', - action='store_true', - help=('list all items.' - ' (default: no-op, included for compatibility.)')) - parser.add_argument( - '--no-trunc', - '--notruncate', - action='store_false', - dest='truncate', - default=True, - help='Display extended information. (default: False)') - parser.add_argument( - '--noheading', - action='store_false', - dest='heading', - default=True, - help=('Omit the table headings from the output.' - ' (default: False)')) - parser.add_argument( - '--quiet', - action='store_true', - help='List only the IDs. (default: %(default)s)') - - def __init__(self, args): - """Construct class.""" - self._args = args - - @property - def remote_uri(self): - """URI for remote side of connection.""" - return self._args.remote_uri - - @property - def local_uri(self): - """URI for local side of connection.""" - return self._args.local_uri - - @property - def identity_file(self): - """Key for authenication.""" - return self._args.identity_file - - @property - @lru_cache(maxsize=1) - def client(self): - """Podman remote client for communicating.""" - return podman.Client( - uri=self.local_uri, - remote_uri=self.remote_uri, - identity_file=self.identity_file) - - def __repr__(self): - """Compute the “official” string representation of object.""" - return ("{}(local_uri='{}', remote_uri='{}'," - " identity_file='{}')").format( - self.__class__, - self.local_uri, - self.remote_uri, - self.identity_file, - ) diff --git a/contrib/python/cmd/lib/actions/__init__.py b/contrib/python/cmd/lib/actions/__init__.py deleted file mode 100644 index cdc58b6ab..000000000 --- a/contrib/python/cmd/lib/actions/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -"""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/cmd/lib/actions/images_action.py b/contrib/python/cmd/lib/actions/images_action.py deleted file mode 100644 index 74c77edbb..000000000 --- a/contrib/python/cmd/lib/actions/images_action.py +++ /dev/null @@ -1,88 +0,0 @@ -"""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(klass=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/cmd/lib/actions/ps_action.py b/contrib/python/cmd/lib/actions/ps_action.py deleted file mode 100644 index 9fc3a155b..000000000 --- a/contrib/python/cmd/lib/actions/ps_action.py +++ /dev/null @@ -1,76 +0,0 @@ -"""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(klass=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/cmd/lib/actions/rm_action.py b/contrib/python/cmd/lib/actions/rm_action.py deleted file mode 100644 index 7595fee6a..000000000 --- a/contrib/python/cmd/lib/actions/rm_action.py +++ /dev/null @@ -1,51 +0,0 @@ -"""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(klass=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/cmd/lib/actions/rmi_action.py b/contrib/python/cmd/lib/actions/rmi_action.py deleted file mode 100644 index db59fe030..000000000 --- a/contrib/python/cmd/lib/actions/rmi_action.py +++ /dev/null @@ -1,50 +0,0 @@ -"""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(klass=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) diff --git a/contrib/python/cmd/lib/future_abstract.py b/contrib/python/cmd/lib/future_abstract.py deleted file mode 100644 index 75a1d42db..000000000 --- a/contrib/python/cmd/lib/future_abstract.py +++ /dev/null @@ -1,29 +0,0 @@ -"""Utilities for with-statement contexts. See PEP 343.""" - -import abc - -import _collections_abc - -try: - from contextlib import AbstractContextManager -except ImportError: - # Copied from python3.7 library as "backport" - class AbstractContextManager(abc.ABC): - """An abstract base class for context managers.""" - - def __enter__(self): - """Return `self` upon entering the runtime context.""" - return self - - @abc.abstractmethod - def __exit__(self, exc_type, exc_value, traceback): - """Raise any exception triggered within the runtime context.""" - return None - - @classmethod - def __subclasshook__(cls, C): - """Check whether subclass is considered a subclass of this ABC.""" - if cls is AbstractContextManager: - return _collections_abc._check_methods(C, "__enter__", - "__exit__") - return NotImplemented diff --git a/contrib/python/cmd/lib/report.py b/contrib/python/cmd/lib/report.py deleted file mode 100644 index 25fe2ae0d..000000000 --- a/contrib/python/cmd/lib/report.py +++ /dev/null @@ -1,67 +0,0 @@ -"""Report Manager.""" -import sys -from collections import namedtuple - -from .future_abstract import AbstractContextManager - - -class ReportColumn(namedtuple('ReportColumn', 'key display width default')): - """Hold attributes of output column.""" - - __slots__ = () - - def __new__(cls, key, display, width, default=None): - """Add defaults for attributes.""" - return super(ReportColumn, cls).__new__(cls, key, display, width, - default) - - -class Report(AbstractContextManager): - """Report Manager.""" - - def __init__(self, columns, heading=True, epilog=None, file=sys.stdout): - """Construct Report. - - columns is a mapping for named fields to column headings. - headers True prints headers on table. - epilog will be printed when the report context is closed. - """ - self._columns = columns - self._file = file - self._heading = heading - self.epilog = epilog - self._format = None - - def row(self, **fields): - """Print row for report.""" - if self._heading: - hdrs = {k: v.display for (k, v) in self._columns.items()} - print(self._format.format(**hdrs), flush=True, file=self._file) - self._heading = False - fields = {k: str(v) for k, v in fields.items()} - print(self._format.format(**fields)) - - def __exit__(self, exc_type, exc_value, traceback): - """Leave Report context and print epilog if provided.""" - if self.epilog: - print(self.epilog, flush=True, file=self._file) - - def layout(self, iterable, keys, truncate=True): - """Use data and headings build format for table to fit.""" - format = [] - - for key in keys: - value = max(map(lambda x: len(str(x.get(key, ''))), iterable)) - # print('key', key, 'value', value) - - if truncate: - row = self._columns.get( - key, ReportColumn(key, key.upper(), len(key))) - if value < row.width: - step = row.width if value == 0 else value - value = max(len(key), step) - elif value > row.width: - value = row.width if row.width != 0 else value - - format.append('{{{0}:{1}.{1}}}'.format(key, value)) - self._format = ' '.join(format) |