chalkcompute 2.1.2__tar.gz → 2.1.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/PKG-INFO +6 -2
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/README.md +4 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/__init__.py +6 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/__init__.pyi +8 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_auth_config.py +4 -6
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_cls.py +15 -14
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_concurrency.py +1 -3
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_connect.py +46 -2
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_container.py +99 -33
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_function.py +34 -129
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_ignore.py +1 -1
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_image.py +9 -3
- chalkcompute-2.1.8/chalkcompute/_local_dev.py +185 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_model.py +3 -1
- chalkcompute-2.1.8/chalkcompute/_native.pyi +124 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_proto_pool.py +7 -1
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_remote_call_client.py +80 -10
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_remote_function_tracing.py +1 -2
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_sandbox.py +8 -2
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_scaling_group.py +12 -7
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_secret.py +4 -4
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_volume.py +30 -25
- chalkcompute-2.1.8/chalkcompute/_vvolume.py +1280 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/pyproject.toml +11 -4
- {chalkcompute-2.1.2/rust/chalkcompute_remote_client → chalkcompute-2.1.8/rust/chalkcompute_native}/Cargo.lock +835 -31
- {chalkcompute-2.1.2/rust/chalkcompute_remote_client → chalkcompute-2.1.8/rust/chalkcompute_native}/Cargo.toml +3 -2
- {chalkcompute-2.1.2/rust/chalkcompute_remote_client → chalkcompute-2.1.8/rust/chalkcompute_native}/src/lib.rs +3 -2
- chalkcompute-2.1.2/chalkcompute/_remote_call_native.pyi +0 -52
- chalkcompute-2.1.2/chalkcompute/_vvolume.py +0 -1437
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_arrow_schema.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/buf/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/buf/validate/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/buf/validate/validate_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/buf/validate/validate_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/arrow/v1/arrow_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/agent_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/agent_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/agent_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/agent_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/audit_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/audit_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/audit_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/audit_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/displayagent_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/featurepermission_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/auth/v1/permissions_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/common/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/common/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/common/v1/chalk_error_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/v1/service_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/container/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/externalfunctioncatalog/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/runtime/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/runtime/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/runtime/v1/remote_python_call_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/sandbox/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/scalinggroup/v1/service_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/encoding_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/field_change_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/utils/v1/sensitive_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v1/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v1/volume_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v1/volume_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v1/volume_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v1/volume_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v2/__init__.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v2/volume_pb2.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v2/volume_pb2.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v2/volume_pb2_grpc.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_gen/chalk/volume/v2/volume_pb2_grpc.pyi +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_logging.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_naming.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_progress.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_quota.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_rate_limit.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_retry.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/_tracing.py +0 -0
- {chalkcompute-2.1.2 → chalkcompute-2.1.8}/chalkcompute/py.typed +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: chalkcompute
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.8
|
|
4
4
|
Requires-Dist: grpcio>=1.60.0
|
|
5
5
|
Requires-Dist: protobuf>=4.25.0
|
|
6
6
|
Requires-Dist: httpx>=0.25.0
|
|
7
7
|
Requires-Dist: blake3>=1.0.0
|
|
8
|
-
Requires-Dist: chalk-remote-call-python>=1.
|
|
8
|
+
Requires-Dist: chalk-remote-call-python>=1.8.1
|
|
9
9
|
Requires-Dist: pyyaml>=6.0.0
|
|
10
10
|
Requires-Dist: opentelemetry-api>=1.20.0
|
|
11
11
|
Requires-Dist: opentelemetry-sdk>=1.20.0
|
|
@@ -25,6 +25,10 @@ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
|
25
25
|
|
|
26
26
|
Python SDK for the Chalk Sandbox gRPC service. Create sandboxes, execute commands, and stream output over bidirectional gRPC streams.
|
|
27
27
|
|
|
28
|
+
Contributor note: for testing deployed functions against local `chalkcompute`
|
|
29
|
+
or local `chalk-remote-call-python` changes, see
|
|
30
|
+
`local-sdk-remote-call-testing.md`.
|
|
31
|
+
|
|
28
32
|
## Install
|
|
29
33
|
|
|
30
34
|
```
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Python SDK for the Chalk Sandbox gRPC service. Create sandboxes, execute commands, and stream output over bidirectional gRPC streams.
|
|
4
4
|
|
|
5
|
+
Contributor note: for testing deployed functions against local `chalkcompute`
|
|
6
|
+
or local `chalk-remote-call-python` changes, see
|
|
7
|
+
`local-sdk-remote-call-testing.md`.
|
|
8
|
+
|
|
5
9
|
## Install
|
|
6
10
|
|
|
7
11
|
```
|
|
@@ -18,6 +18,7 @@ _LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
|
18
18
|
"AllowedRoute": ("chalkcompute._container", "AllowedRoute"),
|
|
19
19
|
"ImageBuildError": ("chalkcompute._container", "ImageBuildError"),
|
|
20
20
|
"KernelPolicy": ("chalkcompute._container", "KernelPolicy"),
|
|
21
|
+
"ComputeClass": ("chalkcompute._container", "ComputeClass"),
|
|
21
22
|
"NetworkPolicy": ("chalkcompute._container", "NetworkPolicy"),
|
|
22
23
|
"PortRange": ("chalkcompute._container", "PortRange"),
|
|
23
24
|
# _cls.py
|
|
@@ -65,6 +66,7 @@ _LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
|
65
66
|
"LazyLocalFile": ("chalkcompute._image", "LazyLocalFile"),
|
|
66
67
|
# _secret.py
|
|
67
68
|
"Secret": ("chalkcompute._secret", "Secret"),
|
|
69
|
+
"resolve_lazy_secrets": ("chalkcompute._secret", "resolve_lazy_secrets"),
|
|
68
70
|
# _sandbox.py
|
|
69
71
|
"ExecError": ("chalkcompute._sandbox", "ExecError"),
|
|
70
72
|
"ExecEvent": ("chalkcompute._sandbox", "ExecEvent"),
|
|
@@ -92,6 +94,10 @@ _LAZY_MAP: dict[str, tuple[str, str]] = {
|
|
|
92
94
|
"VolumeFileNotFoundError": ("chalkcompute._volume", "VolumeFileNotFoundError"),
|
|
93
95
|
"VolumeInfo": ("chalkcompute._volume", "VolumeInfo"),
|
|
94
96
|
"VolumeNotFoundError": ("chalkcompute._volume", "VolumeNotFoundError"),
|
|
97
|
+
"resolve_referenced_volume_type": (
|
|
98
|
+
"chalkcompute._volume",
|
|
99
|
+
"resolve_referenced_volume_type",
|
|
100
|
+
),
|
|
95
101
|
# _vvolume.py
|
|
96
102
|
"VersionInfo": ("chalkcompute._vvolume", "VersionInfo"),
|
|
97
103
|
"VersionedVolume": ("chalkcompute._vvolume", "VersionedVolume"),
|
|
@@ -18,6 +18,7 @@ from chalkcompute._container import ContainerInfo as ContainerInfo
|
|
|
18
18
|
from chalkcompute._container import ContainerSecurityPolicy as ContainerSecurityPolicy
|
|
19
19
|
from chalkcompute._container import ExecResult as ContainerExecResult
|
|
20
20
|
from chalkcompute._container import ImageBuildError as ImageBuildError
|
|
21
|
+
from chalkcompute._container import ComputeClass as ComputeClass
|
|
21
22
|
from chalkcompute._container import KernelPolicy as KernelPolicy
|
|
22
23
|
from chalkcompute._container import NetworkPolicy as NetworkPolicy
|
|
23
24
|
from chalkcompute._container import PortRange as PortRange
|
|
@@ -55,6 +56,7 @@ from chalkcompute._scaling_group import ScalingGroupBuildError as ScalingGroupBu
|
|
|
55
56
|
from chalkcompute._scaling_group import ScalingGroupError as ScalingGroupError
|
|
56
57
|
from chalkcompute._scaling_group import ScalingGroupInfo as ScalingGroupInfo
|
|
57
58
|
from chalkcompute._secret import Secret as Secret
|
|
59
|
+
from chalkcompute._secret import resolve_lazy_secrets as resolve_lazy_secrets
|
|
58
60
|
from chalkcompute._tracing import span as span
|
|
59
61
|
from chalkcompute._tracing import traced as traced
|
|
60
62
|
from chalkcompute._volume import FileInfo as FileInfo
|
|
@@ -66,6 +68,9 @@ from chalkcompute._volume import VolumeError as VolumeError
|
|
|
66
68
|
from chalkcompute._volume import VolumeFileNotFoundError as VolumeFileNotFoundError
|
|
67
69
|
from chalkcompute._volume import VolumeInfo as VolumeInfo
|
|
68
70
|
from chalkcompute._volume import VolumeNotFoundError as VolumeNotFoundError
|
|
71
|
+
from chalkcompute._volume import (
|
|
72
|
+
resolve_referenced_volume_type as resolve_referenced_volume_type,
|
|
73
|
+
)
|
|
69
74
|
from chalkcompute._vvolume import VersionInfo as VersionInfo
|
|
70
75
|
from chalkcompute._vvolume import VersionedVolume as VersionedVolume
|
|
71
76
|
from chalkcompute._vvolume import VersionedVolumeClient as VersionedVolumeClient
|
|
@@ -78,6 +83,7 @@ __all__ = [
|
|
|
78
83
|
"ContainerExecResult",
|
|
79
84
|
"AllowedRoute",
|
|
80
85
|
"ImageBuildError",
|
|
86
|
+
"ComputeClass",
|
|
81
87
|
"KernelPolicy",
|
|
82
88
|
"NetworkPolicy",
|
|
83
89
|
"PortRange",
|
|
@@ -113,6 +119,7 @@ __all__ = [
|
|
|
113
119
|
"Image",
|
|
114
120
|
"LazyLocalFile",
|
|
115
121
|
"Secret",
|
|
122
|
+
"resolve_lazy_secrets",
|
|
116
123
|
"ExecError",
|
|
117
124
|
"ExecEvent",
|
|
118
125
|
"ExecProcess",
|
|
@@ -137,6 +144,7 @@ __all__ = [
|
|
|
137
144
|
"VolumeFileNotFoundError",
|
|
138
145
|
"VolumeInfo",
|
|
139
146
|
"VolumeNotFoundError",
|
|
147
|
+
"resolve_referenced_volume_type",
|
|
140
148
|
"VersionInfo",
|
|
141
149
|
"VersionedVolume",
|
|
142
150
|
"VersionedVolumeClient",
|
|
@@ -152,11 +152,7 @@ def load_token(
|
|
|
152
152
|
activeEnvironment=active_environment,
|
|
153
153
|
)
|
|
154
154
|
|
|
155
|
-
global_cfg = (
|
|
156
|
-
_load_global_config_uncached()
|
|
157
|
-
if skip_cache
|
|
158
|
-
else _load_global_config()
|
|
159
|
-
)
|
|
155
|
+
global_cfg = _load_global_config_uncached() if skip_cache else _load_global_config()
|
|
160
156
|
if global_cfg is None:
|
|
161
157
|
return None
|
|
162
158
|
|
|
@@ -186,7 +182,9 @@ def _load_project_config_at_path(filename: Path) -> ProjectSettings | None:
|
|
|
186
182
|
except OSError:
|
|
187
183
|
return None
|
|
188
184
|
except ValueError as exc:
|
|
189
|
-
raise ValueError(
|
|
185
|
+
raise ValueError(
|
|
186
|
+
f"Failed to load project config from {filename}: {exc}"
|
|
187
|
+
) from exc
|
|
190
188
|
|
|
191
189
|
|
|
192
190
|
def load_project_config() -> ProjectSettings | None:
|
|
@@ -54,15 +54,8 @@ from dataclasses import dataclass, field
|
|
|
54
54
|
from pathlib import Path
|
|
55
55
|
from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload
|
|
56
56
|
|
|
57
|
+
from chalkcompute._concurrency import ConcurrencyPolicy
|
|
57
58
|
from chalkcompute._connect import ConnectClient
|
|
58
|
-
from chalkcompute._naming import sanitize_dns_label, validate_dns_label, validate_env
|
|
59
|
-
from chalkcompute._tracing import _instrumented
|
|
60
|
-
from chalkcompute._volume import (
|
|
61
|
-
VolumeDriver,
|
|
62
|
-
VolumeMount,
|
|
63
|
-
_resolve_driver,
|
|
64
|
-
resolve_referenced_volume_type,
|
|
65
|
-
)
|
|
66
59
|
from chalkcompute._function import (
|
|
67
60
|
_CATALOG_SVC,
|
|
68
61
|
_REMOTE_ENV_VAR,
|
|
@@ -85,10 +78,18 @@ from chalkcompute._function import (
|
|
|
85
78
|
_source_text_for_deploy,
|
|
86
79
|
_write_temp,
|
|
87
80
|
)
|
|
88
|
-
from chalkcompute.
|
|
81
|
+
from chalkcompute._naming import sanitize_dns_label, validate_dns_label, validate_env
|
|
89
82
|
from chalkcompute._quota import QueuePolicy
|
|
90
83
|
from chalkcompute._rate_limit import RateLimitPolicy
|
|
91
84
|
from chalkcompute._retry import RetryPolicy
|
|
85
|
+
from chalkcompute._tracing import _instrumented
|
|
86
|
+
from chalkcompute._volume import (
|
|
87
|
+
VolumeDriver,
|
|
88
|
+
VolumeMount,
|
|
89
|
+
cleanup_owned_volumes,
|
|
90
|
+
resolve_referenced_volume_type,
|
|
91
|
+
)
|
|
92
|
+
from chalkcompute._vvolume import VersionedVolumeClient
|
|
92
93
|
|
|
93
94
|
if TYPE_CHECKING:
|
|
94
95
|
from chalkcompute._image import Image as _Image
|
|
@@ -1163,8 +1164,7 @@ class RemoteClass:
|
|
|
1163
1164
|
if resp.status_code != 200:
|
|
1164
1165
|
progress_fail(mkey)
|
|
1165
1166
|
raise ClassBuildError(
|
|
1166
|
-
f"CreateExternalFunctionVersion failed for "
|
|
1167
|
-
f"'{func_name}': {resp.text}"
|
|
1167
|
+
f"CreateExternalFunctionVersion failed for '{func_name}': {resp.text}"
|
|
1168
1168
|
)
|
|
1169
1169
|
|
|
1170
1170
|
data = resp.json()
|
|
@@ -1294,9 +1294,10 @@ class RemoteClass:
|
|
|
1294
1294
|
if self._volumes:
|
|
1295
1295
|
# Driver is used here only to perform the delete action, not to
|
|
1296
1296
|
# derive a mount type.
|
|
1297
|
-
driver = self._volume_driver or
|
|
1298
|
-
|
|
1299
|
-
|
|
1297
|
+
driver = self._volume_driver or VersionedVolumeClient.from_connect(
|
|
1298
|
+
self._client
|
|
1299
|
+
)
|
|
1300
|
+
cleanup_owned_volumes(driver, self._volumes, self._referenced_volumes)
|
|
1300
1301
|
self._volumes = []
|
|
1301
1302
|
self._volume_driver = None
|
|
1302
1303
|
self._deployed = False
|
|
@@ -26,9 +26,7 @@ class ConcurrencyPolicy:
|
|
|
26
26
|
return d
|
|
27
27
|
|
|
28
28
|
@classmethod
|
|
29
|
-
def from_int_or_policy(
|
|
30
|
-
cls, value: int | ConcurrencyPolicy
|
|
31
|
-
) -> ConcurrencyPolicy:
|
|
29
|
+
def from_int_or_policy(cls, value: int | ConcurrencyPolicy) -> ConcurrencyPolicy:
|
|
32
30
|
if isinstance(value, bool):
|
|
33
31
|
raise TypeError(f"Expected int or {cls.__name__}, got bool")
|
|
34
32
|
if isinstance(value, int):
|
|
@@ -44,6 +44,38 @@ def service_auth_context_from_env() -> ServiceAuthContext | None:
|
|
|
44
44
|
return None
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
def chalk_client_from_env(
|
|
48
|
+
*,
|
|
49
|
+
api_server: str | None = None,
|
|
50
|
+
environment: str | None = None,
|
|
51
|
+
additional_headers: dict[str, str] | None = None,
|
|
52
|
+
**kwargs: Any,
|
|
53
|
+
) -> Any:
|
|
54
|
+
from chalk.client import ChalkClient
|
|
55
|
+
|
|
56
|
+
headers = additional_headers
|
|
57
|
+
has_authorization = any(key.lower() == "authorization" for key in headers or {})
|
|
58
|
+
service_auth = service_auth_context_from_env()
|
|
59
|
+
if service_auth is not None and not has_authorization:
|
|
60
|
+
client = ConnectClient()
|
|
61
|
+
client._ensure_auth()
|
|
62
|
+
assert client._access_token is not None
|
|
63
|
+
assert client._api_server is not None
|
|
64
|
+
headers = {
|
|
65
|
+
**(headers or {}),
|
|
66
|
+
"Authorization": f"Bearer {client._access_token}",
|
|
67
|
+
}
|
|
68
|
+
api_server = api_server or client._api_server
|
|
69
|
+
environment = environment or service_auth.environment_id
|
|
70
|
+
|
|
71
|
+
if api_server is not None:
|
|
72
|
+
kwargs["api_server"] = api_server
|
|
73
|
+
if environment is not None:
|
|
74
|
+
kwargs["environment"] = environment
|
|
75
|
+
kwargs["additional_headers"] = headers
|
|
76
|
+
return ChalkClient(**kwargs)
|
|
77
|
+
|
|
78
|
+
|
|
47
79
|
class ConnectClient:
|
|
48
80
|
"""Authenticated Connect-protocol (HTTP/JSON) client for Chalk APIs.
|
|
49
81
|
|
|
@@ -97,6 +129,14 @@ class ConnectClient:
|
|
|
97
129
|
resp.raise_for_status()
|
|
98
130
|
data = resp.json()
|
|
99
131
|
self._access_token = data.get("accessToken") or data["access_token"]
|
|
132
|
+
self._grpc_engines = _string_map(
|
|
133
|
+
data.get("grpcEngines")
|
|
134
|
+
or data.get("grpc_engines")
|
|
135
|
+
or data.get("engines"),
|
|
136
|
+
)
|
|
137
|
+
self._environment_id_to_name = _string_map(
|
|
138
|
+
data.get("environment_id_to_name") or data.get("environmentIdToName"),
|
|
139
|
+
)
|
|
100
140
|
self._env_id = self._resolve_environment_id(service_auth.environment_id)
|
|
101
141
|
self._headers = {
|
|
102
142
|
"Content-Type": "application/json",
|
|
@@ -430,12 +470,16 @@ def build_image_with_volumes(
|
|
|
430
470
|
from chalkcompute._volume import VolumeClient
|
|
431
471
|
|
|
432
472
|
image_uri = build_image(
|
|
433
|
-
client,
|
|
473
|
+
client,
|
|
474
|
+
image,
|
|
475
|
+
poll_interval=poll_interval,
|
|
476
|
+
timeout=timeout,
|
|
434
477
|
)
|
|
435
478
|
volumes: list[VolumeMount] = []
|
|
436
479
|
if image.lazy_local_files:
|
|
437
480
|
volumes = VolumeClient.from_connect(client).upload_lazy_files(
|
|
438
|
-
image,
|
|
481
|
+
image,
|
|
482
|
+
volume_prefix=volume_prefix,
|
|
439
483
|
)
|
|
440
484
|
return image_uri, volumes
|
|
441
485
|
|
|
@@ -28,20 +28,26 @@ from enum import Enum
|
|
|
28
28
|
from typing import TYPE_CHECKING, Any
|
|
29
29
|
|
|
30
30
|
from chalkcompute._connect import ConnectClient
|
|
31
|
+
from chalkcompute._naming import (
|
|
32
|
+
sanitize_dns_label,
|
|
33
|
+
validate_dns_label,
|
|
34
|
+
validate_env,
|
|
35
|
+
)
|
|
36
|
+
from chalkcompute._tracing import _instrumented
|
|
31
37
|
from chalkcompute._volume import (
|
|
32
38
|
VolumeDriver,
|
|
33
39
|
VolumeError,
|
|
34
40
|
VolumeMount,
|
|
35
|
-
|
|
41
|
+
cleanup_owned_volumes,
|
|
36
42
|
resolve_referenced_volume_type,
|
|
37
43
|
)
|
|
38
|
-
from chalkcompute.
|
|
39
|
-
from chalkcompute._tracing import _instrumented
|
|
44
|
+
from chalkcompute._vvolume import VersionedVolumeClient
|
|
40
45
|
|
|
41
46
|
logger = logging.getLogger(__name__)
|
|
42
47
|
|
|
43
48
|
if TYPE_CHECKING:
|
|
44
49
|
from collections.abc import Iterable
|
|
50
|
+
|
|
45
51
|
from chalkcompute._image import Image as _Image
|
|
46
52
|
from chalkcompute._secret import Secret
|
|
47
53
|
|
|
@@ -53,6 +59,7 @@ _IMAGE_SVC = "chalk.sandbox.v1.CustomImageService"
|
|
|
53
59
|
# Exceptions
|
|
54
60
|
# ---------------------------------------------------------------------------
|
|
55
61
|
|
|
62
|
+
|
|
56
63
|
class ContainerError(Exception):
|
|
57
64
|
"""Base exception for Container errors."""
|
|
58
65
|
|
|
@@ -65,6 +72,7 @@ class ImageBuildError(ContainerError):
|
|
|
65
72
|
# Data classes
|
|
66
73
|
# ---------------------------------------------------------------------------
|
|
67
74
|
|
|
75
|
+
|
|
68
76
|
@dataclass
|
|
69
77
|
class ExecResult:
|
|
70
78
|
"""Result of a one-shot command executed inside a container.
|
|
@@ -107,6 +115,11 @@ class KernelPolicy(Enum):
|
|
|
107
115
|
OPEN = "OPEN"
|
|
108
116
|
|
|
109
117
|
|
|
118
|
+
class ComputeClass(Enum):
|
|
119
|
+
K8S = "COMPUTE_CLASS_K8S"
|
|
120
|
+
HOST = "COMPUTE_CLASS_HOST"
|
|
121
|
+
|
|
122
|
+
|
|
110
123
|
@dataclass
|
|
111
124
|
class ContainerSecurityPolicy:
|
|
112
125
|
"""Security policy settings for a container.
|
|
@@ -233,6 +246,7 @@ class ContainerInfo:
|
|
|
233
246
|
# Container
|
|
234
247
|
# ---------------------------------------------------------------------------
|
|
235
248
|
|
|
249
|
+
|
|
236
250
|
class Container:
|
|
237
251
|
"""A managed container backed by the Chalk ``ContainerService``.
|
|
238
252
|
|
|
@@ -277,6 +291,7 @@ class Container:
|
|
|
277
291
|
enable_ssh: bool = False,
|
|
278
292
|
security_policy: ContainerSecurityPolicy | None = None,
|
|
279
293
|
network_policy: NetworkPolicy | None = None,
|
|
294
|
+
compute_class: ComputeClass | None = None,
|
|
280
295
|
tags: dict[str, str] | None = None,
|
|
281
296
|
chalk_client: Any | None = None,
|
|
282
297
|
) -> None:
|
|
@@ -287,7 +302,9 @@ class Container:
|
|
|
287
302
|
if cpu is not None and not isinstance(cpu, str):
|
|
288
303
|
raise TypeError(f"cpu must be a string such as '2' or '500m', got {cpu!r}")
|
|
289
304
|
if memory is not None and not isinstance(memory, str):
|
|
290
|
-
raise TypeError(
|
|
305
|
+
raise TypeError(
|
|
306
|
+
f"memory must be a string such as '2Gi' or '512Mi', got {memory!r}"
|
|
307
|
+
)
|
|
291
308
|
if gpu is not None and not isinstance(gpu, str):
|
|
292
309
|
raise TypeError(f"gpu must be a string such as 'nvidia-l4', got {gpu!r}")
|
|
293
310
|
self._cpu = cpu
|
|
@@ -299,7 +316,11 @@ class Container:
|
|
|
299
316
|
referenced_volumes: list[tuple[str, str]] = []
|
|
300
317
|
if volumes is not None:
|
|
301
318
|
for item in volumes:
|
|
302
|
-
if not (
|
|
319
|
+
if not (
|
|
320
|
+
isinstance(item, (tuple, list))
|
|
321
|
+
and len(item) == 2
|
|
322
|
+
and all(isinstance(s, str) for s in item)
|
|
323
|
+
):
|
|
303
324
|
raise ValueError(
|
|
304
325
|
f"Each volumes entry must be a (name, mount_path) string tuple, got {item!r}. "
|
|
305
326
|
f"Example: volumes=[('my-volume', '/data')]"
|
|
@@ -320,6 +341,7 @@ class Container:
|
|
|
320
341
|
if lifetime is not None:
|
|
321
342
|
from google.protobuf import duration_pb2
|
|
322
343
|
from google.protobuf.json_format import Parse, ParseError
|
|
344
|
+
|
|
323
345
|
try:
|
|
324
346
|
_parsed_lifetime = Parse(f'"{lifetime}"', duration_pb2.Duration()) # ty: ignore[unresolved-attribute]
|
|
325
347
|
except ParseError:
|
|
@@ -336,6 +358,7 @@ class Container:
|
|
|
336
358
|
self._enable_ssh = enable_ssh
|
|
337
359
|
self._security_policy = security_policy
|
|
338
360
|
self._network_policy = network_policy
|
|
361
|
+
self._compute_class = compute_class
|
|
339
362
|
self._tags: dict[str, str] = dict(tags or {})
|
|
340
363
|
|
|
341
364
|
# Set after .run()
|
|
@@ -349,7 +372,9 @@ class Container:
|
|
|
349
372
|
# -- Alternate constructors ------------------------------------------------
|
|
350
373
|
|
|
351
374
|
@classmethod
|
|
352
|
-
def from_id(
|
|
375
|
+
def from_id(
|
|
376
|
+
cls, container_id: str, *, chalk_client: Any | None = None
|
|
377
|
+
) -> Container:
|
|
353
378
|
"""Attach to an existing container by ID.
|
|
354
379
|
|
|
355
380
|
Parameters
|
|
@@ -421,7 +446,10 @@ class Container:
|
|
|
421
446
|
resp = c._client.rpc(_SVC, "ListContainers", {})
|
|
422
447
|
if resp.status_code != 200:
|
|
423
448
|
raise ContainerError(f"ListContainers failed: {resp.text}")
|
|
424
|
-
return [
|
|
449
|
+
return [
|
|
450
|
+
_parse_container_response(item)
|
|
451
|
+
for item in resp.json().get("containers", [])
|
|
452
|
+
]
|
|
425
453
|
|
|
426
454
|
@classmethod
|
|
427
455
|
def _make_empty(cls, *, chalk_client: Any | None = None) -> Container:
|
|
@@ -453,7 +481,10 @@ class Container:
|
|
|
453
481
|
# -- Image building (Container uses BuildCustomImage with retries) ---------
|
|
454
482
|
|
|
455
483
|
def _build_image(
|
|
456
|
-
self,
|
|
484
|
+
self,
|
|
485
|
+
*,
|
|
486
|
+
poll_interval: float = 0.5,
|
|
487
|
+
timeout: float = 600.0,
|
|
457
488
|
) -> str:
|
|
458
489
|
"""Build the ``Image`` spec via ``CustomImageService`` and return the URI.
|
|
459
490
|
|
|
@@ -480,8 +511,10 @@ class Container:
|
|
|
480
511
|
assert isinstance(self._image, Image)
|
|
481
512
|
try:
|
|
482
513
|
return build_image(
|
|
483
|
-
self._client,
|
|
484
|
-
|
|
514
|
+
self._client,
|
|
515
|
+
self._image,
|
|
516
|
+
poll_interval=poll_interval,
|
|
517
|
+
timeout=timeout,
|
|
485
518
|
)
|
|
486
519
|
except ConnectError as e:
|
|
487
520
|
raise ImageBuildError(str(e)) from e
|
|
@@ -586,20 +619,24 @@ class Container:
|
|
|
586
619
|
>>> c.stop()
|
|
587
620
|
"""
|
|
588
621
|
if self._container_id is not None:
|
|
589
|
-
raise ContainerError(
|
|
622
|
+
raise ContainerError(
|
|
623
|
+
"Container is already running. Call .stop() before calling .run() again."
|
|
624
|
+
)
|
|
590
625
|
|
|
626
|
+
from chalkcompute._image import Image
|
|
591
627
|
from chalkcompute._progress import (
|
|
592
628
|
progress_add,
|
|
593
629
|
progress_done,
|
|
594
630
|
progress_fail,
|
|
595
631
|
progress_finish,
|
|
596
632
|
)
|
|
597
|
-
from chalkcompute._image import Image
|
|
598
633
|
|
|
599
|
-
container_name = sanitize_dns_label(
|
|
634
|
+
container_name = sanitize_dns_label(
|
|
635
|
+
self._name or f"container-{uuid.uuid4().hex[:8]}"
|
|
636
|
+
)
|
|
600
637
|
self._name = container_name
|
|
601
638
|
ckey = f"container:{container_name}"
|
|
602
|
-
progress_add(ckey, "container", f
|
|
639
|
+
progress_add(ckey, "container", f'Container "{container_name}"')
|
|
603
640
|
|
|
604
641
|
try:
|
|
605
642
|
# 1. Resolve image URI
|
|
@@ -608,10 +645,13 @@ class Container:
|
|
|
608
645
|
progress_add(ikey, "image", "Building image", parent=ckey)
|
|
609
646
|
logger.info("Building image from %r...", self._image)
|
|
610
647
|
self._built_image_uri = self._build_image(
|
|
611
|
-
poll_interval=poll_interval,
|
|
648
|
+
poll_interval=poll_interval,
|
|
649
|
+
timeout=build_timeout,
|
|
612
650
|
)
|
|
613
651
|
logger.info("Image built: %s", self._built_image_uri)
|
|
614
|
-
progress_done(
|
|
652
|
+
progress_done(
|
|
653
|
+
ikey, detail="cached" if self._built_image_uri else "built"
|
|
654
|
+
)
|
|
615
655
|
else:
|
|
616
656
|
self._built_image_uri = self._image
|
|
617
657
|
|
|
@@ -628,24 +668,33 @@ class Container:
|
|
|
628
668
|
|
|
629
669
|
# 2b. Upload lazy local files to a volume (if any)
|
|
630
670
|
lazy_files = (
|
|
631
|
-
self._image.lazy_local_files
|
|
671
|
+
self._image.lazy_local_files
|
|
672
|
+
if isinstance(self._image, Image)
|
|
673
|
+
else set()
|
|
632
674
|
)
|
|
633
675
|
if lazy_files:
|
|
634
676
|
vkey = f"volume:{container_name}"
|
|
635
677
|
progress_add(
|
|
636
|
-
vkey,
|
|
678
|
+
vkey,
|
|
679
|
+
"volume",
|
|
637
680
|
f"Uploading {len(lazy_files)} file(s)",
|
|
638
681
|
parent=ckey,
|
|
639
682
|
)
|
|
640
|
-
logger.info(
|
|
683
|
+
logger.info(
|
|
684
|
+
"Uploading %d local file(s) to volume(s)...",
|
|
685
|
+
len(lazy_files),
|
|
686
|
+
)
|
|
641
687
|
assert isinstance(self._image, Image)
|
|
642
|
-
driver =
|
|
688
|
+
driver = VersionedVolumeClient.from_connect(self._client)
|
|
643
689
|
self._volume_driver = driver
|
|
644
690
|
self._volumes += driver.upload_lazy_files(
|
|
645
|
-
self._image,
|
|
691
|
+
self._image,
|
|
692
|
+
volume_prefix="container-files",
|
|
646
693
|
)
|
|
647
694
|
for v in self._volumes:
|
|
648
|
-
logger.info(
|
|
695
|
+
logger.info(
|
|
696
|
+
" Volume created: %s (mount: %s)", v.name, v.mount_path
|
|
697
|
+
)
|
|
649
698
|
progress_done(vkey)
|
|
650
699
|
|
|
651
700
|
# 3. Resolve lazy secrets (from_local_env / from_local_env_file)
|
|
@@ -657,7 +706,10 @@ class Container:
|
|
|
657
706
|
resolved, upserted = resolve_lazy_secrets(self._secrets, self._client)
|
|
658
707
|
self._secrets = resolved
|
|
659
708
|
self._upserted_secret_names = upserted
|
|
660
|
-
logger.info(
|
|
709
|
+
logger.info(
|
|
710
|
+
"Upserted %d secret(s) from local environment.",
|
|
711
|
+
len(upserted),
|
|
712
|
+
)
|
|
661
713
|
progress_done(skey, detail=f"{len(upserted)} secret(s)")
|
|
662
714
|
|
|
663
715
|
# 4. Build the ContainerService spec
|
|
@@ -679,6 +731,8 @@ class Container:
|
|
|
679
731
|
spec["securityPolicy"] = self._security_policy.to_dict()
|
|
680
732
|
if self._network_policy is not None:
|
|
681
733
|
spec["networkPolicy"] = self._network_policy.to_dict()
|
|
734
|
+
if self._compute_class is not None:
|
|
735
|
+
spec["computeClass"] = self._compute_class.value
|
|
682
736
|
if self._tags:
|
|
683
737
|
spec["tags"] = dict(self._tags)
|
|
684
738
|
|
|
@@ -706,7 +760,10 @@ class Container:
|
|
|
706
760
|
|
|
707
761
|
logger.info("Starting container '%s'...", container_name)
|
|
708
762
|
resp = self._client.rpc(
|
|
709
|
-
_SVC,
|
|
763
|
+
_SVC,
|
|
764
|
+
"RunContainer",
|
|
765
|
+
{"container": {"spec": spec}},
|
|
766
|
+
timeout=60,
|
|
710
767
|
)
|
|
711
768
|
if resp.status_code != 200:
|
|
712
769
|
raise ContainerError(f"RunContainer failed: {resp.text}")
|
|
@@ -716,7 +773,8 @@ class Container:
|
|
|
716
773
|
self._container_id = self._container_info.id
|
|
717
774
|
logger.info(
|
|
718
775
|
"Container created: %s (status=%s)",
|
|
719
|
-
self._container_id,
|
|
776
|
+
self._container_id,
|
|
777
|
+
self._container_info.status,
|
|
720
778
|
)
|
|
721
779
|
|
|
722
780
|
# 5. Poll until Running
|
|
@@ -725,7 +783,8 @@ class Container:
|
|
|
725
783
|
|
|
726
784
|
progress_update(ckey, detail="booting")
|
|
727
785
|
self._poll_until_running(
|
|
728
|
-
poll_interval=poll_interval,
|
|
786
|
+
poll_interval=poll_interval,
|
|
787
|
+
timeout=ready_timeout,
|
|
729
788
|
)
|
|
730
789
|
|
|
731
790
|
# 6. Wait for ChalkFS volume files to become visible
|
|
@@ -747,7 +806,10 @@ class Container:
|
|
|
747
806
|
return self
|
|
748
807
|
|
|
749
808
|
def _poll_until_running(
|
|
750
|
-
self,
|
|
809
|
+
self,
|
|
810
|
+
*,
|
|
811
|
+
poll_interval: float,
|
|
812
|
+
timeout: float,
|
|
751
813
|
) -> None:
|
|
752
814
|
assert self._container_id is not None
|
|
753
815
|
deadline = time.monotonic() + timeout
|
|
@@ -773,12 +835,14 @@ class Container:
|
|
|
773
835
|
time.sleep(poll_interval)
|
|
774
836
|
status = self._container_info.status if self._container_info else "unknown"
|
|
775
837
|
raise ContainerError(
|
|
776
|
-
f"Container {self._container_id} timed out after {timeout}s "
|
|
777
|
-
f"(last status: {status})"
|
|
838
|
+
f"Container {self._container_id} timed out after {timeout}s (last status: {status})"
|
|
778
839
|
)
|
|
779
840
|
|
|
780
841
|
def _wait_for_volume_files(
|
|
781
|
-
self,
|
|
842
|
+
self,
|
|
843
|
+
*,
|
|
844
|
+
timeout: float = 120.0,
|
|
845
|
+
poll_interval: float = 0.5,
|
|
782
846
|
) -> None:
|
|
783
847
|
"""Poll until at least one uploaded file is visible in the ChalkFS mount.
|
|
784
848
|
|
|
@@ -934,9 +998,10 @@ class Container:
|
|
|
934
998
|
if self._volumes:
|
|
935
999
|
# Driver is used here only to perform the delete action, not to
|
|
936
1000
|
# derive a mount type.
|
|
937
|
-
driver = self._volume_driver or
|
|
938
|
-
|
|
939
|
-
|
|
1001
|
+
driver = self._volume_driver or VersionedVolumeClient.from_connect(
|
|
1002
|
+
self._client
|
|
1003
|
+
)
|
|
1004
|
+
cleanup_owned_volumes(driver, self._volumes, self._referenced_volumes)
|
|
940
1005
|
self._volumes = []
|
|
941
1006
|
self._volume_driver = None
|
|
942
1007
|
|
|
@@ -1005,6 +1070,7 @@ class Container:
|
|
|
1005
1070
|
# Helpers
|
|
1006
1071
|
# ---------------------------------------------------------------------------
|
|
1007
1072
|
|
|
1073
|
+
|
|
1008
1074
|
def _parse_container_response(data: dict) -> ContainerInfo:
|
|
1009
1075
|
return ContainerInfo(
|
|
1010
1076
|
id=data["id"],
|