def create_container( self, image_name: str, *, name: Optional[str] = None, entrypoint: Optional[str] = None, remove: bool = False, interactive: bool = False, tty: bool = False, detach: bool = False, command: Optional[Union[List[str], str]] = None, mount_volumes: Optional[List[SimpleVolumeBind]] = None, ports: Optional[PortMappings] = None, env_vars: Optional[Dict[str, str]] = None, user: Optional[str] = None, cap_add: Optional[List[str]] = None, cap_drop: Optional[List[str]] = None, security_opt: Optional[List[str]] = None, network: Optional[str] = None, dns: Optional[str] = None, additional_flags: Optional[str] = None, workdir: Optional[str] = None, ) -> str: LOG.debug("Creating container with attributes: %s", locals()) extra_hosts = None if additional_flags: env_vars, ports, mount_volumes, extra_hosts, network = Util.parse_additional_flags( additional_flags, env_vars, ports, mount_volumes, network ) try: kwargs = {} if cap_add: kwargs["cap_add"] = cap_add if cap_drop: kwargs["cap_drop"] = cap_drop if security_opt: kwargs["security_opt"] = security_opt if dns: kwargs["dns"] = [dns] if ports: kwargs["ports"] = ports.to_dict() if workdir: kwargs["working_dir"] = workdir mounts = None if mount_volumes: mounts = Util.convert_mount_list_to_dict(mount_volumes) def create_container(): return self.client().containers.create( image=image_name, command=command, auto_remove=remove, name=name, stdin_open=interactive, tty=tty, entrypoint=entrypoint, environment=env_vars, detach=detach, user=user, network=network, volumes=mounts, extra_hosts=extra_hosts, **kwargs, ) try: container = create_container() except ImageNotFound: self.pull_image(image_name) container = create_container() return container.id except ImageNotFound: raise NoSuchImage(image_name) except APIError as e: raise ContainerException() from e
def test_argument_parsing(): test_port_string = "-p 80:8080/udp" test_port_string_with_host = "-p 127.0.0.1:6000:7000/tcp" test_port_string_many_to_one = "-p 9230-9231:9230" test_env_string = "-e TEST_ENV_VAR=test_string=123" test_mount_string = "-v /var/test:/opt/test" argument_string = f"{test_port_string} {test_env_string} {test_mount_string} {test_port_string_with_host} {test_port_string_many_to_one}" env_vars = {} ports = PortMappings() mounts = [] Util.parse_additional_flags(argument_string, env_vars, ports, mounts) assert env_vars == {"TEST_ENV_VAR": "test_string=123"} assert ports.to_str() == "-p 80:8080/udp -p 6000:7000 -p 9230-9231:9230" assert mounts == [("/var/test", "/opt/test")] argument_string = ( "--add-host host.docker.internal:host-gateway --add-host arbitrary.host:127.0.0.1" ) _, _, _, extra_hosts, _ = Util.parse_additional_flags( argument_string, env_vars, ports, mounts) assert { "host.docker.internal": "host-gateway", "arbitrary.host": "127.0.0.1" } == extra_hosts with pytest.raises(NotImplementedError): argument_string = "--somerandomargument" Util.parse_additional_flags(argument_string, env_vars, ports, mounts) with pytest.raises(ValueError): argument_string = "--publish 80:80:80:80" Util.parse_additional_flags(argument_string, env_vars, ports, mounts) # Test windows paths argument_string = r'-v "C:\Users\SomeUser\SomePath:/var/task"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [(r"C:\Users\SomeUser\SomePath", "/var/task")] argument_string = r'-v "C:\Users\SomeUser\SomePath:/var/task:ro"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [(r"C:\Users\SomeUser\SomePath", "/var/task")] argument_string = r'-v "C:\Users\Some User\Some Path:/var/task:ro"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [(r"C:\Users\Some User\Some Path", "/var/task")] argument_string = r'-v "/var/test:/var/task:ro"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [("/var/test", "/var/task")] # Test file paths argument_string = r'-v "/tmp/test.jar:/tmp/foo bar/test.jar"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [(r"/tmp/test.jar", "/tmp/foo bar/test.jar")] argument_string = r'-v "/tmp/test-foo_bar.jar:/tmp/test-foo_bar2.jar"' _, _, mounts, _, _ = Util.parse_additional_flags(argument_string) assert mounts == [(r"/tmp/test-foo_bar.jar", "/tmp/test-foo_bar2.jar")] # Test file paths argument_string = r'-v "/tmp/test.jar:/tmp/foo bar/test.jar" --network mynet123' _, _, _, _, network = Util.parse_additional_flags(argument_string) assert network == "mynet123"