示例#1
0
文件: docker.py 项目: worxli/scion
def _get_networks() -> List[_Network]:
    """Gets information about existing docker networks.

    Returns:
        A slice containing one entry for each docker network.
        Default networks (e.g., bridge and host) are included.

    Raises:
        plumbum.commands.processes.ProcessExecutionError: One
            of the docker commands returns a non-zero exit code.
    """

    nets = []
    net_json = cmd.docker('network', 'ls', '-q', '--format={{json .}}')
    for net_json in net_json.splitlines():
        net = json.loads(net_json)
        net_inspect_json = cmd.docker('network', 'inspect',
                                      '--format={{json .}}', net['ID'])
        net_inspect = json.loads(net_inspect_json)

        containers = []
        for container_id, prop in net_inspect['Containers'].items():
            ipv4 = prop.get('IPv4Address', '')
            ipv6 = prop.get('IPv6Address', '')
            containers.append('%s: %s %s' % (prop['Name'], ipv4, ipv6))
        nets.append(
            _Network(net_inspect['Name'], net_inspect['Driver'], containers))
    return nets
示例#2
0
def proxy(**env_vars):
    """A context manager that starts the proxy with the specified env.

    While inside the block, `$DOCKER_HOST` will be modified to talk to the proxy
    instead of the raw docker socket.
    """
    container_id = None
    env_list = [f"--env={key}={value}" for key, value in env_vars.items()]
    info(f"Starting {DOCKER_IMAGE_NAME} container with: {env_list}")
    try:
        container_id = docker(
            "container",
            "run",
            "--detach",
            "--privileged",
            "--publish=2375",
            "--volume=/var/run/docker.sock:/var/run/docker.sock",
            *env_list,
            DOCKER_IMAGE_NAME,
        ).strip()
        container_data = json.loads(
            docker("container", "inspect", container_id.strip()))
        socket_port = container_data[0]["NetworkSettings"]["Ports"][
            "2375/tcp"][0]["HostPort"]
        with local.env(DOCKER_HOST=f"tcp://localhost:{socket_port}"):
            yield container_id
    finally:
        if container_id:
            info(f"Removing {container_id}...")
            docker(
                "container",
                "rm",
                "-f",
                container_id,
            )
示例#3
0
 def _proxy(**env_vars):
     container_id = None
     env_list = [f"--env={key}={value}" for key, value in env_vars.items()]
     _logger.info(f"Starting {image} container with: {env_list}")
     try:
         container_id = docker(
             "container",
             "run",
             "--detach",
             "--privileged",
             "--publish=2375",
             "--volume=/var/run/docker.sock:/var/run/docker.sock",
             *env_list,
             image,
         ).strip()
         container_data = json.loads(
             docker("container", "inspect", container_id.strip()))
         socket_port = container_data[0]["NetworkSettings"]["Ports"][
             "2375/tcp"][0]["HostPort"]
         with local.env(DOCKER_HOST=f"tcp://localhost:{socket_port}"):
             yield container_id
     finally:
         if container_id:
             _logger.info(f"Removing {container_id}...")
             docker(
                 "container",
                 "rm",
                 "-f",
                 container_id,
             )
示例#4
0
def traefik_host(docker: LocalCommand, request):
    """Fixture to indicate where to find a running traefik instance."""
    traefik_run = docker[
        "container", "run", "--detach", "--privileged",
        "--network=inverseproxy_shared",
        "--volume=/var/run/docker.sock:/var/run/docker.sock:ro",
        f"traefik:{request.param}", ]
    try:
        if request.param == "latest" or version.parse(
                request.param) >= version.parse("2"):
            traefik_container = traefik_run(
                "--entrypoints.web-main.address=:80",
                "--log.level=debug",
                "--providers.docker.exposedByDefault=false",
                "--providers.docker.network=inverseproxy_shared",
                "--providers.docker=true",
            ).strip()
        else:
            traefik_container = traefik_run(
                "--logLevel=debug",
                "--defaultEntryPoints=http",
                "--docker.exposedByDefault=false",
                "--docker.watch",
                "--docker",
                "--entryPoints=Name:http Address::80 Compress:on",
            ).strip()
        traefik_details = json.loads(
            docker("container", "inspect", traefik_container))
        assert (len(traefik_details) == 1
                ), "Impossible... did you trigger a race condition?"
        yield traefik_details[0]["NetworkSettings"]["Networks"][
            "inverseproxy_shared"]["IPAddress"]
    finally:
        docker("container", "rm", "--force", traefik_container)
示例#5
0
 def setup_prepare(self):
     """Unpacks loads local docker images and generates the topology.
     """
     # Delete old artifacts, if any.
     cmd.rm("-rf", self.test_state.artifacts)
     cmd.mkdir(self.test_state.artifacts)
     print("artifacts dir: %s" % self.test_state.artifacts)
     for tar in self.test_state.containers_tars:
         print(cmd.docker("image", "load", "-i", tar))
     for loader in self.test_state.container_loaders:
         parts = loader.split("#")
         if len(parts) != 2:
             logger.error("Invalid container loader argument: %s, ignored" %
                          loader)
             continue
         tag, script = parts[0], parts[1]
         o = subprocess.check_output([script]).decode("utf-8")
         idx = o.index("as ")
         if idx < 0:
             logger.error("extracting tag from loader script %s" % loader)
             continue
         bazel_tag = o[idx + len("as "):].strip()
         logger.info("docker tag %s %s" % (bazel_tag, tag))
         subprocess.run(["docker", "tag", bazel_tag, tag], check=True)
     # Define where coredumps will be stored.
     print(
         cmd.docker("run", "--rm", "--privileged", "alpine", "sysctl", "-w",
                    "kernel.core_pattern=/share/coredump"))
     self._setup_generate()
def test_docker_bin(container_factory):
    for tag in ["docker-s3", "docker"]:
        with container_factory(tag) as test_container:
            docker(
                "exec",
                test_container,
                "docker",
                "--version",
            )
示例#7
0
def cexec(image):
    """Return an exec shorthand for a running ci-base container."""
    cid = None
    try:
        cid = docker("container", "run", "--detach", image, "sleep", "3600")
        yield docker["container", "exec", cid.strip()]
    finally:
        if cid:
            docker("container", "rm", "--force", cid.strip())
示例#8
0
def traefik_host(docker: LocalCommand, request):
    """Fixture to indicate where to find a running traefik instance."""
    traefik_run = docker[
        "container",
        "run",
        "--detach",
        "--privileged",
        "--network=inverseproxy_shared",
        "--volume=/var/run/docker.sock:/var/run/docker.sock:ro",
        f"traefik:{request.param}",
    ]
    try:
        if request.param == "latest" or version.parse(request.param) >= version.parse(
            "2"
        ):
            traefik_container = traefik_run(
                "--accessLog=true",
                "--entrypoints.web-alt.address=:8080",
                "--entrypoints.web-insecure.address=:80",
                "--entrypoints.web-main.address=:443",
                "--log.level=debug",
                "--providers.docker.exposedByDefault=false",
                "--providers.docker.network=inverseproxy_shared",
                "--providers.docker=true",
            ).strip()
        else:
            traefik_container = traefik_run(
                "--defaultEntryPoints=web-insecure,web-main",
                "--docker.exposedByDefault=false",
                "--docker.watch",
                "--docker",
                "--entryPoints=Name:web-alt Address::8080 Compress:on",
                "--entryPoints=Name:web-insecure Address::80 Redirect.EntryPoint:web-main",
                "--entryPoints=Name:web-main Address::443 Compress:on TLS TLS.minVersion:VersionTLS12",
                "--logLevel=debug",
            ).strip()
        traefik_details = json.loads(docker("container", "inspect", traefik_container))
        assert (
            len(traefik_details) == 1
        ), "Impossible... did you trigger a race condition?"
        interesting_details = {
            "ip": traefik_details[0]["NetworkSettings"]["Networks"][
                "inverseproxy_shared"
            ]["IPAddress"],
            "traefik_version": traefik_details[0]["Config"]["Labels"][
                "org.opencontainers.image.version"
            ],
            "traefik_image": traefik_details[0]["Image"],
        }
        interesting_details["hostname"] = f"{interesting_details['ip']}.sslip.io"
        yield interesting_details
        # Make sure there were no errors or warnings in logs
        traefik_logs = docker("container", "logs", traefik_container)
        assert " level=error " not in traefik_logs
        assert " level=warn " not in traefik_logs
    finally:
        docker("container", "rm", "--force", traefik_container)
示例#9
0
 def tearDown(self):
     try:
         print("Postgres container logs:")
         docker["container", "logs", self.postgres_container] & FG
         docker["container", "stop", self.postgres_container] & FG
         docker["container", "rm", self.postgres_container] & FG
     except AttributeError:
         pass  # No postgres daemon
     docker("network", "rm", "lan", "wan")
     return super().tearDown()
示例#10
0
 def _connect_wan_network(self, alias="example.com"):
     """Bind a new network, to imitate WAN connections."""
     docker(
         "network",
         "connect",
         "--alias",
         alias,
         "wan",
         self.postgres_container,
     )
示例#11
0
 def _setup_container_loaders(self):
     for tag, script in self.container_loaders:
         o = local[script]()
         idx = o.index("as ")
         if idx < 0:
             logger.error("extracting tag from loader script %s" % tag)
             continue
         bazel_tag = o[idx + len("as "):].strip()
         logger.info("docker tag %s %s" % (bazel_tag, tag))
         cmd.docker("tag", bazel_tag, tag)
示例#12
0
def test_containers_start(container_factory):
    for tag in [
            "docker-s3", "postgres-s3", "docker", "postgres", "s3", "base"
    ]:
        with container_factory(tag) as test_container:
            docker(
                "exec",
                test_container,
                "dup",
                "--version",
            )
示例#13
0
 def setup_prepare(self):
     """Unpacks the topology and loads local docker images.
     """
     # Delete old artifacts, if any.
     cmd.rm("-rf", self.test_state.artifacts)
     cmd.mkdir(self.test_state.artifacts)
     print('artifacts dir: %s' % self.test_state.artifacts)
     self._unpack_topo()
     print(cmd.docker('image', 'load', '-i',
                      self.test_state.containers_tar))
     # Define where coredumps will be stored.
     print(
         cmd.docker("run", "--rm", "--privileged", "alpine", "sysctl", "-w",
                    "kernel.core_pattern=/share/coredump"))
示例#14
0
 def setUp(self):
     with local.cwd(local.cwd / ".."):
         print("Building image")
         local["./hooks/build"] & FG
     docker("network", "create", "lan")
     docker("network", "create", "wan")
     self.version = os.environ["DOCKER_TAG"]
     self.image = "tecnativa/postgres-autoconf:{}".format(self.version),
     self.cert_files = {
         "client.ca.cert.pem",
         "server.cert.pem",
         "server.key.pem",
     }
     return super().setUp()
示例#15
0
 def main(self):
     tmpdir = tempfile.mkdtemp(prefix='service_filelog.')
     print(
         docker('image', 'load', '-i',
                './integration/service_filelog/cs.tar'))
     name = 'service_filelog_test'
     try:
         args = [
             'run', '--name', name, '-v', '{}:/share/logs'.format(tmpdir),
             'bazel/integration/service_filelog:cs'
         ]
         print('docker', *args)
         print(docker(*args, retcode=1))
         logfile = Path('{}/cs.log'.format(tmpdir))
         if not logfile.is_file():
             print('{} is not a file'.format(logfile))
             sys.exit(1)
         if logfile.stat().st_size == 0:
             print('{} is empty'.format(logfile))
             sys.exit(1)
     finally:
         docker('logs', name)
         docker('rm', '-f', name)
         docker('rmi', 'bazel/integration/service_filelog:cs')
         shutil.rmtree(tmpdir, ignore_errors=True)
示例#16
0
 def setup_prepare(self):
     """Unpacks loads local docker images and generates the topology.
     """
     # Delete old artifacts, if any.
     cmd.rm("-rf", self.test_state.artifacts)
     cmd.mkdir(self.test_state.artifacts)
     print("artifacts dir: %s" % self.test_state.artifacts)
     for tar in self.test_state.containers_tars:
         print(cmd.docker("image", "load", "-i", tar))
     # Define where coredumps will be stored.
     print(
         cmd.docker("run", "--rm", "--privileged", "alpine", "sysctl", "-w",
                    "kernel.core_pattern=/share/coredump"))
     self._setup_generate()
示例#17
0
 def test_server_certs_mount(self):
     """El test server habilita la autenticación cert a través de montajes de archivos."""
     with local.tempdir() as tdir:
         with local.cwd(tdir):
             self._generate_certs()
             cert_vols = [
                 "-v{0}/{1}:/etc/postgres/{1}".format(local.cwd, cert)
                 for cert in [
                     "client.ca.cert.pem",
                     "server.cert.pem",
                     "server.key.pem",
                 ]
             ]
             self.postgres_container = docker(
                 "container",
                 "run",
                 "-d",
                 "--network",
                 "lan",
                 "-e",
                 "POSTGRES_DB=test_db",
                 "-e",
                 "POSTGRES_PASSWORD=test_password",
                 "-e",
                 "POSTGRES_USER=test_user",
                 CONF_EXTRA,
                 *cert_vols,
                 self.image,
             ).strip()
             self._check_local_connection()
             self._check_password_auth()
             self._connect_wan_network()
             self._check_cert_auth()
示例#18
0
 def execute(self, isd_as: ISD_AS, cmd: str, *args: str) -> str:
     expanded = []
     for arg in args:
         if str(arg).startswith('gen/'):
             arg = '/share/' + arg
         expanded.append(arg)
     return docker('exec', 'tester_%s' % isd_as.file_fmt(), cmd, *expanded)
示例#19
0
 def _check_cert_auth(self):
     """Test connection with cert auth work fine."""
     # Test connection with cert auth works fine
     self.assertEqual(
         "1\n",
         docker(
             "container",
             "run",
             "--network",
             "wan",
             "-e",
             "PGDATABASE=test_db",
             "-e",
             "PGSSLCERT=/certs/client.cert.pem",
             "-e",
             "PGSSLKEY=/certs/client.key.pem",
             "-e",
             "PGSSLMODE=verify-full",
             "-e",
             "PGSSLROOTCERT=/certs/server.ca.cert.pem",
             "-e",
             "PGUSER=test_user",
             CONF_EXTRA,
             "-v",
             "{}:/certs".format(local.cwd),
             self.image,
             "psql",
             "--host",
             "example.localdomain",
             "--command",
             "SELECT 1",
             "--no-align",
             "--tuples-only",
         ),
     )
示例#20
0
 def _check_local_connection(self):
     """Check that local connection works fine."""
     # The 1st test could fail while postgres boots
     for attempt in range(10):
         try:
             time.sleep(5)
             # Test local connections via unix socket work
             self.assertEqual(
                 "1\n",
                 docker(
                     "container",
                     "exec",
                     self.postgres_container,
                     "psql",
                     "--command",
                     "SELECT 1",
                     "--dbname",
                     "test_db",
                     "--no-align",
                     "--tuples-only",
                     "--username",
                     "test_user",
                 ),
             )
         except AssertionError:
             if attempt < 9:
                 print("Failure number {}. Retrying...".format(attempt))
             else:
                 raise
         else:
             continue
示例#21
0
 def test_no_certs_wan(self):
     """Unencrypted WAN access works (although this is dangerous)."""
     self.postgres_container = docker(
         "container",
         "run",
         "-d",
         "--network",
         "lan",
         "-e",
         "POSTGRES_DB=test_db",
         "-e",
         "POSTGRES_PASSWORD=test_password",
         "-e",
         "POSTGRES_USER=test_user",
         "-e",
         "WAN_AUTH_METHOD=md5",
         "-e",
         "WAN_CONNECTION=host",
         CONF_EXTRA,
         self.image,
     ).strip()
     self._check_local_connection()
     self._check_password_auth()
     self._connect_wan_network()
     with self.assertRaises(ProcessExecutionError):
         self._check_password_auth("example.localdomain")
示例#22
0
 def _check_password_auth(self, host=None):
     """Test connection with password auth work fine."""
     if not host:
         # Connect via LAN by default
         host = self.postgres_container[:12]
     self.assertEqual(
         "1\n",
         docker(
             "container",
             "run",
             "--network",
             "lan",
             "-e",
             "PGDATABASE=test_db",
             "-e",
             "PGPASSWORD=test_password",
             "-e",
             "PGSSLMODE=disable",
             "-e",
             "PGUSER=test_user",
             self.image,
             "psql",
             "--host",
             host,
             "--command",
             "SELECT 1",
             "--no-align",
             "--tuples-only",
         ),
     )
示例#23
0
    def _setup(self):
        print(
            cmd.docker("image", "load", "-i",
                       "./acceptance/hidden_paths/testcontainers.tar"))

        # TODO(scrye): Mangle configuration files of Daemons and Control Services to enable
        # hidden paths.

        print(self._docker_compose("up", "-d"))
        time.sleep(5)

        self._testers = {
            "2": "tester_1-ff00_0_2",
            "3": "tester_1-ff00_0_3",
            "4": "tester_1-ff00_0_4",
            "5": "tester_1-ff00_0_5",
        }
        self._ases = {
            "2": "1-ff00:0:2",
            "3": "1-ff00:0:3",
            "4": "1-ff00:0:4",
            "5": "1-ff00:0:5",
        }
        self._daemons_api = {
            "2": "172.20.0.52:30255",
            "3": "172.20.0.60:30255",
            "4": "172.20.0.68:30255",
            "5": "172.20.0.76:30255",
        }
示例#24
0
 def _check_cert_auth(self):
     """La conexión con cert auth funciona bien."""
     # La prueba conexión con cert auth funciona bien
     self.assertEqual(
         "1\n",
         docker(
             "container",
             "run",
             "--network",
             "wan",
             "-e",
             "PGDATABASE=test_db",
             "-e",
             "PGSSLCERT=/certs/client.cert.pem",
             "-e",
             "PGSSLKEY=/certs/client.key.pem",
             "-e",
             "PGSSLMODE=verify-full",
             "-e",
             "PGSSLROOTCERT=/certs/server.ca.cert.pem",
             "-e",
             "PGUSER=test_user",
             CONF_EXTRA,
             "-v",
             "{}:/certs".format(local.cwd),
             self.image,
             "psql",
             "--host",
             "ejemplo.localdomain",
             "--command",
             "SELECT 1",
             "--no-align",
             "--tuples-only",
         ),
     )
示例#25
0
 def test_server_certs_var(self):
     """Prueba que el servidor habilita autenticación de cert a través de env vars."""
     with local.tempdir() as tdir:
         with local.cwd(tdir):
             self._generate_certs()
             certs_var = {name: cat(name) for name in self.cert_files}
             self.postgres_container = docker(
                 "container",
                 "run",
                 "-d",
                 "--network",
                 "lan",
                 "-e",
                 "CERTS=" + json.dumps(certs_var),
                 "-e",
                 "POSTGRES_DB=test_db",
                 "-e",
                 "POSTGRES_PASSWORD=test_password",
                 "-e",
                 "POSTGRES_USER=test_user",
                 CONF_EXTRA,
                 self.image,
             ).strip()
             self._check_local_connection()
             self._check_password_auth()
             self._connect_wan_network()
             self._check_cert_auth()
示例#26
0
 def _check_password_auth(self, host=None):
     """La conexión con contraseña de autenticación funciona bien."""
     if not host:
         # Conectarse a través de LAN por defecto
         host = self.postgres_container[:12]
     self.assertEqual(
         "1\n",
         docker(
             "container",
             "run",
             "--network",
             "lan",
             "-e",
             "PGDATABASE=test_db",
             "-e",
             "PGPASSWORD=test_password",
             "-e",
             "PGSSLMODE=disable",
             "-e",
             "PGUSER=test_user",
             self.image,
             "psql",
             "--host",
             host,
             "--command",
             "SELECT 1",
             "--no-align",
             "--tuples-only",
         ),
     )
示例#27
0
 def _check_local_connection(self):
     """Verifica que la conexión local funcione bien."""
     # La primera prueba podría fallar mientras bootea postgres
     for attempt in range(10):
         try:
             time.sleep(5)
             # Probar conexiones locales a través del trabajo de socket Unix
             self.assertEqual(
                 "1\n",
                 docker(
                     "container",
                     "exec",
                     self.postgres_container,
                     "psql",
                     "--command",
                     "SELECT 1",
                     "--dbname",
                     "test_db",
                     "--no-align",
                     "--tuples-only",
                     "--username",
                     "test_user",
                 ),
             )
         except AssertionError:
             if attempt < 9:
                 print("Failure number {}. Retrying...".format(attempt))
             else:
                 raise
         else:
             continue
示例#28
0
 def test_certs_falsy_lan(self):
     """La configuración con valores falsos para certs funciona bien."""
     self.postgres_container = docker(
         "container",
         "run",
         "-d",
         "--network",
         "lan",
         "-e",
         "POSTGRES_DB=test_db",
         "-e",
         "POSTGRES_PASSWORD=test_password",
         "-e",
         "POSTGRES_USER=test_user",
         CONF_EXTRA,
         "-e",
         "CERTS={}".format(
             json.dumps({
                 "client.ca.cert.pem": False,
                 "server.cert.pem": False,
                 "server.key.pem": False,
             })),
         self.image,
     ).strip()
     self._check_local_connection()
     self._check_password_auth()
     self._connect_wan_network()
     with self.assertRaises(ProcessExecutionError):
         self._check_password_auth("ejemplo.localdomain")
示例#29
0
def run_ssh_server(ssh_public_key, target_docker_image):
    cleaned_docker_name = target_docker_image.replace(':',
                                                      '_').replace('/', '_')
    target_container_name = "sshd_on_%s" % cleaned_docker_name

    # start ssh service on a new container based on target_docker_image
    Dodo.run([
        'docker',
        'run',
        '-d',
        '--rm',
        '--publish=0.0.0.0:22:22',
        '--name=%s' % target_container_name,
        target_docker_image,
        '/usr/sbin/sshd',
        '-D',
    ])

    # copy public key to the docker container
    Dodo.run([
        'docker', 'cp', ssh_public_key,
        '%s:/root/.ssh/authorized_keys' % target_container_name
    ])

    # get the ip address
    target_ip = docker(
        'inspect', '-f',
        '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}',
        target_container_name)[:-1]

    return target_ip, target_container_name
示例#30
0
 def test_no_certs_wan(self):
     """El acceso a WAN sin cifrar funciona (aunque esto es peligroso)."""
     self.postgres_container = docker(
         "container",
         "run",
         "-d",
         "--network",
         "lan",
         "-e",
         "POSTGRES_DB=test_db",
         "-e",
         "POSTGRES_PASSWORD=test_password",
         "-e",
         "POSTGRES_USER=test_user",
         "-e",
         "WAN_AUTH_METHOD=md5",
         "-e",
         "WAN_CONNECTION=host",
         CONF_EXTRA,
         self.image,
     ).strip()
     self._check_local_connection()
     self._check_password_auth()
     self._connect_wan_network()
     with self.assertRaises(ProcessExecutionError):
         self._check_password_auth("ejemplo.localdomain")