vantage6 5.0.0a35__py3-none-any.whl → 5.0.0a37__py3-none-any.whl
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.
Potentially problematic release.
This version of vantage6 might be problematic. Click here for more details.
- vantage6/cli/algorithm/generate_algorithm_json.py +9 -10
- vantage6/cli/algorithm/update.py +1 -1
- vantage6/cli/algostore/attach.py +1 -0
- vantage6/cli/algostore/files.py +3 -2
- vantage6/cli/algostore/list.py +0 -3
- vantage6/cli/algostore/new.py +3 -2
- vantage6/cli/algostore/start.py +14 -3
- vantage6/cli/algostore/stop.py +3 -0
- vantage6/cli/auth/attach.py +60 -0
- vantage6/cli/auth/files.py +16 -0
- vantage6/cli/auth/list.py +13 -0
- vantage6/cli/auth/new.py +81 -0
- vantage6/cli/auth/remove.py +31 -0
- vantage6/cli/auth/start.py +94 -0
- vantage6/cli/auth/stop.py +67 -0
- vantage6/cli/cli.py +56 -5
- vantage6/cli/common/decorator.py +24 -5
- vantage6/cli/common/new.py +27 -7
- vantage6/cli/common/start.py +49 -41
- vantage6/cli/common/stop.py +23 -5
- vantage6/cli/common/utils.py +25 -0
- vantage6/cli/config.py +10 -2
- vantage6/cli/{configuration_wizard.py → configuration_create.py} +28 -15
- vantage6/cli/configuration_manager.py +97 -17
- vantage6/cli/context/__init__.py +10 -5
- vantage6/cli/context/algorithm_store.py +11 -5
- vantage6/cli/context/auth.py +125 -0
- vantage6/cli/context/base_server.py +0 -4
- vantage6/cli/context/node.py +25 -8
- vantage6/cli/context/server.py +18 -6
- vantage6/cli/dev/clean.py +28 -0
- vantage6/cli/dev/common.py +34 -0
- vantage6/cli/dev/rebuild.py +39 -0
- vantage6/cli/dev/start.py +36 -0
- vantage6/cli/dev/stop.py +23 -0
- vantage6/cli/globals.py +5 -1
- vantage6/cli/node/common/__init__.py +26 -10
- vantage6/cli/node/list.py +5 -4
- vantage6/cli/node/new.py +13 -6
- vantage6/cli/node/set_api_key.py +1 -1
- vantage6/cli/node/start.py +19 -4
- vantage6/cli/node/stop.py +153 -7
- vantage6/cli/node/task_cleanup/__init__.py +153 -0
- vantage6/cli/node/version.py +5 -4
- vantage6/cli/prometheus/monitoring_manager.py +5 -3
- vantage6/cli/sandbox/config/base.py +101 -0
- vantage6/cli/sandbox/config/core.py +300 -0
- vantage6/cli/sandbox/config/node.py +314 -0
- vantage6/cli/sandbox/data/olympic_athletes_2016.csv +2425 -0
- vantage6/cli/sandbox/new.py +207 -0
- vantage6/cli/sandbox/populate/__init__.py +173 -0
- vantage6/cli/sandbox/populate/helpers/connect_store.py +203 -0
- vantage6/cli/sandbox/populate/helpers/delete_fixtures.py +67 -0
- vantage6/cli/sandbox/populate/helpers/load_fixtures.py +476 -0
- vantage6/cli/sandbox/populate/helpers/utils.py +35 -0
- vantage6/cli/sandbox/remove.py +173 -0
- vantage6/cli/sandbox/start.py +341 -0
- vantage6/cli/sandbox/stop.py +106 -0
- vantage6/cli/server/attach.py +1 -0
- vantage6/cli/server/common/__init__.py +6 -33
- vantage6/cli/server/import_.py +137 -119
- vantage6/cli/server/new.py +22 -7
- vantage6/cli/server/start.py +10 -1
- vantage6/cli/server/stop.py +2 -0
- vantage6/cli/template/auth_config.j2 +253 -0
- vantage6/cli/template/node_config.j2 +8 -8
- vantage6/cli/template/node_config_nonk8s.j2 +33 -0
- vantage6/cli/template/server_config.j2 +10 -7
- vantage6/cli/test/common/diagnostic_runner.py +5 -3
- vantage6/cli/use/namespace.py +2 -1
- vantage6/cli/utils.py +33 -1
- {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/METADATA +4 -4
- vantage6-5.0.0a37.dist-info/RECORD +97 -0
- vantage6/cli/dev/create.py +0 -693
- vantage6/cli/dev/remove.py +0 -112
- vantage6/cli/rabbitmq/__init__.py +0 -0
- vantage6/cli/rabbitmq/definitions.py +0 -26
- vantage6/cli/rabbitmq/queue_manager.py +0 -218
- vantage6/cli/rabbitmq/rabbitmq.config +0 -8
- vantage6/cli/server/shell.py +0 -54
- vantage6-5.0.0a35.dist-info/RECORD +0 -75
- /vantage6/cli/{dev → sandbox}/data/km_dataset.csv +0 -0
- {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/WHEEL +0 -0
- {vantage6-5.0.0a35.dist-info → vantage6-5.0.0a37.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from importlib import resources as impresources
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from colorama import Fore, Style
|
|
7
|
+
|
|
8
|
+
from vantage6.common import error, info
|
|
9
|
+
from vantage6.common.globals import InstanceType
|
|
10
|
+
|
|
11
|
+
import vantage6.cli.sandbox.data as node_datafiles_dir
|
|
12
|
+
from vantage6.cli.common.new import new
|
|
13
|
+
from vantage6.cli.context.node import NodeContext
|
|
14
|
+
from vantage6.cli.globals import (
|
|
15
|
+
DefaultDatasets,
|
|
16
|
+
)
|
|
17
|
+
from vantage6.cli.sandbox.config.base import BaseSandboxConfigManager
|
|
18
|
+
from vantage6.cli.sandbox.populate.helpers.utils import replace_wsl_path
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass
|
|
22
|
+
class NodeDataset:
|
|
23
|
+
label: str
|
|
24
|
+
path: Path
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class NodeSandboxConfigManager(BaseSandboxConfigManager):
|
|
28
|
+
"""
|
|
29
|
+
Class to store the node sandbox configurations.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
server_name : str
|
|
34
|
+
Name of the server.
|
|
35
|
+
api_keys : list[str]
|
|
36
|
+
List of API keys.
|
|
37
|
+
node_names : list[str]
|
|
38
|
+
List of node names.
|
|
39
|
+
server_port : int
|
|
40
|
+
Port of the server.
|
|
41
|
+
node_image : str | None
|
|
42
|
+
Image of the node.
|
|
43
|
+
extra_node_config : Path | None
|
|
44
|
+
Path to the extra node configuration file.
|
|
45
|
+
extra_dataset : NodeDataset | None
|
|
46
|
+
List of tuples with the label and path to the dataset file.
|
|
47
|
+
context : str
|
|
48
|
+
Kubernetes context.
|
|
49
|
+
namespace : str
|
|
50
|
+
Kubernetes namespace.
|
|
51
|
+
k8s_node_name : str
|
|
52
|
+
Kubernetes node name.
|
|
53
|
+
custom_data_dir : Path | None
|
|
54
|
+
Path to the custom data directory. Useful on WSL because of mount issues for
|
|
55
|
+
default directories.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
def __init__(
|
|
59
|
+
self,
|
|
60
|
+
server_name: str,
|
|
61
|
+
api_keys: list[str],
|
|
62
|
+
node_names: list[str],
|
|
63
|
+
server_port: int,
|
|
64
|
+
node_image: str | None,
|
|
65
|
+
extra_node_config: Path | None,
|
|
66
|
+
extra_dataset: NodeDataset | None,
|
|
67
|
+
context: str,
|
|
68
|
+
namespace: str,
|
|
69
|
+
k8s_node_name: str,
|
|
70
|
+
custom_data_dir: Path | None,
|
|
71
|
+
) -> None:
|
|
72
|
+
super().__init__(server_name, custom_data_dir)
|
|
73
|
+
self.api_keys = api_keys
|
|
74
|
+
self.node_names = node_names
|
|
75
|
+
self.num_nodes = len(api_keys)
|
|
76
|
+
self.server_port = server_port
|
|
77
|
+
self.node_image = node_image
|
|
78
|
+
self.extra_node_config = extra_node_config
|
|
79
|
+
if extra_dataset:
|
|
80
|
+
self.node_datasets = [extra_dataset]
|
|
81
|
+
else:
|
|
82
|
+
self.node_datasets = []
|
|
83
|
+
self.context = context
|
|
84
|
+
self.namespace = namespace
|
|
85
|
+
self.k8s_node_name = k8s_node_name
|
|
86
|
+
|
|
87
|
+
self.node_configs = []
|
|
88
|
+
self.node_config_files = []
|
|
89
|
+
self.node_config_names = []
|
|
90
|
+
self.extra_config = None
|
|
91
|
+
|
|
92
|
+
def generate_node_configs(self) -> None:
|
|
93
|
+
"""
|
|
94
|
+
Generates ``num_nodes`` node configuration files.
|
|
95
|
+
"""
|
|
96
|
+
node_data_files = []
|
|
97
|
+
self.extra_config = self._read_extra_config_file(self.extra_node_config)
|
|
98
|
+
|
|
99
|
+
data_directory = impresources.files(node_datafiles_dir)
|
|
100
|
+
|
|
101
|
+
# Add default datasets to the list of dataset provided
|
|
102
|
+
for default_dataset in DefaultDatasets:
|
|
103
|
+
# note that the label is the name of the dataset with the underscores
|
|
104
|
+
# replace with hyphens, to make it valid for k8s
|
|
105
|
+
self.node_datasets.append(
|
|
106
|
+
NodeDataset(
|
|
107
|
+
label=default_dataset.name.lower().replace("_", "-"),
|
|
108
|
+
path=data_directory / default_dataset.value,
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
# Check for duplicate dataset labels
|
|
113
|
+
seen_labels = set()
|
|
114
|
+
duplicates = [
|
|
115
|
+
label
|
|
116
|
+
for label in [dataset.label for dataset in self.node_datasets]
|
|
117
|
+
if (label in seen_labels or seen_labels.add(label))
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
if len(duplicates) > 0:
|
|
121
|
+
error(
|
|
122
|
+
f"Duplicate dataset labels found: {duplicates}. "
|
|
123
|
+
f"Please make sure all dataset labels are unique."
|
|
124
|
+
)
|
|
125
|
+
exit(1)
|
|
126
|
+
|
|
127
|
+
# create the data files for the nodes and get the path and label for each
|
|
128
|
+
# dataset
|
|
129
|
+
for dataset in self.node_datasets:
|
|
130
|
+
node_data_files.append(self._create_node_data_files(dataset))
|
|
131
|
+
|
|
132
|
+
for idx, api_key in enumerate(self.api_keys):
|
|
133
|
+
config = {
|
|
134
|
+
"org_id": idx + 1,
|
|
135
|
+
"api_key": api_key,
|
|
136
|
+
"node_name": self.node_names[idx],
|
|
137
|
+
}
|
|
138
|
+
config_file = self._create_node_config_file(
|
|
139
|
+
config,
|
|
140
|
+
[files[idx] for files in node_data_files],
|
|
141
|
+
)
|
|
142
|
+
self.node_configs.append(config)
|
|
143
|
+
self.node_config_files.append(config_file)
|
|
144
|
+
info(
|
|
145
|
+
f"Created {Fore.GREEN}{len(self.node_config_files)}{Style.RESET_ALL} node "
|
|
146
|
+
f"configuration(s), attaching them to {Fore.GREEN}{self.server_name}"
|
|
147
|
+
f"{Style.RESET_ALL}."
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
def _create_node_data_files(
|
|
151
|
+
self, node_dataset: NodeDataset
|
|
152
|
+
) -> list[tuple[str, Path]]:
|
|
153
|
+
"""
|
|
154
|
+
Create data files for nodes.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
node_dataset : NodeDataset
|
|
159
|
+
Tuple with the label and path to the dataset file.
|
|
160
|
+
|
|
161
|
+
Returns
|
|
162
|
+
-------
|
|
163
|
+
list[tuple[str, Path]]
|
|
164
|
+
List of tuples with the label and path to the dataset file.
|
|
165
|
+
"""
|
|
166
|
+
info(
|
|
167
|
+
f"Creating data files using dataset '{node_dataset.label}' for "
|
|
168
|
+
f"{self.num_nodes} nodes"
|
|
169
|
+
)
|
|
170
|
+
data_files = []
|
|
171
|
+
full_df = pd.read_csv(node_dataset.path)
|
|
172
|
+
length_df = len(full_df)
|
|
173
|
+
for i in range(self.num_nodes):
|
|
174
|
+
node_name = f"{self.server_name}_node_{i + 1}"
|
|
175
|
+
path_to_dev_dir = self._create_and_get_data_dir(
|
|
176
|
+
InstanceType.NODE, is_data_folder=False
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# Split the data over the nodes
|
|
180
|
+
start = i * length_df // self.num_nodes
|
|
181
|
+
end = (i + 1) * length_df // self.num_nodes
|
|
182
|
+
data = full_df[start:end]
|
|
183
|
+
data_file = (
|
|
184
|
+
replace_wsl_path(path_to_dev_dir, to_mnt_wsl=True)
|
|
185
|
+
/ f"df_{node_dataset.label}_{node_name}.csv"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# write data to file
|
|
189
|
+
data.to_csv(data_file, index=False)
|
|
190
|
+
data_files.append(
|
|
191
|
+
(node_dataset.label, replace_wsl_path(data_file, to_mnt_wsl=False))
|
|
192
|
+
)
|
|
193
|
+
return data_files
|
|
194
|
+
|
|
195
|
+
def _create_node_config_file(
|
|
196
|
+
self, config: dict, datasets: list[tuple[str, Path]]
|
|
197
|
+
) -> Path:
|
|
198
|
+
"""
|
|
199
|
+
Create a node configuration file (YAML).
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
----------
|
|
203
|
+
config : dict
|
|
204
|
+
Configuration dictionary.
|
|
205
|
+
datasets : list[tuple[str, Path]]
|
|
206
|
+
List of tuples with the label and path to the dataset file.
|
|
207
|
+
|
|
208
|
+
Returns
|
|
209
|
+
-------
|
|
210
|
+
Path
|
|
211
|
+
Path to the node configuration file.
|
|
212
|
+
"""
|
|
213
|
+
node_name = config["node_name"]
|
|
214
|
+
config_name = f"{self.server_name}-{node_name}"
|
|
215
|
+
|
|
216
|
+
path_to_data_dir = self._create_and_get_data_dir(
|
|
217
|
+
InstanceType.NODE, is_data_folder=True
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# delete old node config if it exists
|
|
221
|
+
NodeContext.remove_config_file_if_exists(
|
|
222
|
+
InstanceType.NODE, config_name, False, is_sandbox=True
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# create new node config
|
|
226
|
+
node_config = new(
|
|
227
|
+
config_producing_func=self.__node_config_return_func,
|
|
228
|
+
config_producing_func_args=(
|
|
229
|
+
config,
|
|
230
|
+
self.extra_config,
|
|
231
|
+
datasets,
|
|
232
|
+
path_to_data_dir,
|
|
233
|
+
),
|
|
234
|
+
name=config_name,
|
|
235
|
+
system_folders=False,
|
|
236
|
+
namespace=self.namespace,
|
|
237
|
+
context=self.context,
|
|
238
|
+
type_=InstanceType.NODE,
|
|
239
|
+
is_sandbox=True,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
self.node_config_names.append(config_name)
|
|
243
|
+
|
|
244
|
+
return node_config
|
|
245
|
+
|
|
246
|
+
def __node_config_return_func(
|
|
247
|
+
self,
|
|
248
|
+
node_specific_config: dict,
|
|
249
|
+
extra_config: dict,
|
|
250
|
+
datasets: list[tuple[str, Path]],
|
|
251
|
+
path_to_data_dir: Path,
|
|
252
|
+
) -> dict:
|
|
253
|
+
"""
|
|
254
|
+
Return a dict with node configuration values to be used in creating the
|
|
255
|
+
config file.
|
|
256
|
+
"""
|
|
257
|
+
config = {
|
|
258
|
+
"node": {
|
|
259
|
+
"proxyPort": 7676 + int(node_specific_config["org_id"]),
|
|
260
|
+
"apiKey": node_specific_config["api_key"],
|
|
261
|
+
"name": node_specific_config["node_name"],
|
|
262
|
+
"image": (
|
|
263
|
+
self.node_image
|
|
264
|
+
# TODO v5+ update
|
|
265
|
+
or "harbor2.vantage6.ai/infrastructure/node:5.0.0a36"
|
|
266
|
+
),
|
|
267
|
+
"logging": {
|
|
268
|
+
"level": "DEBUG",
|
|
269
|
+
"file": f"{node_specific_config['node_name']}.log",
|
|
270
|
+
},
|
|
271
|
+
"keycloakUrl": (
|
|
272
|
+
f"http://vantage6-{self.server_name}-auth-user-auth-keycloak."
|
|
273
|
+
f"{self.namespace}.svc.cluster.local"
|
|
274
|
+
),
|
|
275
|
+
"dev": {
|
|
276
|
+
"task_dir_extension": str(path_to_data_dir),
|
|
277
|
+
},
|
|
278
|
+
"persistence": {
|
|
279
|
+
"tasks": {
|
|
280
|
+
"hostPath": str(path_to_data_dir),
|
|
281
|
+
"size": "1Gi",
|
|
282
|
+
},
|
|
283
|
+
"database": {
|
|
284
|
+
"size": "1Gi",
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
"k8sNodeName": self.k8s_node_name,
|
|
288
|
+
"databases": {
|
|
289
|
+
"fileBased": [
|
|
290
|
+
{
|
|
291
|
+
"name": dataset[0],
|
|
292
|
+
"uri": dataset[1],
|
|
293
|
+
"type": "csv",
|
|
294
|
+
"volumePath": Path(dataset[1]).parent,
|
|
295
|
+
"originalName": dataset[0],
|
|
296
|
+
}
|
|
297
|
+
for dataset in [datasets[0]]
|
|
298
|
+
]
|
|
299
|
+
},
|
|
300
|
+
"server": {
|
|
301
|
+
"url": (
|
|
302
|
+
f"http://vantage6-{self.server_name}-user-server-"
|
|
303
|
+
f"vantage6-server-service.{self.namespace}.svc.cluster.local"
|
|
304
|
+
),
|
|
305
|
+
"port": self.server_port,
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
# merge the extra config with the node config
|
|
311
|
+
if extra_config is not None:
|
|
312
|
+
config.update(extra_config)
|
|
313
|
+
|
|
314
|
+
return config
|