primitive 0.1.58__py3-none-any.whl → 0.1.59__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.
Files changed (63) hide show
  1. primitive/__about__.py +1 -1
  2. primitive/agent/__init__.py +0 -0
  3. primitive/agent/actions.py +7 -4
  4. primitive/agent/runner.py +8 -6
  5. primitive/auth/actions.py +5 -12
  6. primitive/auth/graphql/__init__.py +0 -0
  7. primitive/auth/graphql/queries.py +13 -0
  8. primitive/cli.py +11 -5
  9. primitive/client.py +4 -0
  10. primitive/daemons/__init__.py +0 -0
  11. primitive/exec/__init__.py +0 -0
  12. primitive/exec/actions.py +50 -0
  13. primitive/exec/commands.py +22 -0
  14. primitive/files/__init__.py +0 -0
  15. primitive/files/actions.py +9 -16
  16. primitive/files/graphql/__init__.py +0 -0
  17. primitive/files/graphql/mutations.py +11 -0
  18. primitive/git/actions.py +11 -11
  19. primitive/git/commands.py +7 -6
  20. primitive/git/graphql/__init__.py +0 -0
  21. primitive/git/graphql/queries.py +7 -0
  22. primitive/graphql/relay.py +32 -0
  23. primitive/graphql/utility_fragments.py +19 -0
  24. primitive/hardware/__init__.py +0 -0
  25. primitive/hardware/actions.py +74 -121
  26. primitive/hardware/commands.py +15 -5
  27. primitive/hardware/graphql/__init__.py +0 -0
  28. primitive/hardware/graphql/fragments.py +22 -0
  29. primitive/hardware/graphql/mutations.py +45 -0
  30. primitive/hardware/graphql/queries.py +31 -0
  31. primitive/jobs/__init__.py +0 -0
  32. primitive/jobs/actions.py +32 -201
  33. primitive/jobs/graphql/__init__.py +0 -0
  34. primitive/jobs/graphql/fragments.py +47 -0
  35. primitive/jobs/graphql/mutations.py +11 -0
  36. primitive/jobs/graphql/queries.py +100 -0
  37. primitive/lint/__init__.py +0 -0
  38. primitive/organizations/__init__.py +0 -0
  39. primitive/organizations/actions.py +4 -49
  40. primitive/organizations/graphql/__init__.py +0 -0
  41. primitive/organizations/graphql/fragments.py +10 -0
  42. primitive/organizations/graphql/mutations.py +0 -0
  43. primitive/organizations/graphql/queries.py +38 -0
  44. primitive/projects/actions.py +5 -47
  45. primitive/projects/graphql/__init__.py +0 -0
  46. primitive/projects/graphql/fragments.py +10 -0
  47. primitive/projects/graphql/mutations.py +0 -0
  48. primitive/projects/graphql/queries.py +36 -0
  49. primitive/reservations/__init__.py +0 -0
  50. primitive/reservations/actions.py +134 -0
  51. primitive/reservations/commands.py +67 -0
  52. primitive/reservations/graphql/__init__.py +0 -0
  53. primitive/reservations/graphql/fragments.py +40 -0
  54. primitive/reservations/graphql/mutations.py +29 -0
  55. primitive/reservations/graphql/queries.py +47 -0
  56. primitive/sim/actions.py +12 -9
  57. primitive/utils/__init__.py +0 -0
  58. {primitive-0.1.58.dist-info → primitive-0.1.59.dist-info}/METADATA +1 -1
  59. primitive-0.1.59.dist-info/RECORD +95 -0
  60. primitive-0.1.58.dist-info/RECORD +0 -53
  61. {primitive-0.1.58.dist-info → primitive-0.1.59.dist-info}/WHEEL +0 -0
  62. {primitive-0.1.58.dist-info → primitive-0.1.59.dist-info}/entry_points.txt +0 -0
  63. {primitive-0.1.58.dist-info → primitive-0.1.59.dist-info}/licenses/LICENSE.txt +0 -0
@@ -2,18 +2,27 @@ import csv
2
2
  import io
3
3
  import json
4
4
  import platform
5
- from shutil import which
6
5
  import subprocess
6
+ import typing
7
+ from shutil import which
7
8
  from typing import Dict, List, Optional
9
+
8
10
  import click
11
+ from aiohttp import client_exceptions
12
+ from gql import gql
9
13
  from loguru import logger
14
+
15
+ from primitive.graphql.relay import from_base64
10
16
  from primitive.utils.memory_size import MemorySize
11
- from gql import gql
12
- from aiohttp import client_exceptions
13
- from ..utils.config import update_config_file
14
- from ..utils.auth import guard
15
17
 
16
- import typing
18
+ from ..utils.auth import guard
19
+ from ..utils.config import update_config_file
20
+ from .graphql.mutations import (
21
+ hardware_checkin_mutation,
22
+ hardware_update_mutation,
23
+ register_hardware_mutation,
24
+ )
25
+ from .graphql.queries import hardware_list
17
26
 
18
27
  if typing.TYPE_CHECKING:
19
28
  pass
@@ -269,29 +278,13 @@ class Hardware(BaseAction):
269
278
  @guard
270
279
  def register(self):
271
280
  system_info = self.get_system_info()
272
- mutation = gql(
273
- """
274
- mutation registerHardware($input: RegisterHardwareInput!) {
275
- registerHardware(input: $input) {
276
- ... on Hardware {
277
- fingerprint
278
- }
279
- ... on OperationInfo {
280
- messages {
281
- kind
282
- message
283
- field
284
- code
285
- }
286
- }
287
- }
288
- }
289
- """
290
- )
281
+ mutation = gql(register_hardware_mutation)
291
282
  input = {"systemInfo": system_info}
292
283
  variables = {"input": input}
293
- result = self.primitive.session.execute(mutation, variable_values=variables)
294
- if messages := result.get("registerHardware").get("messages"):
284
+ result = self.primitive.session.execute(
285
+ mutation, variable_values=variables, get_execution_result=True
286
+ )
287
+ if messages := result.data.get("registerHardware").get("messages"):
295
288
  for message in messages:
296
289
  logger.enable("primitive")
297
290
  if message.get("kind") == "ERROR":
@@ -300,7 +293,7 @@ class Hardware(BaseAction):
300
293
  logger.debug(message.get("message"))
301
294
  return False
302
295
 
303
- fingerprint = result.get("registerHardware").get("fingerprint")
296
+ fingerprint = result.data.get("registerHardware").get("fingerprint")
304
297
 
305
298
  self.primitive.host_config["fingerprint"] = fingerprint
306
299
  self.primitive.full_config[self.primitive.host] = self.primitive.host_config
@@ -335,30 +328,14 @@ class Hardware(BaseAction):
335
328
  "systemInfo": system_info,
336
329
  }
337
330
 
338
- mutation = gql(
339
- """
340
- mutation hardwareUpdate($input: HardwareUpdateInput!) {
341
- hardwareUpdate(input: $input) {
342
- ... on Hardware {
343
- systemInfo
344
- }
345
- ... on OperationInfo {
346
- messages {
347
- kind
348
- message
349
- field
350
- code
351
- }
352
- }
353
- }
354
- }
355
- """
356
- )
331
+ mutation = gql(hardware_update_mutation)
357
332
 
358
333
  input = new_state
359
334
  variables = {"input": input}
360
335
  try:
361
- result = self.primitive.session.execute(mutation, variable_values=variables)
336
+ result = self.primitive.session.execute(
337
+ mutation, variable_values=variables, get_execution_result=True
338
+ )
362
339
  except client_exceptions.ClientConnectorError as exception:
363
340
  message = " [*] Failed to update hardware system info! "
364
341
  logger.error(message)
@@ -391,27 +368,7 @@ class Hardware(BaseAction):
391
368
  "isOnline": is_online,
392
369
  }
393
370
 
394
- mutation = gql(
395
- """
396
- mutation checkIn($input: CheckInInput!) {
397
- checkIn(input: $input) {
398
- ... on Hardware {
399
- createdAt
400
- updatedAt
401
- lastCheckIn
402
- }
403
- ... on OperationInfo {
404
- messages {
405
- kind
406
- message
407
- field
408
- code
409
- }
410
- }
411
- }
412
- }
413
- """ # noqa
414
- )
371
+ mutation = gql(hardware_checkin_mutation)
415
372
  input = new_state
416
373
  variables = {"input": input}
417
374
  try:
@@ -459,70 +416,66 @@ class Hardware(BaseAction):
459
416
  raise exception
460
417
 
461
418
  @guard
462
- def get_hardware_list(self, fingerprint: Optional[str] = None):
463
- query = gql(
464
- """
465
- fragment HardwareFragment on Hardware {
466
- id
467
- pk
468
- name
469
- slug
470
- createdAt
471
- updatedAt
472
- isAvailable
473
- isOnline
474
- isQuarantined
475
- isHealthy
476
- capabilities {
477
- id
478
- pk
479
- }
480
- activeReservation {
481
- id
482
- pk
483
- }
484
- }
485
-
486
- query hardwareList(
487
- $before: String
488
- $after: String
489
- $first: Int
490
- $last: Int
491
- $filters: HardwareFilters
492
- ) {
493
- hardwareList(
494
- before: $before
495
- after: $after
496
- first: $first
497
- last: $last
498
- filters: $filters
499
- ) {
500
- totalCount
501
- edges {
502
- cursor
503
- node {
504
- ...HardwareFragment
505
- }
506
- }
507
- }
508
- }
509
- """
510
- )
419
+ def get_hardware_list(
420
+ self, fingerprint: Optional[str] = None, slug: Optional[str] = None
421
+ ):
422
+ query = gql(hardware_list)
511
423
 
512
424
  filters = {}
513
425
  if fingerprint:
514
426
  filters["fingerprint"] = {"exact": fingerprint}
427
+ if slug:
428
+ filters["slug"] = {"exact": slug}
515
429
 
516
430
  variables = {
517
431
  "first": 1,
518
432
  "filters": filters,
519
433
  }
520
- result = self.primitive.session.execute(query, variable_values=variables)
434
+ result = self.primitive.session.execute(
435
+ query, variable_values=variables, get_execution_result=True
436
+ )
521
437
  return result
522
438
 
523
439
  def get_own_hardware_details(self):
524
- hardware_list_data = self.get_hardware_list(
440
+ hardware_list_result = self.get_hardware_list(
525
441
  fingerprint=self.primitive.host_config.get("fingerprint")
526
442
  )
527
- hardware = hardware_list_data.get("hardwareList").get("edges")[0].get("node")
443
+ hardware = (
444
+ hardware_list_result.data.get("hardwareList").get("edges")[0].get("node")
445
+ )
446
+ return hardware
447
+
448
+ def get_hardware_from_slug_or_id(self, hardware_identifier: str):
449
+ is_id = False
450
+ is_slug = False
451
+ # first check if the hardware_identifier is a slug or ID
452
+ try:
453
+ type_name, id = from_base64(hardware_identifier)
454
+
455
+ is_id = True
456
+ if type_name == "Hardware":
457
+ is_hardware_type = True
458
+ else:
459
+ raise Exception(
460
+ f"ID was not for Hardware, you supplied an ID for a {type_name}"
461
+ )
462
+
463
+ except ValueError:
464
+ is_slug = True
465
+
466
+ hardware = None
467
+
468
+ if is_id and is_hardware_type:
469
+ hardware_list_result = self.get_hardware_list(slug=hardware_identifier)
470
+ if edges := hardware_list_result.data["hardwareList"]["edges"]:
471
+ hardware = edges[0]["node"]
472
+ else:
473
+ raise Exception(f"No hardware found with slug {hardware_identifier}")
474
+ elif is_slug:
475
+ hardware_list_result = self.get_hardware_list(slug=hardware_identifier)
476
+ if edges := hardware_list_result.data["hardwareList"]["edges"]:
477
+ hardware = edges[0]["node"]
478
+ else:
479
+ raise Exception(f"No hardware found with slug {hardware_identifier}")
480
+
528
481
  return hardware
@@ -1,9 +1,9 @@
1
+ import typing
2
+
1
3
  import click
2
4
 
3
5
  from ..utils.printer import print_result
4
6
 
5
- import typing
6
-
7
7
  if typing.TYPE_CHECKING:
8
8
  from ..client import Primitive
9
9
 
@@ -31,7 +31,7 @@ def register_command(context):
31
31
  primitive: Primitive = context.obj.get("PRIMITIVE")
32
32
  result = primitive.hardware.register()
33
33
  color = "green" if result else "red"
34
- if result:
34
+ if result.data.get("registerHardware"):
35
35
  message = "Hardware registered successfully"
36
36
  else:
37
37
  message = (
@@ -45,9 +45,19 @@ def register_command(context):
45
45
  def checkin_command(context):
46
46
  """Checkin Hardware with Primitive"""
47
47
  primitive: Primitive = context.obj.get("PRIMITIVE")
48
- result = primitive.hardware.check_in_http()
49
- if messages := result.get("checkIn").get("messages"):
48
+ check_in_http_result = primitive.hardware.check_in_http()
49
+ if messages := check_in_http_result.data.get("checkIn").get("messages"):
50
50
  print_result(message=messages, context=context, fg="yellow")
51
51
  else:
52
52
  message = "Hardware checked in successfully"
53
53
  print_result(message=message, context=context, fg="green")
54
+
55
+
56
+ @cli.command("list")
57
+ @click.pass_context
58
+ def list_command(context):
59
+ """List Hardware"""
60
+ primitive: Primitive = context.obj.get("PRIMITIVE")
61
+ get_hardware_list_result = primitive.hardware.get_hardware_list()
62
+ message = get_hardware_list_result.data
63
+ print_result(message=message, context=context)
File without changes
@@ -0,0 +1,22 @@
1
+ hardware_fragment = """
2
+ fragment HardwareFragment on Hardware {
3
+ id
4
+ pk
5
+ name
6
+ slug
7
+ createdAt
8
+ updatedAt
9
+ isAvailable
10
+ isOnline
11
+ isQuarantined
12
+ isHealthy
13
+ capabilities {
14
+ id
15
+ pk
16
+ }
17
+ activeReservation {
18
+ id
19
+ pk
20
+ }
21
+ }
22
+ """
@@ -0,0 +1,45 @@
1
+ from primitive.graphql.utility_fragments import operation_info_fragment
2
+
3
+ register_hardware_mutation = (
4
+ operation_info_fragment
5
+ + """
6
+ mutation registerHardware($input: RegisterHardwareInput!) {
7
+ registerHardware(input: $input) {
8
+ ... on Hardware {
9
+ fingerprint
10
+ }
11
+ ...OperationInfoFragment
12
+ }
13
+ }
14
+ """
15
+ )
16
+
17
+ hardware_update_mutation = (
18
+ operation_info_fragment
19
+ + """
20
+ mutation hardwareUpdate($input: HardwareUpdateInput!) {
21
+ hardwareUpdate(input: $input) {
22
+ ... on Hardware {
23
+ systemInfo
24
+ }
25
+ ...OperationInfoFragment
26
+ }
27
+ }
28
+ """
29
+ )
30
+
31
+ hardware_checkin_mutation = (
32
+ operation_info_fragment
33
+ + """
34
+ mutation checkIn($input: CheckInInput!) {
35
+ checkIn(input: $input) {
36
+ ... on Hardware {
37
+ createdAt
38
+ updatedAt
39
+ lastCheckIn
40
+ }
41
+ ...OperationInfoFragment
42
+ }
43
+ }
44
+ """
45
+ )
@@ -0,0 +1,31 @@
1
+ from .fragments import hardware_fragment
2
+
3
+ hardware_list = (
4
+ hardware_fragment
5
+ + """
6
+
7
+ query hardwareList(
8
+ $before: String
9
+ $after: String
10
+ $first: Int
11
+ $last: Int
12
+ $filters: HardwareFilters
13
+ ) {
14
+ hardwareList(
15
+ before: $before
16
+ after: $after
17
+ first: $first
18
+ last: $last
19
+ filters: $filters
20
+ ) {
21
+ totalCount
22
+ edges {
23
+ cursor
24
+ node {
25
+ ...HardwareFragment
26
+ }
27
+ }
28
+ }
29
+ }
30
+ """
31
+ )
File without changes
primitive/jobs/actions.py CHANGED
@@ -1,9 +1,18 @@
1
1
  from typing import List, Optional
2
- from gql import gql
3
2
 
3
+ from gql import gql
4
4
 
5
5
  from primitive.utils.actions import BaseAction
6
+
6
7
  from ..utils.auth import guard
8
+ from .graphql.mutations import job_run_update_mutation
9
+ from .graphql.queries import (
10
+ github_app_token_for_job_run_query,
11
+ job_run_query,
12
+ job_run_status_query,
13
+ job_runs_query,
14
+ jobs_query,
15
+ )
7
16
 
8
17
 
9
18
  class Jobs(BaseAction):
@@ -17,52 +26,7 @@ class Jobs(BaseAction):
17
26
  first: Optional[int] = 1,
18
27
  last: Optional[int] = None,
19
28
  ):
20
- query = gql(
21
- """
22
- fragment PageInfoFragment on PageInfo {
23
- hasNextPage
24
- hasPreviousPage
25
- startCursor
26
- endCursor
27
- }
28
-
29
- fragment JobFragment on Job {
30
- id
31
- pk
32
- slug
33
- name
34
- createdAt
35
- updatedAt
36
- }
37
-
38
- query jobs(
39
- $before: String
40
- $after: String
41
- $first: Int
42
- $last: Int
43
- $filters: JobFilters
44
- ) {
45
- jobs(
46
- before: $before
47
- after: $after
48
- first: $first
49
- last: $last
50
- filters: $filters
51
- ) {
52
- totalCount
53
- pageInfo {
54
- ...PageInfoFragment
55
- }
56
- edges {
57
- cursor
58
- node {
59
- ...JobFragment
60
- }
61
- }
62
- }
63
- }
64
- """
65
- )
29
+ query = gql(jobs_query)
66
30
 
67
31
  filters = {}
68
32
  if organization_id:
@@ -101,73 +65,7 @@ class Jobs(BaseAction):
101
65
  first: Optional[int] = 1,
102
66
  last: Optional[int] = None,
103
67
  ):
104
- query = gql(
105
- """
106
- fragment PageInfoFragment on PageInfo {
107
- hasNextPage
108
- hasPreviousPage
109
- startCursor
110
- endCursor
111
- }
112
-
113
- fragment JobRunFragment on JobRun {
114
- id
115
- pk
116
- createdAt
117
- updatedAt
118
- completedAt
119
- startedAt
120
- status
121
- conclusion
122
- job {
123
- id
124
- pk
125
- slug
126
- name
127
- createdAt
128
- updatedAt
129
- }
130
- jobSettings {
131
- containerArgs
132
- rootDirectory
133
- }
134
- gitCommit {
135
- sha
136
- branch
137
- repoFullName
138
- }
139
- }
140
-
141
- query jobRuns(
142
- $before: String
143
- $after: String
144
- $first: Int
145
- $last: Int
146
- $filters: JobRunFilters
147
- $order: JobRunOrder
148
- ) {
149
- jobRuns(
150
- before: $before
151
- after: $after
152
- first: $first
153
- last: $last
154
- filters: $filters
155
- order: $order
156
- ) {
157
- totalCount
158
- pageInfo {
159
- ...PageInfoFragment
160
- }
161
- edges {
162
- cursor
163
- node {
164
- ...JobRunFragment
165
- }
166
- }
167
- }
168
- }
169
- """
170
- )
68
+ query = gql(job_runs_query)
171
69
 
172
70
  filters = {}
173
71
  if organization_id:
@@ -194,50 +92,18 @@ query jobRuns(
194
92
  },
195
93
  }
196
94
 
197
- result = self.primitive.session.execute(query, variable_values=variables)
95
+ result = self.primitive.session.execute(
96
+ query, variable_values=variables, get_execution_result=True
97
+ )
198
98
  return result
199
99
 
200
100
  @guard
201
101
  def get_job_run(self, id: str):
202
- query = gql(
203
- """
204
- fragment JobRunFragment on JobRun {
205
- id
206
- pk
207
- createdAt
208
- updatedAt
209
- completedAt
210
- startedAt
211
- status
212
- conclusion
213
- job {
214
- id
215
- pk
216
- slug
217
- name
218
- createdAt
219
- updatedAt
220
- }
221
- gitCommit {
222
- sha
223
- branch
224
- repoFullName
225
- }
226
- jobSettings {
227
- containerArgs
228
- rootDirectory
229
- }
230
- }
231
-
232
- query jobRun($id: GlobalID!) {
233
- jobRun(id: $id) {
234
- ...JobRunFragment
235
- }
236
- }
237
- """
238
- )
102
+ query = gql(job_run_query)
239
103
  variables = {"id": id}
240
- result = self.primitive.session.execute(query, variable_values=variables)
104
+ result = self.primitive.session.execute(
105
+ query, variable_values=variables, get_execution_result=True
106
+ )
241
107
  return result
242
108
 
243
109
  @guard
@@ -248,19 +114,7 @@ query jobRuns(
248
114
  conclusion: str = None,
249
115
  file_ids: Optional[List[str]] = [],
250
116
  ):
251
- mutation = gql(
252
- """
253
- mutation jobRunUpdate($input: JobRunUpdateInput!) {
254
- jobRunUpdate(input: $input) {
255
- ... on JobRun {
256
- id
257
- status
258
- conclusion
259
- }
260
- }
261
- }
262
- """
263
- )
117
+ mutation = gql(job_run_update_mutation)
264
118
  input = {"id": id}
265
119
  if status:
266
120
  input["status"] = status
@@ -269,21 +123,19 @@ query jobRuns(
269
123
  if file_ids and len(file_ids) > 0:
270
124
  input["files"] = file_ids
271
125
  variables = {"input": input}
272
- result = self.primitive.session.execute(mutation, variable_values=variables)
126
+ result = self.primitive.session.execute(
127
+ mutation, variable_values=variables, get_execution_result=True
128
+ )
273
129
  return result
274
130
 
275
131
  @guard
276
132
  def github_access_token_for_job_run(self, job_run_id: str):
277
- query = gql(
278
- """
279
- query ghAppTokenForJobRun($jobRunId: GlobalID!) {
280
- ghAppTokenForJobRun(jobRunId: $jobRunId)
281
- }
282
- """
283
- )
133
+ query = gql(github_app_token_for_job_run_query)
284
134
  variables = {"jobRunId": job_run_id}
285
- result = self.primitive.session.execute(query, variable_values=variables)
286
- return result["ghAppTokenForJobRun"]
135
+ result = self.primitive.session.execute(
136
+ query, variable_values=variables, get_execution_result=True
137
+ )
138
+ return result.data["ghAppTokenForJobRun"]
287
139
 
288
140
  def get_latest_job_run_for_job(
289
141
  self, job_slug: Optional[str] = None, job_id: Optional[str] = None
@@ -300,32 +152,11 @@ query ghAppTokenForJobRun($jobRunId: GlobalID!) {
300
152
  ]
301
153
  return job_run
302
154
 
303
- def job_run_start(
304
- self,
305
- job_slug: str,
306
- job_id: str,
307
- ):
308
- if not job_slug and not job_id:
309
- raise ValueError("job_slug or job_id is required")
310
-
311
- self.get_jobs(slug=job_slug)
312
-
313
155
  @guard
314
156
  def get_job_status(self, id: str):
315
- query = gql(
316
- """
317
- fragment JobRunFragment on JobRun {
318
- id
319
- status
320
- }
321
-
322
- query jobRun($id: GlobalID!) {
323
- jobRun(id: $id) {
324
- ...JobRunFragment
325
- }
326
- }
327
- """
328
- )
157
+ query = gql(job_run_status_query)
329
158
  variables = {"id": id}
330
- result = self.primitive.session.execute(query, variable_values=variables)
159
+ result = self.primitive.session.execute(
160
+ query, variable_values=variables, get_execution_result=True
161
+ )
331
162
  return result
File without changes