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 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
- input_tag: Union[str, None], path: Union[str, None],
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.input_tag: Union[str, None] = input_tag
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('BYOGS dependencies verified', progress, no_exit=True)
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('BYOGS ECR login successful', progress, no_exit=True)
143
+ return snapctl_success(
144
+ message='BYOGS ECR login successful', progress=progress, no_exit=True)
134
145
  except subprocess.CalledProcessError:
135
- snapctl_error('Snapctl Exception',
136
- SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress)
137
- snapctl_error('BYOGS ECR login failure',
138
- SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress)
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.input_tag}'
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.input_tag,
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.input_tag} " +
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('BYOGS build successful', progress, no_exit=True)
200
+ return snapctl_success(
201
+ message='BYOGS build successful',
202
+ progress=progress, no_exit=True)
186
203
  except subprocess.CalledProcessError:
187
- snapctl_error('Snapctl Exception',
188
- SNAPCTL_BYOGS_BUILD_ERROR, progress)
189
- snapctl_error('BYOGS build failure',
190
- SNAPCTL_BYOGS_BUILD_ERROR, progress)
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.input_tag}'
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.input_tag, full_ecr_repo_url
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.input_tag} {full_ecr_repo_url}"
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('BYOGS tag successful', progress, no_exit=True)
237
+ return snapctl_success(
238
+ message='BYOGS tag successful', progress=progress, no_exit=True)
217
239
  except subprocess.CalledProcessError:
218
- snapctl_error('Snapctl Exception',
219
- SNAPCTL_BYOGS_TAG_ERROR, progress)
220
- snapctl_error('BYOGS tag failure', SNAPCTL_BYOGS_TAG_ERROR, progress)
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.input_tag}'
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('BYOGS upload successful', progress, no_exit=True)
273
+ return snapctl_success(
274
+ message='BYOGS upload successful',
275
+ progress=progress, no_exit=True)
248
276
  except subprocess.CalledProcessError:
249
- snapctl_error('Snapctl Exception',
250
- SNAPCTL_BYOGS_PUBLISH_ERROR, progress)
251
- snapctl_error('BYOGS upload failure. Duplicate image error.',
252
- SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR, progress)
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('Cleanup complete', progress, no_exit=True)
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("Missing API Key.", SNAPCTL_INPUT_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('Invalid token. Please reach out to your support team',
302
- SNAPCTL_INPUT_ERROR)
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.input_tag is None:
305
- snapctl_error("Missing required parameter: tag",
306
- SNAPCTL_INPUT_ERROR)
307
- if len(self.input_tag.split()) > 1 or len(self.input_tag) > ByoGs.TAG_CHARACTER_LIMIT:
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("Missing required parameter: path",
316
- SNAPCTL_INPUT_ERROR)
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
- # elif self.subcommand == 'push':
329
- # if not self.input_tag:
330
- # error("Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
331
- # raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
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('BYOGS publish successful')
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')