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 CHANGED
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2024-present Dylan Stein <dylan@primitive.tech>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.2.22"
4
+ __version__ = "0.2.26"
@@ -1,13 +1,15 @@
1
- import typing
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 typing.TYPE_CHECKING:
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
- result = primitive.hardware.register()
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"
@@ -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
- try:
28
- # hey stupid:
29
- # do not set is_available to True here, it will mess up the reservation logic
30
- # only set is_available after we've checked that no active reservation is present
31
- # setting is_available of the parent also effects the children,
32
- # which may have active reservations as well
33
- self.primitive.hardware.check_in_http(is_online=True)
34
- except Exception as exception:
35
- logger.exception(f"Error checking in hardware: {exception}")
36
- sys.exit(1)
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
- self.primitive.hardware.check_in_http(
193
- is_available=False, is_online=False, stopping_agent=True
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.")
@@ -1,13 +1,15 @@
1
+ from typing import TYPE_CHECKING, Optional
2
+
1
3
  import click
2
- import typing
3
4
 
4
- if typing.TYPE_CHECKING:
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.22
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=ywjcAnYCZQZHX2ntgK8cvx23rSS44olGihhJWtXvKaw,130
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=ixMPhDOpsU-eONxmimqKVynus-Eaq2XPKEK017WM_rM,3229
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=GUQrwuan82pOJ5gI2FvQYzgDoP4fs28PdcI_fg_aXRs,8692
61
- primitive/monitor/commands.py,sha256=dZsD8WKGU4OYO_AlKawfeRNVTMN0xJ-DFRkmKTS464s,258
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=Tgp_rox0jcvfhQ-LmcWc9vkPdeJu5Bk6U1rNuT9oDnw,1088
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.22.dist-info/METADATA,sha256=GofUxo6eFljTu6xAmepzr8PsS3OlZcOaz-RLzyLgnxo,3605
100
- primitive-0.2.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
101
- primitive-0.2.22.dist-info/entry_points.txt,sha256=p1K8DMCWka5FqLlqP1sPek5Uovy9jq8u51gUsP-z334,48
102
- primitive-0.2.22.dist-info/licenses/LICENSE.txt,sha256=B8kmQMJ2sxYygjCLBk770uacaMci4mPSoJJ8WoDBY_c,1098
103
- primitive-0.2.22.dist-info/RECORD,,
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,,