robovast-cluster 2.1.0__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.
- robovast_cluster-2.1.0/PKG-INFO +36 -0
- robovast_cluster-2.1.0/README.md +17 -0
- robovast_cluster-2.1.0/pyproject.toml +63 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/__init__.py +0 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/azure.py +227 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/base_config.py +636 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/gcp.py +765 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/minikube.py +262 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/minio_store.py +252 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_config/rke2.py +314 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/__init__.py +0 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/bucket_ops.py +491 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/buildkitd_deploy.py +886 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/campaign_resume.py +350 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cli.py +1530 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_capacity.py +334 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_context.py +251 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_execution.py +1371 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_image_build.py +519 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_service.py +5064 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/cluster_setup.py +870 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/container_runner.py +948 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/data_paths.py +204 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/data_purge.py +151 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/fetch_cache.py +54 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/helm.py +54 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/image_warm.py +449 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/in_pod_storage.py +1147 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/in_pod_upload.py +50 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/index_deploy.py +248 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/kube_client.py +756 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/kube_exec_lane.py +501 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/kubernetes.py +217 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/kubernetes_backend.py +4170 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/kubernetes_gpu.py +381 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/manifests.py +72 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/node_admission.py +971 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/node_calibration.py +1009 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/node_governor.py +402 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/node_placement.py +853 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/postprocess_host.py +291 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/postprocess_job.py +2284 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/postprocess_reattach.py +147 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/postprocess_stage.py +300 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/postprocess_usage.py +130 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/registry_client.py +834 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/registry_deploy.py +334 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/registry_image_store.py +328 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/serve_backend.py +64 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/service_deploy.py +2697 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/store_errors.py +78 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/store_pod.py +238 -0
- robovast_cluster-2.1.0/robovast/execution/cluster_execution/tailnet_deploy.py +356 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: robovast-cluster
|
|
3
|
+
Version: 2.1.0
|
|
4
|
+
Summary: The Kubernetes execution lane for RoboVAST: cluster campaigns, deployment, and the operator commands.
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Author: Frederik Pasch
|
|
7
|
+
Author-email: fred-labs@mailbox.org
|
|
8
|
+
Requires-Python: >=3.12,<3.14
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Requires-Dist: bcrypt (>=4.0,<5.0)
|
|
13
|
+
Requires-Dist: boto3 (>=1.35,<2.0)
|
|
14
|
+
Requires-Dist: google-cloud-storage (>=2.0,<3.0)
|
|
15
|
+
Requires-Dist: kubernetes (>=34.1,<35.0)
|
|
16
|
+
Requires-Dist: robovast (>=2.0.0,<3.0.0)
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
|
|
19
|
+
# robovast-cluster
|
|
20
|
+
|
|
21
|
+
The Kubernetes execution lane for [RoboVAST](https://github.com/cps-test-lab/robovast):
|
|
22
|
+
running campaigns as Kubernetes Jobs, deploying the service, and the operator commands
|
|
23
|
+
that set a cluster up and take it down.
|
|
24
|
+
|
|
25
|
+
Install it alongside `robovast` when you have a cluster:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install robovast robovast-cluster
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Without it, `robovast` runs the local Docker lane and says so — `vast serve --backend
|
|
32
|
+
cluster` reports which lanes are installed, and `vast doctor` reports the cluster lane as
|
|
33
|
+
absent rather than broken.
|
|
34
|
+
|
|
35
|
+
It ships into the `robovast` namespace, so nothing about the import paths changes.
|
|
36
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# robovast-cluster
|
|
2
|
+
|
|
3
|
+
The Kubernetes execution lane for [RoboVAST](https://github.com/cps-test-lab/robovast):
|
|
4
|
+
running campaigns as Kubernetes Jobs, deploying the service, and the operator commands
|
|
5
|
+
that set a cluster up and take it down.
|
|
6
|
+
|
|
7
|
+
Install it alongside `robovast` when you have a cluster:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install robovast robovast-cluster
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Without it, `robovast` runs the local Docker lane and says so — `vast serve --backend
|
|
14
|
+
cluster` reports which lanes are installed, and `vast doctor` reports the cluster lane as
|
|
15
|
+
absent rather than broken.
|
|
16
|
+
|
|
17
|
+
It ships into the `robovast` namespace, so nothing about the import paths changes.
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "robovast-cluster"
|
|
3
|
+
version = "2.1.0"
|
|
4
|
+
description = "The Kubernetes execution lane for RoboVAST: cluster campaigns, deployment, and the operator commands."
|
|
5
|
+
authors = ["Frederik Pasch <fred-labs@mailbox.org>"]
|
|
6
|
+
license = "Apache-2.0"
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
# Ships into the `robovast` namespace rather than a name of its own, so the import paths
|
|
9
|
+
# do not change: `robovast/` and `robovast/execution/` carry no `__init__.py` in either
|
|
10
|
+
# distribution, which makes them PEP 420 namespace packages and lets the two trees merge.
|
|
11
|
+
packages = [{include = "robovast"}]
|
|
12
|
+
|
|
13
|
+
[tool.poetry.dependencies]
|
|
14
|
+
python = ">=3.12,<3.14"
|
|
15
|
+
# The lane is built on the core, and the edge is safe to declare: `robovast` names
|
|
16
|
+
# `robovast-nav` and `robovast-sim-roqsim` as path dependencies but never this package, so
|
|
17
|
+
# there is no cycle to avoid -- which is why `robovast_sim_roqsim` cannot state its
|
|
18
|
+
# equivalent and this can. It has to be stated rather than assumed: the controller image
|
|
19
|
+
# installs `robovast-cluster` into the pod, and every module here imports `robovast`.
|
|
20
|
+
robovast = "^2.0.0"
|
|
21
|
+
kubernetes = "^34.1"
|
|
22
|
+
# The built-in registry's password file. ``registry:2`` verifies with Go's bcrypt and
|
|
23
|
+
# rejects anything weaker, so this is the hash or no auth at all -- see registry_deploy.
|
|
24
|
+
bcrypt = "^4.0"
|
|
25
|
+
boto3 = "^1.35"
|
|
26
|
+
google-cloud-storage = "^2.0"
|
|
27
|
+
|
|
28
|
+
# `vast serve --backend cluster`. Resolved by name, so the core never imports this package
|
|
29
|
+
# to start a service -- see robovast/service/serve_backends.py.
|
|
30
|
+
[tool.poetry.plugins."robovast.execution_backends"]
|
|
31
|
+
cluster = "robovast.execution.cluster_execution.serve_backend:ClusterServeBackend"
|
|
32
|
+
|
|
33
|
+
# The operator half of `vast cluster` -- the verbs that need a kubeconfig, an API
|
|
34
|
+
# server or a cluster Secret. The `cluster` group itself belongs to robovast-client, whose
|
|
35
|
+
# service-driven verbs (run/stop/stop-job/log/download-cleanup) need none of this; these
|
|
36
|
+
# attach to it lazily, so `vast cluster --help` lists them without importing the
|
|
37
|
+
# Kubernetes client.
|
|
38
|
+
#
|
|
39
|
+
# `monitor` is here rather than in the client because its kubeconfig fallback view and its
|
|
40
|
+
# service view are one command chosen at runtime -- moving it would split one function's
|
|
41
|
+
# body across two distributions. A client-only user gets `vast campaign wait` and the
|
|
42
|
+
# web UI.
|
|
43
|
+
[tool.poetry.plugins."robovast.cluster_plugins"]
|
|
44
|
+
monitor = "robovast.execution.cluster_execution.cli:monitor"
|
|
45
|
+
setup = "robovast.execution.cluster_execution.cli:setup"
|
|
46
|
+
cleanup = "robovast.execution.cluster_execution.cli:cleanup"
|
|
47
|
+
"jobs-cleanup" = "robovast.execution.cluster_execution.cli:run_cleanup"
|
|
48
|
+
|
|
49
|
+
# `vast service upgrade` / `token` act on the deployed SERVICE, not on the cluster, so they
|
|
50
|
+
# attach to that group -- and need an API server, so they attach from here.
|
|
51
|
+
[tool.poetry.plugins."robovast.service_plugins"]
|
|
52
|
+
upgrade = "robovast.execution.cluster_execution.cli:upgrade"
|
|
53
|
+
token = "robovast.execution.cluster_execution.cli:cluster_token"
|
|
54
|
+
|
|
55
|
+
[tool.poetry.plugins."robovast.cluster_configs"]
|
|
56
|
+
minikube = "robovast.execution.cluster_config.minikube:MinikubeClusterConfig"
|
|
57
|
+
rke2 = "robovast.execution.cluster_config.rke2:Rke2ClusterConfig"
|
|
58
|
+
gcp = "robovast.execution.cluster_config.gcp:GcpClusterConfig"
|
|
59
|
+
azure = "robovast.execution.cluster_config.azure:AzureClusterConfig"
|
|
60
|
+
|
|
61
|
+
[build-system]
|
|
62
|
+
requires = ["poetry-core"]
|
|
63
|
+
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Copyright (C) 2025 Frederik Pasch
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing,
|
|
11
|
+
# software distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions
|
|
14
|
+
# and limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
17
|
+
import io
|
|
18
|
+
import logging
|
|
19
|
+
|
|
20
|
+
import yaml
|
|
21
|
+
from kubernetes import client
|
|
22
|
+
|
|
23
|
+
from robovast.execution.cluster_execution.kube_client import load_kube_config
|
|
24
|
+
|
|
25
|
+
from ..cluster_execution import store_pod
|
|
26
|
+
from ..cluster_execution.kubernetes import apply_manifests, delete_manifests
|
|
27
|
+
from .base_config import BaseConfig
|
|
28
|
+
|
|
29
|
+
MINIO_MANIFEST_AZURE = """---
|
|
30
|
+
apiVersion: v1
|
|
31
|
+
kind: PersistentVolumeClaim
|
|
32
|
+
metadata:
|
|
33
|
+
name: robovast-pvc
|
|
34
|
+
spec:
|
|
35
|
+
accessModes:
|
|
36
|
+
- ReadWriteOnce
|
|
37
|
+
resources:
|
|
38
|
+
requests:
|
|
39
|
+
storage: {storage_size}
|
|
40
|
+
storageClassName: managed-csi
|
|
41
|
+
---
|
|
42
|
+
apiVersion: v1
|
|
43
|
+
kind: Pod
|
|
44
|
+
metadata:
|
|
45
|
+
name: robovast
|
|
46
|
+
labels:
|
|
47
|
+
role: robovast
|
|
48
|
+
spec:
|
|
49
|
+
containers:
|
|
50
|
+
- name: minio
|
|
51
|
+
image: minio/minio:latest
|
|
52
|
+
args: ["server", "/data", "--console-address", ":9001"]
|
|
53
|
+
env:
|
|
54
|
+
- name: MINIO_ROOT_USER
|
|
55
|
+
value: "minioadmin"
|
|
56
|
+
- name: MINIO_ROOT_PASSWORD
|
|
57
|
+
value: "minioadmin"
|
|
58
|
+
ports:
|
|
59
|
+
- name: s3
|
|
60
|
+
containerPort: 9000
|
|
61
|
+
- name: console
|
|
62
|
+
containerPort: 9001
|
|
63
|
+
volumeMounts:
|
|
64
|
+
- mountPath: /data
|
|
65
|
+
name: minio-storage
|
|
66
|
+
resources:
|
|
67
|
+
# A floor, not an estimate: every milli-core requested here is capacity campaign jobs
|
|
68
|
+
# cannot be admitted against, so the request covers an idle server. The LIMIT is a
|
|
69
|
+
# different quantity and has to be sized against the peak: MinIO streams objects, but
|
|
70
|
+
# a batch mirrors dozens of multi-part transfers at once, and each carries buffers the
|
|
71
|
+
# request knows nothing about. Sized well above idle on purpose -- a store that is
|
|
72
|
+
# OOM-killed mid-batch takes that batch's bag conversion with it, and the campaign then
|
|
73
|
+
# fails in postprocessing with no conversion log to explain it. No CPU limit --
|
|
74
|
+
# throttling the store slows every upload and download with no visible cause.
|
|
75
|
+
requests:
|
|
76
|
+
cpu: "50m"
|
|
77
|
+
memory: "256Mi"
|
|
78
|
+
limits:
|
|
79
|
+
memory: "4Gi"
|
|
80
|
+
readinessProbe:
|
|
81
|
+
httpGet:
|
|
82
|
+
path: /minio/health/ready
|
|
83
|
+
port: 9000
|
|
84
|
+
initialDelaySeconds: 10
|
|
85
|
+
periodSeconds: 5
|
|
86
|
+
volumes:
|
|
87
|
+
- name: minio-storage
|
|
88
|
+
persistentVolumeClaim:
|
|
89
|
+
claimName: robovast-pvc
|
|
90
|
+
---
|
|
91
|
+
apiVersion: v1
|
|
92
|
+
kind: Service
|
|
93
|
+
metadata:
|
|
94
|
+
name: robovast
|
|
95
|
+
spec:
|
|
96
|
+
ports:
|
|
97
|
+
- name: s3
|
|
98
|
+
port: 9000
|
|
99
|
+
targetPort: 9000
|
|
100
|
+
- name: console
|
|
101
|
+
port: 9001
|
|
102
|
+
targetPort: 9001
|
|
103
|
+
selector:
|
|
104
|
+
role: robovast
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class AzureClusterConfig(BaseConfig):
|
|
109
|
+
|
|
110
|
+
#: AKS node pools are Azure VMs, whose guest kernels expose no cpufreq policy.
|
|
111
|
+
#: See :attr:`BaseConfig.governor_is_settable`.
|
|
112
|
+
governor_is_settable = False
|
|
113
|
+
|
|
114
|
+
def setup_cluster(self, storage_size="10Gi", **kwargs):
|
|
115
|
+
"""Set up MinIO S3 server for Azure cluster.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
storage_size (str): Size of the persistent volume (default: "10Gi")
|
|
119
|
+
**kwargs: Additional cluster-specific options (kube_context, namespace,
|
|
120
|
+
control_node_labels)
|
|
121
|
+
"""
|
|
122
|
+
control_node_labels = kwargs.pop('control_node_labels', None)
|
|
123
|
+
logging.info("Setting up RoboVAST MinIO S3 server in Azure cluster...")
|
|
124
|
+
logging.info(f"Storage size: {storage_size}")
|
|
125
|
+
|
|
126
|
+
load_kube_config(context=kwargs.get('kube_context'))
|
|
127
|
+
k8s_client = client.ApiClient()
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
yaml_objects = list(yaml.safe_load_all(io.StringIO(MINIO_MANIFEST_AZURE.format(storage_size=storage_size))))
|
|
131
|
+
except yaml.YAMLError as e:
|
|
132
|
+
raise RuntimeError(f"Failed to parse MinIO manifest YAML: {str(e)}") from e
|
|
133
|
+
|
|
134
|
+
namespace = kwargs.get('namespace', 'default')
|
|
135
|
+
# The registry and the campaign index ride in this pod: setup-lifetime
|
|
136
|
+
# infrastructure, created once here rather than in the service Deployment that
|
|
137
|
+
# every upgrade rolls. See `cluster_execution.store_pod`.
|
|
138
|
+
yaml_objects = store_pod.attach_infrastructure(
|
|
139
|
+
yaml_objects, namespace,
|
|
140
|
+
index_storage_path=kwargs.get('index_storage_path', ''),
|
|
141
|
+
index_storage_class=kwargs.get('index_storage_class', ''),
|
|
142
|
+
index_storage_size=kwargs.get('index_storage_size', ''),
|
|
143
|
+
registry_storage_path=kwargs.get('registry_storage_path', ''),
|
|
144
|
+
registry_storage_class=kwargs.get('registry_storage_class', ''),
|
|
145
|
+
registry_authenticated=kwargs.get('registry_authenticated', False),
|
|
146
|
+
ingress_class=kwargs.get('ingress_class', ''))
|
|
147
|
+
yaml_objects = self._apply_pod_node_selector(yaml_objects, control_node_labels)
|
|
148
|
+
try:
|
|
149
|
+
apply_manifests(k8s_client, iter(yaml_objects), namespace=namespace)
|
|
150
|
+
except Exception as e:
|
|
151
|
+
raise RuntimeError(f"Error applying MinIO manifest: {str(e)}") from e
|
|
152
|
+
|
|
153
|
+
logging.info(f"MinIO S3 server available at: {self.get_s3_endpoint()}")
|
|
154
|
+
|
|
155
|
+
def cleanup_cluster(self, storage_size="10Gi", **kwargs):
|
|
156
|
+
"""Clean up MinIO S3 server for Azure cluster.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
storage_size (str): Size of the persistent volume (default: "10Gi")
|
|
160
|
+
**kwargs: Additional cluster-specific options (ignored)
|
|
161
|
+
"""
|
|
162
|
+
logging.debug("Cleaning up RoboVAST MinIO in Azure cluster...")
|
|
163
|
+
load_kube_config(context=kwargs.get('kube_context'))
|
|
164
|
+
core_v1 = client.CoreV1Api()
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
yaml_objects = yaml.safe_load_all(io.StringIO(MINIO_MANIFEST_AZURE.format(storage_size=storage_size)))
|
|
168
|
+
except yaml.YAMLError as e:
|
|
169
|
+
raise RuntimeError(f"Failed to parse MinIO manifest YAML: {str(e)}") from e
|
|
170
|
+
|
|
171
|
+
namespace = kwargs.get('namespace', 'default')
|
|
172
|
+
yaml_objects = store_pod.attach_infrastructure(list(yaml_objects), namespace)
|
|
173
|
+
delete_manifests(core_v1, store_pod.infrastructure_claims(namespace) + yaml_objects,
|
|
174
|
+
namespace=namespace)
|
|
175
|
+
logging.debug("MinIO manifest deleted successfully!")
|
|
176
|
+
|
|
177
|
+
def prepare_setup_cluster(self, output_dir, storage_size="10Gi", **kwargs):
|
|
178
|
+
"""Prepare any prerequisites before setting up the cluster.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
output_dir (str): Directory where setup files will be written
|
|
182
|
+
storage_size (str): Size of the persistent volume (default: "10Gi")
|
|
183
|
+
**kwargs: Cluster-specific options (control_node_labels)
|
|
184
|
+
"""
|
|
185
|
+
control_node_labels = kwargs.pop('control_node_labels', None)
|
|
186
|
+
docs = store_pod.attach_infrastructure(
|
|
187
|
+
list(yaml.safe_load_all(io.StringIO(
|
|
188
|
+
MINIO_MANIFEST_AZURE.format(storage_size=storage_size)))),
|
|
189
|
+
kwargs.get('namespace', 'default'))
|
|
190
|
+
docs = self._apply_pod_node_selector(docs, control_node_labels)
|
|
191
|
+
manifest_to_write = "---\n".join(
|
|
192
|
+
yaml.dump(d, default_flow_style=False) for d in docs if d is not None
|
|
193
|
+
)
|
|
194
|
+
with open(f"{output_dir}/robovast-manifest.yaml", "w") as f:
|
|
195
|
+
f.write(manifest_to_write)
|
|
196
|
+
|
|
197
|
+
readme_content = f"""# Azure Cluster Setup Instructions
|
|
198
|
+
|
|
199
|
+
Uses MinIO backed by an Azure managed-csi PVC ({storage_size}).
|
|
200
|
+
|
|
201
|
+
## Setup Steps
|
|
202
|
+
|
|
203
|
+
### 1. Apply the RoboVAST MinIO Manifest
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
kubectl apply -f robovast-manifest.yaml
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 2. Wait for the pod to be ready
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
kubectl wait --for=condition=ready pod/robovast --timeout=120s
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
MinIO S3 API is available at `http://robovast:9000` (cluster-internal).
|
|
216
|
+
MinIO console is available at port 9001.
|
|
217
|
+
"""
|
|
218
|
+
with open(f"{output_dir}/README_azure.md", "w") as f:
|
|
219
|
+
f.write(readme_content)
|
|
220
|
+
|
|
221
|
+
def get_instance_type_command(self):
|
|
222
|
+
"""Get command to retrieve instance type of the current node."""
|
|
223
|
+
return (
|
|
224
|
+
'INSTANCE_TYPE=$(curl -s -H "Metadata: true" '
|
|
225
|
+
'"http://169.254.169.254/metadata/instance/compute/vmSize'
|
|
226
|
+
'?api-version=2021-02-01&format=text")'
|
|
227
|
+
)
|