Beispiel #1
0
    def test_build_config_with_default_values(self):
        config_dict = {"image": "some_image_name"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "latest"
        assert config.filename == POLYAXON_DOCKERFILE_NAME
        assert config.shell == POLYAXON_DOCKER_SHELL
        assert config.workdir == POLYAXON_DOCKER_WORKDIR

        config_dict = {}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)
Beispiel #2
0
 def test_docker_build_context(self, generate_create):
     build_context = V1DockerfileType(image="foo")
     self.runner.invoke(
         docker,
         [
             "generate", "--build-context={}".format(
                 build_context.to_dict(dump=True))
         ],
     )
     assert generate_create.call_count == 1
    def test_get_generated_dockerfile_path(self):
        # Create a repo folder
        repo_path = os.path.join(tempfile.mkdtemp(), "repo")
        os.mkdir(repo_path)
        build_context = V1DockerfileType(image="busybox")

        builder = DockerFileGenerator(build_context=build_context,
                                      destination=repo_path)
        assert builder.dockerfile_path == "{}/{}".format(
            repo_path, POLYAXON_DOCKERFILE_NAME)
        builder.clean()
    def test_generate(self):
        # Create a repo folder
        tmp_path = tempfile.mkdtemp()

        assert not os.path.isfile("{}/{}".format(tmp_path, POLYAXON_DOCKERFILE_NAME))

        build_context = V1DockerfileType(
            image="busybox",
            workdir_path=tmp_path,
            lang_env="en_US.UTF-8",
            uid=100,
            gid=100,
        )
        DockerFileGenerator(build_context=build_context, destination=tmp_path).create()
        assert os.path.isfile("{}/{}".format(tmp_path, POLYAXON_DOCKERFILE_NAME))
Beispiel #5
0
 def test_build_repo_with_install_step_copy_path_config(self):
     config_dict = {
         "image": "tensorflow:1.3.0",
         "path": ["./module"],
         "copy": ["/foo/bar"],
         "run": ["pip install tensor2tensor"],
         "env": {
             "LC_ALL": "en_US.UTF-8"
         },
         "filename": "dockerfile",
         "workdir": "",
         "shell": "sh",
     }
     config = V1DockerfileType.from_dict(config_dict)
     assert config.to_dict() == config_dict
     assert config.image_tag == "1.3.0"
Beispiel #6
0
 def test_build_repo_with_security_context(self):
     config_dict = {
         "image": "tensorflow:1.3.0",
         "run": ["pip install tensor2tensor"],
         "env": {
             "LC_ALL": "en_US.UTF-8"
         },
         "uid": 1000,
         "gid": 3000,
         "filename": "dockerfile",
         "workdir": "",
         "shell": "sh",
     }
     config = V1DockerfileType.from_dict(config_dict)
     assert config.to_dict() == config_dict
     assert config.image_tag == "1.3.0"
     assert config.uid == 1000
     assert config.gid == 3000
Beispiel #7
0
    def test_build_config_image_use_cases(self):
        # Latest
        config_dict = {"image": "some_image_name"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "latest"

        # Latest from with docker registry url
        config_dict = {
            "image": "registry.foobar.com/my/docker/some_image_name"
        }
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "latest"

        # Latest from with docker registry url with port
        config_dict = {"image": "registry.foobar.com:4567/some_image_name"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "latest"

        # Some tag
        config_dict = {"image": "some_image_name:4567"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "4567"

        # Some tag
        config_dict = {"image": "some_image_name:foo"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "foo"

        # Some tag from with docker registry url
        config_dict = {
            "image": "registry.foobar.com/my/docker/some_image_name:foo"
        }
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "foo"

        # Some tag from with docker registry url with port
        config_dict = {"image": "registry.foobar.com:4567/some_image_name:foo"}
        config = V1DockerfileType.from_dict(config_dict)
        assert config.image_tag == "foo"
    def test_get_dockerfile_init_container(self):
        dockerfile_args = V1DockerfileType(image="test/test")
        container = get_dockerfile_init_container(
            polyaxon_init=V1PolyaxonInitContainer(image="foo", image_tag=""),
            dockerfile_args=dockerfile_args,
            env=None,
            contexts=PluginsContextsSpec.from_config(V1Plugins(auth=True)),
            run_path="test",
            run_instance="foo.bar.runs.uuid",
        )
        assert INIT_DOCKERFILE_CONTAINER_PREFIX in container.name
        assert container.image == "foo"
        assert container.image_pull_policy is None
        assert container.command == ["polyaxon", "docker", "generate"]
        assert container.args == [
            "--build-context={}".format(dockerfile_args.to_dict(dump=True)),
            "--destination={}".format(CONTEXT_MOUNT_ARTIFACTS),
            "--copy-path={}".format(
                CONTEXT_MOUNT_RUN_OUTPUTS_FORMAT.format("test")),
            "--track",
        ]
        assert container.env == [
            get_run_instance_env_var(run_instance="foo.bar.runs.uuid")
        ]
        assert container.resources == get_init_resources()
        assert container.volume_mounts == [
            get_connections_context_mount(
                name=constants.CONTEXT_VOLUME_ARTIFACTS,
                mount_path=CONTEXT_MOUNT_ARTIFACTS,
            ),
            get_auth_context_mount(read_only=True),
        ]

        dockerfile_args = V1DockerfileType(
            image="test/test",
            lang_env="LANG",
            run=["step1", "step2"],
            env=[["key1", "val1"], ["key2", "val2"]],
            uid=2222,
            gid=2222,
        )
        container = get_dockerfile_init_container(
            polyaxon_init=V1PolyaxonInitContainer(
                image="init/init",
                image_tag="",
                image_pull_policy="IfNotPresent"),
            env=[],
            dockerfile_args=dockerfile_args,
            mount_path="/somepath",
            contexts=PluginsContextsSpec.from_config(V1Plugins(auth=True)),
            run_path="test",
            run_instance="foo.bar.runs.uuid",
        )
        assert INIT_DOCKERFILE_CONTAINER_PREFIX in container.name
        assert container.image == "init/init"
        assert container.image_pull_policy == "IfNotPresent"
        assert container.command == ["polyaxon", "docker", "generate"]
        assert container.args == [
            "--build-context={}".format(dockerfile_args.to_dict(dump=True)),
            "--destination=/somepath",
            "--copy-path={}".format(
                CONTEXT_MOUNT_RUN_OUTPUTS_FORMAT.format("test")),
            "--track",
        ]
        assert container.env == [
            get_run_instance_env_var(run_instance="foo.bar.runs.uuid")
        ]
        assert container.resources == get_init_resources()
        assert container.volume_mounts == [
            get_connections_context_mount(name=get_volume_name("/somepath"),
                                          mount_path="/somepath"),
            get_auth_context_mount(read_only=True),
        ]
Beispiel #9
0
 def test_build_config(self):
     config_dict = {"image": "some_image_name"}
     config = V1DockerfileType.from_dict(config_dict)
     assert config.image_tag == "latest"
Beispiel #10
0
 def test_does_not_accept_dockerfiles(self):
     config_dict = {"dockerfile": "foo/bar"}
     with self.assertRaises(ValidationError):
         V1DockerfileType.from_dict(config_dict)
Beispiel #11
0
    def test_valid_image(self):
        config_dict = {"image": None}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {"image": ""}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {"image": "some_image_name:sdf:sdf:foo"}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {
            "image": "registry.foobar.com/my/docker/some_image_name:foo:foo"
        }
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {"image": "some_image_name / foo"}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {"image": "some_image_name /foo:sdf"}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {"image": "some_image_name /foo :sdf"}
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {
            "image":
            "registry.foobar.com:foo:foo/my/docker/some_image_name:foo"
        }
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {
            "image": "registry.foobar.com:foo:foo/my/docker/some_image_name"
        }
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)

        config_dict = {
            "image": "registry.foobar.com:/my/docker/some_image_name:foo"
        }
        with self.assertRaises(ValidationError):
            V1DockerfileType.from_dict(config_dict)
    def test_render_works_as_expected(self):  # pylint:disable=too-many-statements
        # Create a repo folder
        repo_path = os.path.join(tempfile.mkdtemp(), "repo")
        os.mkdir(repo_path)

        build_context = V1DockerfileType(image="busybox")

        # By default it should use FROM image declare WORKDIR
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        builder.clean()

        assert "FROM busybox" in dockerfile
        assert "WORKDIR {}".format(POLYAXON_DOCKER_WORKDIR) in dockerfile
        assert "COPY" not in dockerfile

        # By default it should use FROM image declare WORKDIR, and work
        build_context = V1DockerfileType(image="busybox", workdir_path=repo_path)
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        builder.clean()
        assert "COPY {}".format(repo_path) in dockerfile

        # No lang env
        assert "LC_ALL" not in dockerfile
        assert "LANG" not in dockerfile
        assert "LANGUAGE" not in dockerfile

        # Add env vars
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, env=[("BLA", "BLA")]
        )
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "ENV BLA BLA" in dockerfile
        assert "groupadd" not in dockerfile
        assert "useradd" not in dockerfile
        builder.clean()

        # Add copy steps
        copy = ["polyaxon_requirements.txt", "polyaxon_setup.sh", "environment.yml"]
        # Add run steps to act on them
        run = [
            "pip install -r polyaxon_requirements.txt",
            "./polyaxon_setup.sh",
            "conda env update -n base -f environment.yml",
        ]
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, copy=copy, run=run
        )

        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "COPY {} {}".format(copy[0], POLYAXON_DOCKER_WORKDIR) in dockerfile
        assert "COPY {} {}".format(copy[1], POLYAXON_DOCKER_WORKDIR) in dockerfile
        assert "COPY {} {}".format(copy[2], POLYAXON_DOCKER_WORKDIR) in dockerfile

        assert "RUN {}".format(run[0]) in dockerfile
        assert "RUN {}".format(run[1]) in dockerfile
        assert "RUN {}".format(run[2]) in dockerfile
        assert "groupadd" not in dockerfile
        assert "useradd" not in dockerfile
        builder.clean()

        # Add uid but no gid
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, uid=1000
        )

        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "groupadd" not in dockerfile
        assert "useradd" not in dockerfile
        assert "1000" not in dockerfile
        builder.clean()

        # Add gid but no uid
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, gid=1000
        )
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "groupadd" not in dockerfile
        assert "useradd" not in dockerfile
        assert "1000" not in dockerfile
        builder.clean()

        # Add uid and gid
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, uid=1000, gid=1000
        )
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "groupadd" in dockerfile
        assert "useradd" in dockerfile
        assert "-u 1000" in dockerfile
        assert "-g 1000" in dockerfile
        builder.clean()

        # Add lan env
        build_context = V1DockerfileType(
            image="busybox", workdir_path=repo_path, lang_env="en_US.UTF-8"
        )
        builder = DockerFileGenerator(
            build_context=build_context, destination=repo_path
        )

        dockerfile = builder.render()
        assert "en_US.UTF-8" in dockerfile
        assert "LC_ALL" in dockerfile
        assert "LANG" in dockerfile
        assert "LANGUAGE" in dockerfile
        builder.clean()