コード例 #1
0
    def rename_container(self, container, name):
        # TODO(emilien) podman doesn't support rename, we'll handle it
        # in paunch itself for now
        configs = self.list_configs()
        config_id, config = self.discover_container_config(
            configs, container, name)
        # Get config_data dict by the discovered conf ID,
        # paunch needs it for maintaining idempotency within a conf ID
        filter_names = ("[] | [?(Name!='%s' && "
                        "Config.Labels.config_id=='%s')]"
                        ".Name" % (container, config_id))
        filter_cdata = ("[] | [?(Name!='%s' && "
                        "Config.Labels.config_id=='%s')]"
                        ".Config.Labels.config_data" % (container, config_id))
        names = None
        cdata = None
        try:
            names = jmespath.search(filter_names, configs[config_id])
            cdata = jmespath.search(filter_cdata, configs[config_id])
        except jmespath.exceptions.LexerError:
            self.log.error("Failed to rename a container %s into %s: "
                           "used a bad search pattern" % (container, name))
            return

        if not names or not cdata:
            self.log.error("Failed to rename a container %s into %s: "
                           "no config_data was found" % (container, name))
            return

        # Rename the wanted container in the config_data fetched from the
        # discovered config
        config_data = dict(zip(names, map(json.loads, cdata)))
        config_data[name] = json.loads(
            config.get('Config').get('Labels').get('config_data'))

        # Re-apply a container under its amended name using the fetched configs
        self.log.debug("Renaming a container known as %s into %s, "
                       "via re-applying its original config" %
                       (container, name))
        self.log.debug("Removing the destination container %s" % name)
        self.stop_container(name)
        self.remove_container(name)
        self.log.debug("Removing a container known as %s" % container)
        self.stop_container(container)
        self.remove_container(container)
        builder = podman.PodmanBuilder(
            config_id=config_id,
            config=config_data,
            runner=self,
            labels=None,
            log=self.log,
            cont_log_path=self.cont_log_path,
            healthcheck_disabled=self.healthcheck_disabled)
        builder.apply()
コード例 #2
0
ファイル: __init__.py プロジェクト: 4383/paunch
def apply(config_id, config, managed_by, labels=None, cont_cmd='podman',
          default_runtime=None, log_level=None, log_file=None,
          cont_log_path=None, healthcheck_disabled=False):
    """Execute supplied container configuration.

    :param str config_id: Unique config ID, should not be re-used until any
                          running containers with that config ID have been
                          deleted.
    :param dict config: Configuration data describing container actions to
                        apply.
    :param str managed_by: Name of the tool managing the containers. Only
                           containers labelled with this will be modified.
    :param dict labels: Optional keys/values of labels to apply to containers
                        created with this invocation.
    :param str cont_cmd: Optional override to the container command to run.
    :param str default_runtime: (deprecated) does nothing.
    :param int log_level: optional log level for loggers
    :param str log_file: optional log file for messages
    :param str cont_log_path: optional log path for containers. Works only for
                              podman engine. Must be an absolute path.
    :param bool healthcheck_disabled: optional boolean to disable container
                                      healthcheck.

    :returns (list, list, int) lists of stdout and stderr for each execution,
                               and a single return code representing the
                               overall success of the apply.
    :rtype: tuple
    """
    log = common.configure_logging(__name__, log_level, log_file)
    if default_runtime:
        log.warning("DEPRECATION: 'default_runtime' does nothing, "
                    "use 'cont_cmd' instead")

    if cont_cmd == 'podman':
        r = runner.PodmanRunner(managed_by, cont_cmd=cont_cmd, log=log)
        builder = podman.PodmanBuilder(
            config_id=config_id,
            config=config,
            runner=r,
            labels=labels,
            log=log,
            cont_log_path=cont_log_path,
            healthcheck_disabled=healthcheck_disabled
        )
    else:
        r = runner.DockerRunner(managed_by, cont_cmd=cont_cmd, log=log)
        builder = compose1.ComposeV1Builder(
            config_id=config_id,
            config=config,
            runner=r,
            labels=labels,
            log=log
        )
    return builder.apply()
コード例 #3
0
    def rename_container(self, container, name):
        # TODO(emilien) podman doesn't support rename, we'll handle it
        # in paunch itself for now
        # Find the "container's" config & conf ID in the known configs
        configs = self.list_configs()
        config_id, config = self.discover_container_config(
            configs, container, name)
        try:
            # Get the neighbors' config_data by the discovered conf ID,
            # paunch needs it for maintaining idempotency within a conf ID
            jquerry=("[] | [?(Name!='%s' && "
                     "Config.Labels.config_id=='%s')]"
                     ".Name" % (container, config_id))
            names = jmespath.search(jquerry, configs[config_id])
            jquerry=("[] | [?(Name!='%s' && "
                     "Config.Labels.config_id=='%s')]"
                     ".Config.Labels.config_data" % (container, config_id))
            values = jmespath.search(jquerry, configs[config_id])
            config_data = dict(zip(names, map(json.loads, values)))

            # Rename the wanted container in the config_data fetched from the
            # discovered config
            config_data[name] = json.loads(
                config.get('Config').get('Labels').get('config_data'))
        except Exception:
            self.log.error("Failed to rename a container %s into %s: "
                           "no config_data was found" % (container, name))
            return
        # Re-apply a container under its amended name using the fetched configs
        self.log.debug("Renaming a container known as %s into %s, "
                       "via re-applying its original config" %
                       (container, name))
        self.log.debug("Removing the destination container %s" % name)
        self.stop_container(name)
        self.remove_container(name)
        self.log.debug("Removing a container known as %s" % container)
        self.stop_container(container)
        self.remove_container(container)
        builder = podman.PodmanBuilder(
            config_id=config_id,
            config=config_data,
            runner=self,
            labels=None,
            log=self.log
        )
        builder.apply()
コード例 #4
0
    def test_cont_run_args(self):
        config = {
            'one': {
                'image': 'centos:7',
                'privileged': True,
                'user': '******',
                'net': 'host',
                'ipc': 'host',
                'pid': 'container:bar',
                'uts': 'host',
                'restart': 'always',
                'env_file': '/tmp/foo.env',
                'log_tag': '{{.ImageName}}/{{.Name}}/{{.ID}}',
                'cpu_shares': 600,
                'mem_limit': '1G',
                'memswap_limit': '1G',
                'mem_swappiness': '60',
                'security_opt': 'label:disable',
                'cap_add': ['SYS_ADMIN', 'SETUID'],
                'cap_drop': ['NET_RAW'],
                'hostname': 'foohostname',
                'extra_hosts': ['foohost:127.0.0.1', 'barhost:127.0.0.2']
            }
        }
        builder = podman.PodmanBuilder('foo', config, None)

        cmd = ['podman', 'run', '--name', 'one']
        builder.container_run_args(cmd, 'one')
        self.assertEqual([
            'podman', 'run', '--name', 'one',
            '--conmon-pidfile=/var/run/one.pid', '--detach=true',
            '--env-file=/tmp/foo.env', '--net=host', '--ipc=host',
            '--pid=container:bar', '--uts=host', '--privileged=true',
            '--user=bar', '--log-opt=tag={{.ImageName}}/{{.Name}}/{{.ID}}',
            '--cpu-shares=600', '--memory=1G', '--memory-swap=1G',
            '--memory-swappiness=60', '--security-opt=label:disable',
            '--hostname=foohostname', '--add-host=foohost:127.0.0.1',
            '--add-host=barhost:127.0.0.2', '--cap-add=SYS_ADMIN',
            '--cap-add=SETUID', '--cap-drop=NET_RAW', 'centos:7'
        ], cmd)
コード例 #5
0
ファイル: __init__.py プロジェクト: 4383/paunch
def debug(config_id, container_name, action, config, managed_by, labels=None,
          cont_cmd='podman', default_runtime=None, log_level=None,
          log_file=None):
    """Execute supplied container configuration.

    :param str config_id: Unique config ID, should not be re-used until any
                          running containers with that config ID have been
                          deleted.
    :param str container_name: Name of the container in the config you
                               wish to manipulate.
    :param str action: Action to take.
    :param dict config: Configuration data describing container actions to
                        apply.
    :param str managed_by: Name of the tool managing the containers. Only
                           containers labeled with this will be modified.
    :param dict labels: Optional keys/values of labels to apply to containers
                        created with this invocation.
    :param str cont_cmd: Optional override to the container command to run.
    :param str default_runtime: (deprecated) does nothing.
    :param int log_level: optional log level for loggers
    :param int log_file: optional log file for messages

    :returns integer return value from running command or failure for any
             other reason.
    :rtype: int
    """
    log = common.configure_logging(__name__, log_level, log_file)
    if default_runtime:
        log.warning("DEPRECATION: 'default_runtime' does nothing, "
                    "use 'cont_cmd' instead")

    if cont_cmd == 'podman':
        r = runner.PodmanRunner(managed_by, cont_cmd=cont_cmd, log=log)
        builder = podman.PodmanBuilder(
            config_id=config_id,
            config=config,
            runner=r,
            labels=labels,
            log=log
        )
    else:
        r = runner.DockerRunner(managed_by, cont_cmd=cont_cmd, log=log)
        builder = compose1.ComposeV1Builder(
            config_id=config_id,
            config=config,
            runner=r,
            labels=labels,
            log=log
        )
    if action == 'print-cmd':
        cmd = [
            r.cont_cmd,
            'run',
            '--name',
            r.unique_container_name(container_name)
        ]
        builder.container_run_args(cmd, container_name)
        print(' '.join(cmd))
    elif action == 'run':
        cmd = [
            r.cont_cmd,
            'run',
            '--name',
            r.unique_container_name(container_name)
        ]
        builder.container_run_args(cmd, container_name)
        return r.execute_interactive(cmd, log)
    elif action == 'dump-yaml':
        print(yaml.safe_dump(config, default_flow_style=False))
    elif action == 'dump-json':
        print(json.dumps(config, indent=4))
    else:
        raise ValueError('action should be one of: "dump-json", "dump-yaml"',
                         '"print-cmd", or "run"')