Пример #1
0
def run_container(name,
                  image,
                  command=None,
                  environment=None,
                  ro=None,
                  rw=None,
                  links=None,
                  detach=True,
                  volumes_from=None,
                  port_bindings=None,
                  log_syslog=False):
    """
    Wrapper for docker create_container, start calls

    :param log_syslog: bool flag to redirect container's logs to host's syslog

    :returns: container info dict or None if container couldn't be created

    Raises PortAllocatedError if container couldn't start on the
    requested port.
    """
    binds = ro_rw_to_binds(ro, rw)
    log_config = LogConfig(type=LogConfig.types.JSON)
    if log_syslog:
        log_config = LogConfig(type=LogConfig.types.SYSLOG,
                               config={'syslog-tag': name})
    host_config = _get_docker().create_host_config(binds=binds,
                                                   log_config=log_config,
                                                   links=links,
                                                   volumes_from=volumes_from,
                                                   port_bindings=port_bindings)

    c = _get_docker().create_container(
        name=name,
        image=image,
        command=command,
        environment=environment,
        volumes=binds_to_volumes(binds),
        detach=detach,
        stdin_open=False,
        tty=False,
        ports=list(port_bindings) if port_bindings else None,
        host_config=host_config)
    try:
        _get_docker().start(container=c['Id'], )
    except APIError as e:
        if 'address already in use' in e.explanation:
            try:
                _get_docker().remove_container(name, force=True)
            except APIError:
                pass
            raise PortAllocatedError()
        raise
    return c
Пример #2
0
 def test_create_host_config_obj_logconfig(self):
     obj = LogConfig(type=LogConfig.types.SYSLOG, config={'key1': 'val1'})
     config = create_host_config(version=DEFAULT_DOCKER_API_VERSION,
                                 log_config=obj)
     self.assertIn('LogConfig', config)
     self.assertTrue(isinstance(config['LogConfig'], LogConfig))
     self.assertEqual(obj, config['LogConfig'])
Пример #3
0
    def _get_container_host_config(self, override_options, one_off=False):
        options = dict(self.options, **override_options)

        log_config = LogConfig(type=options.get('log_driver', ""),
                               config=options.get('log_opt', None))
        return self.client.create_host_config(
            links=self._get_links(link_to_self=one_off),
            port_bindings=build_port_bindings(options.get('ports') or []),
            binds=options.get('binds'),
            volumes_from=self._get_volumes_from(),
            privileged=options.get('privileged', False),
            network_mode=self.net.mode,
            devices=options.get('devices'),
            dns=options.get('dns'),
            dns_search=options.get('dns_search'),
            restart_policy=options.get('restart'),
            cap_add=options.get('cap_add'),
            cap_drop=options.get('cap_drop'),
            mem_limit=options.get('mem_limit'),
            memswap_limit=options.get('memswap_limit'),
            ulimits=build_ulimits(options.get('ulimits')),
            log_config=log_config,
            extra_hosts=options.get('extra_hosts'),
            read_only=options.get('read_only'),
            pid_mode=options.get('pid'),
            security_opt=options.get('security_opt'),
            ipc_mode=options.get('ipc'),
            cgroup_parent=options.get('cgroup_parent'),
        )
Пример #4
0
def get_log_config(logging_dict):
    log_driver = logging_dict.get('driver', "") if logging_dict else ""
    log_options = logging_dict.get('options', None) if logging_dict else None
    return LogConfig(
        type=log_driver,
        config=log_options
    )
Пример #5
0
    def _get_container_host_config(self, override_options, one_off=False):
        options = dict(self.options, **override_options)
        port_bindings = build_port_bindings(options.get('ports') or [])

        privileged = options.get('privileged', False)
        cap_add = options.get('cap_add', None)
        cap_drop = options.get('cap_drop', None)
        log_config = LogConfig(
            type=options.get('log_driver', ""),
            config=options.get('log_opt', None)
        )
        pid = options.get('pid', None)
        security_opt = options.get('security_opt', None)

        dns = options.get('dns', None)
        if isinstance(dns, six.string_types):
            dns = [dns]

        dns_search = options.get('dns_search', None)
        if isinstance(dns_search, six.string_types):
            dns_search = [dns_search]

        restart = parse_restart_spec(options.get('restart', None))

        extra_hosts = build_extra_hosts(options.get('extra_hosts', None))
        read_only = options.get('read_only', None)

        devices = options.get('devices', None)
        cgroup_parent = options.get('cgroup_parent', None)

        return self.client.create_host_config(
            links=self._get_links(link_to_self=one_off),
            port_bindings=port_bindings,
            binds=options.get('binds'),
            volumes_from=self._get_volumes_from(),
            privileged=privileged,
            network_mode=self.net.mode,
            devices=devices,
            dns=dns,
            dns_search=dns_search,
            restart_policy=restart,
            cap_add=cap_add,
            cap_drop=cap_drop,
            mem_limit=options.get('mem_limit'),
            memswap_limit=options.get('memswap_limit'),
            log_config=log_config,
            extra_hosts=extra_hosts,
            read_only=read_only,
            pid_mode=pid,
            security_opt=security_opt,
            ipc_mode=options.get('ipc'),
            cgroup_parent=cgroup_parent
        )
Пример #6
0
    def _get_container_host_config(self, override_options, one_off=False):
        options = dict(self.options, **override_options)
        port_bindings = build_port_bindings(options.get('ports') or [])

        volume_bindings = dict(
            build_volume_binding(parse_volume_spec(volume))
            for volume in options.get('volumes') or []
            if ':' in volume)

        privileged = options.get('privileged', False)
        cap_add = options.get('cap_add', None)
        cap_drop = options.get('cap_drop', None)
        log_config = LogConfig(type=options.get('log_driver', 'json-file'))
        pid = options.get('pid', None)

        dns = options.get('dns', None)
        if isinstance(dns, six.string_types):
            dns = [dns]

        dns_search = options.get('dns_search', None)
        if isinstance(dns_search, six.string_types):
            dns_search = [dns_search]

        restart = parse_restart_spec(options.get('restart', None))

        extra_hosts = build_extra_hosts(options.get('extra_hosts', None))
        read_only = options.get('read_only', None)

        return create_host_config(
            links=self._get_links(link_to_self=one_off),
            port_bindings=port_bindings,
            binds=volume_bindings,
            volumes_from=options.get('volumes_from'),
            privileged=privileged,
            network_mode=self._get_net(),
            dns=dns,
            dns_search=dns_search,
            restart_policy=restart,
            cap_add=cap_add,
            cap_drop=cap_drop,
            log_config=log_config,
            extra_hosts=extra_hosts,
            read_only=read_only,
            pid_mode=pid
        )
Пример #7
0
 def test_logconfig_invalid_config_type(self):
     with pytest.raises(ValueError):
         LogConfig(type=LogConfig.types.JSON, config='helloworld')
Пример #8
0
def create_one_container(host,
                         version,
                         entrypoint,
                         env='prod',
                         cores=None,
                         ports=None,
                         args=None,
                         cpu_shares=1024,
                         image='',
                         need_network=False):
    # raw方式有些设定不同
    is_raw = bool(image)

    if cores is None:
        cores = []
    if ports is None:
        ports = []
    if args is None:
        args = []

    client = get_docker_client(host.addr)
    local_images = {r['RepoTags'][0] for r in client.images()}

    appconfig = version.appconfig
    appname = appconfig.appname
    entry = appconfig.entrypoints[entrypoint]
    envconfig = version.get_resource_config(env)
    # replace $port1...
    cmd = replace_ports(entry['cmd'], ports)
    # add extend arguments
    cmd = cmd + ' '.join([''] + args)
    if not is_raw:
        starter = 'launcheroot' if entry.get('privileged', '') else 'launcher'
        network = 'network' if need_network else 'nonetwork'
        cmd = '/usr/local/bin/%s %s %s' % (starter, network, cmd)

    network_mode = entry.get('network_mode', config.DOCKER_NETWORK_MODE)
    mem_limit = entry.get('mem_limit', 0)
    restart_policy = {
        'MaximumRetryCount': 3,
        'Name': entry.get('restart', 'no')
    }  # could be no/always/on-failure

    # raw 模式下可以选择暴露端口
    def get_ports(expose):
        inport, hostport = expose.split(':')
        return int(inport), int(hostport)

    exposes = [get_ports(expose) for expose in entry.get('exposes', [])]
    exposed_ports = None
    port_bindings = None
    if is_raw and exposes:
        exposed_ports = [p for p, _ in exposes]
        port_bindings = dict(exposes)

    if not image:
        image = '{0}/{1}:{2}'.format(config.DOCKER_REGISTRY, appname,
                                     version.short_sha)

    if image not in local_images:
        repo, tag = image.split(':', 1)
        for line in client.pull(
                repo,
                tag,
                stream=True,
                insecure_registry=config.DOCKER_REGISTRY_INSECURE):
            _log.info(line)

    env_dict = {
        'APP_NAME': appname,
        'ERU_RUNENV': env.upper(),
        'ERU_POD': host.pod.name,
        'ERU_HOST': host.name,
    }
    env_dict.update(envconfig.to_env_dict())

    volumes = ['/writable-proc/sys']
    volumes.extend(appconfig.get('volumes', []))

    binds = {'/proc/sys': {'bind': '/writable-proc/sys', 'ro': False}}
    binds.update(appconfig.get('binds', {}))

    if config.ERU_CONTAINER_PERMDIR and entry.get('permdir', ''):
        permdir = config.ERU_CONTAINER_PERMDIR % appname
        env_dict['ERU_PERMDIR'] = permdir
        volumes.append(permdir)
        binds[config.ERU_HOST_PERMDIR % appname] = {
            'bind': permdir,
            'ro': False
        }

    extra_hosts = entry.get('hosts', None)

    # container name: {appname}_{entrypoint}_{ident_id}
    container_name = '_'.join([appname, entrypoint, gen_salt(6)])
    # cpuset: '0,1,2,3'
    cpuset = ','.join([c.label for c in cores])
    # host_config, include log_config
    host_config = client.create_host_config(
        binds=binds,
        network_mode=network_mode,
        log_config=LogConfig(type=config.DOCKER_LOG_DRIVER),
        ulimits=[Ulimit(name='nofile', soft=65535, hard=65535)],
        restart_policy=restart_policy,
        mem_limit=mem_limit,
        port_bindings=port_bindings,
        extra_hosts=extra_hosts,
    )
    container = client.create_container(
        image=image,
        command=cmd,
        environment=env_dict,
        name=container_name,
        cpuset=cpuset,
        working_dir=None if is_raw else '/%s' % appname,
        network_disabled=config.DOCKER_NETWORK_DISABLED,
        volumes=volumes,
        host_config=host_config,
        cpu_shares=cpu_shares,
        ports=exposed_ports,
    )
    container_id = container['Id']

    client.start(container=container_id)
    return container_id, container_name
Пример #9
0
 def test_create_host_config_obj_logconfig(self):
     obj = LogConfig(type=LogConfig.types.SYSLOG, config={'key1': 'val1'})
     config = create_host_config(log_config=obj)
     self.assertIn('LogConfig', config)
     self.assertTrue(isinstance(config['LogConfig'], LogConfig))
     self.assertEqual(obj, config['LogConfig'])
Пример #10
0
 def test_logconfig_invalid_type(self):
     self.assertRaises(ValueError, lambda: LogConfig(type='xxx', config={}))
     self.assertRaises(
         ValueError,
         lambda: LogConfig(type=LogConfig.types.JSON, config='helloworld'))