def test_get_init_containers_with_git_without_connection(self):
     git1 = V1GitConnection(revision="test", url="https://test.com")
     git2 = V1GitConnection(revision="test", url="https://test.com")
     containers = self.converter.get_init_containers(
         contexts=None,
         artifacts_store=None,
         init_connections=[
             V1Init(git=git1,
                    container=k8s_schemas.V1Container(name="test")),
             V1Init(git=git2, path="/test"),
         ],
         init_containers=[],
         connection_by_names={},
         polyaxon_init=V1PolyaxonInitContainer(image="foo/foo"),
     )
     assert containers == [
         get_git_init_container(
             connection=V1ConnectionType(name=git1.get_name(),
                                         kind=V1ConnectionKind.GIT,
                                         schema=git1),
             polyaxon_init=V1PolyaxonInitContainer(image="foo/foo"),
             env=self.converter.get_init_service_env_vars(),
             contexts=None,
         ),
         get_git_init_container(
             container=k8s_schemas.V1Container(name="test"),
             connection=V1ConnectionType(name=git2.get_name(),
                                         kind=V1ConnectionKind.GIT,
                                         schema=git1),
             mount_path="/test",
             polyaxon_init=V1PolyaxonInitContainer(image="foo/foo"),
             env=self.converter.get_init_service_env_vars(),
             contexts=None,
         ),
     ]
Beispiel #2
0
    def test_get_service_custom_resource(self):
        main_container = k8s_schemas.V1Container(name="main")
        sidecar_containers = [k8s_schemas.V1Container(name="sidecar")]
        init_containers = [k8s_schemas.V1Container(name="init")]
        termination = V1Termination(timeout=10)
        environment = V1Environment(
            labels={"foo": "bar"},
            annotations={"foo": "bar"},
            node_selector={"foo": "bar"},
            node_name="foo",
            restart_policy="never",
        )
        metadata, pod_spec = get_pod_spec(
            namespace="default",
            main_container=main_container,
            sidecar_containers=sidecar_containers,
            init_containers=init_containers,
            resource_name="foo",
            volumes=[],
            environment=environment,
            labels=environment.labels,
        )
        custom_object = {
            "serviceSpec": {
                "template":
                get_pod_template_spec(metadata=metadata, pod_spec=pod_spec),
            },
            "termination": {
                "activeDeadlineSeconds": termination.timeout
            },
            "collectLogs": True,
            "syncStatuses": True,
            "notifications": [],
        }
        expected_crd = get_custom_object(
            namespace="default",
            resource_name="foo",
            kind="Operation",
            api_version="core.polyaxon.com/v1",
            labels={"foo": "bar"},
            custom_object=custom_object,
        )

        crd = get_service_custom_resource(
            namespace="default",
            resource_name="foo",
            main_container=main_container,
            sidecar_containers=sidecar_containers,
            init_containers=init_containers,
            volumes=[],
            termination=termination,
            environment=environment,
            labels=environment.labels,
            collect_logs=True,
            sync_statuses=True,
            notifications=None,
            ports=[],
        )

        assert crd == expected_crd
Beispiel #3
0
 def get_replica(self, environment):
     main_container = k8s_schemas.V1Container(name="main")
     sidecar_containers = [k8s_schemas.V1Container(name="sidecar")]
     init_containers = [k8s_schemas.V1Container(name="init")]
     replica = ReplicaSpec(
         volumes=[],
         init_containers=init_containers,
         sidecar_containers=sidecar_containers,
         main_container=main_container,
         labels=environment.labels,
         environment=environment,
         num_replicas=12,
     )
     metadata, pod_spec = get_pod_spec(
         namespace="default",
         main_container=main_container,
         sidecar_containers=sidecar_containers,
         init_containers=init_containers,
         resource_name="foo",
         volumes=[],
         environment=environment,
         labels=environment.labels,
     )
     replica_template = {
         "replicas":
         replica.num_replicas,
         "restartPolicy":
         pod_spec.restart_policy,
         "template":
         get_pod_template_spec(metadata=metadata, pod_spec=pod_spec),
     }
     return replica, replica_template
Beispiel #4
0
    def test_get_artifacts_path_container_with_non_managed_mount_store(self):
        store = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/claim/path",
                                     volume_claim="claim"),
        )
        container = get_artifacts_path_container(
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            artifacts_store=store,
            run_path="run_uid",
            auto_resume=True,
        )

        init_args = init_artifact_context_args("run_uid")
        init_args.append(
            get_volume_args(
                store=store,
                mount_path=CONTEXT_MOUNT_ARTIFACTS,
                artifacts=V1ArtifactsType(dirs=["run_uid"]),
            ))

        assert container == get_base_store_container(
            container=k8s_schemas.V1Container(name="init"),
            container_name=generate_container_name(
                INIT_ARTIFACTS_CONTAINER_PREFIX, "default", False),
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            store=store,
            env=[],
            env_from=[],
            volume_mounts=[get_artifacts_context_mount()],
            args=[" ".join(init_args)],
        )

        container = get_artifacts_path_container(
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            artifacts_store=store,
            run_path="run_uid",
            auto_resume=False,
        )

        init_args = init_artifact_context_args("run_uid")
        assert container == get_base_store_container(
            container=k8s_schemas.V1Container(name="init"),
            container_name=generate_container_name(
                INIT_ARTIFACTS_CONTAINER_PREFIX, "default", False),
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            store=store,
            env=[],
            env_from=[],
            volume_mounts=[get_artifacts_context_mount()],
            args=[" ".join(init_args)],
        )
Beispiel #5
0
def get_dockerfile_init_container(
    polyaxon_init: V1PolyaxonInitContainer,
    dockerfile_args: V1DockerfileType,
    contexts: PluginsContextsSpec,
    run_path: str,
    env: List[k8s_schemas.V1EnvVar] = None,
    mount_path: Optional[str] = None,
) -> k8s_schemas.V1Container:
    env = to_list(env, check_none=True)
    env = env + [get_run_instance_env_var()]

    volume_name = (get_volume_name(mount_path)
                   if mount_path else constants.CONTEXT_VOLUME_ARTIFACTS)
    mount_path = mount_path or CONTEXT_MOUNT_ARTIFACTS
    volume_mounts = [
        get_connections_context_mount(name=volume_name, mount_path=mount_path)
    ]
    if contexts and contexts.auth:
        volume_mounts.append(get_auth_context_mount(read_only=True))

    return k8s_schemas.V1Container(
        name=generate_container_name(INIT_DOCKERFILE_CONTAINER_PREFIX),
        image=polyaxon_init.get_image(),
        image_pull_policy=polyaxon_init.image_pull_policy,
        command=["polyaxon", "docker", "generate"],
        args=[
            "--build-context={}".format(dockerfile_args.to_dict(dump=True)),
            "--destination={}".format(mount_path),
            "--copy-path={}".format(
                CONTEXT_MOUNT_ARTIFACTS_FORMAT.format(run_path) + "/outputs"),
        ],
        env=env,
        resources=polyaxon_init.get_resources(),
        volume_mounts=volume_mounts,
    )
Beispiel #6
0
def get_artifacts_path_container(
    polyaxon_init: V1PolyaxonInitContainer,
    artifacts_store: V1ConnectionType,
    run_path: str,
    clean: bool = True,
) -> Optional[k8s_schemas.V1Container]:
    if not artifacts_store:
        raise PolypodException("Init artifacts container requires a store.")

    init_args = init_artifact_context_args(run_path=run_path)
    if not artifacts_store.is_bucket:
        artifacts_path = get_path(artifacts_store.store_path, run_path)
        init_args.append(
            get_artifacts_store_args(artifacts_path=artifacts_path,
                                     clean=clean))

    container_name = INIT_ARTIFACTS_CONTAINER.format(DEFAULT)
    container = k8s_schemas.V1Container(name=container_name)

    return get_base_store_container(
        container_name=container_name,
        container=container,
        polyaxon_init=polyaxon_init,
        store=artifacts_store,
        env=[],
        env_from=[],
        volume_mounts=[get_artifacts_context_mount()],
        # If we are dealing with a volume we need to make sure the path exists for the user
        # We also clean the path if this is not a resume run
        args=[" ".join(init_args)],
        is_artifact_store=True,
    )
Beispiel #7
0
    def test_config_list_args(self):
        config_dict = {
            "name": "foo",
            "image": "foo/bar:latest",
            "args": ["foo"]
        }
        config = k8s_schemas.V1Container(**config_dict)
        assert get_container_command_args(config) == ([], ["foo"])

        config_dict = {
            "name": "foo",
            "image": "foo/bar:latest",
            "args": ["foo", "bar"]
        }
        config = k8s_schemas.V1Container(**config_dict)
        assert get_container_command_args(config) == ([], ["foo", "bar"])
    def test_get_main_container_with_none_values(self):
        container = get_main_container(
            container_id="test",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=None,
            volume_mounts=None,
            log_level=None,
            artifacts_store=None,
            init=None,
            connection_by_names=None,
            connections=None,
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path=None,
        )

        assert container.name == "test"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert container.env == []
        assert container.env_from == []
        assert container.resources is None
        assert container.volume_mounts == []
Beispiel #9
0
    def test_get_base_store_container_with_mount_store(self):
        claim_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/tmp",
                                     volume_claim="test",
                                     read_only=True),
        )

        container = get_base_store_container(
            container=k8s_schemas.V1Container(name="init"),
            container_name="init",
            polyaxon_init=V1PolyaxonInitContainer(image_tag=""),
            store=claim_store,
            env=None,
            env_from=None,
            volume_mounts=None,
            args=None,
        )
        assert container.name == "init"
        assert container.image == "polyaxon/polyaxon-init"
        assert container.image_pull_policy is None
        assert container.command == ["/bin/sh", "-c"]
        assert container.args is None
        assert container.env == get_connection_env_var(connection=claim_store,
                                                       secret=None)
        assert container.env_from == []
        assert container.resources is not None
        assert container.volume_mounts == [
            get_mount_from_store(store=claim_store)
        ]
Beispiel #10
0
 def test_get_base_container(self):
     store = V1ConnectionType(
         name="test_claim",
         kind=V1ConnectionKind.VOLUME_CLAIM,
         schema=V1ClaimConnection(mount_path="/tmp",
                                  volume_claim="test",
                                  read_only=True),
     )
     env = [get_env_var(name="key", value="value")]
     env_from = [k8s_schemas.V1EnvFromSource(secret_ref={"name": "ref"})]
     mounts = [k8s_schemas.V1VolumeMount(name="test", mount_path="/test")]
     container = get_base_store_container(
         container=k8s_schemas.V1Container(name="init"),
         container_name="init",
         polyaxon_init=V1PolyaxonInitContainer(
             image="foo/foo",
             image_tag="",
             image_pull_policy="IfNotPresent"),
         store=store,
         env=env,
         env_from=env_from,
         volume_mounts=mounts,
         args=["test"],
     )
     assert container.name == "init"
     assert container.image == "foo/foo"
     assert container.image_pull_policy == "IfNotPresent"
     assert container.command == ["/bin/sh", "-c"]
     assert container.args == ["test"]
     assert container.env == env
     assert container.env_from == env_from
     assert container.resources is not None
     assert container.volume_mounts == mounts + [
         get_mount_from_store(store=store)
     ]
Beispiel #11
0
def get_artifacts_path_container(
    polyaxon_init: V1PolyaxonInitContainer,
    artifacts_store: V1ConnectionType,
    run_path: str,
    auto_resume: bool,
) -> Optional[k8s_schemas.V1Container]:
    if not artifacts_store:
        raise PolypodException("Init artifacts container requires a store.")

    init_args = init_artifact_context_args(run_path=run_path)
    if auto_resume:
        init_args.append(
            get_volume_args(
                store=artifacts_store,
                mount_path=CONTEXT_MOUNT_ARTIFACTS,
                artifacts=V1ArtifactsType(dirs=[run_path]),
            ))

    container_name = generate_container_name(INIT_ARTIFACTS_CONTAINER_PREFIX,
                                             DEFAULT)
    container = k8s_schemas.V1Container(name=container_name)

    return get_base_store_container(
        container_name=container_name,
        container=container,
        polyaxon_init=polyaxon_init,
        store=artifacts_store,
        env=[],
        env_from=[],
        volume_mounts=[get_artifacts_context_mount()],
        # If we are dealing with a volume we need to make sure the path exists for the user
        # We also clean the path if this is not a resume run
        args=[" ".join(init_args)],
    )
Beispiel #12
0
    def test_get_base_store_container_with_store_without_secret(self):
        bucket_store_without_secret = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.GCS,
            schema=V1BucketConnection(bucket="gs//:foo"),
        )
        container = get_base_store_container(
            container=k8s_schemas.V1Container(name="test"),
            container_name="init",
            polyaxon_init=V1PolyaxonInitContainer(image_tag=""),
            store=bucket_store_without_secret,
            env=None,
            env_from=None,
            volume_mounts=None,
            args=None,
        )

        assert container.name == "init"
        assert container.image == "polyaxon/polyaxon-init"
        assert container.image_pull_policy is None
        assert container.command == ["/bin/sh", "-c"]
        assert container.args is None
        assert container.env == get_connection_env_var(
            connection=bucket_store_without_secret, secret=None)
        assert container.env_from == []
        assert container.resources is not None
        assert container.volume_mounts == []
    def test_get_artifacts_path_container_with_managed_mount_store(self):
        store = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/claim/path", volume_claim="claim"),
        )
        container = get_artifacts_path_container(
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"
            ),
            artifacts_store=store,
            run_path="run_uid",
            clean=True,
        )

        init_args = init_artifact_context_args("run_uid")
        init_args.append(
            get_artifacts_store_args(
                artifacts_path=get_path(store.store_path, "run_uid"), clean=True
            )
        )

        assert container == get_base_store_container(
            container=k8s_schemas.V1Container(name="default"),
            container_name=INIT_ARTIFACTS_CONTAINER.format("default"),
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"
            ),
            store=store,
            env=[],
            env_from=[],
            volume_mounts=[get_artifacts_context_mount()],
            args=[" ".join(init_args)],
            is_artifact_store=True,
        )
    def test_get_artifacts_path_container_with_bucket_store(self):
        store = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.GCS,
            schema=V1BucketConnection(bucket="gs//:foo"),
        )
        container = get_artifacts_path_container(
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            artifacts_store=store,
            run_path="run_uid",
            auto_resume=True,
        )

        init_args = init_artifact_context_args("run_uid")
        init_args.append(
            get_volume_args(
                store=store,
                mount_path=CONTEXT_MOUNT_ARTIFACTS,
                artifacts=V1ArtifactsType(dirs=["run_uid"]),
            ))

        assert container == get_base_store_container(
            container=k8s_schemas.V1Container(name="default"),
            container_name=INIT_ARTIFACTS_CONTAINER.format("default"),
            polyaxon_init=V1PolyaxonInitContainer(
                image="init", image_pull_policy="IfNotPresent"),
            store=store,
            env=[],
            env_from=[],
            volume_mounts=[get_artifacts_context_mount()],
            args=[" ".join(init_args)],
        )
Beispiel #15
0
def get_store_container(
    polyaxon_init: V1PolyaxonInitContainer,
    connection: V1ConnectionType,
    artifacts: V1ArtifactsType,
    container: Optional[k8s_schemas.V1Container] = None,
    env: List[k8s_schemas.V1EnvVar] = None,
    mount_path: str = None,
) -> Optional[k8s_schemas.V1Container]:
    container_name = INIT_ARTIFACTS_CONTAINER.format(connection.name)
    if not container:
        container = k8s_schemas.V1Container(name=container_name)

    volume_name = (get_volume_name(mount_path)
                   if mount_path else constants.CONTEXT_VOLUME_ARTIFACTS)
    mount_path = mount_path or CONTEXT_MOUNT_ARTIFACTS_FORMAT.format(
        connection.name)
    volume_mounts = [
        get_connections_context_mount(name=volume_name, mount_path=mount_path)
    ]

    return get_base_store_container(
        container=container,
        container_name=container_name,
        polyaxon_init=polyaxon_init,
        store=connection,
        env=env,
        env_from=[],
        volume_mounts=volume_mounts,
        args=[
            get_volume_args(store=connection,
                            mount_path=mount_path,
                            artifacts=artifacts)
        ],
    )
Beispiel #16
0
 def test_config_str_command(self):
     config_dict = {
         "name": "foo",
         "image": "foo/bar:latest",
         "command": "foo"
     }
     config = k8s_schemas.V1Container(**config_dict)
     assert get_container_command_args(config) == (["foo"], [])
Beispiel #17
0
    def test_exec_config_with_str_command(self):
        config_dict = {
            "name": "foo",
            "image": "test/test",
            "command": "python t2t-trainer",
        }
        config = k8s_schemas.V1Container(**config_dict)
        assert get_container_command_args(config) == (["python t2t-trainer"],
                                                      [])

        config_dict = {
            "name": "foo",
            "image": "test/test",
            "command": ["python t2t-trainer"],
        }
        config = k8s_schemas.V1Container(**config_dict)
        assert get_container_command_args(config) == (["python t2t-trainer"],
                                                      [])
    def test_get_main_container_simple_params(self):
        initial_mounts = [
            k8s_schemas.V1VolumeMount(name="test",
                                      mount_path="/mount_test",
                                      read_only=True)
        ]
        resources = k8s_schemas.V1ResourceRequirements(
            requests={
                "cpu": "1",
                "memory": "256Mi"
            },
            limits={
                "cpu": "1",
                "memory": "256Mi"
            },
        )
        container = get_main_container(
            container_id="new-name",
            main_container=k8s_schemas.V1Container(
                name="main",
                image="job_docker_image",
                image_pull_policy="IfNotPresent",
                command=["cmd", "-p", "-c"],
                args=["arg1", "arg2"],
                resources=resources,
            ),
            contexts=None,
            volume_mounts=initial_mounts,
            log_level="info",
            artifacts_store=None,
            init=None,
            connection_by_names=None,
            connections=None,
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=23,
            run_path=None,
        )

        assert container.name == "new-name"
        assert container.image == "job_docker_image"
        assert container.image_pull_policy == "IfNotPresent"
        assert container.command == ["cmd", "-p", "-c"]
        assert container.args == ["arg1", "arg2"]
        assert container.ports == [
            k8s_schemas.V1ContainerPort(container_port=23)
        ]
        assert container.env == [
            get_env_var(name=POLYAXON_KEYS_LOG_LEVEL, value="info")
        ]
        assert container.env_from == []
        assert container.resources == resources
        assert container.volume_mounts == initial_mounts
    def test_main_container(self):
        store = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3://foo"),
            secret=None,
        )
        contexts = PluginsContextsSpec.from_config(
            V1Plugins.from_dict({}), default_auth=True
        )
        main_container = k8s_schemas.V1Container(
            name="main",
            image="foo/test",
            image_pull_policy="IfNotPresent",
            command=["foo", "bar"],
            args=["arg1", "arg2"],
        )
        container = self.converter.get_main_container(
            main_container=main_container,
            contexts=contexts,
            artifacts_store=store,
            init_connections=[],
            connections=[],
            connection_by_names={},
            log_level="info",
            secrets=[],
            config_maps=[],
            kv_env_vars=[],
            ports=None,
        )
        expected_container = get_main_container(
            container_id="dummy",
            main_container=main_container,
            contexts=contexts,
            volume_mounts=get_mounts(
                use_auth_context=True,
                use_artifacts_context=False,
                use_docker_context=False,
                use_shm_context=False,
            ),
            log_level="info",
            artifacts_store=store,
            connections=[],
            init=[],
            connection_by_names={},
            secrets=[],
            config_maps=[],
            kv_env_vars=[],
            env=self.converter.get_main_env_vars(),
            ports=None,
            run_path="/test",
        )

        assert container == expected_container
Beispiel #20
0
    def test_get_service_custom_resource_missing_keys(self):
        main_container = k8s_schemas.V1Container(name="main")
        metadata, pod_spec = get_pod_spec(
            namespace="default",
            main_container=main_container,
            sidecar_containers=None,
            init_containers=None,
            resource_name="foo",
            volumes=[],
            environment=None,
            labels=None,
            annotations=None,
        )
        notifications = [
            V1Notification(connections=["test"], trigger=V1Statuses.DONE)
        ]
        custom_object = {
            "template": get_pod_template_spec(metadata=metadata,
                                              pod_spec=pod_spec),
            "ports": [12, 121, 12],
        }
        expected_crd = get_custom_object(
            namespace="default",
            resource_name="foo",
            kind="Operation",
            api_version="core.polyaxon.com/v1",
            labels=None,
            annotations=None,
            custom_object={
                "serviceSpec": custom_object,
                "collectLogs": False,
                "syncStatuses": False,
                "notifications": [n.to_operator() for n in notifications],
            },
        )

        crd = get_service_custom_resource(
            namespace="default",
            resource_name="foo",
            main_container=main_container,
            sidecar_containers=None,
            init_containers=None,
            volumes=[],
            termination=None,
            collect_logs=None,
            sync_statuses=None,
            notifications=notifications,
            environment=None,
            labels=None,
            annotations=None,
            ports=[12, 121, 12],
        )

        assert crd == expected_crd
Beispiel #21
0
 def test_get_base_store_container_with_none_values(self):
     with self.assertRaises(PolypodException):
         get_base_store_container(
             container=k8s_schemas.V1Container(name="init"),
             container_name=None,
             polyaxon_init=V1PolyaxonInitContainer(),
             store=None,
             env=None,
             env_from=None,
             volume_mounts=None,
             args=None,
         )
Beispiel #22
0
def get_auth_context_container(
    polyaxon_init: V1PolyaxonInitContainer, env: List[k8s_schemas.V1EnvVar] = None
) -> k8s_schemas.V1Container:
    env = to_list(env, check_none=True)
    return k8s_schemas.V1Container(
        name=INIT_AUTH_CONTAINER,
        image=polyaxon_init.get_image(),
        image_pull_policy=polyaxon_init.image_pull_policy,
        command=["polyaxon", "initializer", "auth"],
        env=env,
        resources=polyaxon_init.get_resources(),
        volume_mounts=[get_auth_context_mount(read_only=False)],
    )
    def test_get_main_container_host_paths(self):
        contexts = PluginsContextsSpec(
            auth=True,
            docker=False,
            shm=False,
            collect_logs=True,
            collect_artifacts=True,
            collect_resources=True,
            auto_resume=True,
            sync_statuses=True,
            external_host=False,
            sidecar=None,
        )

        volume_mounts = get_mounts(
            use_auth_context=contexts.auth,
            use_artifacts_context=False,
            use_docker_context=contexts.docker,
            use_shm_context=contexts.shm,
        )

        artifacts_store = V1ConnectionType(
            name="plx-outputs",
            kind=V1ConnectionKind.HOST_PATH,
            schema=V1HostPathConnection(mount_path="/tmp/plx/outputs",
                                        host_path="/tmp/plx/outputs"),
        )

        container = get_main_container(
            container_id="test",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True, collect_logs=True)),
            volume_mounts=volume_mounts,
            log_level=None,
            artifacts_store=artifacts_store,
            init=[],
            connections=[],
            connection_by_names={artifacts_store.name: artifacts_store},
            secrets=[],
            config_maps=[],
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.volume_mounts == [
            get_auth_context_mount(read_only=True),
            get_artifacts_context_mount(read_only=False),
        ]
    def test_get_main_container(self):
        container = get_main_container(
            container_id="test",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=None,
            volume_mounts=None,
            log_level=None,
            artifacts_store=None,
            init=[
                V1Init(connection=self.claim_store.name),
                V1Init(connection=self.s3_store.name),
            ],
            connections=[self.host_path_store.name, self.gcs_store.name],
            connection_by_names={
                self.claim_store.name: self.claim_store,
                self.s3_store.name: self.s3_store,
                self.host_path_store.name: self.host_path_store,
                self.gcs_store.name: self.gcs_store,
            },
            secrets=[self.mount_resource1, self.request_non_mount_resource1],
            config_maps=[
                self.non_mount_resource1, self.request_mount_resource2
            ],
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "test"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        # 2 env vars from the secret mount
        # + 2 for the connection (context_path + spec)
        # + 1 for the connection spec (non mount)
        assert len(container.env) == 5
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 4
Beispiel #25
0
def get_file_init_container(
    polyaxon_init: V1PolyaxonInitContainer,
    file_args: V1FileType,
    contexts: PluginsContextsSpec,
    run_path: str,
    run_instance: str,
    env: List[k8s_schemas.V1EnvVar] = None,
    mount_path: Optional[str] = None,
) -> k8s_schemas.V1Container:
    env = to_list(env, check_none=True)
    env = env + [get_run_instance_env_var(run_instance)]

    volume_name = (get_volume_name(mount_path)
                   if mount_path else constants.CONTEXT_VOLUME_ARTIFACTS)
    mount_path = mount_path or CONTEXT_MOUNT_ARTIFACTS
    volume_mounts = [
        get_connections_context_mount(name=volume_name, mount_path=mount_path)
    ]
    if contexts and contexts.auth:
        volume_mounts.append(get_auth_context_mount(read_only=True))

    file_args.filename = file_args.filename or "file"
    return k8s_schemas.V1Container(
        name=generate_container_name(INIT_FILE_CONTAINER_PREFIX),
        image=polyaxon_init.get_image(),
        image_pull_policy=polyaxon_init.image_pull_policy,
        command=["polyaxon", "initializer", "file"],
        args=[
            "--file-context={}".format(file_args.to_dict(dump=True)),
            "--filepath={}".format(mount_path),
            "--copy-path={}".format(
                CONTEXT_MOUNT_RUN_OUTPUTS_FORMAT.format(run_path)),
            "--track",
        ],
        env=env,
        resources=polyaxon_init.get_resources(),
        volume_mounts=volume_mounts,
    )
    def test_get_main_container_with_bucket_artifacts_store(self):
        container = get_main_container(
            container_id="main",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True,
                          collect_logs=True,
                          collect_resources=True)),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.s3_store,
            init=None,
            connections=None,
            connection_by_names={self.s3_store.name: self.s3_store},
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "main"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(container.env) == 2
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 1  # mount context

        container = get_main_container(
            container_id="main1",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(
                    collect_artifacts=True,
                    collect_logs=True,
                    collect_resources=True,
                    sync_statuses=True,
                )),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.s3_store,
            init=None,
            connections=None,
            connection_by_names={self.s3_store.name: self.s3_store},
            secrets=[self.mount_resource1],
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "main1"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(container.env) == 2
        assert container.env_from == []
        assert container.resources is None
        # The mount resource1 is not requested
        assert len(container.volume_mounts) == 1  # one mount resource

        container = get_main_container(
            container_id="main1",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True,
                          collect_logs=True,
                          collect_resources=True)),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.s3_store,
            init=None,
            connections=None,
            connection_by_names={self.s3_store.name: self.s3_store},
            secrets=[self.request_mount_resource2],
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "main1"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(container.env) == 2
        assert container.env_from == []
        assert container.resources is None
        # The mount resource2 is requested
        assert len(container.volume_mounts) == 2  # one mount resource

        container = get_main_container(
            container_id="tensorflow",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True,
                          collect_logs=True,
                          collect_resources=False)),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.s3_store,
            init=None,
            connections=None,
            connection_by_names={self.s3_store.name: self.s3_store},
            secrets=[self.non_mount_resource1],
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "tensorflow"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(container.env) == 1
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 1  # outputs context

        container = get_main_container(
            container_id="pytorch",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True,
                          collect_logs=True,
                          collect_resources=True)),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.s3_store,
            init=None,
            connections=None,
            connection_by_names={self.s3_store.name: self.s3_store},
            secrets=[self.request_non_mount_resource1],
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "pytorch"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(
            container.env) == 2 + 2  # 2 + 2 env vars from the secret mount
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 1
    def test_get_main_container_with_mounted_artifacts_store(self):
        container = get_main_container(
            container_id="test",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=None,
            volume_mounts=None,
            log_level=None,
            artifacts_store=None,
            init=[V1Init(connection=self.claim_store.name)],
            connections=None,
            connection_by_names={self.claim_store.name: self.claim_store},
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "test"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 1

        container = get_main_container(
            container_id="",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=None,
            volume_mounts=None,
            log_level=None,
            artifacts_store=None,
            init=[V1Init(connection=self.claim_store.name)],
            connections=[self.claim_store.name],
            connection_by_names={self.claim_store.name: self.claim_store},
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "main"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 2

        container = get_main_container(
            container_id="main-job",
            main_container=k8s_schemas.V1Container(name="main"),
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_artifacts=True,
                          collect_logs=True,
                          collect_resources=True)),
            volume_mounts=None,
            log_level=None,
            artifacts_store=self.claim_store,
            init=None,
            connections=[],
            connection_by_names={self.claim_store.name: self.claim_store},
            secrets=None,
            config_maps=None,
            kv_env_vars=None,
            env=None,
            ports=None,
            run_path="run_path",
        )

        assert container.name == "main-job"
        assert container.image is None
        assert container.image_pull_policy is None
        assert container.command is None
        assert container.args is None
        assert container.ports == []
        assert len(container.env) == 2
        assert container.env_from == []
        assert container.resources is None
        assert len(container.volume_mounts) == 1
Beispiel #28
0
def get_git_init_container(
    polyaxon_init: V1PolyaxonInitContainer,
    connection: V1ConnectionType,
    contexts: PluginsContextsSpec,
    container: Optional[k8s_schemas.V1Container] = None,
    env: List[k8s_schemas.V1EnvVar] = None,
    mount_path: str = None,
    track: bool = False,
) -> k8s_schemas.V1Container:
    if not connection:
        raise PolypodException(
            "A connection is required to create a repo context.")
    if not container:
        container = k8s_schemas.V1Container(name=generate_container_name(
            INIT_GIT_CONTAINER_PREFIX, connection.name), )

    volume_name = (get_volume_name(mount_path)
                   if mount_path else constants.CONTEXT_VOLUME_ARTIFACTS)
    mount_path = mount_path or CONTEXT_MOUNT_ARTIFACTS
    volume_mounts = [
        get_connections_context_mount(name=volume_name, mount_path=mount_path)
    ]

    if contexts and contexts.auth:
        volume_mounts.append(get_auth_context_mount(read_only=True))

    env = to_list(env, check_none=True)
    env_from = []
    secret = connection.get_secret()
    if secret:
        volume_mounts += to_list(get_mount_from_resource(resource=secret),
                                 check_none=True)
        env += to_list(get_items_from_secret(secret=secret), check_none=True)
        env_from = to_list(get_env_from_secret(secret=secret), check_none=True)
    env += to_list(get_connection_env_var(connection=connection,
                                          secret=secret),
                   check_none=True)
    config_map = connection.get_config_map()
    if config_map:
        volume_mounts += to_list(get_mount_from_resource(resource=config_map),
                                 check_none=True)
        env += to_list(get_items_from_config_map(config_map=config_map),
                       check_none=True)
        env_from = to_list(get_env_from_config_map(config_map=config_map),
                           check_none=True)
    args = get_repo_context_args(
        name=connection.name,
        url=connection.schema.url,
        revision=connection.schema.revision,
        mount_path=mount_path,
        connection=connection.name if track else None,
    )
    return patch_container(
        container=container,
        name=generate_container_name(INIT_GIT_CONTAINER_PREFIX,
                                     connection.name),
        image=polyaxon_init.get_image(),
        image_pull_policy=polyaxon_init.image_pull_policy,
        command=["polyaxon", "initializer", "git"],
        args=args,
        env=env,
        env_from=env_from,
        volume_mounts=volume_mounts,
        resources=polyaxon_init.get_resources(),
    )
Beispiel #29
0
    def test_get_pod_spec(self):
        init_container = k8s_schemas.V1Container(name="init")
        main_container = k8s_schemas.V1Container(name="main")
        sidecar_container = k8s_schemas.V1Container(name="sidecar")
        volumes = [k8s_schemas.V1Volume(name="vol")]
        labels = {"key": "labels"}
        annotations = {"key": "annotations"}
        node_selector = {"key": "selector"}
        affinity = [{"key": "affinity"}]
        tolerations = {"key": "tolerations"}
        security_context = {"uid": 222, "gid": 222}
        restart_policy = "never"

        with self.assertRaises(PolypodException):
            get_pod_spec(
                namespace="default",
                main_container=None,
                sidecar_containers=None,
                init_containers=None,
                resource_name="foo",
                volumes=None,
                environment=V1Environment(),
                labels={},
                annotations={},
            )

        environment = V1Environment(
            service_account_name="sa",
            labels=labels,
            annotations=annotations,
            node_selector=node_selector,
            affinity=affinity,
            tolerations=tolerations,
            security_context=security_context,
            image_pull_secrets=[],
            restart_policy=restart_policy,
        )
        metadata, pod_spec = get_pod_spec(
            namespace="default",
            resource_name="foo",
            main_container=main_container,
            sidecar_containers=None,
            init_containers=None,
            volumes=None,
            environment=environment,
            labels=environment.labels,
            annotations=environment.annotations,
        )

        assert metadata.name == "foo"
        assert metadata.labels == labels
        assert metadata.namespace == "default"
        assert metadata.annotations == annotations

        assert isinstance(pod_spec, k8s_schemas.V1PodSpec)
        assert pod_spec.security_context == security_context
        assert pod_spec.restart_policy == "never"
        assert pod_spec.service_account_name == "sa"
        assert pod_spec.init_containers == []
        assert pod_spec.containers == [main_container]
        assert pod_spec.volumes is None
        assert pod_spec.node_selector == node_selector
        assert pod_spec.tolerations == tolerations
        assert pod_spec.affinity == affinity

        environment = V1Environment(
            service_account_name="sa",
            labels=labels,
            annotations=annotations,
            node_selector=node_selector,
            affinity=affinity,
            tolerations=tolerations,
            security_context=security_context,
            image_pull_secrets=[],
            restart_policy=restart_policy,
        )
        metadata, pod_spec = get_pod_spec(
            namespace="default",
            main_container=main_container,
            sidecar_containers=[sidecar_container],
            init_containers=[init_container],
            resource_name="foo",
            volumes=volumes,
            environment=environment,
            labels={},
            annotations={},
        )

        assert pod_spec.init_containers == [init_container]
        assert pod_spec.containers == [main_container, sidecar_container]
        assert pod_spec.volumes == volumes
        assert metadata.annotations == {}
Beispiel #30
0
def get_sidecar_container(
    container_id: str,
    polyaxon_sidecar: V1PolyaxonSidecarContainer,
    env: List[k8s_schemas.V1EnvVar],
    artifacts_store: V1ConnectionType,
    contexts: PluginsContextsSpec,
    run_path: Optional[str],
) -> Optional[k8s_schemas.V1Container]:

    if artifacts_store and not contexts:
        raise PolypodException(
            "Logs/artifacts store was passed and contexts was not passed.")

    has_artifacts = artifacts_store and contexts.collect_artifacts
    has_logs = artifacts_store and contexts.collect_logs

    if not has_logs and not has_artifacts:
        # No sidecar
        return None

    if (has_artifacts or has_logs) and not run_path:
        raise PolypodException(
            "Logs store / outputs store must have a run_path.")

    env = get_sidecar_env_vars(
        env_vars=env,
        container_id=container_id,
        artifacts_store_name=artifacts_store.name,
    )

    volume_mounts = get_mounts(
        use_auth_context=contexts.auth,
        use_artifacts_context=has_artifacts,
        use_docker_context=False,
        use_shm_context=False,
    )

    sidecar_args = get_sidecar_args(
        container_id=container_id,
        sleep_interval=polyaxon_sidecar.sleep_interval,
        sync_interval=polyaxon_sidecar.sync_interval,
    )

    env_from = []

    secret = None
    if artifacts_store.is_bucket:
        secret = artifacts_store.get_secret()
        volume_mounts += to_list(get_mount_from_resource(resource=secret),
                                 check_none=True)
        env += to_list(get_items_from_secret(secret=secret), check_none=True)
        env_from += to_list(get_env_from_secret(secret=secret),
                            check_none=True)

        config_map = artifacts_store.get_config_map()
        volume_mounts += to_list(get_mount_from_resource(resource=config_map),
                                 check_none=True)
        env += to_list(get_items_from_config_map(config_map=config_map),
                       check_none=True)
        env_from += to_list(get_env_from_config_map(config_map=config_map),
                            check_none=True)
    else:
        volume_mounts += to_list(get_mount_from_store(store=artifacts_store),
                                 check_none=True)
    env += to_list(
        get_connection_env_var(connection=artifacts_store, secret=secret),
        check_none=True,
    )

    return k8s_schemas.V1Container(
        name=SIDECAR_CONTAINER,
        image=polyaxon_sidecar.get_image(),
        image_pull_policy=polyaxon_sidecar.image_pull_policy,
        command=["/bin/bash", "-c"],
        args=[sidecar_args],
        env=env,
        env_from=env_from,
        resources=polyaxon_sidecar.get_resources(),
        volume_mounts=volume_mounts,
    )