docker-devkit 0.3.0.dev113__py3-none-any.whl → 0.4.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.
- docker_devkit/build_docker.py +29 -23
- docker_devkit/down.py +1 -1
- docker_devkit/image_refs.py +8 -21
- docker_devkit/lifecycle.py +10 -14
- docker_devkit/mirror.py +17 -40
- docker_devkit/up.py +4 -22
- {docker_devkit-0.3.0.dev113.dist-info → docker_devkit-0.4.0.dist-info}/METADATA +1 -1
- docker_devkit-0.4.0.dist-info/RECORD +21 -0
- docker_devkit-0.3.0.dev113.dist-info/RECORD +0 -21
- {docker_devkit-0.3.0.dev113.dist-info → docker_devkit-0.4.0.dist-info}/WHEEL +0 -0
- {docker_devkit-0.3.0.dev113.dist-info → docker_devkit-0.4.0.dist-info}/entry_points.txt +0 -0
- {docker_devkit-0.3.0.dev113.dist-info → docker_devkit-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {docker_devkit-0.3.0.dev113.dist-info → docker_devkit-0.4.0.dist-info}/licenses/NOTICE +0 -0
docker_devkit/build_docker.py
CHANGED
|
@@ -14,6 +14,7 @@ import typer
|
|
|
14
14
|
from bashrun.bash import bash, bash_output
|
|
15
15
|
from build_artifact_registry.builds import push_build
|
|
16
16
|
from build_artifact_registry.setup_oras import install_oras
|
|
17
|
+
from .config import MirrorConfig
|
|
17
18
|
from .detect_gpu import GPU_TYPES, Gpu, detect_gpu
|
|
18
19
|
from .documents import BakeDocument, digest_pinned, parse_bake
|
|
19
20
|
from pydantic_settings import BaseSettings
|
|
@@ -21,7 +22,7 @@ from .context_sha import compute_service_shas
|
|
|
21
22
|
|
|
22
23
|
from .image_refs import bake_base_image_refs, resolve_remote_digest
|
|
23
24
|
from .lifecycle import require_manifest, resolve_lock
|
|
24
|
-
from .mirror import
|
|
25
|
+
from .mirror import load_mirror_config, mirrored_ref
|
|
25
26
|
from .modes import parse_env_file
|
|
26
27
|
|
|
27
28
|
|
|
@@ -85,11 +86,10 @@ def run_build(
|
|
|
85
86
|
lock_only: bool = False,
|
|
86
87
|
gpu_only: bool = False,
|
|
87
88
|
no_cache: bool = False,
|
|
88
|
-
env_overlay: dict[str, str] | None = None,
|
|
89
89
|
) -> None:
|
|
90
90
|
root = Path.cwd()
|
|
91
91
|
manifest = require_manifest(root)
|
|
92
|
-
lock_file = resolve_lock(root
|
|
92
|
+
lock_file = resolve_lock(root)
|
|
93
93
|
mirror_config = load_mirror_config(root)
|
|
94
94
|
|
|
95
95
|
bake = parse_bake(manifest)
|
|
@@ -117,24 +117,7 @@ def run_build(
|
|
|
117
117
|
if gpu == "auto" and not lock_only:
|
|
118
118
|
gpu = detect_gpu()
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
# Mirror-prefixed declarations resolve their digest against upstream (crane copies
|
|
122
|
-
# are byte-identical, so the digest is valid under both names) and record it under
|
|
123
|
-
# the mirror name — declaring and re-locking works before CI has mirrored anything.
|
|
124
|
-
for occurrence in bake_base_image_refs(bake):
|
|
125
|
-
if digest_pinned(occurrence.reference):
|
|
126
|
-
lock_data[occurrence.name] = occurrence.reference
|
|
127
|
-
continue
|
|
128
|
-
if (
|
|
129
|
-
not upgrade
|
|
130
|
-
and occurrence.name in lock_data
|
|
131
|
-
and lock_data[occurrence.name].startswith(occurrence.reference + "@")
|
|
132
|
-
):
|
|
133
|
-
continue
|
|
134
|
-
inspect_target = occurrence.reference
|
|
135
|
-
if mirror_config is not None and is_mirrored(occurrence.reference, mirror_config.prefix):
|
|
136
|
-
inspect_target = upstream_ref(occurrence.reference, mirror_config.prefix)
|
|
137
|
-
lock_data[occurrence.name] = f"{occurrence.reference}@{resolve_remote_digest(inspect_target)}"
|
|
120
|
+
update_lock_entries(bake, mirror_config, lock_data, upgrade=upgrade)
|
|
138
121
|
|
|
139
122
|
# Update main lock file
|
|
140
123
|
lock_file.write_text(
|
|
@@ -147,8 +130,6 @@ def run_build(
|
|
|
147
130
|
|
|
148
131
|
# Update environment with external dependency image digests
|
|
149
132
|
os.environ.update(lock_data)
|
|
150
|
-
if env_overlay:
|
|
151
|
-
os.environ.update(env_overlay)
|
|
152
133
|
|
|
153
134
|
# Build command arguments
|
|
154
135
|
command_arguments: list[str] = []
|
|
@@ -226,6 +207,31 @@ def run_build(
|
|
|
226
207
|
push_image_digests(shelf, sha, baked_images, targets)
|
|
227
208
|
|
|
228
209
|
|
|
210
|
+
# One lock entry per declared third-party image: NAME={prefix}/{ref}@sha256:… — the
|
|
211
|
+
# mirror-prefixed form is derived from the mirror prefix, the digest resolves against
|
|
212
|
+
# the upstream reference (crane copies are byte-identical, so the digest is valid
|
|
213
|
+
# under both names) and records under the mirror name.
|
|
214
|
+
def update_lock_entries(
|
|
215
|
+
bake: BakeDocument,
|
|
216
|
+
mirror_config: MirrorConfig | None,
|
|
217
|
+
lock_data: dict[str, str],
|
|
218
|
+
*,
|
|
219
|
+
upgrade: bool,
|
|
220
|
+
) -> None:
|
|
221
|
+
if not bake.base_images:
|
|
222
|
+
return
|
|
223
|
+
if mirror_config is None:
|
|
224
|
+
raise RuntimeError("x-base-images declared without a mirror section in docker-devkit.yaml")
|
|
225
|
+
for occurrence in bake_base_image_refs(bake):
|
|
226
|
+
lock_base = mirrored_ref(occurrence.reference, mirror_config.prefix)
|
|
227
|
+
if digest_pinned(occurrence.reference):
|
|
228
|
+
lock_data[occurrence.name] = lock_base
|
|
229
|
+
continue
|
|
230
|
+
if not upgrade and occurrence.name in lock_data and lock_data[occurrence.name].startswith(lock_base + "@"):
|
|
231
|
+
continue
|
|
232
|
+
lock_data[occurrence.name] = f"{lock_base}@{resolve_remote_digest(occurrence.reference)}"
|
|
233
|
+
|
|
234
|
+
|
|
229
235
|
def leg_key(targets: list[str]) -> str:
|
|
230
236
|
return hashlib.sha256(",".join(sorted(targets)).encode("utf-8")).hexdigest()[:8]
|
|
231
237
|
|
docker_devkit/down.py
CHANGED
|
@@ -31,7 +31,7 @@ def down(
|
|
|
31
31
|
config = load_lifecycle_config(root)
|
|
32
32
|
enforce_bake_declaration(root, config)
|
|
33
33
|
manifest = resolve_manifest(root)
|
|
34
|
-
lock_file = resolve_lock(root
|
|
34
|
+
lock_file = resolve_lock(root)
|
|
35
35
|
|
|
36
36
|
if not ENV_FILE.exists():
|
|
37
37
|
raise RuntimeError("No .env file found")
|
docker_devkit/image_refs.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import datetime
|
|
3
|
+
import datetime as dt
|
|
4
4
|
import re
|
|
5
5
|
import shlex
|
|
6
6
|
import tomllib
|
|
@@ -12,6 +12,7 @@ from bashrun.bash import bash_output
|
|
|
12
12
|
from pydantic import RootModel
|
|
13
13
|
|
|
14
14
|
from .documents import BakeDocument, parse_bake
|
|
15
|
+
from .lifecycle import MANIFEST_PATH
|
|
15
16
|
|
|
16
17
|
BUILD_ARG_PATTERN = re.compile(r"\$\{[A-Za-z0-9_]+\}")
|
|
17
18
|
FROM_PATTERN = re.compile(r"^FROM\s+(?:--platform=\S+\s+)?(\S+)", re.MULTILINE)
|
|
@@ -21,17 +22,7 @@ DIGEST_PATTERN = re.compile(r"^Digest:\s+(sha256:[a-f0-9]+)", re.MULTILINE)
|
|
|
21
22
|
MISSING_VERSION = "<missing>"
|
|
22
23
|
|
|
23
24
|
|
|
24
|
-
type TomlValue =
|
|
25
|
-
str
|
|
26
|
-
| int
|
|
27
|
-
| float
|
|
28
|
-
| bool
|
|
29
|
-
| datetime.datetime
|
|
30
|
-
| datetime.date
|
|
31
|
-
| datetime.time
|
|
32
|
-
| list[TomlValue]
|
|
33
|
-
| dict[str, TomlValue]
|
|
34
|
-
)
|
|
25
|
+
type TomlValue = str | int | float | bool | dt.datetime | dt.date | dt.time | list[TomlValue] | dict[str, TomlValue]
|
|
35
26
|
|
|
36
27
|
|
|
37
28
|
class TomlDocument(RootModel[TomlValue]):
|
|
@@ -70,15 +61,11 @@ def unpinned_references(root: Path) -> list[str]:
|
|
|
70
61
|
]
|
|
71
62
|
|
|
72
63
|
|
|
73
|
-
def declared_references(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
for bake_glob in bake_globs
|
|
79
|
-
for path in sorted(root.glob(bake_glob))
|
|
80
|
-
for reference in bake_base_image_refs(parse_bake(path))
|
|
81
|
-
]
|
|
64
|
+
def declared_references(root: Path) -> list[ImageReference]:
|
|
65
|
+
manifest = root / MANIFEST_PATH
|
|
66
|
+
if not manifest.exists():
|
|
67
|
+
return []
|
|
68
|
+
return bake_base_image_refs(parse_bake(manifest))
|
|
82
69
|
|
|
83
70
|
|
|
84
71
|
def stray_references(
|
docker_devkit/lifecycle.py
CHANGED
|
@@ -8,11 +8,9 @@ from .detect_gpu import Gpu
|
|
|
8
8
|
DEFAULT_COMPOSE_FILE = Path("compose.yml")
|
|
9
9
|
GPU_PLACEHOLDER = "{gpu}"
|
|
10
10
|
|
|
11
|
-
# The image manifest and its lock are a named pair living in the same directory.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
MANIFEST_LOCK_PAIR = {"images.yml": "images.lock", "compose.bake.yml": ".env.lock"}
|
|
15
|
-
LOCK_CANDIDATES = (Path("workloads/images.lock"), Path(".env.lock"))
|
|
11
|
+
# The image manifest and its lock are a named pair living in the same directory.
|
|
12
|
+
MANIFEST_PATH = Path("workloads/images.yml")
|
|
13
|
+
LOCK_PATH = Path("workloads/images.lock")
|
|
16
14
|
|
|
17
15
|
|
|
18
16
|
def load_lifecycle_config(root: Path) -> LifecycleConfig | None:
|
|
@@ -21,27 +19,25 @@ def load_lifecycle_config(root: Path) -> LifecycleConfig | None:
|
|
|
21
19
|
|
|
22
20
|
|
|
23
21
|
def resolve_manifest(root: Path) -> Path | None:
|
|
24
|
-
|
|
22
|
+
manifest = root / MANIFEST_PATH
|
|
23
|
+
return manifest if manifest.exists() else None
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
def require_manifest(root: Path) -> Path:
|
|
28
27
|
manifest = resolve_manifest(root)
|
|
29
28
|
if manifest is None:
|
|
30
|
-
raise RuntimeError(f"No image manifest
|
|
29
|
+
raise RuntimeError(f"No image manifest at {MANIFEST_PATH}")
|
|
31
30
|
return manifest
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
def resolve_lock(root: Path
|
|
35
|
-
|
|
36
|
-
return manifest.parent / MANIFEST_LOCK_PAIR[manifest.name]
|
|
37
|
-
existing = next((root / candidate for candidate in LOCK_CANDIDATES if (root / candidate).exists()), None)
|
|
38
|
-
return existing if existing is not None else root / LOCK_CANDIDATES[0]
|
|
33
|
+
def resolve_lock(root: Path) -> Path:
|
|
34
|
+
return root / LOCK_PATH
|
|
39
35
|
|
|
40
36
|
|
|
41
37
|
def enforce_bake_declaration(root: Path, config: LifecycleConfig | None) -> None:
|
|
42
|
-
if config is None and
|
|
38
|
+
if config is None and (root / MANIFEST_PATH).exists():
|
|
43
39
|
raise RuntimeError(
|
|
44
|
-
"image manifest present without a lifecycle section in docker-devkit.yaml; declare the section
|
|
40
|
+
"image manifest present without a lifecycle section in docker-devkit.yaml; declare the section"
|
|
45
41
|
)
|
|
46
42
|
|
|
47
43
|
|
docker_devkit/mirror.py
CHANGED
|
@@ -2,14 +2,13 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
import shlex
|
|
5
|
-
import tempfile
|
|
6
5
|
from pathlib import Path
|
|
7
6
|
|
|
8
7
|
import typer
|
|
9
8
|
from bashrun.bash import bash, bash_check
|
|
10
9
|
|
|
11
10
|
from .config import MirrorConfig, load_config
|
|
12
|
-
from .image_refs import
|
|
11
|
+
from .image_refs import declared_references
|
|
13
12
|
|
|
14
13
|
app = typer.Typer(add_completion=False, pretty_exceptions_show_locals=False)
|
|
15
14
|
|
|
@@ -23,7 +22,7 @@ def mirror() -> None:
|
|
|
23
22
|
if config is None:
|
|
24
23
|
raise RuntimeError("a mirror section with 'prefix' is required in docker-devkit.yaml to mirror")
|
|
25
24
|
|
|
26
|
-
targets =
|
|
25
|
+
targets = sorted(declared_references(root), key=lambda occurrence: occurrence.reference)
|
|
27
26
|
print(f"Install crane {CRANE_VERSION}")
|
|
28
27
|
sudo = "sudo " if os.geteuid() != 0 else ""
|
|
29
28
|
archive = "go-containerregistry_Linux_x86_64.tar.gz"
|
|
@@ -31,9 +30,9 @@ def mirror() -> None:
|
|
|
31
30
|
bash(f"{sudo}tar -xzf {archive} -C /usr/local/bin crane")
|
|
32
31
|
Path(archive).unlink()
|
|
33
32
|
for target in targets:
|
|
34
|
-
|
|
35
|
-
print(f"Mirror {
|
|
36
|
-
bash(f"crane copy {
|
|
33
|
+
destination = mirrored_ref(target.reference, config.prefix)
|
|
34
|
+
print(f"Mirror {target.reference} -> {destination}")
|
|
35
|
+
bash(f"crane copy {target.reference} {destination}")
|
|
37
36
|
print(f"Mirrored images: {len(targets)}")
|
|
38
37
|
|
|
39
38
|
|
|
@@ -42,49 +41,27 @@ def load_mirror_config(root: Path) -> MirrorConfig | None:
|
|
|
42
41
|
return config.mirror if config is not None else None
|
|
43
42
|
|
|
44
43
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return reference
|
|
44
|
+
def mirrored_ref(reference: str, prefix: str) -> str:
|
|
45
|
+
if reference.startswith(f"{prefix}/"):
|
|
46
|
+
raise RuntimeError(
|
|
47
|
+
f"x-base-images values are upstream-native; {reference} already carries the mirror prefix {prefix}"
|
|
48
|
+
)
|
|
49
|
+
return f"{prefix}/{reference}"
|
|
51
50
|
|
|
52
51
|
|
|
53
52
|
def reference_exists(reference: str) -> bool:
|
|
54
53
|
return bash_check(f"docker buildx imagetools inspect {shlex.quote(reference)}")
|
|
55
54
|
|
|
56
55
|
|
|
57
|
-
def
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def upstream_fallback(lock_data: dict[str, str], prefix: str, *, allow_upstream_fallback: bool) -> dict[str, str]:
|
|
65
|
-
missing = {
|
|
66
|
-
name: value for name, value in lock_data.items() if is_mirrored(value, prefix) and not reference_exists(value)
|
|
67
|
-
}
|
|
68
|
-
if not missing:
|
|
69
|
-
return {}
|
|
70
|
-
if not allow_upstream_fallback:
|
|
71
|
-
value = next(iter(missing.values()))
|
|
56
|
+
def enforce_mirrored(lock_data: dict[str, str]) -> None:
|
|
57
|
+
for value in sorted(lock_data.values()):
|
|
58
|
+
if reference_exists(value):
|
|
59
|
+
continue
|
|
72
60
|
reference, _, digest = value.rpartition("@")
|
|
73
61
|
raise RuntimeError(
|
|
74
|
-
f"Image {reference or value} (digest {digest or 'unknown'}) is not mirrored yet
|
|
75
|
-
"
|
|
76
|
-
"to pull the same digest from upstream for this run."
|
|
62
|
+
f"Image {reference or value} (digest {digest or 'unknown'}) is not mirrored yet; "
|
|
63
|
+
"the CI mirror job populates it when the declaring change runs"
|
|
77
64
|
)
|
|
78
|
-
return {name: upstream_ref(value, prefix) for name, value in missing.items()}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
def write_fallback_overlay(substitutions: dict[str, str]) -> Path:
|
|
82
|
-
overlay = Path(tempfile.gettempdir()) / f"docker-devkit-upstream-fallback-{os.getpid()}.env"
|
|
83
|
-
overlay.write_text(
|
|
84
|
-
"\n".join(f"{name}={value}" for name, value in sorted(substitutions.items())) + "\n",
|
|
85
|
-
encoding="utf-8",
|
|
86
|
-
)
|
|
87
|
-
return overlay
|
|
88
65
|
|
|
89
66
|
|
|
90
67
|
def main() -> None:
|
docker_devkit/up.py
CHANGED
|
@@ -16,7 +16,7 @@ from .lifecycle import (
|
|
|
16
16
|
resolve_lock,
|
|
17
17
|
resolve_manifest,
|
|
18
18
|
)
|
|
19
|
-
from .mirror import
|
|
19
|
+
from .mirror import enforce_mirrored, load_mirror_config
|
|
20
20
|
from .modes import parse_env_file, resolve_auth_mode
|
|
21
21
|
|
|
22
22
|
ENV_FILE = Path(".env")
|
|
@@ -42,19 +42,12 @@ def up(
|
|
|
42
42
|
"--dev",
|
|
43
43
|
help="Layer the declared dev overlay (compose.dev.yml shape) over the production stack for bind-mount/debug bring-up.",
|
|
44
44
|
),
|
|
45
|
-
allow_upstream_fallback: Annotated[
|
|
46
|
-
bool,
|
|
47
|
-
typer.Option(
|
|
48
|
-
"--allow-upstream-fallback",
|
|
49
|
-
help="Pull unmirrored lock entries from upstream at the same digest instead of failing closed.",
|
|
50
|
-
),
|
|
51
|
-
] = False,
|
|
52
45
|
) -> None:
|
|
53
46
|
root = Path.cwd()
|
|
54
47
|
config = load_lifecycle_config(root)
|
|
55
48
|
enforce_bake_declaration(root, config)
|
|
56
49
|
manifest = resolve_manifest(root)
|
|
57
|
-
lock_file = resolve_lock(root
|
|
50
|
+
lock_file = resolve_lock(root)
|
|
58
51
|
|
|
59
52
|
if dev and (config is None or config.dev_file is None):
|
|
60
53
|
raise RuntimeError("--dev requires a dev_file in the lifecycle section of docker-devkit.yaml")
|
|
@@ -75,21 +68,12 @@ def up(
|
|
|
75
68
|
|
|
76
69
|
auth_mode = resolve_auth_mode(ENV_FILE)
|
|
77
70
|
|
|
78
|
-
substitutions: dict[str, str] = {}
|
|
79
|
-
fallback_overlay: Path | None = None
|
|
80
71
|
mirror_config = load_mirror_config(root)
|
|
81
72
|
if mirror_config is not None:
|
|
82
|
-
|
|
83
|
-
parse_env_file(lock_file), mirror_config.prefix, allow_upstream_fallback=allow_upstream_fallback
|
|
84
|
-
)
|
|
85
|
-
if substitutions:
|
|
86
|
-
for name, upstream in sorted(substitutions.items()):
|
|
87
|
-
print(f"Falling back to upstream for {name}: {upstream}", flush=True)
|
|
88
|
-
os.environ.update(substitutions)
|
|
89
|
-
fallback_overlay = write_fallback_overlay(substitutions)
|
|
73
|
+
enforce_mirrored(parse_env_file(lock_file))
|
|
90
74
|
|
|
91
75
|
if build:
|
|
92
|
-
run_build(gpu=gpu
|
|
76
|
+
run_build(gpu=gpu)
|
|
93
77
|
|
|
94
78
|
if manifest is not None:
|
|
95
79
|
os.environ.update(compute_service_shas(root, parse_bake(manifest)))
|
|
@@ -101,8 +85,6 @@ def up(
|
|
|
101
85
|
files_args = " ".join(f"-f {compose_file}" for compose_file in compose_files)
|
|
102
86
|
profile_flag = "--profile keycloak " if auth_mode == "keycloak" else ""
|
|
103
87
|
compose_args = f"{files_args} {profile_flag}--project-directory {root} --env-file .env --env-file {lock_file}"
|
|
104
|
-
if fallback_overlay is not None:
|
|
105
|
-
compose_args += f" --env-file {fallback_overlay}"
|
|
106
88
|
|
|
107
89
|
up_command = f"docker compose {compose_args} up"
|
|
108
90
|
if not build:
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
docker_devkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
docker_devkit/build_docker.py,sha256=-oH0RPIDm1EZOh6UP2MMEDSX0G6W6zM4YgZSHw6_8u0,12978
|
|
3
|
+
docker_devkit/config.py,sha256=UMAS6yF1E9PIbsRs2TVig9XwSNCvQe5w9eTLUHOPKq0,3112
|
|
4
|
+
docker_devkit/context_sha.py,sha256=lhCxUcYM98xCdDum3hsFRFw5WYrjvZUSMbOu_7ZmQjE,3041
|
|
5
|
+
docker_devkit/detect_gpu.py,sha256=C4e3vixvSSJS6xQiMVWp2IdWSAgMr551KrBTuIrkTk4,456
|
|
6
|
+
docker_devkit/documents.py,sha256=c6jqbBNUKyJOltex-8u536_niWhEL7ScOab_MwZmM9k,2195
|
|
7
|
+
docker_devkit/down.py,sha256=WDlq_RBpP84E1-5sp7MtKEhRB9wBOz8Ib59RoviZ8uQ,2179
|
|
8
|
+
docker_devkit/image_refs.py,sha256=dyngpklq8mz4rGzb7gZGg3o3i9q5YO6_DRAC9fBNRfw,5148
|
|
9
|
+
docker_devkit/lifecycle.py,sha256=_2ZTn2xpjhDFzdVacA2oog2CvsDujaoc8oqnRnpHtC8,1631
|
|
10
|
+
docker_devkit/matrix.py,sha256=6NyGL4Ol849dYlcMRzAL2yjFoN6sGkGwVaaxcDm3bG4,4530
|
|
11
|
+
docker_devkit/mirror.py,sha256=AGL_oQUv68DKXjEFVdD-NQoLbC6w3DZJ7h-lzzvdKwM,2334
|
|
12
|
+
docker_devkit/modes.py,sha256=Lwhblzu5Kn7qhfy_QMqE28XuflSIJtCRBYNX7Iq8Qfo,1510
|
|
13
|
+
docker_devkit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
docker_devkit/score_generate.py,sha256=psbQm-MWf9A5YP0ov0rLPUiuVAQbUWn6yfUmB-CXurU,9434
|
|
15
|
+
docker_devkit/up.py,sha256=9h5fNuEfUQbQozae8yrueiSfS_Be_ne0SuR1j6tadbU,3394
|
|
16
|
+
docker_devkit-0.4.0.dist-info/METADATA,sha256=_RO7Dz5QqwAHku7kcbtB9VvCvRID1hpXCrLzsrHAyCM,533
|
|
17
|
+
docker_devkit-0.4.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
18
|
+
docker_devkit-0.4.0.dist-info/entry_points.txt,sha256=6cAHqlMvuXI00uTJLf73MTqWnLd1-m5sDgJrSyHWv4U,244
|
|
19
|
+
docker_devkit-0.4.0.dist-info/licenses/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
|
|
20
|
+
docker_devkit-0.4.0.dist-info/licenses/NOTICE,sha256=jvglZza3GCdN7v4_TLuXUqX9C_uABlwAKUkcIeKwk_8,26
|
|
21
|
+
docker_devkit-0.4.0.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
docker_devkit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
docker_devkit/build_docker.py,sha256=DtvTUTGHdQAkpBVelGObWyYD5Ldc05iPWXkNpCMQt-E,12927
|
|
3
|
-
docker_devkit/config.py,sha256=UMAS6yF1E9PIbsRs2TVig9XwSNCvQe5w9eTLUHOPKq0,3112
|
|
4
|
-
docker_devkit/context_sha.py,sha256=lhCxUcYM98xCdDum3hsFRFw5WYrjvZUSMbOu_7ZmQjE,3041
|
|
5
|
-
docker_devkit/detect_gpu.py,sha256=C4e3vixvSSJS6xQiMVWp2IdWSAgMr551KrBTuIrkTk4,456
|
|
6
|
-
docker_devkit/documents.py,sha256=c6jqbBNUKyJOltex-8u536_niWhEL7ScOab_MwZmM9k,2195
|
|
7
|
-
docker_devkit/down.py,sha256=9OMXPZQ3SIdaSELc46hzkqNpLSwOJ1athCD8Bmlz2BI,2189
|
|
8
|
-
docker_devkit/image_refs.py,sha256=6pHYPWh4lL6qMqHtQBHBbeWijVsT0PhsMS6CMDho5nY,5294
|
|
9
|
-
docker_devkit/lifecycle.py,sha256=FuwaCSRK7qVx_qj-HmIFqMm8Ak4cpAQEqqXRPDNCLmo,2259
|
|
10
|
-
docker_devkit/matrix.py,sha256=6NyGL4Ol849dYlcMRzAL2yjFoN6sGkGwVaaxcDm3bG4,4530
|
|
11
|
-
docker_devkit/mirror.py,sha256=tissqnoqMwRA6s0ykwXZOEgy6F1d3AAebPKGEkSpJRg,3224
|
|
12
|
-
docker_devkit/modes.py,sha256=Lwhblzu5Kn7qhfy_QMqE28XuflSIJtCRBYNX7Iq8Qfo,1510
|
|
13
|
-
docker_devkit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
docker_devkit/score_generate.py,sha256=psbQm-MWf9A5YP0ov0rLPUiuVAQbUWn6yfUmB-CXurU,9434
|
|
15
|
-
docker_devkit/up.py,sha256=32A2_6mxAF00XILecxYTzCQw0QvSjevBWCnayF5X1Xs,4284
|
|
16
|
-
docker_devkit-0.3.0.dev113.dist-info/METADATA,sha256=0NT3OLGPZKW3hL5cvP-avLSORfSbo57cbDvwrZV2aOs,540
|
|
17
|
-
docker_devkit-0.3.0.dev113.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
18
|
-
docker_devkit-0.3.0.dev113.dist-info/entry_points.txt,sha256=6cAHqlMvuXI00uTJLf73MTqWnLd1-m5sDgJrSyHWv4U,244
|
|
19
|
-
docker_devkit-0.3.0.dev113.dist-info/licenses/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
|
|
20
|
-
docker_devkit-0.3.0.dev113.dist-info/licenses/NOTICE,sha256=jvglZza3GCdN7v4_TLuXUqX9C_uABlwAKUkcIeKwk_8,26
|
|
21
|
-
docker_devkit-0.3.0.dev113.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|