예제 #1
0
    def test_get_volume_args_s3(self):
        s3_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        path_to = "/path-to/"
        path_from = os.path.join(s3_store.store_path, "")
        assert get_volume_args(s3_store, path_to, None) == "; ".join(
            [
                get_or_create_args(path=path_to),
                cp_s3_args(path_from=path_from, path_to=path_to, is_file=False),
            ]
        )

        s3_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        base_path = "/path/to/"
        path_to1 = "/path/to/path1"
        path_to2 = "/path/to/path2"
        path_from1 = os.path.join(s3_store.store_path, "path1")
        path_from2 = os.path.join(s3_store.store_path, "path2")
        assert get_volume_args(
            s3_store, "/path/to", artifacts=V1ArtifactsType(files=["path1", "path2"])
        ) == "; ".join(
            [
                get_or_create_args(path=base_path),
                cp_s3_args(path_from=path_from1, path_to=path_to1, is_file=True),
                get_or_create_args(path=base_path),
                cp_s3_args(path_from=path_from2, path_to=path_to2, is_file=True),
            ]
        )
 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,
         ),
     ]
예제 #3
0
 def setUp(self):
     super().setUp()
     self.s3_store = V1ConnectionType(
         name="test",
         kind=V1ConnectionKind.S3,
         schema=V1BucketConnection(bucket="s3//:foo"),
     )
     self.gcs_store = V1ConnectionType(
         name="test",
         kind=V1ConnectionKind.GCS,
         schema=V1BucketConnection(bucket="gs//:foo"),
     )
     self.az_store = V1ConnectionType(
         name="test",
         kind=V1ConnectionKind.WASB,
         schema=V1BucketConnection(
             bucket="Conwasb://[email protected]"),
     )
     self.claim_store = V1ConnectionType(
         name="test",
         kind=V1ConnectionKind.VOLUME_CLAIM,
         schema=V1ClaimConnection(volume_claim="test",
                                  mount_path="/tmp",
                                  read_only=True),
     )
     self.host_path_store = V1ConnectionType(
         name="test",
         kind=V1ConnectionKind.HOST_PATH,
         schema=V1HostPathConnection(host_path="/tmp",
                                     mount_path="/tmp",
                                     read_only=True),
     )
예제 #4
0
    def test_get_mount_from_store(self):
        # Non bucket stores
        assert get_mount_from_store(store=None) is None
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        assert get_mount_from_store(store=store) is None

        # Claim store
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/tmp",
                                     volume_claim="test",
                                     read_only=True),
        )
        mount = get_mount_from_store(store=store)
        assert mount.name == store.name
        assert mount.mount_path == store.schema.mount_path
        assert mount.read_only == store.schema.read_only

        # Host path
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.HOST_PATH,
            schema=V1HostPathConnection(mount_path="/tmp",
                                        host_path="/tmp",
                                        read_only=True),
        )
        mount = get_mount_from_store(store=store)
        assert mount.name == store.name
        assert mount.mount_path == store.schema.mount_path
        assert mount.read_only == store.schema.read_only
예제 #5
0
def get_base_store_container(
    container: Optional[k8s_schemas.V1Container],
    container_name: str,
    polyaxon_init: V1PolyaxonInitContainer,
    store: V1ConnectionType,
    env: List[k8s_schemas.V1EnvVar],
    env_from: List[k8s_schemas.V1EnvFromSource],
    volume_mounts: List[k8s_schemas.V1VolumeMount],
    args: List[str],
    is_artifact_store: Optional[bool] = False,
) -> Optional[k8s_schemas.V1Container]:
    env = env or []
    env_from = env_from or []
    volume_mounts = volume_mounts or []

    # Artifact store needs to allow init the contexts as well, so the store is not required
    if not is_artifact_store and not store:
        raise PolypodException("Init store container requires a store")
    secret = None
    if store.is_bucket:
        if not is_artifact_store:
            secret = store.get_secret()
            volume_mounts = volume_mounts + to_list(
                get_mount_from_resource(resource=secret), check_none=True)
            env = env + to_list(get_items_from_secret(secret=secret),
                                check_none=True)
            env_from = env_from + to_list(get_env_from_secret(secret=secret),
                                          check_none=True)
            env += to_list(get_connection_env_var(connection=store,
                                                  secret=secret),
                           check_none=True)

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

    return patch_container(
        container=container,
        name=container_name,
        image=polyaxon_init.get_image(),
        image_pull_policy=polyaxon_init.image_pull_policy,
        command=["/bin/sh", "-c"],
        args=args,
        env=env,
        env_from=env_from,
        resources=polyaxon_init.get_resources(),
        volume_mounts=volume_mounts,
    )
예제 #6
0
    def test_resolve_connections_with_invalid_config(self):
        fpath = tempfile.mkdtemp()
        AgentConfigManager.CONFIG_PATH = fpath
        secret1 = V1K8sResourceType(
            name="secret1",
            schema=V1K8sResourceSchema(name="secret1"),
            is_requested=True,
        )
        secret2 = V1K8sResourceType(
            name="secret2",
            schema=V1K8sResourceSchema(name="secret2"),
            is_requested=True,
        )
        artifacts_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
            secret=secret1.schema,
        )
        connection1 = V1ConnectionType(
            name="connection1",
            kind=V1ConnectionKind.REGISTRY,
            schema=V1HostConnection(url="localhost:5000"),
            secret=secret2.schema,
        )
        connection2 = V1ConnectionType(
            name="connection2",
            kind=V1ConnectionKind.REGISTRY,
        )
        settings.AGENT_CONFIG = AgentConfig(
            namespace="foo",
            artifacts_store=artifacts_store,
            connections=[connection1, connection2],
        )

        resolver = BaseResolver(
            run=None,
            compiled_operation=self.compiled_operation,
            owner_name="user",
            project_name="p1",
            project_uuid=None,
            run_name="j1",
            run_uuid=None,
            run_path="test",
            params=None,
        )
        resolver.resolve_connections()
        assert resolver.namespace == "foo"
        assert resolver.connection_by_names == {
            artifacts_store.name: artifacts_store,
            connection1.name: connection1,
            connection2.name: connection2,
        }
        assert resolver.artifacts_store == artifacts_store
        assert resolver.polyaxon_sidecar == get_default_sidecar_container()
        assert resolver.polyaxon_init == get_default_init_container()
        resolver.resolve_artifacts_lineage()
        assert len(resolver.artifacts) == 3
예제 #7
0
    def test_get_main_container_with_artifacts_store_with_wrong_paths_raises(self):
        artifacts_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        self.assert_artifacts_store_raises(store=artifacts_store, run_path=None)

        artifacts_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        self.assert_artifacts_store_raises(store=artifacts_store, run_path=[])
예제 #8
0
    def test_get_main_container_with_logs_store_with_wrong_paths_raises(self):
        artifacts_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        self.assert_artifacts_store_raises(store=artifacts_store)

        artifacts_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(volume_claim="foo", mount_path="/foo"),
        )
        self.assert_artifacts_store_raises(store=artifacts_store)
예제 #9
0
    def setUp(self):
        super().setUp()
        # Secrets
        self.resource1 = V1K8sResourceType(
            name="non_mount_test1",
            schema=V1K8sResourceSchema(name="ref", items=["item1", "item2"]),
            is_requested=False,
        )
        self.resource2 = V1K8sResourceType(
            name="non_mount_test2",
            schema=V1K8sResourceSchema(name="ref"),
            is_requested=False,
        )

        self.resource3 = V1K8sResourceType(
            name="non_mount_test1",
            schema=V1K8sResourceSchema(name="ref", items=["item1", "item2"]),
            is_requested=True,
        )
        self.resource4 = V1K8sResourceType(
            name="non_mount_test2",
            schema=V1K8sResourceSchema(name="ref"),
            is_requested=True,
        )

        self.resource5 = V1K8sResourceType(
            name="non_mount_test2",
            schema=V1K8sResourceSchema(name="ref"),
            is_requested=True,
        )

        self.resource6 = V1K8sResourceType(
            name="mount_test",
            schema=V1K8sResourceSchema(name="ref", mount_path="/test"),
            is_requested=True,
        )
        # Connections
        self.bucket_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
            secret=self.resource3.schema,
        )
        self.mount_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/tmp",
                                     volume_claim="test",
                                     read_only=True),
        )
예제 #10
0
def get_custom_init_container(
    connection: V1ConnectionType,
    contexts: PluginsContextsSpec,
    container: Optional[k8s_schemas.V1Container],
    env: List[k8s_schemas.V1EnvVar] = None,
    mount_path: str = None,
) -> k8s_schemas.V1Container:
    if not connection:
        raise PolypodException(
            "A connection is required to create a repo context.")

    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)
    container_name = container.name or generate_container_name(
        INIT_CUSTOM_CONTAINER_PREFIX, connection.name)
    return patch_container(
        container=container,
        name=container_name,
        env=env,
        env_from=env_from,
        volume_mounts=volume_mounts,
    )
예제 #11
0
 def test_get_store_container_mount_stores(self):
     # Managed store
     store = V1ConnectionType(
         name="test_claim",
         kind=V1ConnectionKind.VOLUME_CLAIM,
         schema=V1ClaimConnection(
             mount_path="/tmp", volume_claim="test", read_only=True
         ),
     )
     container = get_store_container(
         polyaxon_init=V1PolyaxonInitContainer(
             image="foo/foo", image_tag="foo", image_pull_policy="IfNotPresent"
         ),
         connection=store,
         artifacts=None,
     )
     mount_path = CONTEXT_MOUNT_ARTIFACTS_FORMAT.format(store.name)
     assert container.name == INIT_ARTIFACTS_CONTAINER.format(store.name)
     assert container.image == "foo/foo:foo"
     assert container.image_pull_policy == "IfNotPresent"
     assert container.command == ["/bin/sh", "-c"]
     assert container.args == [
         get_volume_args(store=store, mount_path=mount_path, artifacts=None)
     ]
     assert container.env == get_connection_env_var(connection=store, secret=None)
     assert container.env_from == []
     assert container.resources is not None
     assert container.volume_mounts == [
         get_connections_context_mount(
             name=constants.CONTEXT_VOLUME_ARTIFACTS,
             mount_path=CONTEXT_MOUNT_ARTIFACTS_FORMAT.format(store.name),
         ),
         get_mount_from_store(store=store),
     ]
예제 #12
0
    def test_get_sidecar_container_with_non_managed_bucket_artifacts_logs_store(
            self):
        env_vars = [
            get_env_var(name="key1", value="value1"),
            get_env_var(name="key2", value="value2"),
        ]
        bucket_non_managed_store = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        sidecar = get_sidecar_container(
            container_id=MAIN_JOB_CONTAINER,
            env=env_vars,
            polyaxon_sidecar=V1PolyaxonSidecarContainer(
                image="sidecar/sidecar",
                image_pull_policy="IfNotPresent",
                sleep_interval=213,
                sync_interval=-1,
            ),
            artifacts_store=bucket_non_managed_store,
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_logs=False,
                          collect_artifacts=False,
                          auth=True)),
            run_path=None,
        )

        assert sidecar is None
예제 #13
0
    def assert_from_mode(spec: V1ConnectionType):
        result = V1ConnectionType.from_model(model=spec)

        assert result.name == spec.name
        assert result.kind == spec.kind
        assert result.schema == spec.schema
        assert result.secret == spec.secret
예제 #14
0
 def assert_config_map(config_map, connection, results):
     dummy_connection = (
         V1ConnectionType(
             name="connection",
             kind=V1ConnectionKind.S3,
             schema=None,
             config_map=config_map.schema,
         )
         if connection
         else None
     )
     connection_by_names = {"connection": dummy_connection} if connection else {}
     connections = ["connection"] if connection else []
     assert (
         get_pod_volumes(
             contexts=None,
             artifacts_store=None,
             init_connections=[],
             connections=connections,
             connection_by_names=connection_by_names,
             secrets=[],
             config_maps=[config_map],
             volumes=[],
         )
         == results
     )
예제 #15
0
    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",
            clean=False,
        )

        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_artifact_context_args("run_uid"))],
            is_artifact_store=True,
        )
예제 #16
0
    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=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)],
        )
예제 #17
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)
     ]
예제 #18
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)
        ]
예제 #19
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 == []
예제 #20
0
    def test_get_sidecar_container_with_non_managed_mount_outputs_logs_store(
            self):
        env_vars = [
            get_env_var(name="key1", value="value1"),
            get_env_var(name="key2", value="value2"),
        ]
        mount_non_managed_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(volume_claim="test",
                                     mount_path="/tmp",
                                     read_only=True),
        )
        sidecar = get_sidecar_container(
            container_id=MAIN_JOB_CONTAINER,
            env=env_vars,
            polyaxon_sidecar=V1PolyaxonSidecarContainer(
                image="sidecar/sidecar",
                image_pull_policy="IfNotPresent",
                sleep_interval=213,
                sync_interval=-1,
            ),
            artifacts_store=mount_non_managed_store,
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_logs=False,
                          collect_artifacts=False,
                          auth=True)),
            run_path=None,
        )

        assert sidecar is None
예제 #21
0
    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",
            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)],
        )
예제 #22
0
    def test_resolver_init_and_connections_contexts(self):
        store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(
                mount_path="/claim/path", volume_claim="claim", read_only=True
            ),
        )

        compiled_operation = V1CompiledOperation.read(
            {
                "version": 1.05,
                "kind": kinds.COMPILED_OPERATION,
                "plugins": {
                    "auth": False,
                    "shm": False,
                    "collectLogs": False,
                    "collectArtifacts": False,
                    "collectResources": False,
                },
                "run": {
                    "kind": V1RunKind.JOB,
                    "container": {"image": "test"},
                    "connections": [store.name],
                    "init": [{"connection": store.name}],
                },
            }
        )
        spec = resolve_contexts(
            namespace="test",
            owner_name="user",
            project_name="project",
            project_uuid="uuid",
            run_uuid="uuid",
            run_name="run",
            run_path="test",
            compiled_operation=compiled_operation,
            artifacts_store=store,
            connection_by_names={store.name: store},
            iteration=12,
        )
        assert spec == {
            "globals": {
                "owner_name": "user",
                "project_unique_name": "user.project",
                "project_name": "project",
                "project_uuid": "uuid",
                "name": "run",
                "uuid": "uuid",
                "artifacts_path": "/claim/path/test",
                "namespace": "test",
                "iteration": 12,
                "run_info": "user.project.runs.uuid",
            },
            "init": {"test_claim": store.schema.to_dict()},
            "connections": {"test_claim": store.schema.to_dict()},
        }
예제 #23
0
    def test_get_env_vars_with_all(self):
        connection = V1ConnectionType(
            name="test_s3",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
            secret=self.resource6.schema,
        )

        env_vars = get_env_vars(
            contexts=PluginsContextsSpec.from_config(
                V1Plugins(collect_logs=False,
                          collect_artifacts=True,
                          collect_resources=True)),
            log_level="info",
            kv_env_vars=[["key1", "val1"], ["key2", "val2"]],
            artifacts_store_name="test",
            connections=[connection],
            secrets=[
                self.resource1,
                self.resource2,
                self.resource3,
                self.resource4,
                self.resource6,
            ],
            config_maps=[
                self.resource1,
                self.resource2,
                self.resource3,
                self.resource4,
            ],
        )
        expected = [
            get_env_var(name=POLYAXON_KEYS_LOG_LEVEL, value="info"),
            get_env_var(name=POLYAXON_KEYS_COLLECT_ARTIFACTS, value=True),
            get_env_var(name=POLYAXON_KEYS_COLLECT_RESOURCES, value=True),
            get_env_var(name=POLYAXON_KEYS_ARTIFACTS_STORE_NAME, value="test"),
        ]
        expected += get_connection_env_var(connection=connection,
                                           secret=self.resource6)
        expected += get_kv_env_vars([["key1", "val1"], ["key2", "val2"]])
        expected += get_env_vars_from_k8s_resources(
            secrets=[
                self.resource1,
                self.resource2,
                self.resource3,
                self.resource4,
                self.resource6,
            ],
            config_maps=[
                self.resource1,
                self.resource2,
                self.resource3,
                self.resource4,
            ],
        )

        assert env_vars == expected
예제 #24
0
    def test_get_sidecar_container_with_managed_mount_outputs_and_blob_logs_store(self):
        env_vars = [
            get_env_var(name="key1", value="value1"),
            get_env_var(name="key2", value="value2"),
        ]
        resource1 = V1K8sResourceType(
            name="test1", schema=V1K8sResourceSchema(name="ref1"), is_requested=False
        )
        blob_managed_store = V1ConnectionType(
            name="test_gcs",
            kind=V1ConnectionKind.GCS,
            schema=V1BucketConnection(bucket="gs//:foo"),
            secret=resource1.schema,
        )

        # logs and outputs
        sidecar = get_sidecar_container(
            container_id=MAIN_JOB_CONTAINER,
            env=env_vars,
            polyaxon_sidecar=V1PolyaxonSidecarContainer(
                image="sidecar/sidecar",
                image_tag="",
                image_pull_policy="IfNotPresent",
                sleep_interval=213,
                sync_interval=212,
            ),
            artifacts_store=blob_managed_store,
            contexts=PluginsContextsSpec.from_config(None, default_auth=True),
            run_path="test",
        )

        assert sidecar.name == SIDECAR_CONTAINER
        assert sidecar.image == "sidecar/sidecar"
        assert sidecar.image_pull_policy == "IfNotPresent"
        assert sidecar.command == ["polyaxon", "sidecar"]
        assert sidecar.args == get_sidecar_args(
            container_id=MAIN_JOB_CONTAINER,
            sleep_interval=213,
            sync_interval=212,
            monitor_logs=False,
        )
        assert (
            sidecar.env
            == get_sidecar_env_vars(
                env_vars=env_vars,
                container_id=MAIN_JOB_CONTAINER,
                artifacts_store_name=blob_managed_store.name,
            )
            + get_connection_env_var(connection=blob_managed_store, secret=resource1)
        )
        assert sidecar.env_from == [get_env_from_secret(secret=resource1)]
        assert sidecar.resources == get_sidecar_resources()
        assert sidecar.volume_mounts == [
            get_auth_context_mount(read_only=True),
            get_artifacts_context_mount(read_only=False),
        ]
예제 #25
0
    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
예제 #26
0
    def test_get_volume_args_host(self):
        host_path_store = V1ConnectionType(
            name="test_path",
            kind=V1ConnectionKind.HOST_PATH,
            schema=V1HostPathConnection(
                mount_path="/tmp", host_path="/tmp", read_only=True
            ),
        )
        path_to = "/path/to/"
        path_from = os.path.join(host_path_store.store_path, "")
        assert get_volume_args(host_path_store, path_to, None) == "; ".join(
            [
                get_or_create_args(path=path_to),
                cp_copy_args(path_from=path_from, path_to=path_to, is_file=False),
            ]
        )

        host_path_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.HOST_PATH,
            schema=V1HostPathConnection(
                mount_path="/tmp", host_path="/tmp", read_only=True
            ),
        )
        base_path = "/path/to/"
        path_to1 = "/path/to/path1"
        path_to2 = "/path/to/path2"
        path_from1 = os.path.join(host_path_store.store_path, "path1")
        path_from2 = os.path.join(host_path_store.store_path, "path2")
        assert get_volume_args(
            host_path_store,
            "/path/to",
            artifacts=V1ArtifactsType(dirs=["path1", "path2"]),
        ) == "; ".join(
            [
                get_or_create_args(path=base_path),
                cp_copy_args(path_from=path_from1, path_to=path_to1, is_file=False),
                get_or_create_args(path=base_path),
                cp_copy_args(path_from=path_from2, path_to=path_to2, is_file=False),
            ]
        )
예제 #27
0
    def test_get_volume_args_claim(self):
        claim_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/tmp",
                                     volume_claim="test",
                                     read_only=True),
        )
        path_to = "/path/to/"
        path_from = os.path.join(claim_store.store_path, "")
        assert get_volume_args(claim_store, path_to, None) == "; ".join([
            get_or_create_args(path=path_to),
            cp_copy_args(path_from=path_from, path_to=path_to, is_file=False),
        ])

        claim_store = V1ConnectionType(
            name="test_claim",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(mount_path="/tmp",
                                     volume_claim="test",
                                     read_only=True),
        )
        base_path = "/path/to/"
        path_to1 = "/path/to/path1"
        path_to2 = "/path/to/path2"
        path_from1 = os.path.join(claim_store.store_path, "path1")
        path_from2 = os.path.join(claim_store.store_path, "path2")
        assert get_volume_args(
            claim_store,
            "/path/to",
            artifacts=V1ArtifactsType(files=["path1", "path2"])) == "; ".join([
                get_or_create_args(path=base_path),
                cp_copy_args(path_from=path_from1,
                             path_to=path_to1,
                             is_file=True),
                get_or_create_args(path=base_path),
                cp_copy_args(path_from=path_from2,
                             path_to=path_to2,
                             is_file=True),
            ])
예제 #28
0
    def setUp(self):
        super().setUp()
        self.store_root = set_store()
        settings.AGENT_CONFIG.notification_connections = [
            V1ConnectionType(
                name="slack",
                kind=V1ConnectionKind.SLACK,
                secret=V1K8sResourceSchema(name="some"),
            )
        ]

        self.client = get_streams_client()
        self.base_url = STREAMS_URL + "/namespace/owner/project/runs/uuid/notify"
예제 #29
0
    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),
        ]
예제 #30
0
    def test_get_volume_from_connection(self):
        # No store
        assert get_volume_from_connection(connection=None) is None

        # Bucket store
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.S3,
            schema=V1BucketConnection(bucket="s3//:foo"),
        )
        assert get_volume_from_connection(connection=store) is None

        # Claim store
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.VOLUME_CLAIM,
            schema=V1ClaimConnection(
                mount_path="/tmp", volume_claim="test", read_only=True
            ),
        )
        volume = get_volume_from_connection(connection=store)
        assert volume.name == store.name
        assert volume.persistent_volume_claim.claim_name == store.schema.volume_claim
        assert volume.persistent_volume_claim.read_only == store.schema.read_only

        # Host path
        store = V1ConnectionType(
            name="test",
            kind=V1ConnectionKind.HOST_PATH,
            schema=V1HostPathConnection(
                mount_path="/tmp", host_path="/tmp", read_only=True
            ),
        )
        volume = get_volume_from_connection(connection=store)
        assert volume.name == store.name
        assert volume.host_path == k8s_schemas.V1HostPathVolumeSource(
            path=store.schema.host_path
        )