Beispiel #1
0
 def test_port_ranges_with_bind_host(self):
     port_mappings = PortMappings(bind_host="0.0.0.0")
     port_mappings.add(5000)
     port_mappings.add(5001)
     port_mappings.add(5003)
     result = port_mappings.to_str()
     self.assertEqual("-p 0.0.0.0:5000-5001:5000-5001 -p 0.0.0.0:5003:5003",
                      result)
 def test_adjacent_port_to_many_to_one(self):
     port_mappings = PortMappings()
     port_mappings.add([7000, 7002], 7000)
     port_mappings.add(6999)
     expected_result = {
         "6999/tcp": 6999,
         "7000/tcp": [7000, 7001, 7002],
     }
     result = port_mappings.to_dict()
     self.assertEqual(expected_result, result)
Beispiel #3
0
def extract_port_flags(user_flags, port_mappings: PortMappings):
    regex = r"-p\s+([0-9]+)(\-([0-9]+))?:([0-9]+)(\-([0-9]+))?"
    matches = re.match(".*%s" % regex, user_flags)
    if matches:
        for match in re.findall(regex, user_flags):
            start = int(match[0])
            end = int(match[2] or match[0])
            start_target = int(match[3] or start)
            end_target = int(match[5] or end)
            port_mappings.add([start, end], [start_target, end_target])
        user_flags = re.sub(regex, r"", user_flags)
    return user_flags
Beispiel #4
0
 def test_port_ranges_with_bind_host_to_dict(self):
     port_mappings = PortMappings(bind_host="0.0.0.0")
     port_mappings.add(5000, 6000)
     port_mappings.add(5001, 7000)
     port_mappings.add(5003, 8000)
     result = port_mappings.to_dict()
     expected_result = {
         "6000/tcp": ("0.0.0.0", 5000),
         "7000/tcp": ("0.0.0.0", 5001),
         "8000/tcp": ("0.0.0.0", 5003),
     }
     self.assertEqual(expected_result, result)
 def test_many_to_one_adjacent_to_uniform(self):
     port_mappings = PortMappings()
     port_mappings.add(5002)
     port_mappings.add(5003)
     port_mappings.add([5004, 5006], 5004)
     expected_result = {
         "5002/tcp": 5002,
         "5003/tcp": 5003,
         "5004/tcp": [5004, 5005, 5006],
     }
     result = port_mappings.to_dict()
     self.assertEqual(expected_result, result)
Beispiel #6
0
 def test_overlapping_port_ranges(self):
     port_mappings = PortMappings()
     port_mappings.add(4590)
     port_mappings.add(4591)
     port_mappings.add(4593)
     port_mappings.add(4592)
     port_mappings.add(4593)
     result = port_mappings.to_str()
     # assert that ranges are non-overlapping, i.e., no duplicate ports
     self.assertEqual("-p 4590-4592:4590-4592 -p 4593:4593", result)
Beispiel #7
0
    def test_port_mappings(self):
        map = PortMappings()
        map.add(123)
        self.assertEqual("-p 123:123", map.to_str())
        map.add(124)
        self.assertEqual("-p 123-124:123-124", map.to_str())
        map.add(234)
        self.assertEqual("-p 123-124:123-124 -p 234:234", map.to_str())
        map.add(345, 346)
        self.assertEqual("-p 123-124:123-124 -p 234:234 -p 345:346",
                         map.to_str())
        map.add([456, 458])
        self.assertEqual(
            "-p 123-124:123-124 -p 234:234 -p 345:346 -p 456-458:456-458",
            map.to_str())

        map = PortMappings()
        map.add([123, 124])
        self.assertEqual("-p 123-124:123-124", map.to_str())
        map.add([234, 237], [345, 348])
        self.assertEqual("-p 123-124:123-124 -p 234-237:345-348", map.to_str())
Beispiel #8
0
 def test_create_with_port_mapping(self, docker_client: ContainerClient,
                                   create_container):
     ports = PortMappings()
     ports.add(45122, 22)
     ports.add(45180, 80)
     create_container("alpine", ports=ports)
Beispiel #9
0
def start_infra_in_docker():
    container_name = config.MAIN_CONTAINER_NAME

    if DOCKER_CLIENT.is_container_running(container_name):
        raise Exception('LocalStack container named "%s" is already running' % container_name)
    if config.TMP_FOLDER != config.HOST_TMP_FOLDER and not config.LAMBDA_REMOTE_DOCKER:
        print(
            f"WARNING: The detected temp folder for localstack ({config.TMP_FOLDER}) is not equal to the "
            f"HOST_TMP_FOLDER environment variable set ({config.HOST_TMP_FOLDER})."
        )  # Logger is not initialized at this point, so the warning is displayed via print

    os.environ[ENV_SCRIPT_STARTING_DOCKER] = "1"

    # load plugins before starting the docker container
    plugin_configs = load_plugins()

    # prepare APIs
    canonicalize_api_names()

    entrypoint = os.environ.get("ENTRYPOINT", "")
    cmd = os.environ.get("CMD", "")
    user_flags = config.DOCKER_FLAGS
    image_name = get_docker_image_to_start()
    service_ports = config.SERVICE_PORTS
    force_noninteractive = os.environ.get("FORCE_NONINTERACTIVE", "")

    # get run params
    plugin_run_params = " ".join(
        [entry.get("docker", {}).get("run_flags", "") for entry in plugin_configs]
    )

    # container for port mappings
    port_mappings = PortMappings(bind_host=config.EDGE_BIND_HOST)

    # get port ranges defined via DOCKER_FLAGS (if any)
    user_flags = extract_port_flags(user_flags, port_mappings)
    plugin_run_params = extract_port_flags(plugin_run_params, port_mappings)

    # construct default port mappings
    if service_ports.get("edge") == 0:
        service_ports.pop("edge")
    for port in service_ports.values():
        port_mappings.add(port)

    env_vars = {}
    for env_var in config.CONFIG_ENV_VARS:
        value = os.environ.get(env_var, None)
        if value is not None:
            env_vars[env_var] = value

    bind_mounts = []
    data_dir = os.environ.get("DATA_DIR", None)
    if data_dir is not None:
        container_data_dir = "/tmp/localstack_data"
        bind_mounts.append((data_dir, container_data_dir))
        env_vars["DATA_DIR"] = container_data_dir
    bind_mounts.append((config.TMP_FOLDER, "/tmp/localstack"))
    bind_mounts.append((config.DOCKER_SOCK, config.DOCKER_SOCK))
    env_vars["DOCKER_HOST"] = f"unix://{config.DOCKER_SOCK}"
    env_vars["HOST_TMP_FOLDER"] = config.HOST_TMP_FOLDER

    if config.DEVELOP:
        port_mappings.add(config.DEVELOP_PORT)

    docker_cmd = [config.DOCKER_CMD, "run"]
    if not force_noninteractive and not in_ci():
        docker_cmd.append("-it")
    if entrypoint:
        docker_cmd += shlex.split(entrypoint)
    if env_vars:
        docker_cmd += [item for k, v in env_vars.items() for item in ["-e", "{}={}".format(k, v)]]
    if user_flags:
        docker_cmd += shlex.split(user_flags)
    if plugin_run_params:
        docker_cmd += shlex.split(plugin_run_params)
    docker_cmd += ["--rm", "--privileged"]
    docker_cmd += ["--name", container_name]
    docker_cmd += port_mappings.to_list()
    docker_cmd += [
        volume
        for host_path, docker_path in bind_mounts
        for volume in ["-v", f"{host_path}:{docker_path}"]
    ]
    docker_cmd.append(image_name)
    docker_cmd += shlex.split(cmd)

    mkdir(config.TMP_FOLDER)
    try:
        run(["chmod", "-R", "777", config.TMP_FOLDER], print_error=False, shell=False)
    except Exception:
        pass

    class ShellRunnerThread(threading.Thread):
        def __init__(self, cmd):
            threading.Thread.__init__(self)
            self.daemon = True
            self.cmd = cmd

        def run(self):
            self.process = run(self.cmd, asynchronous=True, shell=False)

    # keep this print output here for debugging purposes
    print(docker_cmd)
    t = ShellRunnerThread(docker_cmd)
    t.start()
    time.sleep(2)

    if DO_CHMOD_DOCKER_SOCK:
        # fix permissions on /var/run/docker.sock
        for i in range(0, 100):
            if DOCKER_CLIENT.is_container_running(container_name):
                break
            time.sleep(2)
        DOCKER_CLIENT.exec_in_container(
            container_name, command=["chmod", "777", "/var/run/docker.sock"], user="******"
        )

    t.process.wait()
    sys.exit(t.process.returncode)