snapctl 0.32.0__tar.gz → 0.32.1__tar.gz

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.

Files changed (30) hide show
  1. {snapctl-0.32.0 → snapctl-0.32.1}/PKG-INFO +92 -2
  2. {snapctl-0.32.0 → snapctl-0.32.1}/README.md +88 -0
  3. {snapctl-0.32.0 → snapctl-0.32.1}/pyproject.toml +4 -2
  4. snapctl-0.32.1/snapctl/commands/byogs.py +319 -0
  5. snapctl-0.32.1/snapctl/commands/byosnap.py +653 -0
  6. snapctl-0.32.1/snapctl/commands/game.py +113 -0
  7. snapctl-0.32.1/snapctl/commands/generate.py +93 -0
  8. snapctl-0.32.1/snapctl/commands/snapend.py +691 -0
  9. snapctl-0.32.1/snapctl/config/constants.py +91 -0
  10. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/main.py +100 -135
  11. snapctl-0.32.1/snapctl/types/definitions.py +28 -0
  12. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/utils/echo.py +10 -2
  13. snapctl-0.32.1/snapctl/utils/helper.py +95 -0
  14. snapctl-0.32.0/snapctl/commands/byogs.py +0 -325
  15. snapctl-0.32.0/snapctl/commands/byosnap.py +0 -646
  16. snapctl-0.32.0/snapctl/commands/game.py +0 -107
  17. snapctl-0.32.0/snapctl/commands/generate.py +0 -77
  18. snapctl-0.32.0/snapctl/commands/snapend.py +0 -611
  19. snapctl-0.32.0/snapctl/config/constants.py +0 -27
  20. snapctl-0.32.0/snapctl/types/definitions.py +0 -12
  21. snapctl-0.32.0/snapctl/utils/helper.py +0 -38
  22. {snapctl-0.32.0 → snapctl-0.32.1}/LICENSE +0 -0
  23. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/__init__.py +0 -0
  24. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/__main__.py +0 -0
  25. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/commands/__init__.py +0 -0
  26. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/config/__init__.py +0 -0
  27. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/config/endpoints.py +0 -0
  28. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/config/hashes.py +0 -0
  29. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/types/__init__.py +0 -0
  30. {snapctl-0.32.0 → snapctl-0.32.1}/snapctl/utils/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: snapctl
3
- Version: 0.32.0
3
+ Version: 0.32.1
4
4
  Summary: Snapser CLI Tool
5
5
  Author: Ajinkya Apte
6
6
  Author-email: aj@snapser.com
@@ -11,8 +11,10 @@ Classifier: Programming Language :: Python :: 3.11
11
11
  Classifier: Programming Language :: Python :: 3.12
12
12
  Requires-Dist: configparser (>=6.0.0,<7.0.0)
13
13
  Requires-Dist: pyfiglet (>=1.0.2,<2.0.0)
14
+ Requires-Dist: pytest (>=8.2.2,<9.0.0)
15
+ Requires-Dist: pytest-mock (>=3.14.0,<4.0.0)
14
16
  Requires-Dist: requests (>=2.28.2,<3.0.0)
15
- Requires-Dist: typer[all] (>=0.7.0,<0.8.0)
17
+ Requires-Dist: typer[all] (>=0.12.3,<0.13.0)
16
18
  Description-Content-Type: text/markdown
17
19
 
18
20
  # Snapser CLI Tool
@@ -486,3 +488,91 @@ snapctl snapend state --help
486
488
  snapctl snapend state $snapend_id
487
489
  ```
488
490
 
491
+ ## Error codes
492
+ ### CLI Return Codes
493
+
494
+ | Error Code | Description |
495
+ |------------|----------------------------------------------------------|
496
+ | 0 | Operation completed successfully |
497
+ | 1 | General error |
498
+ | 2 | Input error |
499
+
500
+ ### Configuration Errors
501
+
502
+ | Error Code | Description |
503
+ |------------|----------------------------------------------------------|
504
+ | 10 | Configuration incorrect |
505
+ | 11 | Configuration error |
506
+ | 12 | Dependency missing |
507
+
508
+ ### BYOGS Errors
509
+
510
+ | Error Code | Description |
511
+ |------------|----------------------------------------------------------|
512
+ | 20 | Generic BYOGS error |
513
+ | 21 | BYOGS dependency missing |
514
+ | 22 | BYOGS ECR login error |
515
+ | 23 | BYOGS build error |
516
+ | 24 | BYOGS tag error |
517
+ | 25 | BYOGS publish error |
518
+ | 26 | BYOGS publish permission error |
519
+ | 27 | BYOGS publish duplicate tag error |
520
+
521
+ ### BYOSNAP Errors
522
+
523
+ | Error Code | Description |
524
+ |------------|----------------------------------------------------------|
525
+ | 30 | Generic BYOSNAP error |
526
+ | 31 | BYOSNAP dependency missing |
527
+ | 32 | BYOSNAP ECR login error |
528
+ | 33 | BYOSNAP build error |
529
+ | 34 | BYOSNAP tag error |
530
+ | 35 | BYOSNAP publish image error |
531
+ | 36 | BYOSNAP publish image permission error |
532
+ | 37 | BYOSNAP publish image duplicate tag error |
533
+ | 38 | BYOSNAP create error |
534
+ | 39 | BYOSNAP create permission error |
535
+ | 40 | BYOSNAP create duplicate name error |
536
+ | 41 | BYOSNAP publish version error |
537
+ | 42 | BYOSNAP publish version permission error |
538
+ | 43 | BYOSNAP publish version duplicate version error |
539
+ | 44 | BYOSNAP publish version duplicate tag error |
540
+
541
+ ### Game Errors
542
+
543
+ | Error Code | Description |
544
+ |------------|----------------------------------------------------------|
545
+ | 50 | Generic game error |
546
+ | 51 | Game create error |
547
+ | 52 | Game create permission error |
548
+ | 53 | Game create duplicate name error |
549
+ | 54 | Game enumerate error |
550
+
551
+ ### Snapend Errors
552
+
553
+ | Error Code | Description |
554
+ |------------|----------------------------------------------------------|
555
+ | 60 | Generic snapend error |
556
+ | 61 | Snapend enumerate error |
557
+ | 62 | Snapend clone error |
558
+ | 63 | Snapend clone server error |
559
+ | 64 | Snapend clone timeout error |
560
+ | 65 | Snapend apply error |
561
+ | 66 | Snapend apply server error |
562
+ | 67 | Snapend apply timeout error |
563
+ | 68 | Snapend promote error |
564
+ | 69 | Snapend promote server error |
565
+ | 70 | Snapend promote timeout error |
566
+ | 71 | Snapend download error |
567
+ | 72 | Snapend update error |
568
+ | 73 | Snapend update server error |
569
+ | 74 | Snapend update timeout error |
570
+ | 75 | Snapend state error |
571
+
572
+ ### Generate Errors
573
+
574
+ | Error Code | Description |
575
+ |------------|----------------------------------------------------------|
576
+ | 80 | Generic generate error |
577
+ | 81 | Generate BYOSNAP profile error |
578
+
@@ -468,3 +468,91 @@ snapctl snapend state --help
468
468
  # snapctl snapend state gx5x6bc0
469
469
  snapctl snapend state $snapend_id
470
470
  ```
471
+
472
+ ## Error codes
473
+ ### CLI Return Codes
474
+
475
+ | Error Code | Description |
476
+ |------------|----------------------------------------------------------|
477
+ | 0 | Operation completed successfully |
478
+ | 1 | General error |
479
+ | 2 | Input error |
480
+
481
+ ### Configuration Errors
482
+
483
+ | Error Code | Description |
484
+ |------------|----------------------------------------------------------|
485
+ | 10 | Configuration incorrect |
486
+ | 11 | Configuration error |
487
+ | 12 | Dependency missing |
488
+
489
+ ### BYOGS Errors
490
+
491
+ | Error Code | Description |
492
+ |------------|----------------------------------------------------------|
493
+ | 20 | Generic BYOGS error |
494
+ | 21 | BYOGS dependency missing |
495
+ | 22 | BYOGS ECR login error |
496
+ | 23 | BYOGS build error |
497
+ | 24 | BYOGS tag error |
498
+ | 25 | BYOGS publish error |
499
+ | 26 | BYOGS publish permission error |
500
+ | 27 | BYOGS publish duplicate tag error |
501
+
502
+ ### BYOSNAP Errors
503
+
504
+ | Error Code | Description |
505
+ |------------|----------------------------------------------------------|
506
+ | 30 | Generic BYOSNAP error |
507
+ | 31 | BYOSNAP dependency missing |
508
+ | 32 | BYOSNAP ECR login error |
509
+ | 33 | BYOSNAP build error |
510
+ | 34 | BYOSNAP tag error |
511
+ | 35 | BYOSNAP publish image error |
512
+ | 36 | BYOSNAP publish image permission error |
513
+ | 37 | BYOSNAP publish image duplicate tag error |
514
+ | 38 | BYOSNAP create error |
515
+ | 39 | BYOSNAP create permission error |
516
+ | 40 | BYOSNAP create duplicate name error |
517
+ | 41 | BYOSNAP publish version error |
518
+ | 42 | BYOSNAP publish version permission error |
519
+ | 43 | BYOSNAP publish version duplicate version error |
520
+ | 44 | BYOSNAP publish version duplicate tag error |
521
+
522
+ ### Game Errors
523
+
524
+ | Error Code | Description |
525
+ |------------|----------------------------------------------------------|
526
+ | 50 | Generic game error |
527
+ | 51 | Game create error |
528
+ | 52 | Game create permission error |
529
+ | 53 | Game create duplicate name error |
530
+ | 54 | Game enumerate error |
531
+
532
+ ### Snapend Errors
533
+
534
+ | Error Code | Description |
535
+ |------------|----------------------------------------------------------|
536
+ | 60 | Generic snapend error |
537
+ | 61 | Snapend enumerate error |
538
+ | 62 | Snapend clone error |
539
+ | 63 | Snapend clone server error |
540
+ | 64 | Snapend clone timeout error |
541
+ | 65 | Snapend apply error |
542
+ | 66 | Snapend apply server error |
543
+ | 67 | Snapend apply timeout error |
544
+ | 68 | Snapend promote error |
545
+ | 69 | Snapend promote server error |
546
+ | 70 | Snapend promote timeout error |
547
+ | 71 | Snapend download error |
548
+ | 72 | Snapend update error |
549
+ | 73 | Snapend update server error |
550
+ | 74 | Snapend update timeout error |
551
+ | 75 | Snapend state error |
552
+
553
+ ### Generate Errors
554
+
555
+ | Error Code | Description |
556
+ |------------|----------------------------------------------------------|
557
+ | 80 | Generic generate error |
558
+ | 81 | Generate BYOSNAP profile error |
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "snapctl"
3
- version = "0.32.0"
3
+ version = "0.32.1"
4
4
  description = "Snapser CLI Tool"
5
5
  authors = ["Ajinkya Apte <aj@snapser.com>"]
6
6
  readme = "README.md"
@@ -11,10 +11,12 @@ snapctl = "snapctl.main:app"
11
11
 
12
12
  [tool.poetry.dependencies]
13
13
  python = "^3.10"
14
- typer = {extras = ["all"], version = "^0.7.0"}
14
+ typer = {extras = ["all"], version = "^0.12.3"}
15
15
  requests = "^2.28.2"
16
16
  configparser = "^6.0.0"
17
17
  pyfiglet = "^1.0.2"
18
+ pytest = "^8.2.2"
19
+ pytest-mock = "^3.14.0"
18
20
 
19
21
 
20
22
  [build-system]
@@ -0,0 +1,319 @@
1
+ """
2
+ BYOGS CLI commands
3
+ """
4
+ import base64
5
+ from binascii import Error as BinasciiError
6
+ import os
7
+ import subprocess
8
+ from sys import platform
9
+ from typing import Union
10
+
11
+ import typer
12
+ from rich.progress import Progress, SpinnerColumn, TextColumn
13
+ from snapctl.config.constants import SNAPCTL_BYOGS_DEPENDENCY_MISSING, \
14
+ SNAPCTL_BYOGS_ECR_LOGIN_ERROR, SNAPCTL_BYOGS_BUILD_ERROR, \
15
+ SNAPCTL_BYOGS_TAG_ERROR, SNAPCTL_BYOGS_PUBLISH_ERROR, \
16
+ SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR, SNAPCTL_INPUT_ERROR
17
+ from snapctl.utils.echo import error, success
18
+ from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
19
+
20
+
21
+ class ByoGs:
22
+ """
23
+ BYOGS CLI commands
24
+ """
25
+ SID = 'byogs'
26
+ SUBCOMMANDS = ['publish']
27
+ PLATFORMS = ['linux/amd64']
28
+ LANGUAGES = ['go', 'python', 'ruby', 'c#', 'c++', 'rust', 'java', 'node']
29
+ DEFAULT_BUILD_PLATFORM = 'linux/amd64'
30
+ SID_CHARACTER_LIMIT = 47
31
+ TAG_CHARACTER_LIMIT = 80
32
+
33
+ def __init__(
34
+ self, subcommand: str, base_url: str, api_key: str | None,
35
+ input_tag: Union[str, None], path: Union[str, None], dockerfile: str,
36
+ ) -> None:
37
+ self.subcommand: str = subcommand
38
+ self.base_url: str = base_url
39
+ self.api_key: str = api_key
40
+ # self.sid: str = sid
41
+ # if subcommand == 'publish':
42
+ # self.sid = ByoGs.SID
43
+
44
+ self.token: Union[str, None] = get_composite_token(
45
+ base_url, api_key, 'byogs', {'service_id': ByoGs.SID}
46
+ )
47
+ self.token_parts: Union[list, None] = ByoGs._get_token_values(
48
+ self.token) if self.token is not None else None
49
+ self.input_tag: Union[str, None] = input_tag
50
+ self.path: Union[str, None] = path
51
+ self.dockerfile: str = dockerfile
52
+ # Validate input
53
+ self.validate_input()
54
+
55
+ # Protected methods
56
+
57
+ @staticmethod
58
+ def _get_token_values(token: str) -> None | list:
59
+ """
60
+ Get the token values
61
+ """
62
+ try:
63
+ input_token = base64.b64decode(token).decode('ascii')
64
+ token_parts = input_token.split('|')
65
+ # url|web_app_token|service_id|ecr_repo_url|ecr_repo_username|ecr_repo_token
66
+ # url = self.token_parts[0]
67
+ # web_app_token = self.token_parts[1]
68
+ # service_id = self.token_parts[2]
69
+ # ecr_repo_url = self.token_parts[3]
70
+ # ecr_repo_username = self.token_parts[4]
71
+ # ecr_repo_token = self.token_parts[5]
72
+ # platform = self.token_parts[6]
73
+ if len(token_parts) >= 3:
74
+ return token_parts
75
+ except BinasciiError:
76
+ pass
77
+ return None
78
+
79
+ def _check_dependencies(self) -> None:
80
+ progress = Progress(
81
+ SpinnerColumn(),
82
+ TextColumn("[progress.description]{task.description}"),
83
+ transient=True,
84
+ )
85
+ progress.start()
86
+ progress.add_task(
87
+ description='Checking dependencies...', total=None
88
+ )
89
+ try:
90
+ # Check dependencies
91
+ result = subprocess.run([
92
+ "docker", "info"
93
+ ], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
94
+ if not result.returncode:
95
+ return snapctl_success('BYOGS dependencies verified', progress, no_exit=True)
96
+ except subprocess.CalledProcessError:
97
+ snapctl_error('Snapctl Exception',
98
+ SNAPCTL_BYOGS_DEPENDENCY_MISSING, progress)
99
+ snapctl_error('Docker not running. Please start docker.',
100
+ SNAPCTL_BYOGS_DEPENDENCY_MISSING, progress)
101
+
102
+ def _docker_login(self) -> None:
103
+ # Get the data
104
+ ecr_repo_url = self.token_parts[0]
105
+ ecr_repo_username = self.token_parts[1]
106
+ ecr_repo_token = self.token_parts[2]
107
+ progress = Progress(
108
+ SpinnerColumn(),
109
+ TextColumn("[progress.description]{task.description}"),
110
+ transient=True,
111
+ )
112
+ progress.start()
113
+ progress.add_task(
114
+ description='Logging into Snapser Image Registry...', total=None)
115
+ try:
116
+ # Login to Snapser Registry
117
+ if platform == 'win32':
118
+ response = subprocess.run([
119
+ 'docker', 'login', '--username', ecr_repo_username,
120
+ '--password', ecr_repo_token, ecr_repo_url
121
+ ], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
122
+ else:
123
+ response = subprocess.run([
124
+ f'echo "{ecr_repo_token}" | docker login '
125
+ f'--username {ecr_repo_username} --password-stdin {ecr_repo_url}'
126
+ ], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
127
+ if not response.returncode:
128
+ return snapctl_success('BYOGS ECR login successful', progress, no_exit=True)
129
+ except subprocess.CalledProcessError:
130
+ snapctl_error('Snapctl Exception',
131
+ SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress)
132
+ snapctl_error('BYOGS ECR login failure',
133
+ SNAPCTL_BYOGS_ECR_LOGIN_ERROR, progress)
134
+
135
+ def _docker_build(self) -> None:
136
+ # Get the data
137
+ progress = Progress(
138
+ SpinnerColumn(),
139
+ TextColumn("[progress.description]{task.description}"),
140
+ transient=True,
141
+ )
142
+ progress.start()
143
+ progress.add_task(
144
+ description='Building your snap...', total=None)
145
+ try:
146
+ image_tag = f'{ByoGs.SID}.{self.input_tag}'
147
+ build_platform = ByoGs.DEFAULT_BUILD_PLATFORM
148
+ if len(self.token_parts) == 4:
149
+ build_platform = self.token_parts[3]
150
+ # Build your snap
151
+ docker_file_path = os.path.join(self.path, self.dockerfile)
152
+ if platform == "win32":
153
+ response = subprocess.run([
154
+ # f"docker build --no-cache -t {tag} {path}"
155
+ 'docker', 'build', '--platform', build_platform, '-t', image_tag,
156
+ '-f', docker_file_path, self.path
157
+ ], shell=True, check=False)
158
+ # stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
159
+ else:
160
+ response = subprocess.run([
161
+ # f"docker build --no-cache -t {tag} {path}"
162
+ f"docker build --platform {build_platform} -t {image_tag} "
163
+ f"-f {docker_file_path} {self.path}"
164
+ ], shell=True, check=False)
165
+ # stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
166
+ if not response.returncode:
167
+ return snapctl_success('BYOGS build successful', progress, no_exit=True)
168
+ except subprocess.CalledProcessError:
169
+ snapctl_error('Snapctl Exception',
170
+ SNAPCTL_BYOGS_BUILD_ERROR, progress)
171
+ snapctl_error('BYOGS build failure',
172
+ SNAPCTL_BYOGS_BUILD_ERROR, progress)
173
+
174
+ def _docker_tag(self) -> None:
175
+ # Get the data
176
+ progress = Progress(
177
+ SpinnerColumn(),
178
+ TextColumn("[progress.description]{task.description}"),
179
+ transient=True,
180
+ )
181
+ progress.start()
182
+ progress.add_task(
183
+ description='Tagging your snap...', total=None)
184
+ try:
185
+ ecr_repo_url = self.token_parts[0]
186
+ image_tag = f'{ByoGs.SID}.{self.input_tag}'
187
+ full_ecr_repo_url = f'{ecr_repo_url}:{image_tag}'
188
+ # Tag the repo
189
+ if platform == "win32":
190
+ response = subprocess.run([
191
+ 'docker', 'tag', image_tag, full_ecr_repo_url
192
+ ], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
193
+ else:
194
+ response = subprocess.run([
195
+ f"docker tag {image_tag} {full_ecr_repo_url}"
196
+ ], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
197
+ if not response.returncode:
198
+ return snapctl_success('BYOGS tag successful', progress, no_exit=True)
199
+ except subprocess.CalledProcessError:
200
+ snapctl_error('Snapctl Exception',
201
+ SNAPCTL_BYOGS_TAG_ERROR, progress)
202
+ snapctl_error('BYOGS tag failure', SNAPCTL_BYOGS_TAG_ERROR, progress)
203
+
204
+ def _docker_push(self) -> None:
205
+ progress = Progress(
206
+ SpinnerColumn(),
207
+ TextColumn("[progress.description]{task.description}"),
208
+ transient=True,
209
+ )
210
+ progress.start()
211
+ progress.add_task(
212
+ description='Pushing your snap...', total=None)
213
+ try:
214
+ ecr_repo_url = self.token_parts[0]
215
+ image_tag = f'{ByoGs.SID}.{self.input_tag}'
216
+ full_ecr_repo_url = f'{ecr_repo_url}:{image_tag}'
217
+ # Push the image
218
+ if platform == "win32":
219
+ response = subprocess.run([
220
+ 'docker', 'push', full_ecr_repo_url
221
+ ], shell=True, check=False)
222
+ # stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
223
+ else:
224
+ response = subprocess.run([
225
+ f"docker push {full_ecr_repo_url}"
226
+ ], shell=True, check=False)
227
+ # stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
228
+ if not response.returncode:
229
+ return snapctl_success('BYOGS upload successful', progress, no_exit=True)
230
+ except subprocess.CalledProcessError:
231
+ snapctl_error('Snapctl Exception',
232
+ SNAPCTL_BYOGS_PUBLISH_ERROR, progress)
233
+ snapctl_error('BYOGS upload failure. Duplicate image error.',
234
+ SNAPCTL_BYOGS_PUBLISH_DUPLICATE_TAG_ERROR, progress)
235
+
236
+ # Public methods
237
+
238
+ # Validator
239
+ def validate_input(self) -> None:
240
+ """
241
+ Validator
242
+ """
243
+ # Check API Key and Base URL
244
+ if not self.api_key or self.base_url == '':
245
+ snapctl_error("Missing API Key.", SNAPCTL_INPUT_ERROR)
246
+ # Check subcommand
247
+ if not self.subcommand in ByoGs.SUBCOMMANDS:
248
+ snapctl_error(
249
+ f"Invalid command. Valid commands are {', '.join(ByoGs.SUBCOMMANDS)}.",
250
+ SNAPCTL_INPUT_ERROR)
251
+ # Validation for subcommands
252
+ if self.token_parts is None:
253
+ snapctl_error('Invalid token. Please reach out to your support team',
254
+ SNAPCTL_INPUT_ERROR)
255
+ # Check tag
256
+ if self.input_tag is None:
257
+ snapctl_error("Missing required parameter: tag",
258
+ SNAPCTL_INPUT_ERROR)
259
+ if len(self.input_tag.split()) > 1 or len(self.input_tag) > ByoGs.TAG_CHARACTER_LIMIT:
260
+ snapctl_error(
261
+ "Tag should be a single word with maximum of "
262
+ f"{ByoGs.TAG_CHARACTER_LIMIT} characters",
263
+ SNAPCTL_INPUT_ERROR
264
+ )
265
+ if self.subcommand in ['build', 'publish']:
266
+ if not self.path:
267
+ snapctl_error("Missing required parameter: path",
268
+ SNAPCTL_INPUT_ERROR)
269
+ # Check path
270
+ if not os.path.isfile(f"{self.path}/{self.dockerfile}"):
271
+ snapctl_error(
272
+ f"Unable to find {self.dockerfile} at path {self.path}", SNAPCTL_INPUT_ERROR)
273
+ # elif self.subcommand == 'push':
274
+ # if not self.input_tag:
275
+ # error("Missing required parameter: tag", SNAPCTL_INPUT_ERROR)
276
+ # raise typer.Exit(code=SNAPCTL_INPUT_ERROR)
277
+
278
+ # CRUD methods
279
+ def build(self) -> None:
280
+ """
281
+ Build the image
282
+ 1. Check Dependencies
283
+ 2. Login to Snapser Registry
284
+ 3. Build your snap
285
+ """
286
+ self._check_dependencies()
287
+ self._docker_login()
288
+ self._docker_build()
289
+
290
+ def push(self) -> None:
291
+ """
292
+ Tag the image
293
+ 1. Check Dependencies
294
+ 2. Login to Snapser Registry
295
+ 3. Tag the snap
296
+ 4. Push your snap
297
+ """
298
+ self._check_dependencies()
299
+ self._docker_login()
300
+ self._docker_tag()
301
+ self._docker_push()
302
+
303
+ # Upper echelon commands
304
+ def publish(self) -> None:
305
+ """
306
+ Publish the image
307
+ 1. Check Dependencies
308
+ 2. Login to Snapser Registry
309
+ 3. Build your snap
310
+ 4. Tag the repo
311
+ 5. Push the image
312
+ 6. Upload swagger.json
313
+ """
314
+ self._check_dependencies()
315
+ self._docker_login()
316
+ self._docker_build()
317
+ self._docker_tag()
318
+ self._docker_push()
319
+ snapctl_success('BYOGS publish successful')