primitive 0.1.62__py3-none-any.whl → 0.1.63__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.
- primitive/__about__.py +1 -1
- primitive/agent/actions.py +12 -1
- primitive/client.py +13 -10
- primitive/exec/actions.py +7 -28
- primitive/hardware/actions.py +2 -15
- primitive/hardware/graphql/fragments.py +2 -0
- primitive/hardware/graphql/queries.py +0 -10
- primitive/provisioning/__init__.py +0 -0
- primitive/provisioning/actions.py +62 -0
- primitive/provisioning/graphql/__init__.py +0 -0
- primitive/provisioning/graphql/queries.py +5 -0
- primitive/reservations/graphql/fragments.py +1 -1
- {primitive-0.1.62.dist-info → primitive-0.1.63.dist-info}/METADATA +2 -3
- {primitive-0.1.62.dist-info → primitive-0.1.63.dist-info}/RECORD +17 -13
- {primitive-0.1.62.dist-info → primitive-0.1.63.dist-info}/WHEEL +1 -1
- {primitive-0.1.62.dist-info → primitive-0.1.63.dist-info}/entry_points.txt +0 -0
- {primitive-0.1.62.dist-info → primitive-0.1.63.dist-info}/licenses/LICENSE.txt +0 -0
primitive/__about__.py
CHANGED
primitive/agent/actions.py
CHANGED
@@ -20,7 +20,7 @@ class Agent(BaseAction):
|
|
20
20
|
logger.info(" [*] primitive")
|
21
21
|
logger.info(f" [*] Version: {__version__}")
|
22
22
|
|
23
|
-
# Create cache dir if it
|
23
|
+
# Create cache dir if it doesn't exist
|
24
24
|
cache_dir = get_sources_cache()
|
25
25
|
|
26
26
|
# Create uploader
|
@@ -53,6 +53,11 @@ class Agent(BaseAction):
|
|
53
53
|
logger.debug("Active Reservation:")
|
54
54
|
logger.debug(f"Node ID: {active_reservation_id}")
|
55
55
|
logger.debug(f"PK: {active_reservation_pk}")
|
56
|
+
|
57
|
+
logger.debug("Running pre provisioning steps for reservation.")
|
58
|
+
self.primitive.provisioning.add_reservation_authorized_keys(
|
59
|
+
reservation_id=active_reservation_id
|
60
|
+
)
|
56
61
|
else:
|
57
62
|
if (
|
58
63
|
hardware["activeReservation"] is None
|
@@ -62,6 +67,12 @@ class Agent(BaseAction):
|
|
62
67
|
logger.debug("Previous Reservation is Complete:")
|
63
68
|
logger.debug(f"Node ID: {active_reservation_id}")
|
64
69
|
logger.debug(f"PK: {active_reservation_pk}")
|
70
|
+
logger.debug(
|
71
|
+
"Running cleanup provisioning steps for reservation."
|
72
|
+
)
|
73
|
+
self.primitive.provisioning.remove_reservation_authorized_keys(
|
74
|
+
reservation_id=active_reservation_id
|
75
|
+
)
|
65
76
|
active_reservation_id = None
|
66
77
|
active_reservation_pk = None
|
67
78
|
|
primitive/client.py
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
import sys
|
2
|
+
|
3
|
+
from loguru import logger
|
4
|
+
|
5
|
+
from .agent.actions import Agent
|
2
6
|
from .auth.actions import Auth
|
3
|
-
from .
|
4
|
-
from .
|
7
|
+
from .daemons.actions import Daemons
|
8
|
+
from .exec.actions import Exec
|
5
9
|
from .files.actions import Files
|
6
|
-
from .sim.actions import Sim
|
7
|
-
from .hardware.actions import Hardware
|
8
|
-
from .lint.actions import Lint
|
9
|
-
from .agent.actions import Agent
|
10
10
|
from .git.actions import Git
|
11
|
-
from .
|
11
|
+
from .hardware.actions import Hardware
|
12
12
|
from .jobs.actions import Jobs
|
13
|
+
from .lint.actions import Lint
|
13
14
|
from .organizations.actions import Organizations
|
14
|
-
from .
|
15
|
+
from .projects.actions import Projects
|
16
|
+
from .provisioning.actions import Provisioning
|
15
17
|
from .reservations.actions import Reservations
|
16
|
-
|
17
|
-
from
|
18
|
+
from .sim.actions import Sim
|
19
|
+
from .utils.config import read_config_file
|
18
20
|
|
19
21
|
logger.disable("primitive")
|
20
22
|
|
@@ -67,6 +69,7 @@ class Primitive:
|
|
67
69
|
self.git: Git = Git(self)
|
68
70
|
self.daemons: Daemons = Daemons(self)
|
69
71
|
self.exec: Exec = Exec(self)
|
72
|
+
self.provisioning: Provisioning = Provisioning(self)
|
70
73
|
|
71
74
|
def get_host_config(self):
|
72
75
|
self.full_config = read_config_file()
|
primitive/exec/actions.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import tempfile
|
2
1
|
import typing
|
3
2
|
|
4
3
|
from primitive.exec.interactive import interactive_shell
|
@@ -46,34 +45,16 @@ class Exec(BaseAction):
|
|
46
45
|
reservation_id=reservation["id"], desired_status="in_progress"
|
47
46
|
)
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
)
|
52
|
-
|
53
|
-
ssh_hostname = ssh_credentials["ssh_hostname"]
|
54
|
-
ssh_username = ssh_credentials["ssh_username"]
|
55
|
-
ssh_password = ssh_credentials["ssh_password"]
|
56
|
-
ssh_private_key = ssh_credentials["ssh_private_key"]
|
48
|
+
ssh_hostname = hardware["hostname"]
|
49
|
+
ssh_username = hardware["ssh_username"]
|
57
50
|
|
58
51
|
ssh_client = SSHClient()
|
59
52
|
ssh_client.load_system_host_keys()
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
ssh_client.connect(
|
66
|
-
hostname=ssh_hostname,
|
67
|
-
username=ssh_username,
|
68
|
-
key_filename=keyfile.name,
|
69
|
-
)
|
70
|
-
else:
|
71
|
-
ssh_client.connect(
|
72
|
-
hostname=ssh_hostname,
|
73
|
-
username=ssh_username,
|
74
|
-
pkey=ssh_private_key,
|
75
|
-
password=ssh_password,
|
76
|
-
)
|
53
|
+
|
54
|
+
ssh_client.connect(
|
55
|
+
hostname=ssh_hostname,
|
56
|
+
username=ssh_username,
|
57
|
+
)
|
77
58
|
|
78
59
|
if command:
|
79
60
|
formatted_command = " ".join(command)
|
@@ -86,8 +67,6 @@ class Exec(BaseAction):
|
|
86
67
|
channel.invoke_shell()
|
87
68
|
interactive_shell(channel)
|
88
69
|
ssh_client.close()
|
89
|
-
if keyfile:
|
90
|
-
keyfile.close()
|
91
70
|
|
92
71
|
if created_reservation_on_behalf_of_user:
|
93
72
|
print("Cleaning up reservation.")
|
primitive/hardware/actions.py
CHANGED
@@ -22,7 +22,7 @@ from .graphql.mutations import (
|
|
22
22
|
hardware_update_mutation,
|
23
23
|
register_hardware_mutation,
|
24
24
|
)
|
25
|
-
from .graphql.queries import hardware_list
|
25
|
+
from .graphql.queries import hardware_list
|
26
26
|
|
27
27
|
if typing.TYPE_CHECKING:
|
28
28
|
pass
|
@@ -303,7 +303,7 @@ class Hardware(BaseAction):
|
|
303
303
|
# and headers are set correctly
|
304
304
|
self.primitive.get_host_config()
|
305
305
|
self.check_in_http(is_healthy=True)
|
306
|
-
return
|
306
|
+
return result
|
307
307
|
|
308
308
|
@guard
|
309
309
|
def update_hardware_system_info(self):
|
@@ -479,16 +479,3 @@ class Hardware(BaseAction):
|
|
479
479
|
raise Exception(f"No hardware found with slug {hardware_identifier}")
|
480
480
|
|
481
481
|
return hardware
|
482
|
-
|
483
|
-
@guard
|
484
|
-
def get_hardware_ssh_credentials(self, hardware_id: str):
|
485
|
-
query = gql(hardware_ssh_credentials)
|
486
|
-
|
487
|
-
variables = {
|
488
|
-
"id": hardware_id,
|
489
|
-
}
|
490
|
-
result = self.primitive.session.execute(
|
491
|
-
query, variable_values=variables, get_execution_result=True
|
492
|
-
)
|
493
|
-
ssh_credentials = result.data.get("hardware").get("sshCredentials")
|
494
|
-
return ssh_credentials
|
File without changes
|
@@ -0,0 +1,62 @@
|
|
1
|
+
from pathlib import Path
|
2
|
+
|
3
|
+
from gql import gql
|
4
|
+
|
5
|
+
from primitive.utils.actions import BaseAction
|
6
|
+
|
7
|
+
from ..utils.auth import guard
|
8
|
+
from .graphql.queries import authorized_keys_query
|
9
|
+
|
10
|
+
HOME_DIRECTORY = Path.home()
|
11
|
+
AUTHORIZED_KEYS_FILEPATH = Path(HOME_DIRECTORY / ".ssh" / "authorized_keys")
|
12
|
+
|
13
|
+
|
14
|
+
class Provisioning(BaseAction):
|
15
|
+
@guard
|
16
|
+
def get_authorized_keys(self, reservation_id: str) -> str:
|
17
|
+
variables = {
|
18
|
+
"reservationId": reservation_id,
|
19
|
+
}
|
20
|
+
query = gql(authorized_keys_query)
|
21
|
+
result = self.primitive.session.execute(
|
22
|
+
query, variable_values=variables, get_execution_result=True
|
23
|
+
)
|
24
|
+
return result.data["authorizedKeys"]
|
25
|
+
|
26
|
+
def add_reservation_authorized_keys(self, reservation_id: str) -> None:
|
27
|
+
AUTHORIZED_KEYS_BACKUP_FILEPATH = Path(
|
28
|
+
HOME_DIRECTORY / ".ssh" / f"authorized_keys.bak-{reservation_id}"
|
29
|
+
)
|
30
|
+
|
31
|
+
if AUTHORIZED_KEYS_FILEPATH.exists():
|
32
|
+
AUTHORIZED_KEYS_BACKUP_FILEPATH.write_text(
|
33
|
+
AUTHORIZED_KEYS_FILEPATH.read_text()
|
34
|
+
)
|
35
|
+
else:
|
36
|
+
AUTHORIZED_KEYS_FILEPATH.touch()
|
37
|
+
|
38
|
+
authorized_keys = self.get_authorized_keys(reservation_id=reservation_id)
|
39
|
+
|
40
|
+
AUTHORIZED_KEYS_FILEPATH.write_text(
|
41
|
+
AUTHORIZED_KEYS_FILEPATH.read_text()
|
42
|
+
+ f"\n## START PRIMITIVE SSH PUBLIC KEYS FOR RESERVATION ID {reservation_id}\n"
|
43
|
+
+ authorized_keys
|
44
|
+
+ f"\n## END PRIMITIVE SSH PUBLIC KEYS FOR RESERVATION ID {reservation_id}\n"
|
45
|
+
)
|
46
|
+
|
47
|
+
# self.primitive.sshd.reload()
|
48
|
+
|
49
|
+
def remove_reservation_authorized_keys(self, reservation_id: str) -> None:
|
50
|
+
AUTHORIZED_KEYS_BACKUP_FILEPATH = Path(
|
51
|
+
HOME_DIRECTORY / ".ssh" / f"authorized_keys.bak-{reservation_id}"
|
52
|
+
)
|
53
|
+
|
54
|
+
if AUTHORIZED_KEYS_BACKUP_FILEPATH.exists():
|
55
|
+
AUTHORIZED_KEYS_FILEPATH.write_text(
|
56
|
+
AUTHORIZED_KEYS_BACKUP_FILEPATH.read_text()
|
57
|
+
)
|
58
|
+
AUTHORIZED_KEYS_BACKUP_FILEPATH.unlink()
|
59
|
+
else:
|
60
|
+
AUTHORIZED_KEYS_FILEPATH.unlink()
|
61
|
+
|
62
|
+
# self.primitive.sshd.reload()
|
File without changes
|
@@ -1,12 +1,11 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: primitive
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.63
|
4
4
|
Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
|
5
5
|
Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
|
6
6
|
Project-URL: Source, https://github.com//primitivecorp/primitive-cli
|
7
7
|
Author-email: Dylan Stein <dylan@primitive.tech>, Chase Zimmerman <chase@primitive.tech>
|
8
|
-
License
|
9
|
-
License-File: LICENSE.txt
|
8
|
+
License: MIT
|
10
9
|
Classifier: Development Status :: 4 - Beta
|
11
10
|
Classifier: Programming Language :: Python
|
12
11
|
Classifier: Programming Language :: Python :: 3
|
@@ -1,9 +1,9 @@
|
|
1
|
-
primitive/__about__.py,sha256=
|
1
|
+
primitive/__about__.py,sha256=uiVaG3uarbeydunpM548F3cr2wnnZhtxTkRYjlZVUoU,130
|
2
2
|
primitive/__init__.py,sha256=bwKdgggKNVssJFVPfKSxqFMz4IxSr54WWbmiZqTMPNI,106
|
3
3
|
primitive/cli.py,sha256=CGmWiqqCLMHtHGOUPuf3tVO6VvChBZ1VdSwCCglnBgA,2582
|
4
|
-
primitive/client.py,sha256=
|
4
|
+
primitive/client.py,sha256=P7cCDperMu3pxlmRAP-H2owM-cj1kRlZWrqujxnWa4o,2473
|
5
5
|
primitive/agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
primitive/agent/actions.py,sha256=
|
6
|
+
primitive/agent/actions.py,sha256=Hosy2o2FntfBtcNqqHuMFq9dm99EVfySy0v2JGeufvc,6474
|
7
7
|
primitive/agent/commands.py,sha256=-dVDilELfkGfbZB7qfEPs77Dm1oT62qJj4tsIk4KoxI,254
|
8
8
|
primitive/agent/process.py,sha256=LVI-RB4a0YEuXUTYMXKL5Xi9euNwUI2nxj00mv8EFOg,2253
|
9
9
|
primitive/agent/provision.py,sha256=rmwnro1K5F8mwtd45XAq7RVQmpDWnbBCQ8X_qgWhm3M,1546
|
@@ -20,7 +20,7 @@ primitive/daemons/commands.py,sha256=-Muh-6ib4uAVtPn_67AcMrDwuCwYlCnRQozCi2Xurmk
|
|
20
20
|
primitive/daemons/launch_agents.py,sha256=qovt32gwpjGDd82z_SY5EGCUjaUyNA49pZFajZsw3eE,4796
|
21
21
|
primitive/daemons/launch_service.py,sha256=FPB9qKEjhllRfEpct0ng2L9lpIaGJbQwn1JdFT8uBA8,5600
|
22
22
|
primitive/exec/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
|
-
primitive/exec/actions.py,sha256=
|
23
|
+
primitive/exec/actions.py,sha256=hgUYi_G69SPbMRpVZv8EjeqIy41apXZIIw9lcg37zAY,2633
|
24
24
|
primitive/exec/commands.py,sha256=66LO2kkJC-ynNZQpUCXv4Ol15QoacdSZAHblePDcmLo,510
|
25
25
|
primitive/exec/interactive.py,sha256=TscY6s2ZysijidKPheq6y-fCErUVLS0zcdTW8XyFWGI,2435
|
26
26
|
primitive/files/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -38,12 +38,12 @@ primitive/graphql/relay.py,sha256=bmij2AjdpURQ6GGVCxwWhauF-r_SxuAU2oJ4sDbLxpI,72
|
|
38
38
|
primitive/graphql/sdk.py,sha256=BhCGmDtc4sNnH8CxbQSJyFwOZ-ZSqMtjsxMB3JRBhPw,1456
|
39
39
|
primitive/graphql/utility_fragments.py,sha256=uIjwILC4QtWNyO5vu77VjQf_p0jvP3A9q_6zRq91zqs,303
|
40
40
|
primitive/hardware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
41
|
-
primitive/hardware/actions.py,sha256=
|
41
|
+
primitive/hardware/actions.py,sha256=jtthNgRyeRD8txt4WqEZskPtsDWU2Yg2gJZLSrEx1io,18603
|
42
42
|
primitive/hardware/commands.py,sha256=_HaWOdRQSkhnA1xZZHZWgadSQ9Gijxtnzg2vc_IDSMA,1854
|
43
43
|
primitive/hardware/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
|
-
primitive/hardware/graphql/fragments.py,sha256=
|
44
|
+
primitive/hardware/graphql/fragments.py,sha256=PuqhW42fKUvRqOli5W7nOs2RfJ8FruSQC1gKBp3psBQ,271
|
45
45
|
primitive/hardware/graphql/mutations.py,sha256=Zd6HxnIgTJ9mJQAfKJkdeDfstcPAal6Bj38pnKb_RuI,904
|
46
|
-
primitive/hardware/graphql/queries.py,sha256=
|
46
|
+
primitive/hardware/graphql/queries.py,sha256=dhihQwr4O7zxDNRjeNWhkAXaSDOBsK-uqIczEGy1XLI,430
|
47
47
|
primitive/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
48
48
|
primitive/jobs/actions.py,sha256=CtyO-Z9614TgIoXJJX1QGsoll0fgpBIjG9PJH5JwCQs,4901
|
49
49
|
primitive/jobs/commands.py,sha256=MxPCkBEYW_eLNqgCRYeyj7ZcLOFAWfpVZlqDR2Y_S0o,830
|
@@ -68,11 +68,15 @@ primitive/projects/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
68
68
|
primitive/projects/graphql/fragments.py,sha256=02F5nyI8i-ML_bV5FFHUgFWM5bBBfjmz_tkP-4QOXjU,127
|
69
69
|
primitive/projects/graphql/mutations.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
70
70
|
primitive/projects/graphql/queries.py,sha256=nFaVf6YOHA2L_FTgIUdRK-80hYTmv1a1X5ac7QPMp1k,646
|
71
|
+
primitive/provisioning/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
|
+
primitive/provisioning/actions.py,sha256=IYZYAbtomtZtlkqDaBxx4e7PFKGkRNqek_tABH6q_zY,2116
|
73
|
+
primitive/provisioning/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
74
|
+
primitive/provisioning/graphql/queries.py,sha256=cBtuKa6shoatYZfKSnQoPJP6B8g8y3QhFqJ_pkvMcG0,134
|
71
75
|
primitive/reservations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
76
|
primitive/reservations/actions.py,sha256=XjjF0UJAgKryuSJqakLMAWshZIbuM-DkTmdU95cANs4,4434
|
73
77
|
primitive/reservations/commands.py,sha256=OwWWE9DrvtrVBcBki0bKTOqCzCQk090c0rPIAt89JLY,2243
|
74
78
|
primitive/reservations/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
|
-
primitive/reservations/graphql/fragments.py,sha256=
|
79
|
+
primitive/reservations/graphql/fragments.py,sha256=_TQfJeHky-Hh3WCHWobQ6-A1lpSvU-YkS0V9cqj2nOU,476
|
76
80
|
primitive/reservations/graphql/mutations.py,sha256=IqzwQL7OclN7RpIcidrTQo9cGYofY7wqoBOdnY0pwN8,651
|
77
81
|
primitive/reservations/graphql/queries.py,sha256=x31wTRelskX2fc0fx2qrY7XT1q74nvzLv_Xef3o9weg,746
|
78
82
|
primitive/sim/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -89,8 +93,8 @@ primitive/utils/memory_size.py,sha256=4xfha21kW82nFvOTtDFx9Jk2ZQoEhkfXii-PGNTpIU
|
|
89
93
|
primitive/utils/printer.py,sha256=f1XUpqi5dkTL3GWvYRUGlSwtj2IxU1q745T4Fxo7Tn4,370
|
90
94
|
primitive/utils/shell.py,sha256=j7E1YwgNWw57dFHVfEbqRNVcPHX0xDefX2vFSNgeI_8,1648
|
91
95
|
primitive/utils/verible.py,sha256=Zb5NUISvcaIgEvgCDBWr-GCoceMa79Tcwvr5Wl9lfnA,2252
|
92
|
-
primitive-0.1.
|
93
|
-
primitive-0.1.
|
94
|
-
primitive-0.1.
|
95
|
-
primitive-0.1.
|
96
|
-
primitive-0.1.
|
96
|
+
primitive-0.1.63.dist-info/METADATA,sha256=o-IZgpjA7lYJYn-sxuRBDA4EXxHA_c57G1U8Q3dcZzE,3774
|
97
|
+
primitive-0.1.63.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
|
98
|
+
primitive-0.1.63.dist-info/entry_points.txt,sha256=p1K8DMCWka5FqLlqP1sPek5Uovy9jq8u51gUsP-z334,48
|
99
|
+
primitive-0.1.63.dist-info/licenses/LICENSE.txt,sha256=B8kmQMJ2sxYygjCLBk770uacaMci4mPSoJJ8WoDBY_c,1098
|
100
|
+
primitive-0.1.63.dist-info/RECORD,,
|
File without changes
|
File without changes
|