kalavai-client 0.5.26__py3-none-any.whl → 0.5.28__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.
- kalavai_client/__init__.py +1 -1
- kalavai_client/assets/apps.yaml +1 -1
- kalavai_client/assets/docker-compose-gui.yaml +20 -1
- kalavai_client/bridge_api.py +11 -3
- kalavai_client/bridge_models.py +6 -1
- kalavai_client/cli.py +74 -99
- kalavai_client/core.py +81 -14
- kalavai_client/utils.py +18 -2
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.28.dist-info}/METADATA +1 -1
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.28.dist-info}/RECORD +13 -13
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.28.dist-info}/LICENSE +0 -0
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.28.dist-info}/WHEEL +0 -0
- {kalavai_client-0.5.26.dist-info → kalavai_client-0.5.28.dist-info}/entry_points.txt +0 -0
kalavai_client/__init__.py
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
|
2
|
-
__version__ = "0.5.
|
2
|
+
__version__ = "0.5.28"
|
kalavai_client/assets/apps.yaml
CHANGED
@@ -2,7 +2,26 @@ services:
|
|
2
2
|
kalavai_gui:
|
3
3
|
container_name: kalavai_gui
|
4
4
|
image: bundenth/kalavai-gui:latest
|
5
|
-
network_mode: host
|
5
|
+
#network_mode: host
|
6
|
+
extra_hosts:
|
7
|
+
- "host.docker.internal:host-gateway"
|
8
|
+
networks:
|
9
|
+
- kalavai-net
|
10
|
+
environment:
|
11
|
+
- KALAVAI_BRIDGE_URL=http://host.docker.internal
|
12
|
+
- KALAVAI_BRIDGE_PORT={{bridge_port}}
|
13
|
+
entrypoint: ["reflex"]
|
14
|
+
command: >
|
15
|
+
run
|
16
|
+
--backend-port {{gui_backend_port}}
|
17
|
+
--frontend-port {{gui_frontend_port}}
|
18
|
+
ports:
|
19
|
+
- "{{gui_backend_port}}:{{gui_backend_port}}"
|
20
|
+
- "{{gui_frontend_port}}:{{gui_frontend_port}}"
|
6
21
|
volumes:
|
7
22
|
- "{{path}}:/root/.cache/kalavai"
|
8
23
|
restart: always
|
24
|
+
|
25
|
+
networks:
|
26
|
+
kalavai-net:
|
27
|
+
driver: bridge
|
kalavai_client/bridge_api.py
CHANGED
@@ -7,6 +7,7 @@ import uvicorn
|
|
7
7
|
|
8
8
|
from kalavai_client.bridge_models import (
|
9
9
|
CreatePoolRequest,
|
10
|
+
InvitesRequest,
|
10
11
|
JoinPoolRequest,
|
11
12
|
StopPoolRequest,
|
12
13
|
DeployJobRequest,
|
@@ -18,6 +19,7 @@ from kalavai_client.core import (
|
|
18
19
|
create_pool,
|
19
20
|
join_pool,
|
20
21
|
attach_to_pool,
|
22
|
+
send_invites,
|
21
23
|
stop_pool,
|
22
24
|
fetch_devices,
|
23
25
|
fetch_resources,
|
@@ -57,7 +59,9 @@ def pool_create(request: CreatePoolRequest):
|
|
57
59
|
num_gpus=request.num_gpus,
|
58
60
|
node_name=request.node_name,
|
59
61
|
only_registered_users=request.only_registered_users,
|
60
|
-
location=request.location
|
62
|
+
location=request.location,
|
63
|
+
description=request.description,
|
64
|
+
token_mode=request.token_mode
|
61
65
|
)
|
62
66
|
return result
|
63
67
|
|
@@ -108,14 +112,18 @@ def device_uncordon(request: NodesActionRequest):
|
|
108
112
|
return result
|
109
113
|
|
110
114
|
@app.get("/get_pool_token")
|
111
|
-
def
|
115
|
+
def get_token(mode: int):
|
112
116
|
|
113
117
|
return get_pool_token(mode=TokenType(mode))
|
114
118
|
|
115
119
|
@app.get("/fetch_devices")
|
116
|
-
def
|
120
|
+
def get_devices():
|
117
121
|
return fetch_devices()
|
118
122
|
|
123
|
+
@app.post("/send_pool_invites")
|
124
|
+
def send_pool_invites(request: InvitesRequest):
|
125
|
+
return send_invites(invitees=request.invitees)
|
126
|
+
|
119
127
|
@app.get("/fetch_resources")
|
120
128
|
def resources():
|
121
129
|
return fetch_resources()
|
kalavai_client/bridge_models.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
from pydantic import BaseModel
|
2
2
|
|
3
|
-
from kalavai_client.core import Job
|
3
|
+
from kalavai_client.core import Job, TokenType
|
4
4
|
|
5
5
|
|
6
|
+
class InvitesRequest(BaseModel):
|
7
|
+
invitees: list[str]
|
8
|
+
|
6
9
|
class CreatePoolRequest(BaseModel):
|
7
10
|
cluster_name: str
|
8
11
|
ip_address: str
|
@@ -11,6 +14,8 @@ class CreatePoolRequest(BaseModel):
|
|
11
14
|
node_name: str = None
|
12
15
|
only_registered_users: bool = False
|
13
16
|
location: str = None
|
17
|
+
token_mode: TokenType = TokenType.USER
|
18
|
+
description: str = ""
|
14
19
|
|
15
20
|
class NodesActionRequest(BaseModel):
|
16
21
|
nodes: list[str]
|
kalavai_client/cli.py
CHANGED
@@ -34,6 +34,7 @@ from kalavai_client.env import (
|
|
34
34
|
resource_path,
|
35
35
|
)
|
36
36
|
from kalavai_client.core import (
|
37
|
+
deploy_test_job,
|
37
38
|
fetch_resources,
|
38
39
|
fetch_job_names,
|
39
40
|
fetch_job_details,
|
@@ -51,12 +52,15 @@ from kalavai_client.core import (
|
|
51
52
|
create_pool,
|
52
53
|
get_ip_addresses,
|
53
54
|
pause_agent,
|
55
|
+
register_pool,
|
54
56
|
resume_agent,
|
55
57
|
get_pool_token,
|
56
58
|
delete_nodes,
|
57
59
|
cordon_nodes,
|
60
|
+
stop_pool,
|
58
61
|
uncordon_nodes,
|
59
|
-
TokenType
|
62
|
+
TokenType,
|
63
|
+
unregister_pool
|
60
64
|
)
|
61
65
|
from kalavai_client.utils import (
|
62
66
|
check_gpu_drivers,
|
@@ -206,11 +210,15 @@ def input_gpus():
|
|
206
210
|
@arguably.command
|
207
211
|
def gui__start(*others, backend_only=False, gui_frontend_port=3000, gui_backend_port=8000, bridge_port=8001, log_level="critical"):
|
208
212
|
"""Run GUI (docker) and kalavai core backend (api)"""
|
209
|
-
|
213
|
+
if len(set([gui_frontend_port, gui_backend_port, bridge_port])) < 3:
|
214
|
+
console.log("[red]Error: ports must be unique")
|
215
|
+
return
|
216
|
+
|
210
217
|
if not backend_only:
|
211
218
|
values = {
|
212
219
|
"gui_frontend_port": gui_frontend_port,
|
213
220
|
"gui_backend_port": gui_backend_port,
|
221
|
+
"bridge_port": bridge_port,
|
214
222
|
"path": user_path("")
|
215
223
|
}
|
216
224
|
compose_yaml = load_template(
|
@@ -222,6 +230,9 @@ def gui__start(*others, backend_only=False, gui_frontend_port=3000, gui_backend_
|
|
222
230
|
run_cmd(f"docker compose --file {USER_GUI_COMPOSE_FILE} up -d")
|
223
231
|
|
224
232
|
console.log(f"[green]Loading GUI, may take a few minutes. It will be available at http://localhost:{gui_frontend_port}")
|
233
|
+
print(
|
234
|
+
"Deploying bridge API"
|
235
|
+
)
|
225
236
|
run_api(port=bridge_port, log_level=log_level)
|
226
237
|
|
227
238
|
if not backend_only:
|
@@ -286,7 +297,7 @@ def location__list(*others):
|
|
286
297
|
console.log(table)
|
287
298
|
|
288
299
|
@arguably.command
|
289
|
-
def pool__publish(*others, description=None):
|
300
|
+
def pool__publish(*others, description=None, is_private=True):
|
290
301
|
"""
|
291
302
|
[AUTH] Publish pool to Kalavai platform, where other users may be able to join
|
292
303
|
"""
|
@@ -300,26 +311,29 @@ def pool__publish(*others, description=None):
|
|
300
311
|
console.log(f"[red]Problems with your pool: {str(e)}")
|
301
312
|
return
|
302
313
|
choices = select_token_type()
|
303
|
-
|
314
|
+
if choices["admin"]:
|
315
|
+
mode = TokenType.ADMIN
|
316
|
+
elif choices["user"]:
|
317
|
+
mode = TokenType.USER
|
318
|
+
else:
|
319
|
+
mode = TokenType.WORKER
|
304
320
|
|
305
321
|
if description is None:
|
306
322
|
console.log("[yellow] [Markdown] In a few words (max 500 chars), describe your goals with this cluster. Remember, this is what other users will see to decide whether to share their resources with you, [blue]so inspire them!")
|
307
|
-
description = input(f"(You can edit this later
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
console.log(f"[green]Your cluster is now
|
321
|
-
except Exception as e:
|
322
|
-
console.log(f"[red]Error when publishing cluster. {str(e)}")
|
323
|
+
description = input(f"(You can edit this later at {KALAVAI_PLATFORM_URL}\n")
|
324
|
+
cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
|
325
|
+
|
326
|
+
result = register_pool(
|
327
|
+
cluster_name=cluster_name,
|
328
|
+
token_mode=mode,
|
329
|
+
description=description,
|
330
|
+
is_private=is_private
|
331
|
+
)
|
332
|
+
|
333
|
+
if "error" in result:
|
334
|
+
console.log(f"[red]Error when publishing cluster: {result['error']}")
|
335
|
+
else:
|
336
|
+
console.log(f"[green]Your cluster is now registered with {KALAVAI_PLATFORM_URL}")
|
323
337
|
|
324
338
|
@arguably.command
|
325
339
|
def pool__unpublish(cluster_name=None, *others):
|
@@ -335,15 +349,13 @@ def pool__unpublish(cluster_name=None, *others):
|
|
335
349
|
console.log(f"[red]Problems with your pool: {str(e)}")
|
336
350
|
return
|
337
351
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
352
|
+
result = unregister_pool()
|
353
|
+
if "error" in result:
|
354
|
+
console.log(f"[red]{result['error']}")
|
355
|
+
elif "warning" in result:
|
356
|
+
console.log(f"[yellow]{result['warning']}")
|
357
|
+
else:
|
344
358
|
console.log(f"[green]Your cluster has been removed from {KALAVAI_PLATFORM_URL}")
|
345
|
-
except Exception as e:
|
346
|
-
console.log(f"[red]Error when unpublishing cluster. {str(e)}")
|
347
359
|
|
348
360
|
@arguably.command
|
349
361
|
def pool__list(*others, user_only=False):
|
@@ -411,6 +423,9 @@ def pool__start(cluster_name, *others, only_registered_users: bool=False, ip_ad
|
|
411
423
|
location=location
|
412
424
|
)
|
413
425
|
|
426
|
+
if "warning" in result:
|
427
|
+
console.log(f"[yellow]Warning: {result['warning']}")
|
428
|
+
|
414
429
|
if "error" in result:
|
415
430
|
console.log(f"[red]{result}")
|
416
431
|
|
@@ -520,38 +535,13 @@ def pool__stop(*others, skip_node_deletion=False):
|
|
520
535
|
*others: all the other positional arguments go here
|
521
536
|
"""
|
522
537
|
console.log("[white] Stopping kalavai app...")
|
523
|
-
# delete local node from server
|
524
|
-
if not skip_node_deletion:
|
525
|
-
node__delete(load_server_info(data_key=NODE_NAME_KEY, file=USER_LOCAL_SERVER_FILE))
|
526
|
-
# unpublish event (only if seed node)
|
527
|
-
# TODO: no, this should be done via the platform!!!
|
528
|
-
# try:
|
529
|
-
# if CLUSTER.is_seed_node():
|
530
|
-
# console.log("Unregistering pool...")
|
531
|
-
# unregister_cluster(
|
532
|
-
# name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
533
|
-
# user_cookie=USER_COOKIE)
|
534
|
-
# except Exception as e:
|
535
|
-
# console.log(f"[red][WARNING]: (ignore if not a public pool) Error when unpublishing cluster. {str(e)}")
|
536
|
-
# remove local node agent
|
537
|
-
console.log("Removing agent and local cache")
|
538
|
-
|
539
|
-
# disconnect from VPN first, then remove agent, then remove local files
|
540
|
-
console.log("Disconnecting from VPN...")
|
541
|
-
try:
|
542
|
-
vpns = leave_vpn(container_name=DEFAULT_VPN_CONTAINER_NAME)
|
543
|
-
if vpns is not None:
|
544
|
-
for vpn in vpns:
|
545
|
-
console.log(f"You have left {vpn} VPN")
|
546
|
-
except:
|
547
|
-
# no vpn
|
548
|
-
pass
|
549
538
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
539
|
+
result = stop_pool(skip_node_deletion=skip_node_deletion)
|
540
|
+
if "error" in result:
|
541
|
+
console.log(f"[red]{result['error']}")
|
542
|
+
else:
|
543
|
+
console.log(result)
|
544
|
+
console.log("[white] Kalavai has stopped sharing your resources. Use [yellow]kalavai pool start[white] or [yellow]kalavai pool join[white] to start again!")
|
555
545
|
|
556
546
|
@arguably.command
|
557
547
|
def pool__pause(*others):
|
@@ -1046,7 +1036,7 @@ def job__run(template_name, *others, values: str=None, force_namespace: str=None
|
|
1046
1036
|
console.log(f"[green]{template_name} job deployed")
|
1047
1037
|
|
1048
1038
|
@arguably.command
|
1049
|
-
def job__test(local_template_dir, *others, values,
|
1039
|
+
def job__test(local_template_dir, *others, values, force_namespace: str=None):
|
1050
1040
|
"""
|
1051
1041
|
Helper to test local templates, useful for development
|
1052
1042
|
"""
|
@@ -1056,13 +1046,18 @@ def job__test(local_template_dir, *others, values, defaults, force_namespace: st
|
|
1056
1046
|
console.log(f"[red]Problems with your pool: {str(e)}")
|
1057
1047
|
return
|
1058
1048
|
|
1059
|
-
if not os.path.
|
1060
|
-
console.log(f"[red]
|
1049
|
+
if not os.path.isfile(os.path.join(local_template_dir, "template.yaml")):
|
1050
|
+
console.log(f"[red]template.yaml not found under {local_template_dir}")
|
1051
|
+
return
|
1052
|
+
if not os.path.isfile(os.path.join(local_template_dir, "values.yaml")):
|
1053
|
+
console.log(f"[red]values.yaml not found under {local_template_dir}")
|
1061
1054
|
return
|
1062
1055
|
|
1063
1056
|
# load template
|
1064
1057
|
with open(os.path.join(local_template_dir, "template.yaml"), "r") as f:
|
1065
1058
|
template_str = f.read()
|
1059
|
+
with open(os.path.join(local_template_dir, "values.yaml"), "r") as f:
|
1060
|
+
defaults = f.read()
|
1066
1061
|
|
1067
1062
|
# load values
|
1068
1063
|
if not os.path.isfile(values):
|
@@ -1072,37 +1067,17 @@ def job__test(local_template_dir, *others, values, defaults, force_namespace: st
|
|
1072
1067
|
raw_values = yaml.load(f, Loader=yaml.SafeLoader)
|
1073
1068
|
values_dict = {variable["name"]: variable['value'] for variable in raw_values}
|
1074
1069
|
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
defaults = f.read()
|
1070
|
+
result = deploy_test_job(
|
1071
|
+
template_str=template_str,
|
1072
|
+
values_dict=values_dict,
|
1073
|
+
default_values=defaults,
|
1074
|
+
force_namespace=force_namespace)
|
1081
1075
|
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
"
|
1086
|
-
|
1087
|
-
}
|
1088
|
-
if force_namespace is not None:
|
1089
|
-
data["force_namespace"] = force_namespace
|
1090
|
-
|
1091
|
-
try:
|
1092
|
-
result = request_to_server(
|
1093
|
-
method="post",
|
1094
|
-
endpoint="/v1/deploy_custom_job",
|
1095
|
-
data=data,
|
1096
|
-
server_creds=USER_LOCAL_SERVER_FILE,
|
1097
|
-
user_cookie=USER_COOKIE
|
1098
|
-
)
|
1099
|
-
console.log("Deployment result:")
|
1100
|
-
print(
|
1101
|
-
json.dumps(result,indent=3)
|
1102
|
-
)
|
1103
|
-
except Exception as e:
|
1104
|
-
console.log(f"[red]Error when connecting to kalavai service: {str(e)}")
|
1105
|
-
|
1076
|
+
if "error" in result:
|
1077
|
+
console.log(f"[red]Error: {result['error']}")
|
1078
|
+
else:
|
1079
|
+
console.log("[green]Successfully deployed:")
|
1080
|
+
console.log(result)
|
1106
1081
|
|
1107
1082
|
@arguably.command
|
1108
1083
|
def job__defaults(template_name, *others):
|
@@ -1141,7 +1116,7 @@ def job__delete(name, *others, force_namespace: str=None):
|
|
1141
1116
|
# deploy template with kube-watcher
|
1142
1117
|
result = delete_job(name=name, force_namespace=force_namespace)
|
1143
1118
|
if "error" in result:
|
1144
|
-
console.log(f"[red]Error when deleting job: {
|
1119
|
+
console.log(f"[red]Error when deleting job: {result['error']}")
|
1145
1120
|
else:
|
1146
1121
|
console.log(f"{result}")
|
1147
1122
|
|
@@ -1273,19 +1248,19 @@ def job__logs(name, *others, pod_name=None, stream=False, tail=100, force_namesp
|
|
1273
1248
|
while True:
|
1274
1249
|
try:
|
1275
1250
|
if not stream:
|
1276
|
-
for pod,
|
1251
|
+
for pod, info in all_logs.items():
|
1277
1252
|
if pod_name is not None and pod_name != pod:
|
1278
1253
|
continue
|
1279
|
-
console.log(f"[yellow]Pod {pod}")
|
1280
|
-
console.log(f"[green]{logs}")
|
1254
|
+
console.log(f"[yellow]Pod {pod} in {info['pod']['spec']['node_name']}")
|
1255
|
+
console.log(f"[green]{info['logs']}")
|
1281
1256
|
break
|
1282
1257
|
else:
|
1283
1258
|
os.system("clear")
|
1284
|
-
for pod,
|
1259
|
+
for pod, info in all_logs.items():
|
1285
1260
|
if pod_name is not None and pod_name != pod:
|
1286
1261
|
continue
|
1287
|
-
print(f"Pod {pod}")
|
1288
|
-
print(f"{logs}")
|
1262
|
+
print(f"Pod {pod} in {info['pod']['spec']['node_name']}")
|
1263
|
+
print(f"{info['logs']}")
|
1289
1264
|
time.sleep(1)
|
1290
1265
|
except KeyboardInterrupt:
|
1291
1266
|
break
|
kalavai_client/core.py
CHANGED
@@ -9,15 +9,19 @@ import netifaces as ni
|
|
9
9
|
from typing import Optional
|
10
10
|
from pydantic import BaseModel
|
11
11
|
from enum import Enum
|
12
|
+
import re
|
12
13
|
|
13
14
|
from kalavai_client.cluster import CLUSTER
|
14
15
|
from kalavai_client.utils import (
|
15
16
|
check_gpu_drivers,
|
16
17
|
generate_join_token,
|
18
|
+
register_cluster,
|
17
19
|
request_to_server,
|
18
20
|
load_server_info,
|
19
21
|
decode_dict,
|
20
22
|
get_vpn_details,
|
23
|
+
send_pool_invite,
|
24
|
+
unregister_cluster,
|
21
25
|
validate_join_public_seed,
|
22
26
|
generate_compose_config,
|
23
27
|
store_server_info,
|
@@ -356,6 +360,29 @@ def deploy_job(template_name, values_dict, force_namespace=None):
|
|
356
360
|
except Exception as e:
|
357
361
|
return {"error": str(e)}
|
358
362
|
|
363
|
+
def deploy_test_job(template_str, values_dict, default_values, force_namespace=None):
|
364
|
+
|
365
|
+
# submit custom deployment
|
366
|
+
data = {
|
367
|
+
"template": template_str,
|
368
|
+
"template_values": values_dict,
|
369
|
+
"default_values": default_values
|
370
|
+
}
|
371
|
+
if force_namespace is not None:
|
372
|
+
data["force_namespace"] = force_namespace
|
373
|
+
|
374
|
+
try:
|
375
|
+
result = request_to_server(
|
376
|
+
method="post",
|
377
|
+
endpoint="/v1/deploy_custom_job",
|
378
|
+
data=data,
|
379
|
+
server_creds=USER_LOCAL_SERVER_FILE,
|
380
|
+
user_cookie=USER_COOKIE
|
381
|
+
)
|
382
|
+
return result
|
383
|
+
except Exception as e:
|
384
|
+
return {"error": str(e)}
|
385
|
+
|
359
386
|
def delete_job(name, force_namespace=None):
|
360
387
|
data = {
|
361
388
|
"label": TEMPLATE_LABEL, # this ensures that both lws template and services are deleted
|
@@ -419,7 +446,7 @@ def fetch_job_logs(job_name, force_namespace=None, pod_name=None, tail=100):
|
|
419
446
|
server_creds=USER_LOCAL_SERVER_FILE,
|
420
447
|
user_cookie=USER_COOKIE
|
421
448
|
)
|
422
|
-
return {pod:
|
449
|
+
return {pod: info for pod, info in all_logs.items() if pod_name is None or pod_name == pod}
|
423
450
|
|
424
451
|
except Exception as e:
|
425
452
|
return {"error": str(e)}
|
@@ -703,7 +730,7 @@ def join_pool(token, num_gpus=None, node_name=None, ip_address=None):
|
|
703
730
|
|
704
731
|
return cluster_name
|
705
732
|
|
706
|
-
def create_pool(cluster_name: str, ip_address: str, app_values: str=None, pool_config_values: str=None, num_gpus: int=0, node_name: str=None, only_registered_users: bool=False, location: str=None):
|
733
|
+
def create_pool(cluster_name: str, ip_address: str, description: str="", token_mode: TokenType=TokenType.USER, app_values: str=None, pool_config_values: str=None, num_gpus: int=0, node_name: str=None, only_registered_users: bool=False, location: str=None):
|
707
734
|
|
708
735
|
if not check_seed_compatibility():
|
709
736
|
return {"error": "Requirements failed"}
|
@@ -829,6 +856,18 @@ def create_pool(cluster_name: str, ip_address: str, app_values: str=None, pool_c
|
|
829
856
|
# init user namespace
|
830
857
|
init_user_workspace()
|
831
858
|
|
859
|
+
# register cluster (if user is logged in)
|
860
|
+
result = register_pool(
|
861
|
+
cluster_name=cluster_name,
|
862
|
+
description=description,
|
863
|
+
is_private=True,
|
864
|
+
token_mode=token_mode)
|
865
|
+
|
866
|
+
if "error" in result:
|
867
|
+
return {"warning": result["error"]}
|
868
|
+
if "warning" in result:
|
869
|
+
return {"warning": result["warning"]}
|
870
|
+
|
832
871
|
return {"success"}
|
833
872
|
|
834
873
|
def get_pool_token(mode: TokenType):
|
@@ -887,6 +926,33 @@ def pool_init(pool_config_values_path=None):
|
|
887
926
|
return result
|
888
927
|
except Exception as e:
|
889
928
|
return {"error": f"[red]Error when connecting to kalavai service: {str(e)}"}
|
929
|
+
|
930
|
+
def register_pool(cluster_name, description, is_private=True, token_mode=TokenType.USER):
|
931
|
+
token = get_pool_token(mode=token_mode)["token"]
|
932
|
+
valid = check_token(token=token, public=not is_private)
|
933
|
+
if "error" in valid:
|
934
|
+
return {"error": valid}
|
935
|
+
try:
|
936
|
+
result = register_cluster(
|
937
|
+
name=cluster_name,
|
938
|
+
token=token,
|
939
|
+
description=description,
|
940
|
+
user_cookie=USER_COOKIE,
|
941
|
+
is_private=is_private)
|
942
|
+
|
943
|
+
return {"success": result}
|
944
|
+
except Exception as e:
|
945
|
+
return {"warning": str(e)}
|
946
|
+
|
947
|
+
def unregister_pool():
|
948
|
+
cluster_name = load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE)
|
949
|
+
try:
|
950
|
+
unregister_cluster(
|
951
|
+
name=cluster_name,
|
952
|
+
user_cookie=USER_COOKIE)
|
953
|
+
except Exception as e:
|
954
|
+
return {"warning": str(e)}
|
955
|
+
return {"success"}
|
890
956
|
|
891
957
|
def is_connected():
|
892
958
|
if not os.path.isfile(USER_LOCAL_SERVER_FILE):
|
@@ -957,16 +1023,8 @@ def stop_pool(skip_node_deletion=False):
|
|
957
1023
|
delete_node(load_server_info(data_key=NODE_NAME_KEY, file=USER_LOCAL_SERVER_FILE))
|
958
1024
|
)
|
959
1025
|
# unpublish event (only if seed node)
|
960
|
-
|
961
|
-
|
962
|
-
# if CLUSTER.is_seed_node():
|
963
|
-
# console.log("Unregistering pool...")
|
964
|
-
# unregister_cluster(
|
965
|
-
# name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
966
|
-
# user_cookie=USER_COOKIE)
|
967
|
-
# except Exception as e:
|
968
|
-
# console.log(f"[red][WARNING]: (ignore if not a public pool) Error when unpublishing cluster. {str(e)}")
|
969
|
-
# remove local node agent
|
1026
|
+
if CLUSTER.is_seed_node():
|
1027
|
+
unregister_pool()
|
970
1028
|
|
971
1029
|
# disconnect from VPN first, then remove agent, then remove local files
|
972
1030
|
try:
|
@@ -978,13 +1036,22 @@ def stop_pool(skip_node_deletion=False):
|
|
978
1036
|
# no vpn
|
979
1037
|
pass
|
980
1038
|
|
1039
|
+
# remove local node agent
|
981
1040
|
CLUSTER.remove_agent()
|
982
1041
|
|
983
1042
|
# clean local files
|
984
1043
|
cleanup_local()
|
985
1044
|
|
986
|
-
return logs
|
1045
|
+
return {"logs": logs}
|
987
1046
|
|
988
1047
|
def list_available_pools(user_only=False):
|
989
1048
|
pools = get_public_seeds(user_only=user_only, user_cookie=USER_COOKIE)
|
990
|
-
return pools
|
1049
|
+
return pools
|
1050
|
+
|
1051
|
+
def send_invites(invitees):
|
1052
|
+
result = send_pool_invite(
|
1053
|
+
cluster_name=load_server_info(data_key=CLUSTER_NAME_KEY, file=USER_LOCAL_SERVER_FILE),
|
1054
|
+
invitee_addresses=invitees,
|
1055
|
+
user_cookie=USER_COOKIE
|
1056
|
+
)
|
1057
|
+
return result
|
kalavai_client/utils.py
CHANGED
@@ -206,7 +206,7 @@ def get_vpn_details(location, user_cookie):
|
|
206
206
|
)
|
207
207
|
return vpn
|
208
208
|
|
209
|
-
def register_cluster(name, token, description, user_cookie):
|
209
|
+
def register_cluster(name, token, description, user_cookie, is_private=True):
|
210
210
|
auth = KalavaiAuthClient(
|
211
211
|
user_cookie_file=user_cookie
|
212
212
|
)
|
@@ -218,7 +218,8 @@ def register_cluster(name, token, description, user_cookie):
|
|
218
218
|
name,
|
219
219
|
user,
|
220
220
|
description,
|
221
|
-
token
|
221
|
+
token,
|
222
|
+
is_private
|
222
223
|
)
|
223
224
|
return seed
|
224
225
|
|
@@ -251,6 +252,21 @@ def validate_join_public_seed(cluster_name, join_key, user_cookie):
|
|
251
252
|
)
|
252
253
|
return seed
|
253
254
|
|
255
|
+
def send_pool_invite(cluster_name, invitee_addresses, user_cookie):
|
256
|
+
auth = KalavaiAuthClient(
|
257
|
+
user_cookie_file=user_cookie
|
258
|
+
)
|
259
|
+
if not auth.is_logged_in():
|
260
|
+
raise ValueError("Cannot notify join cluster, user is not authenticated")
|
261
|
+
user = auth.load_user_session()
|
262
|
+
result = auth.call_function(
|
263
|
+
"send_pool_invite",
|
264
|
+
user,
|
265
|
+
cluster_name,
|
266
|
+
invitee_addresses
|
267
|
+
)
|
268
|
+
return result
|
269
|
+
|
254
270
|
def validate_poolconfig(poolconfig_file):
|
255
271
|
if not Path(poolconfig_file).is_file():
|
256
272
|
return False
|
@@ -1,9 +1,9 @@
|
|
1
|
-
kalavai_client/__init__.py,sha256=
|
1
|
+
kalavai_client/__init__.py,sha256=cT1oeGgH8MJStuRZQWhfuhB2_qJUuu6VbZGyOgIiFOo,23
|
2
2
|
kalavai_client/__main__.py,sha256=WQUfxvRsBJH5gsCJg8pLz95QnZIj7Ol8psTO77m0QE0,73
|
3
3
|
kalavai_client/assets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
-
kalavai_client/assets/apps.yaml,sha256=
|
4
|
+
kalavai_client/assets/apps.yaml,sha256=FnKRSGnFFQ6zbe5BT5nck_WdM62bATRSyZA3IPCpMG0,5982
|
5
5
|
kalavai_client/assets/apps_values.yaml,sha256=CjKVelPQHd-hm-DTMEuya92feKiphU9mh3HrosLYYPE,1676
|
6
|
-
kalavai_client/assets/docker-compose-gui.yaml,sha256=
|
6
|
+
kalavai_client/assets/docker-compose-gui.yaml,sha256=6OHZIDDTl_PwXSYo1d05JasWfT0iiUDhrja0nQDjrlw,692
|
7
7
|
kalavai_client/assets/docker-compose-template.yaml,sha256=ii24Nn-dM5cZk9lxFgrzxnmK7yv_6kIIw7KUlWhvYeI,2831
|
8
8
|
kalavai_client/assets/nginx.conf,sha256=drVVCg8GHucz7hmt_BI6giAhK92OV71257NTs3LthwM,225
|
9
9
|
kalavai_client/assets/pool_config_template.yaml,sha256=fFz4w2-fMKD5KvyzFdfcWD_jSneRlmnjLc8hCctweX0,576
|
@@ -11,15 +11,15 @@ kalavai_client/assets/pool_config_values.yaml,sha256=VrM3XHQfQo6QLZ68qvagooUptaY
|
|
11
11
|
kalavai_client/assets/user_workspace.yaml,sha256=wDvlMYknOPABAEo0dsQwU7bac8iubjAG9tdkFbJZ5Go,476
|
12
12
|
kalavai_client/assets/user_workspace_values.yaml,sha256=G0HOzQUxrDMCwuW9kbWUZaKMzDDPVwDwzBHCL2Xi2ZM,542
|
13
13
|
kalavai_client/auth.py,sha256=QsBh28L2LwjBBK6pTUE4Xu36lLDTyetyU1YfS1Hbb6g,1717
|
14
|
-
kalavai_client/bridge_api.py,sha256=
|
15
|
-
kalavai_client/bridge_models.py,sha256=
|
16
|
-
kalavai_client/cli.py,sha256=
|
14
|
+
kalavai_client/bridge_api.py,sha256=rXTz6WpzQtsDmBDUUOqPEjWx8vfiIWEfvP1iM4MYDGM,5501
|
15
|
+
kalavai_client/bridge_models.py,sha256=WwGIaWBIk4s32YemgDB2CcrrCWC-KeZjTT3iBi-kaa0,936
|
16
|
+
kalavai_client/cli.py,sha256=88xJq0fBpvfb863UXWTRF0vUVtY0nNx-SxYd1_cHijs,46713
|
17
17
|
kalavai_client/cluster.py,sha256=gwjmdsd--YrffT0BmZDOEpbrdm3lPskUuN5jdgcrOR0,12947
|
18
|
-
kalavai_client/core.py,sha256=
|
18
|
+
kalavai_client/core.py,sha256=Iq2MRUwEOfOCQ2RZDZIkyAaboLWS5LooZmpyGRrwBiE,32954
|
19
19
|
kalavai_client/env.py,sha256=Zg2pP-xGJpQumo56KMBxBLgIsBmcNN0S9R-ZP2-s630,2604
|
20
|
-
kalavai_client/utils.py,sha256=
|
21
|
-
kalavai_client-0.5.
|
22
|
-
kalavai_client-0.5.
|
23
|
-
kalavai_client-0.5.
|
24
|
-
kalavai_client-0.5.
|
25
|
-
kalavai_client-0.5.
|
20
|
+
kalavai_client/utils.py,sha256=OPmrsycNyrs2ZpTsjAzBuPN8hQNJtsYDLPKU13tnf-U,13862
|
21
|
+
kalavai_client-0.5.28.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
22
|
+
kalavai_client-0.5.28.dist-info/METADATA,sha256=jhK6wpLjQ1ezEFZB-X-kWGgFRVTmsOt4v4CQe6hKetk,14443
|
23
|
+
kalavai_client-0.5.28.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
24
|
+
kalavai_client-0.5.28.dist-info/entry_points.txt,sha256=9T6D45gxwzfVbglMm1r6XPdXuuZdHfy_7fCeu2jUphc,50
|
25
|
+
kalavai_client-0.5.28.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|