snapctl 0.32.0__py3-none-any.whl → 0.32.2__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 +175 -181
- snapctl/commands/byosnap.py +378 -371
- snapctl/commands/game.py +63 -57
- snapctl/commands/generate.py +48 -32
- snapctl/commands/snapend.py +361 -281
- snapctl/config/constants.py +72 -8
- snapctl/main.py +100 -135
- snapctl/types/definitions.py +20 -4
- snapctl/utils/echo.py +10 -2
- snapctl/utils/helper.py +60 -3
- {snapctl-0.32.0.dist-info → snapctl-0.32.2.dist-info}/METADATA +120 -8
- snapctl-0.32.2.dist-info/RECORD +23 -0
- snapctl-0.32.0.dist-info/RECORD +0 -23
- {snapctl-0.32.0.dist-info → snapctl-0.32.2.dist-info}/LICENSE +0 -0
- {snapctl-0.32.0.dist-info → snapctl-0.32.2.dist-info}/WHEEL +0 -0
- {snapctl-0.32.0.dist-info → snapctl-0.32.2.dist-info}/entry_points.txt +0 -0
snapctl/commands/byogs.py
CHANGED
|
@@ -8,10 +8,14 @@ import subprocess
|
|
|
8
8
|
from sys import platform
|
|
9
9
|
from typing import Union
|
|
10
10
|
|
|
11
|
+
import typer
|
|
11
12
|
from rich.progress import Progress, SpinnerColumn, TextColumn
|
|
12
|
-
from snapctl.
|
|
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
|
|
13
17
|
from snapctl.utils.echo import error, success
|
|
14
|
-
from snapctl.utils.helper import get_composite_token
|
|
18
|
+
from snapctl.utils.helper import get_composite_token, snapctl_error, snapctl_success
|
|
15
19
|
|
|
16
20
|
|
|
17
21
|
class ByoGs:
|
|
@@ -19,7 +23,7 @@ class ByoGs:
|
|
|
19
23
|
BYOGS CLI commands
|
|
20
24
|
"""
|
|
21
25
|
SID = 'byogs'
|
|
22
|
-
SUBCOMMANDS = ['
|
|
26
|
+
SUBCOMMANDS = ['publish']
|
|
23
27
|
PLATFORMS = ['linux/amd64']
|
|
24
28
|
LANGUAGES = ['go', 'python', 'ruby', 'c#', 'c++', 'rust', 'java', 'node']
|
|
25
29
|
DEFAULT_BUILD_PLATFORM = 'linux/amd64'
|
|
@@ -45,6 +49,8 @@ class ByoGs:
|
|
|
45
49
|
self.input_tag: Union[str, None] = input_tag
|
|
46
50
|
self.path: Union[str, None] = path
|
|
47
51
|
self.dockerfile: str = dockerfile
|
|
52
|
+
# Validate input
|
|
53
|
+
self.validate_input()
|
|
48
54
|
|
|
49
55
|
# Protected methods
|
|
50
56
|
|
|
@@ -70,232 +76,218 @@ class ByoGs:
|
|
|
70
76
|
pass
|
|
71
77
|
return None
|
|
72
78
|
|
|
73
|
-
def _check_dependencies(self) ->
|
|
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
|
+
)
|
|
74
89
|
try:
|
|
75
90
|
# Check dependencies
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
progress.add_task(
|
|
82
|
-
description='Checking dependencies...', total=None)
|
|
83
|
-
try:
|
|
84
|
-
subprocess.run([
|
|
85
|
-
"docker", "--version"
|
|
86
|
-
], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
87
|
-
except subprocess.CalledProcessError:
|
|
88
|
-
error('Docker not present')
|
|
89
|
-
return False
|
|
90
|
-
success('Dependencies Verified')
|
|
91
|
-
return True
|
|
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)
|
|
92
96
|
except subprocess.CalledProcessError:
|
|
93
|
-
|
|
94
|
-
|
|
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)
|
|
95
101
|
|
|
96
|
-
def _docker_login(self) ->
|
|
102
|
+
def _docker_login(self) -> None:
|
|
97
103
|
# Get the data
|
|
98
104
|
ecr_repo_url = self.token_parts[0]
|
|
99
105
|
ecr_repo_username = self.token_parts[1]
|
|
100
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)
|
|
101
115
|
try:
|
|
102
116
|
# Login to Snapser Registry
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
else:
|
|
116
|
-
response = subprocess.run([
|
|
117
|
-
f'echo "{ecr_repo_token}" | docker login '
|
|
118
|
-
f'--username {ecr_repo_username} --password-stdin {ecr_repo_url}'
|
|
119
|
-
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
120
|
-
if response.returncode:
|
|
121
|
-
error(
|
|
122
|
-
'Unable to connect to the Snapser Container Repository. '
|
|
123
|
-
'Please confirm if docker is running or try restarting docker'
|
|
124
|
-
)
|
|
125
|
-
return False
|
|
126
|
-
success('Login Successful')
|
|
127
|
-
return True
|
|
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)
|
|
128
129
|
except subprocess.CalledProcessError:
|
|
129
|
-
|
|
130
|
-
|
|
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)
|
|
131
134
|
|
|
132
|
-
def _docker_build(self) ->
|
|
135
|
+
def _docker_build(self) -> None:
|
|
133
136
|
# Get the data
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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)
|
|
138
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]
|
|
139
150
|
# Build your snap
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# f"docker build --no-cache -t {tag} {path}"
|
|
158
|
-
f"docker build --platform {build_platform} -t {image_tag} -f {docker_file_path} {self.path}"
|
|
159
|
-
], shell=True, check=False)
|
|
160
|
-
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
161
|
-
if response.returncode:
|
|
162
|
-
error('Unable to build docker')
|
|
163
|
-
return False
|
|
164
|
-
success('Build Successful')
|
|
165
|
-
return True
|
|
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)
|
|
166
168
|
except subprocess.CalledProcessError:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
+
snapctl_error('Snapctl Exception',
|
|
170
|
+
SNAPCTL_BYOGS_BUILD_ERROR, progress)
|
|
171
|
+
snapctl_error('BYOGS build failure',
|
|
172
|
+
SNAPCTL_BYOGS_BUILD_ERROR, progress)
|
|
169
173
|
|
|
170
|
-
def _docker_tag(self) ->
|
|
174
|
+
def _docker_tag(self) -> None:
|
|
171
175
|
# Get the data
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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)
|
|
175
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}'
|
|
176
188
|
# Tag the repo
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
188
|
-
else:
|
|
189
|
-
response = subprocess.run([
|
|
190
|
-
f"docker tag {image_tag} {full_ecr_repo_url}"
|
|
191
|
-
], shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, check=False)
|
|
192
|
-
if response.returncode:
|
|
193
|
-
error('Unable to tag your snap')
|
|
194
|
-
return False
|
|
195
|
-
success('Tag Successful')
|
|
196
|
-
return True
|
|
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)
|
|
197
199
|
except subprocess.CalledProcessError:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
+
snapctl_error('Snapctl Exception',
|
|
201
|
+
SNAPCTL_BYOGS_TAG_ERROR, progress)
|
|
202
|
+
snapctl_error('BYOGS tag failure', SNAPCTL_BYOGS_TAG_ERROR, progress)
|
|
200
203
|
|
|
201
|
-
def _docker_push(self) ->
|
|
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)
|
|
202
213
|
try:
|
|
203
214
|
ecr_repo_url = self.token_parts[0]
|
|
204
215
|
image_tag = f'{ByoGs.SID}.{self.input_tag}'
|
|
205
216
|
full_ecr_repo_url = f'{ecr_repo_url}:{image_tag}'
|
|
206
|
-
|
|
207
217
|
# Push the image
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
else:
|
|
221
|
-
response = subprocess.run([
|
|
222
|
-
f"docker push {full_ecr_repo_url}"
|
|
223
|
-
], shell=True, check=False)
|
|
224
|
-
# stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
|
|
225
|
-
if response.returncode:
|
|
226
|
-
error('Unable to push your snap')
|
|
227
|
-
return False
|
|
228
|
-
success('Snap Upload Successful')
|
|
229
|
-
return True
|
|
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
230
|
except subprocess.CalledProcessError:
|
|
231
|
-
|
|
232
|
-
|
|
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)
|
|
233
235
|
|
|
234
236
|
# Public methods
|
|
235
237
|
|
|
236
238
|
# Validator
|
|
237
|
-
def validate_input(self) ->
|
|
239
|
+
def validate_input(self) -> None:
|
|
238
240
|
"""
|
|
239
241
|
Validator
|
|
240
242
|
"""
|
|
241
|
-
response: ResponseType = {
|
|
242
|
-
'error': True,
|
|
243
|
-
'msg': '',
|
|
244
|
-
'data': []
|
|
245
|
-
}
|
|
246
243
|
# Check API Key and Base URL
|
|
247
244
|
if not self.api_key or self.base_url == '':
|
|
248
|
-
|
|
249
|
-
return response
|
|
245
|
+
snapctl_error("Missing API Key.", SNAPCTL_INPUT_ERROR)
|
|
250
246
|
# Check subcommand
|
|
251
247
|
if not self.subcommand in ByoGs.SUBCOMMANDS:
|
|
252
|
-
|
|
253
|
-
|
|
248
|
+
snapctl_error(
|
|
249
|
+
f"Invalid command. Valid commands are {', '.join(ByoGs.SUBCOMMANDS)}.",
|
|
250
|
+
SNAPCTL_INPUT_ERROR)
|
|
254
251
|
# Validation for subcommands
|
|
255
252
|
if self.token_parts is None:
|
|
256
|
-
|
|
257
|
-
|
|
253
|
+
snapctl_error('Invalid token. Please reach out to your support team',
|
|
254
|
+
SNAPCTL_INPUT_ERROR)
|
|
258
255
|
# Check tag
|
|
259
|
-
if self.input_tag is None
|
|
260
|
-
|
|
261
|
-
|
|
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(
|
|
262
261
|
"Tag should be a single word with maximum of "
|
|
263
|
-
f"{ByoGs.TAG_CHARACTER_LIMIT} characters"
|
|
262
|
+
f"{ByoGs.TAG_CHARACTER_LIMIT} characters",
|
|
263
|
+
SNAPCTL_INPUT_ERROR
|
|
264
264
|
)
|
|
265
|
-
return response
|
|
266
265
|
if self.subcommand in ['build', 'publish']:
|
|
267
|
-
if not self.input_tag:
|
|
268
|
-
response['msg'] = "Missing required parameter: tag"
|
|
269
|
-
return response
|
|
270
266
|
if not self.path:
|
|
271
|
-
|
|
272
|
-
|
|
267
|
+
snapctl_error("Missing required parameter: path",
|
|
268
|
+
SNAPCTL_INPUT_ERROR)
|
|
273
269
|
# Check path
|
|
274
270
|
if not os.path.isfile(f"{self.path}/{self.dockerfile}"):
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
elif self.subcommand == 'push':
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
# Send success
|
|
282
|
-
response['error'] = False
|
|
283
|
-
return response
|
|
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)
|
|
284
277
|
|
|
285
278
|
# CRUD methods
|
|
286
|
-
def build(self) ->
|
|
279
|
+
def build(self) -> None:
|
|
287
280
|
"""
|
|
288
281
|
Build the image
|
|
289
282
|
1. Check Dependencies
|
|
290
283
|
2. Login to Snapser Registry
|
|
291
284
|
3. Build your snap
|
|
292
285
|
"""
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return True
|
|
286
|
+
self._check_dependencies()
|
|
287
|
+
self._docker_login()
|
|
288
|
+
self._docker_build()
|
|
297
289
|
|
|
298
|
-
def push(self) ->
|
|
290
|
+
def push(self) -> None:
|
|
299
291
|
"""
|
|
300
292
|
Tag the image
|
|
301
293
|
1. Check Dependencies
|
|
@@ -303,13 +295,13 @@ class ByoGs:
|
|
|
303
295
|
3. Tag the snap
|
|
304
296
|
4. Push your snap
|
|
305
297
|
"""
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
298
|
+
self._check_dependencies()
|
|
299
|
+
self._docker_login()
|
|
300
|
+
self._docker_tag()
|
|
301
|
+
self._docker_push()
|
|
310
302
|
|
|
311
303
|
# Upper echelon commands
|
|
312
|
-
def publish(self) ->
|
|
304
|
+
def publish(self) -> None:
|
|
313
305
|
"""
|
|
314
306
|
Publish the image
|
|
315
307
|
1. Check Dependencies
|
|
@@ -319,7 +311,9 @@ class ByoGs:
|
|
|
319
311
|
5. Push the image
|
|
320
312
|
6. Upload swagger.json
|
|
321
313
|
"""
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
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')
|