Loading src/openop_tfsdk/contract/adapters/kubernetes.py +12 −11 Changes for src/openop_tfsdk/contract/adapters/kubernetes.py: 12 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -99,17 +99,18 @@ def _chart_args(unit) -> list: raise ValidationError( "kubernetes container does not support mixed internal and external ports" ) compute = unit.resource_requirements.compute if unit.resource_requirements else None resources = {} if compute: cpu = f"{compute.cpu_millicores}m" memory = f"{compute.memory_mb}Mi" resources = { "requests": { "cpu": cpu, "memory": memory, } } compute = ( getattr(unit.resource_requirements, "compute", None) if unit.resource_requirements else None ) requests: dict[str, str] = {} if compute is not None: cpu_millicores = getattr(compute, "cpu_millicores", None) memory_mb = getattr(compute, "memory_mb", None) if cpu_millicores is not None: requests["cpu"] = f"{cpu_millicores}m" if memory_mb is not None: requests["memory"] = f"{memory_mb}Mi" resources = {"requests": requests} if requests else {} values = { "image": unit.artifact_ref, "ports": list(ports.values()), Loading src/openop_tfsdk/contract/execution_models.py +3 −3 Changes for src/openop_tfsdk/contract/execution_models.py: 3 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -100,8 +100,8 @@ class StorageVolume(BaseModel): class ComputeResources(BaseModel): cpu_millicores: int memory_mb: int cpu_millicores: Optional[int] = None memory_mb: Optional[int] = None accelerator: Optional[Accelerator] = None storage: List[StorageVolume] Loading @@ -126,7 +126,7 @@ class ComputeRequirements(BaseModel): schema_version: str # srm.compute/v1 compute: ComputeResources topology: TopologyConstraints topology: Optional[TopologyConstraints] = None interfaces: List[NetworkInterface] standalone: bool Loading tests/contract/test_kubernetes_container.py +36 −2 Changes for tests/contract/test_kubernetes_container.py: 36 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -22,8 +22,14 @@ def _interface(port, protocol="tcp", visibility="internal"): return SimpleNamespace(interface_id="api", port=port, protocol=protocol, visibility=visibility) def _request(runtime_type, artifact_ref="nginx:1.25", interfaces=None): resources = None if interfaces is None else SimpleNamespace(interfaces=interfaces) def _request(runtime_type, artifact_ref="nginx:1.25", interfaces=None, compute=None): if interfaces is None and compute is None: resources = None else: resources = SimpleNamespace( interfaces=interfaces or [], compute=compute, ) return SimpleNamespace( operation_id="op", target=SimpleNamespace(control_path_ref="test-k8s"), Loading Loading @@ -95,6 +101,34 @@ def test_container_without_ports_gets_no_external_service(kubernetes_settings, h } @pytest.mark.parametrize( "compute, expected_resources", [ (None, {}), (SimpleNamespace(cpu_millicores=None, memory_mb=None), {}), ( SimpleNamespace(cpu_millicores=500, memory_mb=None), {"requests": {"cpu": "500m"}}, ), ( SimpleNamespace(cpu_millicores=None, memory_mb=1024), {"requests": {"memory": "1024Mi"}}, ), ( SimpleNamespace(cpu_millicores=500, memory_mb=1024), {"requests": {"cpu": "500m", "memory": "1024Mi"}}, ), ], ) def test_container_maps_optional_compute_to_resource_requests( kubernetes_settings, helm_calls, compute, expected_resources ): KubernetesCapabilityAdapter(kubernetes_settings).activate( _request("container", compute=compute) ) assert _values(helm_calls[0])["resources"] == expected_resources def test_helm_unit_still_installs_its_own_chart(kubernetes_settings, helm_calls): KubernetesCapabilityAdapter(kubernetes_settings).activate( _request("helm", artifact_ref="oci://registry/video:1.0") Loading Loading
src/openop_tfsdk/contract/adapters/kubernetes.py +12 −11 Changes for src/openop_tfsdk/contract/adapters/kubernetes.py: 12 added lines, 11 removed lines. Original line number Diff line number Diff line Loading @@ -99,17 +99,18 @@ def _chart_args(unit) -> list: raise ValidationError( "kubernetes container does not support mixed internal and external ports" ) compute = unit.resource_requirements.compute if unit.resource_requirements else None resources = {} if compute: cpu = f"{compute.cpu_millicores}m" memory = f"{compute.memory_mb}Mi" resources = { "requests": { "cpu": cpu, "memory": memory, } } compute = ( getattr(unit.resource_requirements, "compute", None) if unit.resource_requirements else None ) requests: dict[str, str] = {} if compute is not None: cpu_millicores = getattr(compute, "cpu_millicores", None) memory_mb = getattr(compute, "memory_mb", None) if cpu_millicores is not None: requests["cpu"] = f"{cpu_millicores}m" if memory_mb is not None: requests["memory"] = f"{memory_mb}Mi" resources = {"requests": requests} if requests else {} values = { "image": unit.artifact_ref, "ports": list(ports.values()), Loading
src/openop_tfsdk/contract/execution_models.py +3 −3 Changes for src/openop_tfsdk/contract/execution_models.py: 3 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -100,8 +100,8 @@ class StorageVolume(BaseModel): class ComputeResources(BaseModel): cpu_millicores: int memory_mb: int cpu_millicores: Optional[int] = None memory_mb: Optional[int] = None accelerator: Optional[Accelerator] = None storage: List[StorageVolume] Loading @@ -126,7 +126,7 @@ class ComputeRequirements(BaseModel): schema_version: str # srm.compute/v1 compute: ComputeResources topology: TopologyConstraints topology: Optional[TopologyConstraints] = None interfaces: List[NetworkInterface] standalone: bool Loading
tests/contract/test_kubernetes_container.py +36 −2 Changes for tests/contract/test_kubernetes_container.py: 36 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -22,8 +22,14 @@ def _interface(port, protocol="tcp", visibility="internal"): return SimpleNamespace(interface_id="api", port=port, protocol=protocol, visibility=visibility) def _request(runtime_type, artifact_ref="nginx:1.25", interfaces=None): resources = None if interfaces is None else SimpleNamespace(interfaces=interfaces) def _request(runtime_type, artifact_ref="nginx:1.25", interfaces=None, compute=None): if interfaces is None and compute is None: resources = None else: resources = SimpleNamespace( interfaces=interfaces or [], compute=compute, ) return SimpleNamespace( operation_id="op", target=SimpleNamespace(control_path_ref="test-k8s"), Loading Loading @@ -95,6 +101,34 @@ def test_container_without_ports_gets_no_external_service(kubernetes_settings, h } @pytest.mark.parametrize( "compute, expected_resources", [ (None, {}), (SimpleNamespace(cpu_millicores=None, memory_mb=None), {}), ( SimpleNamespace(cpu_millicores=500, memory_mb=None), {"requests": {"cpu": "500m"}}, ), ( SimpleNamespace(cpu_millicores=None, memory_mb=1024), {"requests": {"memory": "1024Mi"}}, ), ( SimpleNamespace(cpu_millicores=500, memory_mb=1024), {"requests": {"cpu": "500m", "memory": "1024Mi"}}, ), ], ) def test_container_maps_optional_compute_to_resource_requests( kubernetes_settings, helm_calls, compute, expected_resources ): KubernetesCapabilityAdapter(kubernetes_settings).activate( _request("container", compute=compute) ) assert _values(helm_calls[0])["resources"] == expected_resources def test_helm_unit_still_installs_its_own_chart(kubernetes_settings, helm_calls): KubernetesCapabilityAdapter(kubernetes_settings).activate( _request("helm", artifact_ref="oci://registry/video:1.0") Loading