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, )
def test_get_env_vars_with_secrets(self): assert (get_env_vars( contexts=None, log_level=None, kv_env_vars=None, artifacts_store_name=None, connections=None, secrets=[self.resource1, self.resource2], config_maps=None, ) == get_items_from_secret(secret=self.resource1) + get_items_from_secret(secret=self.resource2)) assert (get_env_vars( contexts=None, log_level=None, kv_env_vars=None, artifacts_store_name=None, connections=None, secrets=[ self.resource1, self.resource2, self.resource3, self.resource4, ], config_maps=None, ) == get_items_from_secret(secret=self.resource1) + get_items_from_secret(secret=self.resource2) + get_items_from_secret(secret=self.resource3) + get_items_from_secret(secret=self.resource4))
def test_get_env_vars_from_k8s_resources(self): assert get_env_vars_from_k8s_resources(secrets=[], config_maps=[]) == [] res1 = V1K8sResourceType(name="test", schema=V1K8sResourceSchema(name="test"), is_requested=True) res2 = V1K8sResourceType(name="test2", schema=V1K8sResourceSchema(name="test2"), is_requested=True) assert (get_env_vars_from_k8s_resources(secrets=[res1, res2], config_maps=[]) == []) assert get_env_vars_from_k8s_resources(secrets=[res1], config_maps=[res2]) == [] assert (get_env_vars_from_k8s_resources(secrets=[], config_maps=[res1, res2]) == []) res1 = V1K8sResourceType( name="test", schema=V1K8sResourceSchema(name="test", items=["item1", "item2"]), is_requested=True, ) res2 = V1K8sResourceType( name="test2", schema=V1K8sResourceSchema(name="test2", items=["item1", "item2"]), is_requested=True, ) expected = get_items_from_secret(res1) + get_items_from_secret(res2) assert (get_env_vars_from_k8s_resources(secrets=[res1, res2], config_maps=[]) == expected) expected = get_items_from_secret(res1) + get_items_from_config_map( res2) assert (get_env_vars_from_k8s_resources(secrets=[res1], config_maps=[res2 ]) == expected) expected = get_items_from_config_map(res1) + get_items_from_config_map( res2) assert (get_env_vars_from_k8s_resources(secrets=[], config_maps=[res1, res2 ]) == expected)
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, )
def get_items_from_config_map(self): # None assert get_items_from_secret(None) == [] # Secret without items secret = V1K8sResourceType(name="test", schema=V1K8sResourceSchema(name="test"), is_requested=True) assert get_items_from_secret(secret) == [] secret = V1K8sResourceType( name="test", schema=V1K8sResourceSchema(name="test", items=[]), is_requested=True, ) assert get_items_from_secret(secret) == [] # Secret with items secret = V1K8sResourceType( name="test", schema=V1K8sResourceSchema(name="test", items=["item1", "item2"]), is_requested=True, ) assert get_items_from_secret(secret) == [ get_from_config_map("item1", "item1", secret.schema.name), get_from_config_map("item2", "item2", secret.schema.name), ]
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, )
def test_get_sidecar_container_with_managed_bucket_outputs_logs_store_and_env_from( self, ): env_vars = [ get_env_var(name="key1", value="value1"), get_env_var(name="key2", value="value2"), ] resource1 = V1K8sResourceType(name="test1", schema=V1K8sResourceSchema(name="ref"), is_requested=False) bucket_managed_store = V1ConnectionType( name="test_gcs", kind=V1ConnectionKind.GCS, schema=V1BucketConnection(bucket="gs//:foo"), secret=resource1.schema, ) # both 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=bucket_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=bucket_managed_store.name, ) + get_items_from_secret(secret=resource1) + get_connection_env_var( connection=bucket_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), ] # logs and no 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=bucket_managed_store, contexts=PluginsContextsSpec.from_config( V1Plugins(collect_artifacts=False, 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=bucket_managed_store.name, ) + get_items_from_secret(secret=resource1) + get_connection_env_var( connection=bucket_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), ] # outputs and no logs 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=bucket_managed_store, contexts=PluginsContextsSpec.from_config( V1Plugins(collect_logs=False, 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=bucket_managed_store.name, ) + get_items_from_secret(secret=resource1) + get_connection_env_var( connection=bucket_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), ]
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(), )
def test_get_base_store_container_with_store_with_secret(self): non_mount_resource1 = V1K8sResourceType( name="resource", schema=V1K8sResourceSchema(name="ref", items=["item1", "item2"]), is_requested=False, ) bucket_store_with_secret = V1ConnectionType( name="test_gcs", kind=V1ConnectionKind.GCS, schema=V1BucketConnection(bucket="gs//:foo"), secret=non_mount_resource1.schema, ) container = get_base_store_container( container=k8s_schemas.V1Container(name="init"), container_name="init", polyaxon_init=V1PolyaxonInitContainer(image_tag=""), store=bucket_store_with_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 env = get_items_from_secret( secret=non_mount_resource1) + get_connection_env_var( connection=bucket_store_with_secret, secret=non_mount_resource1) assert container.env == env assert container.env_from == [] assert container.resources is not None assert container.volume_mounts == [] mount_resource1 = V1K8sResourceType( name="resource", schema=V1K8sResourceSchema(name="resource", items=["item1", "item2"], mount_path="/tmp1"), is_requested=False, ) bucket_store_with_secret.secret = mount_resource1.schema container = get_base_store_container( container=k8s_schemas.V1Container(name="init"), container_name="init", polyaxon_init=V1PolyaxonInitContainer(image_tag=""), store=bucket_store_with_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_with_secret, secret=mount_resource1) assert container.env_from == [] assert container.resources is not None assert container.volume_mounts == [ get_mount_from_resource(resource=mount_resource1) ]