snapctl 0.39.3__py3-none-any.whl → 0.41.0__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.
Potentially problematic release.
This version of snapctl might be problematic. Click here for more details.
- snapctl/commands/byogs.py +135 -56
- snapctl/commands/byosnap.py +450 -225
- snapctl/commands/game.py +49 -25
- snapctl/commands/generate.py +48 -40
- snapctl/commands/snapend.py +225 -142
- snapctl/config/constants.py +16 -4
- snapctl/config/hashes.py +5 -3
- snapctl/main.py +106 -34
- snapctl/utils/helper.py +2 -4
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/METADATA +66 -15
- snapctl-0.41.0.dist-info/RECORD +23 -0
- snapctl-0.39.3.dist-info/RECORD +0 -23
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/LICENSE +0 -0
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/WHEEL +0 -0
- {snapctl-0.39.3.dist-info → snapctl-0.41.0.dist-info}/entry_points.txt +0 -0
snapctl/commands/byogs.py
CHANGED
|
@@ -5,11 +5,13 @@ import base64
|
|
|
5
5
|
from binascii import Error as BinasciiError
|
|
6
6
|
import os
|
|
7
7
|
import subprocess
|
|
8
|
+
import time
|
|
8
9
|
import platform as sys_platform
|
|
9
10
|
from sys import platform
|
|
10
11
|
from typing import Union, List
|
|
11
12
|
|
|
12
13
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
14
|
+
from snapctl.commands.snapend import Snapend
|
|
13
15
|
from snapctl.config.constants import SNAPCTL_BYOGS_DEPENDENCY_MISSING, \
|
|
14
16
|
SNAPCTL_BYOGS_ECR_LOGIN_ERROR, SNAPCTL_BYOGS_BUILD_ERROR, \
|
|
15
17
|
SNAPCTL_BYOGS_TAG_ERROR, SNAPCTL_BYOGS_PUBLISH_ERROR, \
|
|
@@ -24,7 +26,7 @@ class ByoGs:
|
|
|
24
26
|
BYOGS CLI commands
|
|
25
27
|
"""
|
|
26
28
|
SID = 'byogs'
|
|
27
|
-
SUBCOMMANDS = ['publish']
|
|
29
|
+
SUBCOMMANDS = ['publish', 'sync']
|
|
28
30
|
PLATFORMS = ['linux/amd64']
|
|
29
31
|
LANGUAGES = ['go', 'python', 'ruby', 'c#', 'c++', 'rust', 'java', 'node']
|
|
30
32
|
DEFAULT_BUILD_PLATFORM = 'linux/amd64'
|
|
@@ -32,14 +34,15 @@ class ByoGs:
|
|
|
32
34
|
TAG_CHARACTER_LIMIT = 80
|
|
33
35
|
|
|
34
36
|
def __init__(
|
|
35
|
-
self, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
36
|
-
|
|
37
|
-
resources_path: Union[str, None], dockerfile: str,
|
|
38
|
-
skip_build: bool = False
|
|
37
|
+
self, *, subcommand: str, base_url: str, api_key: Union[str, None],
|
|
38
|
+
tag: Union[str, None] = None, path: Union[str, None] = None,
|
|
39
|
+
resources_path: Union[str, None] = None, dockerfile: Union[str, None] = None,
|
|
40
|
+
skip_build: bool = False, snapend_id: Union[str, None] = None,
|
|
41
|
+
fleet_name: Union[str, None] = None, blocking: bool = False
|
|
39
42
|
) -> None:
|
|
40
43
|
self.subcommand: str = subcommand
|
|
41
44
|
self.base_url: str = base_url
|
|
42
|
-
self.api_key: str = api_key
|
|
45
|
+
self.api_key: Union[str, None] = api_key
|
|
43
46
|
# self.sid: str = sid
|
|
44
47
|
# if subcommand == 'publish':
|
|
45
48
|
# self.sid = ByoGs.SID
|
|
@@ -49,11 +52,14 @@ class ByoGs:
|
|
|
49
52
|
)
|
|
50
53
|
self.token_parts: Union[List, None] = ByoGs._get_token_values(
|
|
51
54
|
self.token) if self.token is not None else None
|
|
52
|
-
self.
|
|
55
|
+
self.tag: Union[str, None] = tag
|
|
53
56
|
self.path: Union[str, None] = path
|
|
54
57
|
self.resources_path: Union[str, None] = resources_path
|
|
55
58
|
self.dockerfile: str = dockerfile
|
|
56
59
|
self.skip_build: bool = skip_build
|
|
60
|
+
self.snapend_id: Union[str, None] = snapend_id
|
|
61
|
+
self.fleet_name: Union[str, None] = fleet_name
|
|
62
|
+
self.blocking: bool = blocking
|
|
57
63
|
# Validate input
|
|
58
64
|
self.validate_input()
|
|
59
65
|
|
|
@@ -97,10 +103,14 @@ class ByoGs:
|
|
|
97
103
|
"docker", "info"
|
|
98
104
|
], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
99
105
|
if not result.returncode:
|
|
100
|
-
return snapctl_success(
|
|
106
|
+
return snapctl_success(
|
|
107
|
+
message='BYOGS dependencies verified',
|
|
108
|
+
progress=progress, no_exit=True)
|
|
101
109
|
except subprocess.CalledProcessError:
|
|
102
110
|
snapctl_error('Snapctl Exception',
|
|
103
111
|
SNAPCTL_BYOGS_DEPENDENCY_MISSING, progress)
|
|
112
|
+
finally:
|
|
113
|
+
progress.stop()
|
|
104
114
|
snapctl_error('Docker not running. Please start docker.',
|
|
105
115
|
SNAPCTL_BYOGS_DEPENDENCY_MISSING, progress)
|
|
106
116
|
|
|
@@ -130,12 +140,17 @@ class ByoGs:
|
|
|
130
140
|
f'--username {ecr_repo_username} --password-stdin {ecr_repo_url}'
|
|
131
141
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
132
142
|
if not response.returncode:
|
|
133
|
-
return snapctl_success(
|
|
143
|
+
return snapctl_success(
|
|
144
|
+
message='BYOGS ECR login successful', progress=progress, no_exit=True)
|
|
134
145
|
except subprocess.CalledProcessError:
|
|
135
|
-
snapctl_error(
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
snapctl_error(
|
|
147
|
+
message='Snapctl Exception',
|
|
148
|
+
code=SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress=progress)
|
|
149
|
+
finally:
|
|
150
|
+
progress.stop()
|
|
151
|
+
snapctl_error(
|
|
152
|
+
message='BYOGS ECR login failure',
|
|
153
|
+
code=SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress=progress)
|
|
139
154
|
|
|
140
155
|
def _docker_build(self) -> None:
|
|
141
156
|
# Get the data
|
|
@@ -148,7 +163,7 @@ class ByoGs:
|
|
|
148
163
|
progress.add_task(
|
|
149
164
|
description='Building your snap...', total=None)
|
|
150
165
|
try:
|
|
151
|
-
# image_tag = f'{ByoGs.SID}.{self.
|
|
166
|
+
# image_tag = f'{ByoGs.SID}.{self.tag}'
|
|
152
167
|
build_platform = ByoGs.DEFAULT_BUILD_PLATFORM
|
|
153
168
|
if len(self.token_parts) == 4:
|
|
154
169
|
build_platform = self.token_parts[3]
|
|
@@ -169,7 +184,7 @@ class ByoGs:
|
|
|
169
184
|
if platform == "win32":
|
|
170
185
|
response = subprocess.run([
|
|
171
186
|
# f"docker build --no-cache -t {tag} {path}"
|
|
172
|
-
'docker', 'build', '--platform', build_platform, '-t', self.
|
|
187
|
+
'docker', 'build', '--platform', build_platform, '-t', self.tag,
|
|
173
188
|
'-f', docker_file_path, self.path
|
|
174
189
|
], shell=True, check=False)
|
|
175
190
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
@@ -177,17 +192,23 @@ class ByoGs:
|
|
|
177
192
|
response = subprocess.run([
|
|
178
193
|
# f"docker build --no-cache -t {tag} {path}"
|
|
179
194
|
"docker build --platform " +
|
|
180
|
-
f"{build_platform} -t {self.
|
|
195
|
+
f"{build_platform} -t {self.tag} " +
|
|
181
196
|
f"-f {docker_file_path} {self.path}"
|
|
182
197
|
], shell=True, check=False)
|
|
183
198
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
184
199
|
if not response.returncode:
|
|
185
|
-
return snapctl_success(
|
|
200
|
+
return snapctl_success(
|
|
201
|
+
message='BYOGS build successful',
|
|
202
|
+
progress=progress, no_exit=True)
|
|
186
203
|
except subprocess.CalledProcessError:
|
|
187
|
-
snapctl_error(
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
204
|
+
snapctl_error(
|
|
205
|
+
message='Snapctl Exception',
|
|
206
|
+
code=SNAPCTL_BYOGS_BUILD_ERROR, progress=progress)
|
|
207
|
+
finally:
|
|
208
|
+
progress.stop()
|
|
209
|
+
snapctl_error(
|
|
210
|
+
message='BYOGS build failure',
|
|
211
|
+
code=SNAPCTL_BYOGS_BUILD_ERROR, progress=progress)
|
|
191
212
|
|
|
192
213
|
def _docker_tag(self) -> None:
|
|
193
214
|
# Get the data
|
|
@@ -201,23 +222,28 @@ class ByoGs:
|
|
|
201
222
|
description='Tagging your snap...', total=None)
|
|
202
223
|
try:
|
|
203
224
|
ecr_repo_url = self.token_parts[0]
|
|
204
|
-
image_tag = f'{ByoGs.SID}.{self.
|
|
225
|
+
image_tag = f'{ByoGs.SID}.{self.tag}'
|
|
205
226
|
full_ecr_repo_url = f'{ecr_repo_url}:{image_tag}'
|
|
206
227
|
# Tag the repo
|
|
207
228
|
if platform == "win32":
|
|
208
229
|
response = subprocess.run([
|
|
209
|
-
'docker', 'tag', self.
|
|
230
|
+
'docker', 'tag', self.tag, full_ecr_repo_url
|
|
210
231
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
211
232
|
else:
|
|
212
233
|
response = subprocess.run([
|
|
213
|
-
f"docker tag {self.
|
|
234
|
+
f"docker tag {self.tag} {full_ecr_repo_url}"
|
|
214
235
|
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
215
236
|
if not response.returncode:
|
|
216
|
-
return snapctl_success(
|
|
237
|
+
return snapctl_success(
|
|
238
|
+
message='BYOGS tag successful', progress=progress, no_exit=True)
|
|
217
239
|
except subprocess.CalledProcessError:
|
|
218
|
-
snapctl_error(
|
|
219
|
-
|
|
220
|
-
|
|
240
|
+
snapctl_error(
|
|
241
|
+
message='Snapctl Exception',
|
|
242
|
+
code=SNAPCTL_BYOGS_TAG_ERROR, progress=progress)
|
|
243
|
+
finally:
|
|
244
|
+
progress.stop()
|
|
245
|
+
snapctl_error(
|
|
246
|
+
message='BYOGS tag failure', code=SNAPCTL_BYOGS_TAG_ERROR, progress=progress)
|
|
221
247
|
|
|
222
248
|
def _docker_push(self) -> None:
|
|
223
249
|
progress = Progress(
|
|
@@ -230,7 +256,7 @@ class ByoGs:
|
|
|
230
256
|
description='Pushing your snap...', total=None)
|
|
231
257
|
try:
|
|
232
258
|
ecr_repo_url = self.token_parts[0]
|
|
233
|
-
image_tag = f'{ByoGs.SID}.{self.
|
|
259
|
+
image_tag = f'{ByoGs.SID}.{self.tag}'
|
|
234
260
|
full_ecr_repo_url = f'{ecr_repo_url}:{image_tag}'
|
|
235
261
|
# Push the image
|
|
236
262
|
if platform == "win32":
|
|
@@ -244,12 +270,18 @@ class ByoGs:
|
|
|
244
270
|
], shell=True, check=False)
|
|
245
271
|
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
246
272
|
if not response.returncode:
|
|
247
|
-
return snapctl_success(
|
|
273
|
+
return snapctl_success(
|
|
274
|
+
message='BYOGS upload successful',
|
|
275
|
+
progress=progress, no_exit=True)
|
|
248
276
|
except subprocess.CalledProcessError:
|
|
249
|
-
snapctl_error(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
277
|
+
snapctl_error(
|
|
278
|
+
message='Snapctl Exception',
|
|
279
|
+
code=SNAPCTL_BYOGS_PUBLISH_ERROR, progress=progress)
|
|
280
|
+
finally:
|
|
281
|
+
progress.stop()
|
|
282
|
+
snapctl_error(
|
|
283
|
+
message='BYOGS upload failure. Duplicate image error.',
|
|
284
|
+
code=SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR, progress=progress)
|
|
253
285
|
|
|
254
286
|
def _clean_slate(self) -> None:
|
|
255
287
|
progress = Progress(
|
|
@@ -274,7 +306,9 @@ class ByoGs:
|
|
|
274
306
|
f"docker logout {ecr_repo_url}"
|
|
275
307
|
], shell=True, check=False)
|
|
276
308
|
if not logout_response.returncode:
|
|
277
|
-
return snapctl_success(
|
|
309
|
+
return snapctl_success(
|
|
310
|
+
message='Cleanup complete',
|
|
311
|
+
progress=progress, no_exit=True)
|
|
278
312
|
except subprocess.CalledProcessError:
|
|
279
313
|
warning('Unable to initialize with a clean slate.')
|
|
280
314
|
finally:
|
|
@@ -289,31 +323,35 @@ class ByoGs:
|
|
|
289
323
|
"""
|
|
290
324
|
# Check API Key and Base URL
|
|
291
325
|
if not self.api_key or self.base_url == '':
|
|
292
|
-
snapctl_error(
|
|
326
|
+
snapctl_error(
|
|
327
|
+
message="Missing API Key.", code=SNAPCTL_INPUT_ERROR)
|
|
293
328
|
# Check subcommand
|
|
294
329
|
if not self.subcommand in ByoGs.SUBCOMMANDS:
|
|
295
330
|
snapctl_error(
|
|
296
|
-
"Invalid command. Valid commands are " +
|
|
331
|
+
message="Invalid command. Valid commands are " +
|
|
297
332
|
f"{', '.join(ByoGs.SUBCOMMANDS)}.",
|
|
298
|
-
SNAPCTL_INPUT_ERROR)
|
|
333
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
299
334
|
# Validation for subcommands
|
|
300
335
|
if self.token_parts is None:
|
|
301
|
-
snapctl_error(
|
|
302
|
-
|
|
336
|
+
snapctl_error(
|
|
337
|
+
message='Invalid token. Please reach out to your support team',
|
|
338
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
303
339
|
# Check tag
|
|
304
|
-
if self.
|
|
305
|
-
snapctl_error(
|
|
306
|
-
|
|
307
|
-
|
|
340
|
+
if self.tag is None:
|
|
341
|
+
snapctl_error(
|
|
342
|
+
message="Missing required parameter: tag",
|
|
343
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
344
|
+
if len(self.tag.split()) > 1 or len(self.tag) > ByoGs.TAG_CHARACTER_LIMIT:
|
|
308
345
|
snapctl_error(
|
|
309
|
-
"Tag should be a single word with maximum of " +
|
|
346
|
+
message="Tag should be a single word with maximum of " +
|
|
310
347
|
f"{ByoGs.TAG_CHARACTER_LIMIT} characters",
|
|
311
|
-
SNAPCTL_INPUT_ERROR
|
|
348
|
+
code=SNAPCTL_INPUT_ERROR
|
|
312
349
|
)
|
|
313
350
|
if self.subcommand in ['build', 'publish']:
|
|
314
351
|
if not self.skip_build and not self.path:
|
|
315
|
-
snapctl_error(
|
|
316
|
-
|
|
352
|
+
snapctl_error(
|
|
353
|
+
message="Missing required parameter: path",
|
|
354
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
317
355
|
# Check path
|
|
318
356
|
if self.resources_path:
|
|
319
357
|
docker_file_path = f"{self.resources_path}/{self.dockerfile}"
|
|
@@ -322,13 +360,33 @@ class ByoGs:
|
|
|
322
360
|
|
|
323
361
|
if not self.skip_build and not os.path.isfile(docker_file_path):
|
|
324
362
|
snapctl_error(
|
|
325
|
-
"Unable to find " +
|
|
363
|
+
message="Unable to find " +
|
|
326
364
|
f"{self.dockerfile} at path {docker_file_path}",
|
|
327
|
-
SNAPCTL_INPUT_ERROR)
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
365
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
366
|
+
elif self.subcommand == 'sync':
|
|
367
|
+
if not self.skip_build and not self.path:
|
|
368
|
+
snapctl_error(
|
|
369
|
+
message="Missing required parameter: path",
|
|
370
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
371
|
+
# Check path
|
|
372
|
+
if self.resources_path:
|
|
373
|
+
docker_file_path = f"{self.resources_path}/{self.dockerfile}"
|
|
374
|
+
else:
|
|
375
|
+
docker_file_path = f"{self.path}/{self.dockerfile}"
|
|
376
|
+
|
|
377
|
+
if not self.skip_build and not os.path.isfile(docker_file_path):
|
|
378
|
+
snapctl_error(
|
|
379
|
+
message="Unable to find " +
|
|
380
|
+
f"{self.dockerfile} at path {docker_file_path}",
|
|
381
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
382
|
+
if not self.snapend_id:
|
|
383
|
+
snapctl_error(
|
|
384
|
+
message="Missing required parameter: snapend_id",
|
|
385
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
386
|
+
if not self.fleet_name:
|
|
387
|
+
snapctl_error(
|
|
388
|
+
message="Missing required parameter: fleet_name",
|
|
389
|
+
code=SNAPCTL_INPUT_ERROR)
|
|
332
390
|
|
|
333
391
|
# CRUD methods
|
|
334
392
|
def build(self) -> None:
|
|
@@ -356,7 +414,7 @@ class ByoGs:
|
|
|
356
414
|
self._docker_push()
|
|
357
415
|
|
|
358
416
|
# Upper echelon commands
|
|
359
|
-
def publish(self) -> None:
|
|
417
|
+
def publish(self, no_exit: bool = False) -> None:
|
|
360
418
|
"""
|
|
361
419
|
Publish the image
|
|
362
420
|
1. Check Dependencies
|
|
@@ -375,4 +433,25 @@ class ByoGs:
|
|
|
375
433
|
self._clean_slate()
|
|
376
434
|
self._docker_login()
|
|
377
435
|
self._docker_push()
|
|
378
|
-
snapctl_success(
|
|
436
|
+
snapctl_success(
|
|
437
|
+
message='BYOGS publish successful', no_exit=no_exit)
|
|
438
|
+
|
|
439
|
+
def sync(self) -> None:
|
|
440
|
+
"""
|
|
441
|
+
Sync the image
|
|
442
|
+
1. Check Dependencies
|
|
443
|
+
2. Login to Snapser Registry
|
|
444
|
+
3. Build your snap
|
|
445
|
+
4. Tag the repo
|
|
446
|
+
5. Push the image
|
|
447
|
+
6. Upload swagger.json
|
|
448
|
+
"""
|
|
449
|
+
self.tag = f'{self.tag}-{int(time.time())}'
|
|
450
|
+
self.publish(no_exit=True)
|
|
451
|
+
byogs_list: str = f"{self.fleet_name}:{self.tag}"
|
|
452
|
+
snapend = Snapend(
|
|
453
|
+
subcommand='update', base_url=self.base_url, api_key=self.api_key,
|
|
454
|
+
snapend_id=self.snapend_id, byogs=byogs_list, blocking=self.blocking
|
|
455
|
+
)
|
|
456
|
+
snapend.update(no_exit=True)
|
|
457
|
+
return snapctl_success(message='BYOGs sync successful')
|