primitive 0.2.22__py3-none-any.whl → 0.2.26__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/hardware/commands.py +20 -4
- primitive/monitor/actions.py +35 -14
- primitive/monitor/commands.py +6 -4
- primitive/organizations/actions.py +28 -0
- {primitive-0.2.22.dist-info → primitive-0.2.26.dist-info}/METADATA +1 -2
- {primitive-0.2.22.dist-info → primitive-0.2.26.dist-info}/RECORD +10 -10
- {primitive-0.2.22.dist-info → primitive-0.2.26.dist-info}/WHEEL +0 -0
- {primitive-0.2.22.dist-info → primitive-0.2.26.dist-info}/entry_points.txt +0 -0
- {primitive-0.2.22.dist-info → primitive-0.2.26.dist-info}/licenses/LICENSE.txt +0 -0
primitive/__about__.py
CHANGED
primitive/hardware/commands.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
import
|
1
|
+
from typing import TYPE_CHECKING, Optional
|
2
2
|
|
3
3
|
import click
|
4
4
|
|
5
5
|
from ..utils.printer import print_result
|
6
6
|
from .ui import render_hardware_table
|
7
7
|
|
8
|
-
if
|
8
|
+
if TYPE_CHECKING:
|
9
9
|
from ..client import Primitive
|
10
10
|
|
11
|
+
from loguru import logger
|
12
|
+
|
11
13
|
|
12
14
|
@click.group()
|
13
15
|
@click.pass_context
|
@@ -26,11 +28,25 @@ def systeminfo_command(context):
|
|
26
28
|
|
27
29
|
|
28
30
|
@cli.command("register")
|
31
|
+
@click.option(
|
32
|
+
"--organization",
|
33
|
+
type=str,
|
34
|
+
help="Organization [slug] to register hardware with",
|
35
|
+
)
|
29
36
|
@click.pass_context
|
30
|
-
def register_command(context):
|
37
|
+
def register_command(context, organization: Optional[str] = None):
|
31
38
|
"""Register Hardware with Primitive"""
|
32
39
|
primitive: Primitive = context.obj.get("PRIMITIVE")
|
33
|
-
|
40
|
+
|
41
|
+
organization_id = None
|
42
|
+
if organization:
|
43
|
+
organization_data = primitive.organizations.get_organization(slug=organization)
|
44
|
+
organization_id = organization_data.get("id")
|
45
|
+
|
46
|
+
if not organization_id:
|
47
|
+
logger.info("Registering hardware with the default organization.")
|
48
|
+
|
49
|
+
result = primitive.hardware.register(organization_id=organization_id)
|
34
50
|
color = "green" if result else "red"
|
35
51
|
if result.data.get("registerHardware"):
|
36
52
|
message = "Hardware registered successfully"
|
primitive/monitor/actions.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import sys
|
2
2
|
from time import sleep
|
3
|
+
from typing import Optional
|
3
4
|
|
4
5
|
import psutil
|
5
6
|
from loguru import logger
|
@@ -12,7 +13,7 @@ from primitive.utils.exceptions import P_CLI_100
|
|
12
13
|
|
13
14
|
|
14
15
|
class Monitor(BaseAction):
|
15
|
-
def start(self):
|
16
|
+
def start(self, job_run_id: Optional[str] = None):
|
16
17
|
logger.remove()
|
17
18
|
logger.add(
|
18
19
|
sink=sys.stderr,
|
@@ -24,21 +25,33 @@ class Monitor(BaseAction):
|
|
24
25
|
logger.info("[*] primitive monitor")
|
25
26
|
logger.info(f"[*] Version: {__version__}")
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
28
|
+
# TODO: tighten logic for determining if we're running in a container
|
29
|
+
RUNNING_IN_CONTAINER = False
|
30
|
+
if job_run_id is not None:
|
31
|
+
logger.info("[*] Running in container...")
|
32
|
+
RUNNING_IN_CONTAINER = True
|
33
|
+
|
34
|
+
# can't check if if it is a container
|
35
|
+
if not RUNNING_IN_CONTAINER:
|
36
|
+
try:
|
37
|
+
# hey stupid:
|
38
|
+
# do not set is_available to True here, it will mess up the reservation logic
|
39
|
+
# only set is_available after we've checked that no active reservation is present
|
40
|
+
# setting is_available of the parent also effects the children,
|
41
|
+
# which may have active reservations as well
|
42
|
+
self.primitive.hardware.check_in_http(is_online=True)
|
43
|
+
except Exception as exception:
|
44
|
+
logger.exception(f"Error checking in hardware: {exception}")
|
45
|
+
sys.exit(1)
|
37
46
|
|
38
47
|
# Initialize the database
|
39
48
|
sqlite.init()
|
40
49
|
|
41
50
|
try:
|
51
|
+
if job_run_id is not None:
|
52
|
+
JobRun.objects.create(job_run_id=job_run_id, pid=None)
|
53
|
+
logger.debug(f"Creating job run in database: {job_run_id}")
|
54
|
+
|
42
55
|
active_reservation_id = None
|
43
56
|
active_reservation_pk = None
|
44
57
|
|
@@ -95,6 +108,13 @@ class Monitor(BaseAction):
|
|
95
108
|
sleep(1)
|
96
109
|
continue
|
97
110
|
|
111
|
+
if RUNNING_IN_CONTAINER:
|
112
|
+
# if we get here and we're running in a container,
|
113
|
+
# it means the job run is complete and there is nothing left in the database
|
114
|
+
# so we can exit
|
115
|
+
logger.debug("Running in container, initial job complete.")
|
116
|
+
sys.exit(0)
|
117
|
+
|
98
118
|
# Second, check for active reservations
|
99
119
|
hardware = self.primitive.hardware.get_own_hardware_details()
|
100
120
|
if hardware["activeReservation"]:
|
@@ -189,9 +209,10 @@ class Monitor(BaseAction):
|
|
189
209
|
except KeyboardInterrupt:
|
190
210
|
logger.info("[*] Stopping primitive monitor...")
|
191
211
|
try:
|
192
|
-
|
193
|
-
|
194
|
-
|
212
|
+
if not RUNNING_IN_CONTAINER:
|
213
|
+
self.primitive.hardware.check_in_http(
|
214
|
+
is_available=False, is_online=False, stopping_agent=True
|
215
|
+
)
|
195
216
|
|
196
217
|
except P_CLI_100 as exception:
|
197
218
|
logger.error("[*] Error stopping primitive monitor.")
|
primitive/monitor/commands.py
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Optional
|
2
|
+
|
1
3
|
import click
|
2
|
-
import typing
|
3
4
|
|
4
|
-
if
|
5
|
+
if TYPE_CHECKING:
|
5
6
|
from ..client import Primitive
|
6
7
|
|
7
8
|
|
8
9
|
@click.command("monitor")
|
10
|
+
@click.option("--job-run-id", type=str, help="Explicit Job Run to pull")
|
9
11
|
@click.pass_context
|
10
|
-
def cli(context):
|
12
|
+
def cli(context, job_run_id: Optional[str] = None):
|
11
13
|
"""monitor"""
|
12
14
|
primitive: Primitive = context.obj.get("PRIMITIVE")
|
13
|
-
primitive.monitor.start()
|
15
|
+
primitive.monitor.start(job_run_id=job_run_id)
|
@@ -39,3 +39,31 @@ class Organizations(BaseAction):
|
|
39
39
|
)
|
40
40
|
organizations = [edge["node"] for edge in result.data["organizations"]["edges"]]
|
41
41
|
return organizations
|
42
|
+
|
43
|
+
@guard
|
44
|
+
def get_organization(
|
45
|
+
self,
|
46
|
+
organization_id: Optional[str] = None,
|
47
|
+
slug: Optional[str] = None,
|
48
|
+
):
|
49
|
+
query = gql(organizations_query)
|
50
|
+
|
51
|
+
filters = {}
|
52
|
+
if organization_id:
|
53
|
+
filters["organization"] = {"id": organization_id}
|
54
|
+
if slug:
|
55
|
+
filters["slug"] = {"exact": slug}
|
56
|
+
|
57
|
+
variables = {
|
58
|
+
"first": 1,
|
59
|
+
"filters": filters,
|
60
|
+
"order": {
|
61
|
+
"createdAt": "DESC",
|
62
|
+
},
|
63
|
+
}
|
64
|
+
|
65
|
+
result = self.primitive.session.execute(
|
66
|
+
query, variable_values=variables, get_execution_result=True
|
67
|
+
)
|
68
|
+
organizations = [edge["node"] for edge in result.data["organizations"]["edges"]]
|
69
|
+
return organizations[0]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: primitive
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.26
|
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
|
@@ -22,7 +22,6 @@ Requires-Dist: click
|
|
22
22
|
Requires-Dist: gql[all]
|
23
23
|
Requires-Dist: loguru
|
24
24
|
Requires-Dist: paramiko[invoke]
|
25
|
-
Requires-Dist: primitive-pal==0.1.4
|
26
25
|
Requires-Dist: psutil>=7.0.0
|
27
26
|
Requires-Dist: pyyaml
|
28
27
|
Requires-Dist: rich>=13.9.4
|
@@ -1,4 +1,4 @@
|
|
1
|
-
primitive/__about__.py,sha256=
|
1
|
+
primitive/__about__.py,sha256=oMpyVg2UpvXjSCtuQGv9QEUGqwIl1DtBLRAtQa5pBhE,130
|
2
2
|
primitive/__init__.py,sha256=bwKdgggKNVssJFVPfKSxqFMz4IxSr54WWbmiZqTMPNI,106
|
3
3
|
primitive/cli.py,sha256=g7EtHI9MATAB0qQu5w-WzbXtxz_8zu8z5E7sETmMkKU,2509
|
4
4
|
primitive/client.py,sha256=h8WZVnQylVe0vbpuyC8YZHl2JyITSPC-1HbUcmrE5pc,3623
|
@@ -44,7 +44,7 @@ primitive/graphql/utility_fragments.py,sha256=uIjwILC4QtWNyO5vu77VjQf_p0jvP3A9q_
|
|
44
44
|
primitive/hardware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
45
45
|
primitive/hardware/actions.py,sha256=d5KwuSsceOhDH9rgOL7YTCpQPhqT2inRTiZnROtiDic,26076
|
46
46
|
primitive/hardware/android.py,sha256=tu7pBPxWFrIwb_mm5CEdFFf1_veNDOKjOCQg13i_Lh4,2758
|
47
|
-
primitive/hardware/commands.py,sha256=
|
47
|
+
primitive/hardware/commands.py,sha256=NMliVHBZDl4UAvhmNEjrvN9KWPuqn87-d7eVb0ZqEYA,3752
|
48
48
|
primitive/hardware/ui.py,sha256=12rucuZ2s-w5R4bKyxON5dEbrdDnVf5sbj3K_nbdo44,2473
|
49
49
|
primitive/hardware/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
50
|
primitive/hardware/graphql/fragments.py,sha256=kI6qnTNjaEaUr-C6eD55COphtueVYbYOWZwN5EW_3qw,350
|
@@ -57,10 +57,10 @@ primitive/jobs/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
|
|
57
57
|
primitive/jobs/graphql/fragments.py,sha256=1_ZttT7dx36KDC3DClJz9M8LMpsPwXySBygHSiUEcGg,619
|
58
58
|
primitive/jobs/graphql/mutations.py,sha256=8ASvCmwQh7cMeeiykOdYaYVryG8FRIuVF6v_J8JJZuw,219
|
59
59
|
primitive/jobs/graphql/queries.py,sha256=BrU_GnLjK0bTAmWsLSmGEUea7EM8MqTKxN1Qp6sSjwc,1597
|
60
|
-
primitive/monitor/actions.py,sha256=
|
61
|
-
primitive/monitor/commands.py,sha256=
|
60
|
+
primitive/monitor/actions.py,sha256=Fem8i-I1CZnLGNCHq8gKqURTHUtfmYEJ9h5zAv1wD18,9726
|
61
|
+
primitive/monitor/commands.py,sha256=VDlEL_Qpm_ysHxug7VpI0cVAZ0ny6AS91Y58D7F1zkU,409
|
62
62
|
primitive/organizations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
63
|
-
primitive/organizations/actions.py,sha256=
|
63
|
+
primitive/organizations/actions.py,sha256=kVHOhG1oS2sI5p8uldSo5L-RUZsnG36eaulVuKLyZ-M,1863
|
64
64
|
primitive/organizations/commands.py,sha256=_dwgVEJCqMa5VgB_7P1wLPFc0AuT1p9dtyR9JRr4kpw,487
|
65
65
|
primitive/organizations/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
66
|
primitive/organizations/graphql/fragments.py,sha256=a1qKq4FZB5qze0XTo1fOUeGAscIasjn_Ig4gA2_vStY,142
|
@@ -96,8 +96,8 @@ primitive/utils/memory_size.py,sha256=4xfha21kW82nFvOTtDFx9Jk2ZQoEhkfXii-PGNTpIU
|
|
96
96
|
primitive/utils/printer.py,sha256=f1XUpqi5dkTL3GWvYRUGlSwtj2IxU1q745T4Fxo7Tn4,370
|
97
97
|
primitive/utils/shell.py,sha256=jWzb7ky7p987dJas6ZvarK3IJNZ5cwBXcryRWb9Uh6U,2072
|
98
98
|
primitive/utils/text.py,sha256=XiESMnlhjQ534xE2hMNf08WehE1SKaYFRNih0MmnK0k,829
|
99
|
-
primitive-0.2.
|
100
|
-
primitive-0.2.
|
101
|
-
primitive-0.2.
|
102
|
-
primitive-0.2.
|
103
|
-
primitive-0.2.
|
99
|
+
primitive-0.2.26.dist-info/METADATA,sha256=IJmRQR_Wu5dMULSvjr_n0Pp5CIFDMGlrixZAuxtVUJ0,3569
|
100
|
+
primitive-0.2.26.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
101
|
+
primitive-0.2.26.dist-info/entry_points.txt,sha256=p1K8DMCWka5FqLlqP1sPek5Uovy9jq8u51gUsP-z334,48
|
102
|
+
primitive-0.2.26.dist-info/licenses/LICENSE.txt,sha256=B8kmQMJ2sxYygjCLBk770uacaMci4mPSoJJ8WoDBY_c,1098
|
103
|
+
primitive-0.2.26.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|