konduktor-nightly 0.1.0.dev20250903104451__py3-none-any.whl → 0.1.0.dev20250905104548__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 konduktor-nightly might be problematic. Click here for more details.

konduktor/__init__.py CHANGED
@@ -11,7 +11,7 @@ from konduktor.task import Task
11
11
  __all__ = ['launch', 'Resources', 'Task', 'Serving']
12
12
 
13
13
  # Replaced with the current commit when building the wheels.
14
- _KONDUKTOR_COMMIT_SHA = 'cb72c75ad328b535768794b5979a5ec56edb3d8e'
14
+ _KONDUKTOR_COMMIT_SHA = 'fc389d2cefc1394a2bb1f1c5e03cb900f3ce8406'
15
15
  os.makedirs(os.path.expanduser('~/.konduktor'), exist_ok=True)
16
16
 
17
17
 
@@ -45,5 +45,5 @@ def _get_git_commit():
45
45
 
46
46
 
47
47
  __commit__ = _get_git_commit()
48
- __version__ = '1.0.0.dev0.1.0.dev20250903104451'
48
+ __version__ = '1.0.0.dev0.1.0.dev20250905104548'
49
49
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
@@ -578,8 +578,8 @@ def show_status_table(
578
578
  num_accelerators = job['metadata']['labels'].get(
579
579
  JOBSET_NUM_ACCELERATORS_LABEL, None
580
580
  )
581
- if accelerator:
582
- if num_accelerators:
581
+ if accelerator and accelerator != 'None':
582
+ if num_accelerators and num_accelerators != '0':
583
583
  accelerator_with_count = f'{accelerator}:{num_accelerators}'
584
584
  else:
585
585
  accelerator_with_count = accelerator
konduktor/cli.py CHANGED
@@ -58,6 +58,7 @@ from konduktor.utils import (
58
58
  kubernetes_utils,
59
59
  log_utils,
60
60
  ux_utils,
61
+ validator,
61
62
  )
62
63
 
63
64
  _CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
@@ -419,6 +420,8 @@ def _parse_override_params(
419
420
  if image_id.lower() == 'none':
420
421
  override_params['image_id'] = None
421
422
  else:
423
+ # Validate Docker image before adding to override params
424
+ validator.validate_and_warn_image(image_id, 'task')
422
425
  override_params['image_id'] = image_id
423
426
  if disk_size is not None:
424
427
  override_params['disk_size'] = disk_size
@@ -133,7 +133,7 @@ spec:
133
133
  spec:
134
134
  containers:
135
135
  - name: apoxy
136
- image: apoxy/apoxy:v0.11.10
136
+ image: apoxy/apoxy:v0.11.14
137
137
  command: ["apoxy", "tunnel", "run", "UNIQUE-TEMPNAME", "--insecure-skip-verify"]
138
138
  volumeMounts:
139
139
  - name: kubeconfig-volume
konduktor/resource.py CHANGED
@@ -16,7 +16,13 @@ import functools
16
16
  from typing import Any, Dict, List, Optional, Union
17
17
 
18
18
  from konduktor import logging
19
- from konduktor.utils import accelerator_registry, common_utils, schemas, ux_utils
19
+ from konduktor.utils import (
20
+ accelerator_registry,
21
+ common_utils,
22
+ schemas,
23
+ ux_utils,
24
+ validator,
25
+ )
20
26
 
21
27
  logger = logging.get_logger(__name__)
22
28
 
@@ -117,6 +123,8 @@ class Resources:
117
123
  self._image_id = image_id
118
124
  if isinstance(image_id, str):
119
125
  self._image_id = image_id.strip()
126
+ # Validate Docker image format and existence
127
+ validator.validate_and_warn_image(self._image_id, 'task')
120
128
 
121
129
  self._labels = labels
122
130
  self._cluster_config_overrides = _cluster_config_overrides
konduktor/task.py CHANGED
@@ -29,7 +29,7 @@ import konduktor
29
29
  from konduktor import constants, logging
30
30
  from konduktor.data import data_utils
31
31
  from konduktor.data import storage as storage_lib
32
- from konduktor.utils import common_utils, exceptions, schemas, ux_utils
32
+ from konduktor.utils import common_utils, exceptions, schemas, ux_utils, validator
33
33
 
34
34
  logger = logging.get_logger(__name__)
35
35
 
@@ -387,6 +387,11 @@ class Task:
387
387
  'experimental.config_overrides'
388
388
  )
389
389
  resources_config['_cluster_config_overrides'] = cluster_config_override
390
+
391
+ # Validate Docker image if specified in resources
392
+ if 'image_id' in resources_config and resources_config['image_id']:
393
+ validator.validate_and_warn_image(resources_config['image_id'], 'task')
394
+
390
395
  task.set_resources(konduktor.Resources.from_yaml_config(resources_config))
391
396
 
392
397
  # Parse serving field.
@@ -77,6 +77,8 @@ kubernetes:
77
77
  # flush logs immediately to stdout for more reactive log streaming
78
78
  - name: PYTHONUNBUFFERED
79
79
  value: "0"
80
+ - name: KONDUKTOR_JOB_NAME
81
+ value: "{{ job_name }}"
80
82
  - name: NODE_HOST_IPS
81
83
  value: "{{ node_hostnames }}"
82
84
  - name: MASTER_ADDR
@@ -5,9 +5,14 @@ allow for case-insensitive enum matching since this is currently not supported
5
5
  by the JSON Schema specification.
6
6
  """
7
7
 
8
+ import base64
8
9
  import json
10
+ import os
11
+ import re
12
+ import subprocess
9
13
  import time
10
14
  from pathlib import Path
15
+ from typing import Tuple
11
16
 
12
17
  import jsonschema
13
18
  import requests
@@ -124,3 +129,321 @@ def validate_service_spec(service_spec: dict) -> None:
124
129
  def validate_horizontalpodautoscaler_spec(hpa_spec: dict) -> None:
125
130
  """Validate a Kubernetes HorizontalPodAutoscaler spec."""
126
131
  _validate_k8s_spec(hpa_spec, 'horizontalpodautoscaler', 'horizontalpodautoscaler')
132
+
133
+
134
+ def validate_docker_image(image_id: str) -> Tuple[str, str]:
135
+ """Validate if a Docker image exists and is accessible.
136
+
137
+ Args:
138
+ image_id: The Docker image ID to validate
139
+ (e.g., 'ubuntu:latest', 'gcr.io/project/image:tag')
140
+
141
+ Returns:
142
+ Tuple of (status, message) where status is:
143
+ - 'valid': Image definitely exists
144
+ - 'warning': Couldn't validate, but might be valid
145
+ - 'invalid': Image definitely doesn't exist
146
+ """
147
+ if not image_id or not isinstance(image_id, str):
148
+ return 'invalid', 'Image ID must be a non-empty string'
149
+
150
+ # Basic format validation
151
+ if not _is_valid_docker_image_format(image_id):
152
+ return 'invalid', f'Invalid Docker image format: {image_id}'
153
+
154
+ # Try registry API validation first (works without Docker daemon)
155
+ registry_result = _validate_image_in_registry(image_id)
156
+ if registry_result[0] in ['valid', 'invalid']:
157
+ return registry_result
158
+
159
+ # If registry validation couldn't determine, try local Docker as fallback
160
+ if _can_pull_image_locally(image_id):
161
+ return 'valid', f"Docker image '{image_id}' validated locally"
162
+
163
+ # Return the registry result (warning)
164
+ return registry_result
165
+
166
+
167
+ def _is_valid_docker_image_format(image_id: str) -> bool:
168
+ """Check if the image ID follows valid Docker image naming conventions."""
169
+ # Basic regex for Docker image names
170
+ # Supports: name:tag, registry/name:tag, registry/namespace/name:tag
171
+ pattern = (
172
+ r'^[a-zA-Z0-9][a-zA-Z0-9._-]*'
173
+ r'(?:\/[a-zA-Z0-9][a-zA-Z0-9._-]*)*'
174
+ r'(?::[a-zA-Z0-9._-]+)?$'
175
+ )
176
+ return bool(re.match(pattern, image_id))
177
+
178
+
179
+ def _can_pull_image_locally(image_id: str) -> bool:
180
+ """Try to inspect the image manifest locally to check if it exists."""
181
+ try:
182
+ # Use docker manifest inspect instead of pull for faster validation
183
+ result = subprocess.run(
184
+ ['docker', 'manifest', 'inspect', image_id],
185
+ capture_output=True,
186
+ text=True,
187
+ timeout=30, # 30 second timeout
188
+ )
189
+
190
+ # Debug logging
191
+ logger.debug(
192
+ f'Local Docker manifest inspect for {image_id}: '
193
+ f'returncode={result.returncode}, '
194
+ f"stdout='{result.stdout}', "
195
+ f"stderr='{result.stderr}'"
196
+ )
197
+
198
+ return result.returncode == 0
199
+ except (
200
+ subprocess.TimeoutExpired,
201
+ FileNotFoundError,
202
+ subprocess.SubprocessError,
203
+ ) as e:
204
+ # Docker not available or timeout
205
+ logger.debug(f'Local Docker manifest inspect failed for {image_id}: {e}')
206
+ return False
207
+
208
+
209
+ def _validate_image_in_registry(image_id: str) -> Tuple[str, str]:
210
+ """Validate image exists in registry using API calls."""
211
+ try:
212
+ registry, repo, tag = _parse_image_components(image_id)
213
+
214
+ if registry == 'docker.io':
215
+ return _validate_dockerhub_image(repo, tag)
216
+ elif registry.endswith('gcr.io'):
217
+ return _validate_gcr_image(registry, repo, tag)
218
+ elif registry.endswith('ecr.') and '.amazonaws.com' in registry:
219
+ return _validate_ecr_image(registry, repo, tag)
220
+ elif registry == 'nvcr.io':
221
+ return _validate_nvcr_image(registry, repo, tag)
222
+ elif registry == 'ghcr.io':
223
+ return _validate_ghcr_image(registry, repo, tag)
224
+ elif registry == 'quay.io':
225
+ return _validate_quay_image(registry, repo, tag)
226
+ else:
227
+ # For other registries, we can't easily validate without credentials
228
+ # Return warning that we couldn't verify
229
+ return (
230
+ 'warning',
231
+ f"Could not validate '{image_id}' in registry {registry} "
232
+ f'(not supported)',
233
+ )
234
+
235
+ except Exception as e:
236
+ logger.debug(f'Error validating image {image_id}: {e}')
237
+ return 'warning', f"Could not validate '{image_id}' due to validation error"
238
+
239
+
240
+ def _parse_image_components(image_id: str) -> Tuple[str, str, str]:
241
+ """Parse image ID into registry, repository, and tag components."""
242
+ # Default to Docker Hub
243
+ if '/' not in image_id or '.' not in image_id.split('/')[0]:
244
+ registry = 'docker.io'
245
+ # For Docker Hub official images (single word), add 'library/' prefix
246
+ if ':' in image_id:
247
+ repo, tag = image_id.rsplit(':', 1)
248
+ else:
249
+ repo = image_id
250
+ tag = 'latest'
251
+ # Only add 'library/' prefix for single-word official images
252
+ if '/' not in repo:
253
+ repo = f'library/{repo}'
254
+ else:
255
+ parts = image_id.split('/')
256
+ if '.' in parts[0] or parts[0] in ['localhost']:
257
+ registry = parts[0]
258
+ repo = '/'.join(parts[1:])
259
+ else:
260
+ registry = 'docker.io'
261
+ repo = image_id
262
+
263
+ # Split repository and tag
264
+ if ':' in repo:
265
+ repo, tag = repo.rsplit(':', 1)
266
+ else:
267
+ tag = 'latest'
268
+
269
+ return registry, repo, tag
270
+
271
+
272
+ def _validate_dockerhub_image(repo: str, tag: str) -> Tuple[str, str]:
273
+ """Validate image exists in Docker Hub using the official API."""
274
+ try:
275
+ # Use Docker Hub's official API v2 endpoint
276
+ # This endpoint checks if a specific tag exists for a repository
277
+ url = f'https://registry.hub.docker.com/v2/repositories/{repo}/tags/{tag}'
278
+
279
+ # Add User-Agent to avoid being blocked
280
+ headers = {'User-Agent': 'Konduktor-Docker-Validator/1.0'}
281
+
282
+ response = requests.get(url, headers=headers, timeout=10)
283
+
284
+ if response.status_code == 200:
285
+ return 'valid', f"Docker image '{repo}:{tag}' validated via Docker Hub"
286
+ else:
287
+ # API error, can't determine
288
+ return ('warning', f"Could not validate '{repo}:{tag}' in Docker Hub")
289
+
290
+ except requests.RequestException:
291
+ # Network error, can't determine
292
+ return (
293
+ 'warning',
294
+ f"Could not validate '{repo}:{tag}' in Docker Hub " f'(network error)',
295
+ )
296
+
297
+
298
+ def _validate_gcr_image(registry: str, repo: str, tag: str) -> Tuple[str, str]:
299
+ """Validate image exists in Google Container Registry."""
300
+ try:
301
+ # GCR manifest endpoint
302
+ url = f'https://{registry}/v2/{repo}/manifests/{tag}'
303
+ response = requests.get(url, timeout=10)
304
+
305
+ if response.status_code == 200:
306
+ return 'valid', f"Docker image '{repo}:{tag}' validated via {registry}"
307
+ else:
308
+ # API error, can't determine
309
+ return ('warning', f"Could not validate '{repo}:{tag}' in {registry} ")
310
+
311
+ except requests.RequestException:
312
+ # Network error, can't determine
313
+ return (
314
+ 'warning',
315
+ f"Could not validate '{repo}:{tag}' in {registry} " f'(network error)',
316
+ )
317
+
318
+
319
+ def _validate_ecr_image(registry: str, repo: str, tag: str) -> Tuple[str, str]:
320
+ """Validate image exists in Amazon ECR."""
321
+ # ECR requires AWS credentials and is complex to validate
322
+ # For now, return warning that we couldn't verify
323
+ return ('warning', f"Could not validate '{repo}:{tag}' in {registry}")
324
+
325
+
326
+ def _validate_nvcr_image(registry: str, repo: str, tag: str) -> Tuple[str, str]:
327
+ """Validate image exists in NVIDIA Container Registry."""
328
+ # NVCR requires NVIDIA credentials and is complex to validate
329
+ # For now, return warning that we couldn't verify
330
+ return ('warning', f"Could not validate '{repo}:{tag}' in {registry}")
331
+
332
+
333
+ def _validate_ghcr_image(registry: str, repo: str, tag: str) -> Tuple[str, str]:
334
+ """Validate image exists in GitHub Container Registry."""
335
+ try:
336
+ # Check if GITHUB_TOKEN is available
337
+ github_token = os.environ.get('GITHUB_TOKEN')
338
+
339
+ # If not in environment, try to get from konduktor secrets
340
+ if not github_token:
341
+ try:
342
+ # these imports are inside the try block to avoid circular import error
343
+ from konduktor.backends import constants as backend_constants
344
+ from konduktor.utils import common_utils, kubernetes_utils
345
+
346
+ context = kubernetes_utils.get_current_kube_config_context_name()
347
+ namespace = kubernetes_utils.get_kube_config_context_namespace(context)
348
+ user_hash = common_utils.get_user_hash()
349
+ label_selector = f'{backend_constants.SECRET_OWNER_LABEL}={user_hash}'
350
+ user_secrets = kubernetes_utils.list_secrets(
351
+ namespace, context, label_filter=label_selector
352
+ )
353
+
354
+ for secret in user_secrets:
355
+ kind = kubernetes_utils.get_secret_kind(secret)
356
+ if kind == 'env' and secret.data and 'GITHUB_TOKEN' in secret.data:
357
+ # Decode the base64 encoded token
358
+ github_token = base64.b64decode(
359
+ secret.data['GITHUB_TOKEN']
360
+ ).decode()
361
+ logger.debug('GITHUB_TOKEN found in konduktor secret')
362
+ break
363
+
364
+ except Exception as e:
365
+ logger.debug(f'Failed to check konduktor secrets: {e}')
366
+
367
+ if not github_token:
368
+ return (
369
+ 'warning',
370
+ 'GITHUB_TOKEN unset, cannot verify this image. '
371
+ 'To enable validation, either:\n'
372
+ ' 1. Set GITHUB_TOKEN locally: export GITHUB_TOKEN=<token>\n'
373
+ ' 2. Create a secret: konduktor secret create --kind=env '
374
+ '--inline GITHUB_TOKEN=<token> <name>\n'
375
+ 'See: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry',
376
+ )
377
+
378
+ # Base64 encode the token
379
+ ghcr_token = base64.b64encode(github_token.encode()).decode()
380
+
381
+ # GHCR manifest endpoint
382
+ url = f'https://{registry}/v2/{repo}/manifests/{tag}'
383
+ headers = {'Authorization': f'Bearer {ghcr_token}'}
384
+ response = requests.get(url, headers=headers, timeout=10)
385
+
386
+ if response.status_code == 200:
387
+ return 'valid', f"Docker image '{repo}:{tag}' validated via {registry}"
388
+ else:
389
+ # API error, can't determine
390
+ return ('warning', f"Could not validate '{repo}:{tag}' in {registry}")
391
+
392
+ except requests.RequestException:
393
+ # Network error, can't determine
394
+ return (
395
+ 'warning',
396
+ f"Could not validate '{repo}:{tag}' in {registry} " f'(network error)',
397
+ )
398
+
399
+
400
+ def _validate_quay_image(registry: str, repo: str, tag: str) -> Tuple[str, str]:
401
+ """Validate image exists in Quay.io Container Registry."""
402
+ # Quay.io requires authentication and is complex to validate
403
+ # For now, return warning that we couldn't verify
404
+ return ('warning', f"Could not validate '{repo}:{tag}' in {registry}")
405
+
406
+
407
+ # Track which images we've already warned about to avoid duplicate warnings
408
+ _warned_images = set()
409
+
410
+
411
+ def validate_and_warn_image(image_id: str, context: str = 'task') -> None:
412
+ """Validate Docker image and show appropriate warnings.
413
+
414
+ Args:
415
+ image_id: The Docker image ID to validate
416
+ context: Context for the validation (e.g., "task", "deployment")
417
+
418
+ """
419
+ if not image_id:
420
+ return
421
+
422
+ status, message = validate_docker_image(image_id)
423
+
424
+ if status == 'invalid':
425
+ # Invalid images should fail - they definitely don't exist
426
+ raise ValueError(
427
+ f'{message}\n'
428
+ f'This Docker image does not exist and will cause the {context} to fail.\n'
429
+ f"Please check that the image '{image_id}' is correct and accessible.\n"
430
+ )
431
+ elif status == 'warning':
432
+ # Only warn once per image per session for warnings
433
+ if image_id not in _warned_images:
434
+ _warned_images.add(image_id)
435
+
436
+ logger.warning(
437
+ f'⚠️ Basic public image validation using Docker Daemon failed. ⚠️\n'
438
+ f'⚠️ {message} ⚠️\n'
439
+ f'⚠️ The {context} will be submitted anyway, but may be stuck '
440
+ f'PENDING forever. ⚠️\n'
441
+ f"⚠️ Check for 'ErrImagePull' or 'ImagePullBackOff' in "
442
+ f'kubectl get pods if issues occur. ⚠️'
443
+ )
444
+
445
+ # Add info about private registries
446
+ logger.info(
447
+ '⚠️ If pulling from a private registry, using ecr/nvcr, or not '
448
+ 'logged into Docker, this is safe to ignore. ⚠️'
449
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: konduktor-nightly
3
- Version: 0.1.0.dev20250903104451
3
+ Version: 0.1.0.dev20250905104548
4
4
  Summary: GPU Cluster Health Management
5
5
  Author: Andrew Aikawa
6
6
  Author-email: asai@berkeley.edu
@@ -1,4 +1,4 @@
1
- konduktor/__init__.py,sha256=eP-TAqlKh2SiD1M1RAojmEwvxGpk5MYSaGUiXXLGrAA,1574
1
+ konduktor/__init__.py,sha256=Dyw5hlLhSCFtpMeL-JWwV19f2wevLViezmNWcq5RmF8,1574
2
2
  konduktor/adaptors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  konduktor/adaptors/aws.py,sha256=s47Ra-GaqCQibzVfmD0pmwEWHif1EGO5opMbwkLxTCU,8244
4
4
  konduktor/adaptors/common.py,sha256=ZIqzjx77PIHUwpjfAQ1uX8B2aX78YMuGj4Bppd-MdyM,4183
@@ -10,10 +10,10 @@ konduktor/backends/constants.py,sha256=nt9G9AmFCOMwO4GuKgRQSzJJuKapOmaROp4_Y0tMF
10
10
  konduktor/backends/deployment.py,sha256=fswN9hX_7NwcEogYmo1xn3WgWF8XCcGDvV5yx54_CA0,5860
11
11
  konduktor/backends/deployment_utils.py,sha256=qcuoLPeMvEVqgD_h71hQZXAp4ZCdXsFeSBxhtXW6pAA,39846
12
12
  konduktor/backends/jobset.py,sha256=E9THHmcpxTohsx6Goi9mKF4dy_mYpR2DHloSwGVr9jA,8509
13
- konduktor/backends/jobset_utils.py,sha256=lapJB6_Xqy0GgGpWAU49skgS5EOQ0zvWd8iZtnr67Gw,26016
13
+ konduktor/backends/jobset_utils.py,sha256=7j-HCu7UqrFbmmoz9um3an8NNETRPo0y3lp14Mii6HQ,26070
14
14
  konduktor/backends/pod_utils.py,sha256=KP_PAgsdNHFgt4Od-5gAtpifAKIL7DMBg7NJ44uqikg,14885
15
15
  konduktor/check.py,sha256=JennyWoaqSKhdyfUldd266KwVXTPJpcYQa4EED4a_BA,7569
16
- konduktor/cli.py,sha256=j41g7zQ24sxvBOl9nwZdWZnsbPsI2_fUgrRPfTX4XEc,57465
16
+ konduktor/cli.py,sha256=OwVdT4ibAQoAJO79YzlThQv_VKlHpsD-CHRwOzehGQ8,57613
17
17
  konduktor/config.py,sha256=9upqgCCYvcu6fKw7tovEYC1MWTkAAir0_WHPdayylbI,15536
18
18
  konduktor/constants.py,sha256=T3AeXXxuQHINW_bAWyztvDeS8r4g8kXBGIwIq13cys0,1814
19
19
  konduktor/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -68,19 +68,19 @@ konduktor/data/storage_utils.py,sha256=n4GivkN0KMqmyOTDznF0Z-hzsJvm7KCEh5i5HgFAT
68
68
  konduktor/execution.py,sha256=d0EP79iSrW2uFsoqn0YV_4kgIupPIqpMOParXx0y3kg,18519
69
69
  konduktor/kube_client.py,sha256=WELs9jClRW9r-imNJF3gJi3Z7ygkFDnYDmMXu5nJhEM,6213
70
70
  konduktor/logging.py,sha256=xtcCdnecmC3rqMTyunK-klQRINojI7NI4Apag78i9jM,3221
71
- konduktor/manifests/apoxy-setup.yaml,sha256=Laak_JFG_Mg6qPBr_oes0nH_yOZ_mGI-DfJXeudB3g4,3319
71
+ konduktor/manifests/apoxy-setup.yaml,sha256=HDZu7Evm_siIpK1E4tNZ9WVTnFV2LhBXwjJlFOYSTcU,3319
72
72
  konduktor/manifests/apoxy-setup2.yaml,sha256=BhXsgcVrLBruLXnF7xlj0Ej6YVJFYMABJIpYtwakQMo,731
73
73
  konduktor/manifests/controller_deployment.yaml,sha256=6p3oSLkEVONZsvKZGqVop0Dhn4bo3lrigRmhf8NXBHE,1730
74
74
  konduktor/manifests/dashboard_deployment.yaml,sha256=xJLd4FbPMAosI0fIv5_8y7dV9bw0Vsf81l-w4MB_aU8,2837
75
75
  konduktor/manifests/dmesg_daemonset.yaml,sha256=pSWt7YOeTYjS0l0iki1fvHOs7MhY-sH-RQfVW6JJyno,1391
76
76
  konduktor/manifests/pod_cleanup_controller.yaml,sha256=hziL1Ka1kCAEL9R7Tjvpb80iw1vcq9_3gwHCu75Bi0A,3939
77
- konduktor/resource.py,sha256=epOkJngNGtSBvMqiQeO8j0C7g0PzYhwjTMbG9VapvyQ,20628
77
+ konduktor/resource.py,sha256=kfdhnUR_9kDLSm2sUAkv1sLQXyAkI08p3wIzCz1p7-M,20791
78
78
  konduktor/serving.py,sha256=sh8TPAUXg23Bkt0ByatIMdxFFqzRm18HJTEkt3wHzdo,5147
79
- konduktor/task.py,sha256=97iLCo62qpN9wLGNPeFw64E8k1nch7AyySY3BUXHPWY,37496
79
+ konduktor/task.py,sha256=oFRHdMevg7lGYkHugCHl89FUREfq9M-l0Qd3N-rjHMA,37727
80
80
  konduktor/templates/apoxy-deployment.yaml.j2,sha256=_EdT7w0rBK3if1INHT6GGUEugy0mOkRfYOWRgBcKLdo,942
81
81
  konduktor/templates/deployment.yaml.j2,sha256=uXFjDQaimbpFdAn2RJGaIvS_PzDY136cw_L3QMjz3ZA,3452
82
82
  konduktor/templates/jobset.yaml.j2,sha256=NQcVeRNsTLLmTnJRnkL1vr45mSeth-b11YShXn_RoSg,1323
83
- konduktor/templates/pod.yaml.j2,sha256=owid7Wpo-kmQ-Gvx1zVoyG_feOiKviGDsnWLTlReXPo,19086
83
+ konduktor/templates/pod.yaml.j2,sha256=p9yE-AQkCF2Tgjd1QQiOLtzgI6Gbpps-MZYJZ9fQWIs,19159
84
84
  konduktor/usage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  konduktor/usage/constants.py,sha256=gCL8afIHZhO0dcxbJGpESE9sCC1cBSbeRnQ8GwNOY4M,612
86
86
  konduktor/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -99,9 +99,9 @@ konduktor/utils/rich_utils.py,sha256=ycADW6Ij3wX3uT8ou7T8qxX519RxlkJivsLvUahQaJo
99
99
  konduktor/utils/schemas.py,sha256=UPCb6gDcWUP7ygtEZSlHx6QZDQkrHgSxoCS97jMGmXA,18737
100
100
  konduktor/utils/subprocess_utils.py,sha256=WoFkoFhGecPR8-rF8WJxbIe-YtV94LXz9UG64SDhCY4,9448
101
101
  konduktor/utils/ux_utils.py,sha256=7-Lt3QbDVvBQUli5_U9lOdXKeC-ip8rZBpO9gQ6vPJw,7955
102
- konduktor/utils/validator.py,sha256=5C1kE57Eyj1OPnAbvojqMNHHtf5fnl47FK_vEttd8aw,4331
103
- konduktor_nightly-0.1.0.dev20250903104451.dist-info/LICENSE,sha256=MuuqTZbHvmqXR_aNKAXzggdV45ANd3wQ5YI7tnpZhm0,6586
104
- konduktor_nightly-0.1.0.dev20250903104451.dist-info/METADATA,sha256=Qlu1fo45gDXsknnO7wc_2-nz8i7n4USQ2oYHKCrZ7CE,4247
105
- konduktor_nightly-0.1.0.dev20250903104451.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
106
- konduktor_nightly-0.1.0.dev20250903104451.dist-info/entry_points.txt,sha256=k3nG5wDFIJhNqsZWrHk4d0irIB2Ns9s47cjRWYsTCT8,48
107
- konduktor_nightly-0.1.0.dev20250903104451.dist-info/RECORD,,
102
+ konduktor/utils/validator.py,sha256=gCB5v9Up9bCWD_92fS5ChfRRXj_m56Ky9uzd_77wXGI,16927
103
+ konduktor_nightly-0.1.0.dev20250905104548.dist-info/LICENSE,sha256=MuuqTZbHvmqXR_aNKAXzggdV45ANd3wQ5YI7tnpZhm0,6586
104
+ konduktor_nightly-0.1.0.dev20250905104548.dist-info/METADATA,sha256=YjtizOdI00MfuHHg6PtghiIjVMB5hnTd5BrdndRUQQY,4247
105
+ konduktor_nightly-0.1.0.dev20250905104548.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
106
+ konduktor_nightly-0.1.0.dev20250905104548.dist-info/entry_points.txt,sha256=k3nG5wDFIJhNqsZWrHk4d0irIB2Ns9s47cjRWYsTCT8,48
107
+ konduktor_nightly-0.1.0.dev20250905104548.dist-info/RECORD,,