예제 #1
0
 def test_create_kwargs_with_host_config(self):
     cfg_name = 'app_server'
     cfg = self.sample_map.get_existing(cfg_name)
     c_name = 'main.app_server'
     hc_kwargs = dict(binds={'/new_h': {'bind': '/new_c', 'ro': False}})
     kwargs = BasePolicy.get_create_kwargs(self.sample_map, cfg_name, cfg, '__default__',
                                           self.sample_client_config, c_name, 'instance1',
                                           include_host_config=True, kwargs=dict(host_config=hc_kwargs))
     self.assertDictEqual(kwargs, dict(
         name=c_name,
         image='registry.example.com/app',
         environment=[],
         volumes=[
             '/var/lib/app/config',
             '/var/lib/app/data'
         ],
         user='******',
         hostname='main.app_server',
         domainname=None,
         ports=[8880],
         host_config=create_host_config(
             links={},
             binds={
                 '/var/lib/site/config/app1': {'bind': '/var/lib/app/config', 'ro': True},
                 '/var/lib/site/data/app1': {'bind': '/var/lib/app/data', 'ro': False},
                 '/new_h': {'bind': '/new_c', 'ro': False},
             },
             volumes_from=['main.app_log', 'main.app_server_socket'],
             port_bindings={},
         ),
     ))
예제 #2
0
 def test_attached_preparation_create_kwargs(self):
     cfg_name = 'app_server'
     cfg = self.sample_map.get_existing(cfg_name)
     c_name = 'temp'
     alias = 'app_server_socket'
     v_name = 'main.app_server_socket'
     kwargs = BasePolicy.get_attached_preparation_create_kwargs(
         self.sample_map,
         cfg_name,
         cfg,
         '__default__',
         self.sample_client_config,
         c_name,
         alias,
         v_name,
         include_host_config=True)
     self.assertDictEqual(
         kwargs,
         dict(
             image=BasePolicy.core_image,
             command=
             'chown -R 2000:2000 /var/lib/app/socket && chmod -R u=rwX,g=rX,o= /var/lib/app/socket',
             user='******',
             host_config=create_host_config(
                 volumes_from=[v_name],
                 version=self.client_version,
             ),
             network_disabled=True,
         ))
예제 #3
0
 def test_create_kwargs_with_host_config(self):
     cfg_name = "app_server"
     cfg = self.sample_map.get_existing(cfg_name)
     c_name = "main.app_server"
     self.sample_client_config.use_host_config = True
     config = ActionConfig(
         "main", self.sample_map, cfg_name, cfg, "__default__", self.sample_client_config, None, "instance1"
     )
     hc_kwargs = dict(binds=["/new_h:/new_c:rw"])
     kwargs = self.runner.get_create_kwargs(config, c_name, kwargs=dict(host_config=hc_kwargs))
     self.assertDictEqual(
         kwargs,
         dict(
             name=c_name,
             image="registry.example.com/app:custom",
             volumes=["/var/lib/app/config", "/var/lib/app/data"],
             user="******",
             hostname="main.app_server",
             domainname=None,
             ports=[8880],
             host_config=create_host_config(
                 links={},
                 binds=[
                     "/var/lib/site/config/app1:/var/lib/app/config:ro",
                     "/var/lib/site/data/app1:/var/lib/app/data:rw",
                     "/new_h:/new_c:rw",
                 ],
                 volumes_from=["main.app_log", "main.app_server_socket"],
                 port_bindings={},
                 version=self.client_version,
             ),
         ),
     )
예제 #4
0
    def get_attached_preparation_create_kwargs(cls, container_map, config_name, container_config, client_name,
                                               client_config, container_name, alias, volume_container,
                                               include_host_config=True, kwargs=None):
        """
        Generates keyword arguments for the Docker client to prepare an attached container (i.e. adjust user and
        permissions).

        :param container_map: Container map object.
        :type container_map: dockermap.map.container.ContainerMap
        :param config_name: Container configuration name.
        :type config_name: unicode
        :param container_config: Container configuration object.
        :type container_config: dockermap.map.config.ContainerConfiguration
        :param client_name: Client configuration name.
        :type client_name: unicode
        :param client_config: Client configuration object.
        :type client_config: dockermap.map.config.ClientConfiguration
        :param container_name: Container name.
        :type container_name: unicode
        :param alias: Alias name of the container volume.
        :type alias: unicode
        :param volume_container: Name of the container that shares the volume.
        :type volume_container: unicode
        :param include_host_config: Whether to generate and include the HostConfig.
        :type include_host_config: Set to ``False``, if calling :meth:`get_start_kwargs:` later.
        :param kwargs: Additional keyword arguments to complement or override the configuration-based values.
        :type kwargs: dict | NoneType
        :return: Resulting keyword arguments.
        :rtype: dict
        """
        def _get_cmd():
            user = resolve_value(container_config.user)
            if user:
                yield 'chown -R {0} {1}'.format(get_user_group(user), str_arg(path))
            permissions = container_config.permissions
            if permissions:
                yield 'chmod -R {0} {1}'.format(permissions, str_arg(path))

        path = resolve_value(container_map.volumes[alias])
        c_kwargs = dict(
            image=cls.core_image,
            command=' && '.join(_get_cmd()),
            user='******',
            network_disabled=True,
        )
        hc_extra_kwargs = kwargs.pop('host_config', None) if kwargs else None
        if include_host_config:
            hc_kwargs = cls.get_attached_preparation_host_config_kwargs(container_map, config_name, container_config,
                                                                        client_name, client_config, None, alias,
                                                                        volume_container, kwargs=hc_extra_kwargs)
            if hc_kwargs:
                c_kwargs['host_config'] = create_host_config(**hc_kwargs)
        update_kwargs(c_kwargs, kwargs)
        return c_kwargs
예제 #5
0
    def get_create_kwargs(cls, container_map, config_name, container_config, client_name, client_config, container_name,
                          instance, include_host_config=True, kwargs=None):
        """
        Generates keyword arguments for the Docker client to create a container.

        :param config_name:
        :param container_map: Container map object.
        :type container_map: dockermap.map.container.ContainerMap
        :param config_name: Container configuration name.
        :type config_name: unicode
        :param container_config: Container configuration object.
        :type container_config: dockermap.map.config.ContainerConfiguration
        :param client_name: Client configuration name.
        :type client_name: unicode
        :param client_config: Client configuration object.
        :type client_config: dockermap.map.config.ClientConfiguration
        :param container_name: Container name.
        :type container_name: unicode
        :param instance: Instance name.
        :type instance: unicode | NoneType
        :param include_host_config: Whether to generate and include the HostConfig.
        :type include_host_config: Set to ``False``, if calling :meth:`get_start_kwargs:` later.
        :param kwargs: Additional keyword arguments to complement or override the configuration-based values.
        :type kwargs: dict | NoneType
        :return: Resulting keyword arguments.
        :rtype: dict
        """
        c_kwargs = dict(
            name=container_name,
            image=cls.iname(container_map, container_config.image or config_name),
            volumes=get_volumes(container_map, container_config),
            user=extract_user(container_config.user),
            ports=[resolve_value(port_binding.exposed_port)
                   for port_binding in container_config.exposes if port_binding.exposed_port],
            hostname=cls.get_hostname(client_name, container_name) if container_map.set_hostname else None,
            domainname=cls.get_domainname(container_map, container_config, client_config),
            environment=get_environment(container_map, container_config)
        )
        if container_config.network == 'disabled':
            c_kwargs['network_disabled'] = True
        hc_extra_kwargs = kwargs.pop('host_config', None) if kwargs else None
        if include_host_config:
            hc_kwargs = cls.get_host_config_kwargs(container_map, config_name, container_config, client_name,
                                                   client_config, None, instance, kwargs=hc_extra_kwargs)
            if hc_kwargs:
                c_kwargs['host_config'] = create_host_config(**hc_kwargs)
        update_kwargs(c_kwargs, init_options(container_config.create_options), kwargs)
        return c_kwargs
예제 #6
0
 def test_create_kwargs_with_host_config(self):
     cfg_name = 'app_server'
     cfg = self.sample_map.get_existing(cfg_name)
     c_name = 'main.app_server'
     hc_kwargs = dict(binds={'/new_h': {'bind': '/new_c', 'ro': False}})
     kwargs = BasePolicy.get_create_kwargs(
         self.sample_map,
         cfg_name,
         cfg,
         '__default__',
         self.sample_client_config,
         c_name,
         'instance1',
         include_host_config=True,
         kwargs=dict(host_config=hc_kwargs))
     self.assertDictEqual(
         kwargs,
         dict(
             name=c_name,
             image='registry.example.com/app:custom',
             volumes=['/var/lib/app/config', '/var/lib/app/data'],
             user='******',
             hostname='main.app_server',
             domainname=None,
             ports=[8880],
             host_config=create_host_config(
                 links={},
                 binds={
                     '/var/lib/site/config/app1': {
                         'bind': '/var/lib/app/config',
                         'ro': True
                     },
                     '/var/lib/site/data/app1': {
                         'bind': '/var/lib/app/data',
                         'ro': False
                     },
                     '/new_h': {
                         'bind': '/new_c',
                         'ro': False
                     },
                 },
                 volumes_from=['main.app_log', 'main.app_server_socket'],
                 port_bindings={},
                 version=self.client_version,
             ),
         ))
예제 #7
0
 def test_attached_preparation_create_kwargs(self):
     cfg_name = 'app_server'
     cfg = self.sample_map.get_existing(cfg_name)
     c_name = 'temp'
     alias = 'app_server_socket'
     v_name = 'main.app_server_socket'
     kwargs = BasePolicy.get_attached_preparation_create_kwargs(self.sample_map, cfg_name, cfg, '__default__',
                                                                self.sample_client_config, c_name, alias,
                                                                v_name, include_host_config=True)
     self.assertDictEqual(kwargs, dict(
         image=BasePolicy.core_image,
         command='chown -R 2000:2000 /var/lib/app/socket && chmod -R u=rwX,g=rX,o= /var/lib/app/socket',
         user='******',
         host_config=create_host_config(
             volumes_from=[v_name],
         ),
         network_disabled=True,
     ))
예제 #8
0
    def _host_config(self, service_name):
        """Returns a host configuration object for use with docker commands.

        This is mostly the network mode and the binding to the folders on the file system.
        """

        res = self.ctx.fs.info_deploy(service_name)
        binds = {
            res['log']: {
                'bind': '/data/log',
                'ro': False,
                },
            res['config']: {
                'bind': '/data/config',
                'ro': True
            }
        }

        return create_host_config(binds=binds, network_mode='host')
예제 #9
0
    def get_attached_create_kwargs(cls, container_map, config_name, container_config, client_name, client_config,
                                   container_name, alias, include_host_config=True, kwargs=None):
        """
        Generates keyword arguments for the Docker client to create an attached container.

        :param container_map: Container map object.
        :type container_map: dockermap.map.container.ContainerMap
        :param config_name: Container configuration name.
        :type config_name: unicode
        :param container_config: Container configuration object.
        :type container_config: dockermap.map.config.ContainerConfiguration
        :param client_name: Client configuration name.
        :type client_name: unicode
        :param client_config: Client configuration object.
        :type client_config: dockermap.map.config.ClientConfiguration
        :param container_name: Container name.
        :type container_name: unicode
        :param alias: Alias name of the container volume.
        :type alias: unicode
        :param include_host_config: Whether to generate and include the HostConfig.
        :type include_host_config: Set to ``False``, if calling :meth:`get_start_kwargs:` later.
        :param kwargs: Additional keyword arguments to complement or override the configuration-based values.
        :type kwargs: dict | NoneType
        :return: Resulting keyword arguments.
        :rtype: dict
        """
        path = resolve_value(container_map.volumes[alias])
        user = extract_user(container_config.user)
        c_kwargs = dict(
            name=container_name,
            image=cls.base_image,
            volumes=[path],
            user=user,
            network_disabled=True,
        )
        hc_extra_kwargs = kwargs.pop('host_config', None) if kwargs else None
        if include_host_config:
            hc_kwargs = cls.get_attached_host_config_kwargs(container_map, config_name, container_config, client_name,
                                                            client_config, None, alias, kwargs=hc_extra_kwargs)
            if hc_kwargs:
                c_kwargs['host_config'] = create_host_config(**hc_kwargs)
        update_kwargs(c_kwargs, kwargs)
        return c_kwargs
예제 #10
0
    def _host_config(self, service_name):
        """Returns a host configuration object for use with docker commands.

        This is mostly the network mode and the binding to the folders on the file system.
        """

        res = self.ctx.fs.info_deploy(service_name)
        binds = {
            res['log']: {
                'bind': '/data/log',
                'ro': False,
            },
            res['config']: {
                'bind': '/data/config',
                'ro': True
            }
        }

        return create_host_config(binds=binds, network_mode='host')
예제 #11
0
 def test_attached_preparation_create_kwargs(self):
     cfg_name = "app_server"
     cfg = self.sample_map.get_existing(cfg_name)
     alias = "app_server_socket"
     v_name = "main.app_server_socket"
     self.sample_client_config.use_host_config = True
     config = ActionConfig(
         "main", self.sample_map, cfg_name, cfg, "__default__", self.sample_client_config, None, alias
     )
     kwargs = self.runner.get_attached_preparation_create_kwargs(config, v_name)
     self.assertDictEqual(
         kwargs,
         dict(
             image=BasePolicy.core_image,
             command="chown -R 2000:2000 /var/lib/app/socket && chmod -R u=rwX,g=rX,o= /var/lib/app/socket",
             user="******",
             host_config=create_host_config(volumes_from=[v_name], version=self.client_version),
             network_disabled=True,
         ),
     )
예제 #12
0
    def create_container(self, conf, detach, tty):
        """Create a single container"""

        name = conf.name
        image_name = conf.image_name
        container_name = conf.container_name

        env = dict(e.pair for e in conf.env)
        ports = [port.host_port for port in conf.ports]
        links = [link.pair for link in conf.links]
        binds = conf.volumes.binds
        command = conf.formatted_command
        volume_names = conf.volumes.volume_names
        volumes_from = list(conf.volumes.share_with_names)
        port_bindings = dict([port.pair for port in conf.ports])

        uncreated = []
        for name in binds:
            if not os.path.exists(name):
                log.info("Making volume for mounting\tvolume=%s", name)
                try:
                    os.makedirs(name)
                except OSError as error:
                    uncreated.append((name, error))
        if uncreated:
            raise BadOption("Failed to create some volumes on the host",
                            uncreated=uncreated)

        log.info(
            "Creating container from %s\timage=%s\tcontainer_name=%s\ttty=%s",
            image_name, name, container_name, tty)
        if binds:
            log.info("\tUsing volumes\tvolumes=%s", volume_names)
        if env:
            log.info("\tUsing environment\tenv=%s", sorted(env.keys()))
        if links:
            log.info("\tLinks: %s", links)
        if ports:
            log.info("\tUsing ports\tports=%s", ports)
        if port_bindings:
            log.info("\tPort bindings: %s", ports)
        if volumes_from:
            log.info("\tVolumes from: %s", volumes_from)

        host_config = utils.create_host_config(
            links=links,
            binds=binds,
            volumes_from=volumes_from,
            port_bindings=port_bindings,
            devices=conf.devices,
            lxc_conf=conf.lxc_conf,
            privileged=conf.privileged,
            restart_policy=conf.restart_policy,
            dns=conf.network.dns,
            dns_search=conf.network.dns_search,
            extra_hosts=conf.network.extra_hosts,
            network_mode=conf.network.network_mode,
            publish_all_ports=conf.network.publish_all_ports,
            cap_add=conf.cpu.cap_add,
            cap_drop=conf.cpu.cap_drop,
            mem_limit=conf.cpu.mem_limit,
            memswap_limit=conf.cpu.memswap_limit,
            ulimits=conf.ulimits,
            read_only=conf.read_only_rootfs,
            log_config=conf.log_config,
            security_opt=conf.security_opt,
            **conf.other_options.host_config)

        container_id = conf.harpoon.docker_context.create_container(
            image_name,
            name=container_name,
            detach=detach,
            command=command,
            volumes=volume_names,
            environment=env,
            tty=tty,
            user=conf.user,
            ports=ports,
            stdin_open=tty,
            dns=conf.network.dns,
            hostname=conf.network.hostname,
            domainname=conf.network.domainname,
            network_disabled=conf.network.disabled,
            cpuset=conf.cpu.cpuset,
            cpu_shares=conf.cpu.cpu_shares,
            host_config=host_config,
            **conf.other_options.create)

        if isinstance(container_id, dict):
            if "errorDetail" in container_id:
                raise BadImage("Failed to create container",
                               image=name,
                               error=container_id["errorDetail"])
            container_id = container_id["Id"]

        return container_id
예제 #13
0
파일: runner.py 프로젝트: Atry/harpoon
    def create_container(self, conf, detach, tty):
        """Create a single container"""

        name = conf.name
        image_name = conf.image_name
        container_name = conf.container_name

        env = dict(e.pair for e in conf.env)
        ports = [port.host_port for port in conf.ports]
        links = [link.pair for link in conf.links]
        binds = conf.volumes.binds
        command = conf.formatted_command
        volume_names = conf.volumes.volume_names
        volumes_from = list(conf.volumes.share_with_names)
        port_bindings = dict([port.pair for port in conf.ports])

        uncreated = []
        for name in binds:
            if not os.path.exists(name):
                log.info("Making volume for mounting\tvolume=%s", name)
                try:
                    os.makedirs(name)
                except OSError as error:
                    uncreated.append((name, error))
        if uncreated:
            raise BadOption("Failed to create some volumes on the host", uncreated=uncreated)

        log.info("Creating container from %s\timage=%s\tcontainer_name=%s\ttty=%s", image_name, name, container_name, tty)
        if binds:
            log.info("\tUsing volumes\tvolumes=%s", volume_names)
        if env:
            log.info("\tUsing environment\tenv=%s", sorted(env.keys()))
        if links:
            log.info("\tLinks: %s", links)
        if ports:
            log.info("\tUsing ports\tports=%s", ports)
        if port_bindings:
            log.info("\tPort bindings: %s", ports)
        if volumes_from:
            log.info("\tVolumes from: %s", volumes_from)

        host_config = utils.create_host_config(
              links = links
            , binds = binds
            , volumes_from = volumes_from
            , port_bindings = port_bindings

            , devices = conf.devices
            , lxc_conf = conf.lxc_conf
            , privileged = conf.privileged
            , restart_policy = conf.restart_policy

            , dns = conf.network.dns
            , dns_search = conf.network.dns_search
            , extra_hosts = conf.network.extra_hosts
            , network_mode = conf.network.network_mode
            , publish_all_ports = conf.network.publish_all_ports

            , cap_add = conf.cpu.cap_add
            , cap_drop = conf.cpu.cap_drop
            , mem_limit = conf.cpu.mem_limit
            , memswap_limit = conf.cpu.memswap_limit

            , ulimits = conf.ulimits
            , read_only = conf.read_only_rootfs
            , log_config = conf.log_config
            , security_opt = conf.security_opt

            , **conf.other_options.host_config
            )

        container_id = conf.harpoon.docker_context.create_container(image_name
            , name=container_name
            , detach=detach
            , command=command
            , volumes=volume_names
            , environment=env

            , tty = tty
            , user = conf.user
            , ports = ports
            , stdin_open = tty

            , dns = conf.network.dns
            , hostname = conf.network.hostname
            , domainname = conf.network.domainname
            , network_disabled = conf.network.disabled

            , cpuset = conf.cpu.cpuset
            , cpu_shares = conf.cpu.cpu_shares

            , host_config = host_config

            , **conf.other_options.create
            )

        if isinstance(container_id, dict):
            if "errorDetail" in container_id:
                raise BadImage("Failed to create container", image=name, error=container_id["errorDetail"])
            container_id = container_id["Id"]

        return container_id