diff options
Diffstat (limited to 'contrib/python/cmd/pydman.py')
| -rwxr-xr-x | contrib/python/cmd/pydman.py | 248 | 
1 files changed, 0 insertions, 248 deletions
| diff --git a/contrib/python/cmd/pydman.py b/contrib/python/cmd/pydman.py deleted file mode 100755 index 5008c706d..000000000 --- a/contrib/python/cmd/pydman.py +++ /dev/null @@ -1,248 +0,0 @@ -#!/usr/bin/env python3 -"""Remote podman client.""" - -import argparse -import curses -import getpass -import inspect -import logging -import os -import sys - -import pkg_resources - -import lib.actions -import pytoml - -assert lib.actions  # silence pyflakes - -# TODO: setup.py and obtain __version__ from rpm.spec -try: -    __version__ = pkg_resources.get_distribution('pydman').version -except Exception: -    __version__ = '0.0.0' - - -class HelpFormatter(argparse.RawDescriptionHelpFormatter): -    """Set help width to screen size.""" - -    def __init__(self, *args, **kwargs): -        """Construct HelpFormatter using screen width.""" -        if 'width' not in kwargs: -            kwargs['width'] = 80 -            try: -                height, width = curses.initscr().getmaxyx() -                kwargs['width'] = width -            finally: -                curses.endwin() -        super().__init__(*args, **kwargs) - - -class PodmanArgumentParser(argparse.ArgumentParser): -    """Default remote podman configuration.""" - -    def __init__(self, **kwargs): -        """Construct the parser.""" -        kwargs['add_help'] = True -        kwargs['allow_abbrev'] = True -        kwargs['description'] = __doc__ -        kwargs['formatter_class'] = HelpFormatter - -        super().__init__(**kwargs) - -    def initialize_parser(self): -        """Initialize parser without causing recursion meltdown.""" -        self.add_argument( -            '--version', -            action='version', -            version='%(prog)s v. ' + __version__) -        self.add_argument( -            '--log-level', -            choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], -            default='INFO', -            type=str.upper, -            help='set logging level for events. (default: %(default)s)', -        ) -        self.add_argument( -            '--run-dir', -            help=('directory to place local socket bindings.' -                  ' (default: XDG_RUNTIME_DIR)')) -        self.add_argument( -            '--user', -            help=('Authenicating user on remote host.' -                  ' (default: {})').format(getpass.getuser())) -        self.add_argument( -            '--host', help='name of remote host. (default: None)') -        self.add_argument( -            '--remote-socket-path', -            help=('path of podman socket on remote host' -                  ' (default: /run/podman/io.projectatomic.podman)')) -        self.add_argument( -            '--identity-file', -            help=('path to ssh identity file. (default: ~/.ssh/id_rsa)')) -        self.add_argument( -            '--config', -            default='/etc/containers/podman_client.conf', -            dest='config_file', -            help='path of configuration file. (default: %(default)s)') - -        actions_parser = self.add_subparsers( -            dest='subparser_name', help='actions') - -        for name, obj in inspect.getmembers( -                sys.modules['lib.actions'], -                lambda member: inspect.isclass(member)): -            if hasattr(obj, 'subparser'): -                try: -                    obj.subparser(actions_parser) -                except NameError as e: -                    logging.critical(e) -                    logging.warning( -                        'See subparser configuration for Class "{}"'.format( -                            name)) -                    sys.exit(3) - -    def parse_args(self, args=None, namespace=None): -        """Parse command line arguments, backed by env var and config_file.""" -        self.initialize_parser() -        cooked = super().parse_args(args, namespace) -        return self.resolve_configuration(cooked) - -    def resolve_configuration(self, args): -        """Find and fill in any arguments not passed on command line.""" -        try: -            # Configuration file optionall, arguments may be provided elsewhere -            with open(args.config_file, 'r') as stream: -                config = pytoml.load(stream) -        except OSError: -            logging.info( -                'Failed to read: {}'.format(args.config_file), -                exc_info=args.log_level == logging.DEBUG) -            config = {'default': {}} -        else: -            if 'default' not in config: -                config['default'] = {} - -        def resolve(name, value): -            if value: -                setattr(args, name, value) -                return value -            self.error('Required argument "%s" is not configured.' % name) - -        xdg = os.path.join(os.environ['XDG_RUNTIME_DIR'], 'podman') \ -            if os.environ.get('XDG_RUNTIME_DIR') else None - -        resolve( -            'run_dir', -            getattr(args, 'run_dir') -            or os.environ.get('RUN_DIR') -            or config['default'].get('run_dir') -            or xdg -            or '/tmp/podman' if os.path.isdir('/tmp') else None -        )   # yapf: disable - -        args.local_socket_path = os.path.join(args.run_dir, "podman.socket") - -        resolve( -            'host', -            getattr(args, 'host') -            or os.environ.get('HOST') -            or config['default'].get('host') -        )   # yapf:disable - -        resolve( -            'user', -            getattr(args, 'user') -            or os.environ.get('USER') -            or config['default'].get('user') -            or getpass.getuser() -        )   # yapf:disable - -        resolve( -            'remote_socket_path', -            getattr(args, 'remote_socket_path') -            or os.environ.get('REMOTE_SOCKET_PATH') -            or config['default'].get('remote_socket_path') -            or '/run/podman/io.projectatomic.podman' -        )   # yapf:disable - -        resolve( -            'identity_file', -            getattr(args, 'identity_file') -            or os.environ.get('IDENTITY_FILE') -            or config['default'].get('identity_file') -            or os.path.expanduser('~{}/.ssh/id_rsa'.format(args.user)) -        )   # yapf:disable - -        args.local_uri = "unix:{}".format(args.local_socket_path) -        args.remote_uri = "ssh://{}@{}{}".format(args.user, args.host, -                                                 args.remote_socket_path) -        return args - -    def exit(self, status=0, message=None): -        """Capture message and route to logger.""" -        if message: -            log = logging.info if status == 0 else logging.error -            log(message) -        super().exit(status) - -    def error(self, message): -        """Capture message and route to logger.""" -        logging.error('{}: {}'.format(self.prog, message)) -        logging.error("Try '{} --help' for more information.".format( -            self.prog)) -        super().exit(2) - - -if __name__ == '__main__': -    # Setup logging so we use stderr and can change logging level later -    # Do it now before there is any chance of a default setup. -    log = logging.getLogger() -    fmt = logging.Formatter('%(asctime)s | %(levelname)-8s | %(message)s', -                            '%Y-%m-%d %H:%M:%S %Z') -    stderr = logging.StreamHandler(stream=sys.stderr) -    stderr.setFormatter(fmt) -    log.addHandler(stderr) -    log.setLevel(logging.INFO) - -    parser = PodmanArgumentParser() -    args = parser.parse_args() - -    log.setLevel(args.log_level) -    logging.debug('Logging initialized at level {}'.format( -        logging.getLevelName(logging.getLogger().getEffectiveLevel()))) - -    def istraceback(): -        """Add traceback when logging events.""" -        return log.getEffectiveLevel() == logging.DEBUG - -    try: -        if not os.path.exists(args.run_dir): -            os.makedirs(args.run_dir) -    except PermissionError as e: -        logging.critical(e, exc_info=istraceback()) -        sys.exit(6) - -    # Klass(args).method() are setup by the sub-command's parser -    returncode = None -    try: -        obj = args.klass(args) -    except Exception as e: -        logging.critical(repr(e), exc_info=istraceback()) -        logging.warning('See subparser "{}" configuration.'.format( -            args.subparser_name)) -        sys.exit(5) - -    try: -        returncode = getattr(obj, args.method)() -    except AttributeError as e: -        logging.critical(e, exc_info=istraceback()) -        logging.warning('See subparser "{}" configuration.'.format( -            args.subparser_name)) -        returncode = 3 -    except (ConnectionResetError, TimeoutError) as e: -        logging.critical(e, exc_info=istraceback()) -        logging.info('Review connection arguments for correctness.') -        returncode = 4 - -    sys.exit(0 if returncode is None else returncode) | 
