container-magic 4.2.2__tar.gz → 4.2.3__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.
- {container_magic-4.2.2/src/container_magic.egg-info → container_magic-4.2.3}/PKG-INFO +1 -1
- {container_magic-4.2.2 → container_magic-4.2.3}/pyproject.toml +1 -1
- container_magic-4.2.3/src/container_magic/__init__.py +5 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/cli/main.py +3 -5
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/config.py +4 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/runner.py +9 -9
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/run_script.py +13 -15
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/run.sh.j2 +2 -1
- {container_magic-4.2.2 → container_magic-4.2.3/src/container_magic.egg-info}/PKG-INFO +1 -1
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/SOURCES.txt +0 -1
- container_magic-4.2.2/src/container_magic/__init__.py +0 -3
- container_magic-4.2.2/src/container_magic/templates/_macros.j2 +0 -7
- {container_magic-4.2.2 → container_magic-4.2.3}/LICENSE +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/README.md +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/setup.cfg +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/cli/__init__.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/__init__.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/builder.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/cache.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/registry.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/runtime.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/steps.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/symlinks.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/templates.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/volumes.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/__init__.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/build_script.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/dockerfile.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/registry/__init__.py +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/Dockerfile.j2 +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/build.sh.j2 +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/dependency_links.txt +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/entry_points.txt +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/requires.txt +0 -0
- {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "container-magic"
|
|
7
|
-
version = "4.2.
|
|
7
|
+
version = "4.2.3"
|
|
8
8
|
description = "A tool for rapidly creating containerised development environments"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Mark Hedley Jones", email = "mark@hedleyjones.com"}
|
|
@@ -97,7 +97,7 @@ def cli():
|
|
|
97
97
|
"--in-place",
|
|
98
98
|
"in_place",
|
|
99
99
|
is_flag=True,
|
|
100
|
-
help="
|
|
100
|
+
help="Initialise in current directory instead of creating new one",
|
|
101
101
|
)
|
|
102
102
|
def init(
|
|
103
103
|
template: str,
|
|
@@ -122,7 +122,7 @@ def init(
|
|
|
122
122
|
|
|
123
123
|
# Determine project path
|
|
124
124
|
if in_place:
|
|
125
|
-
#
|
|
125
|
+
# Initialise in current directory
|
|
126
126
|
path = Path.cwd()
|
|
127
127
|
elif path is None:
|
|
128
128
|
# Create new directory with project name
|
|
@@ -141,7 +141,7 @@ def init(
|
|
|
141
141
|
click.echo(f"Creating project at {path}")
|
|
142
142
|
path.mkdir(parents=True)
|
|
143
143
|
else:
|
|
144
|
-
click.echo(f"
|
|
144
|
+
click.echo(f"Initialising in {path}")
|
|
145
145
|
|
|
146
146
|
# Create default config with base, development, and production stages
|
|
147
147
|
# If no tag specified, append :latest
|
|
@@ -323,8 +323,6 @@ def cache_list(path: Path):
|
|
|
323
323
|
size_mb = asset["size"] / (1024 * 1024)
|
|
324
324
|
click.echo(f" {asset['filename']} ({size_mb:.2f} MB)")
|
|
325
325
|
click.echo(f" URL: {asset['url']}")
|
|
326
|
-
if asset.get("dest"):
|
|
327
|
-
click.echo(f" Dest: {asset['dest']}")
|
|
328
326
|
click.echo(f" Hash: {asset['hash'][:16]}...")
|
|
329
327
|
|
|
330
328
|
|
|
@@ -395,6 +395,10 @@ class ContainerMagicConfig(BaseModel):
|
|
|
395
395
|
with open(path) as f:
|
|
396
396
|
data = yaml.safe_load(f)
|
|
397
397
|
|
|
398
|
+
if not isinstance(data, dict):
|
|
399
|
+
print("Error: cm.yaml must contain a YAML mapping", file=sys.stderr)
|
|
400
|
+
sys.exit(1)
|
|
401
|
+
|
|
398
402
|
try:
|
|
399
403
|
config = cls(**data)
|
|
400
404
|
except ValidationError as e:
|
|
@@ -62,7 +62,7 @@ def _detect_shell(config: ContainerMagicConfig) -> str:
|
|
|
62
62
|
|
|
63
63
|
Priority: runtime.shell > distro field > image-name detection.
|
|
64
64
|
"""
|
|
65
|
-
runtime_shell = config.runtime.shell
|
|
65
|
+
runtime_shell = config.runtime.shell
|
|
66
66
|
if runtime_shell:
|
|
67
67
|
return runtime_shell
|
|
68
68
|
dev_stage = "development" if "development" in config.stages else "base"
|
|
@@ -73,14 +73,14 @@ def _detect_shell(config: ContainerMagicConfig) -> str:
|
|
|
73
73
|
return detect_shell(resolve_base_image(dev_stage_config.frm, config.stages))
|
|
74
74
|
|
|
75
75
|
|
|
76
|
-
def
|
|
76
|
+
def build_feature_flags(config: ContainerMagicConfig) -> Dict[str, bool]:
|
|
77
77
|
"""Build feature flags dict from runtime config."""
|
|
78
|
-
|
|
78
|
+
features = config.runtime.features
|
|
79
79
|
return {
|
|
80
|
-
"display": "display" in
|
|
81
|
-
"gpu": "gpu" in
|
|
82
|
-
"audio": "audio" in
|
|
83
|
-
"aws_credentials": "aws_credentials" in
|
|
80
|
+
"display": "display" in features,
|
|
81
|
+
"gpu": "gpu" in features,
|
|
82
|
+
"audio": "audio" in features,
|
|
83
|
+
"aws_credentials": "aws_credentials" in features,
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
|
|
@@ -301,7 +301,7 @@ def run_container(
|
|
|
301
301
|
runtime_cmd = runtime.value
|
|
302
302
|
shell = _detect_shell(config)
|
|
303
303
|
container_home = _detect_container_home()
|
|
304
|
-
features =
|
|
304
|
+
features = build_feature_flags(config)
|
|
305
305
|
image = f"{config.names.image}:development"
|
|
306
306
|
container_name = f"{config.names.image}-development"
|
|
307
307
|
|
|
@@ -584,7 +584,7 @@ def stop_container(config: ContainerMagicConfig) -> int:
|
|
|
584
584
|
)
|
|
585
585
|
|
|
586
586
|
# xhost cleanup if display feature enabled with Docker
|
|
587
|
-
features =
|
|
587
|
+
features = build_feature_flags(config)
|
|
588
588
|
if features["display"] and runtime == Runtime.DOCKER and os.environ.get("DISPLAY"):
|
|
589
589
|
try:
|
|
590
590
|
subprocess.run(["xhost", "-local:"], capture_output=True)
|
{container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/run_script.py
RENAMED
|
@@ -6,7 +6,12 @@ from pathlib import Path
|
|
|
6
6
|
from jinja2 import Environment, PackageLoader
|
|
7
7
|
|
|
8
8
|
from container_magic.core.config import ContainerMagicConfig
|
|
9
|
-
from container_magic.core.
|
|
9
|
+
from container_magic.core.runner import build_feature_flags
|
|
10
|
+
from container_magic.core.templates import (
|
|
11
|
+
detect_shell,
|
|
12
|
+
resolve_base_image,
|
|
13
|
+
resolve_distro_shell,
|
|
14
|
+
)
|
|
10
15
|
from container_magic.core.volumes import expand_volumes_for_script, label_volumes
|
|
11
16
|
|
|
12
17
|
|
|
@@ -38,7 +43,7 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
|
|
|
38
43
|
workdir = f"/home/{production_user}"
|
|
39
44
|
|
|
40
45
|
# Determine interactive shell: runtime.shell > distro > image-name detection
|
|
41
|
-
runtime_shell = config.runtime.shell
|
|
46
|
+
runtime_shell = config.runtime.shell
|
|
42
47
|
prod_stage = "production" if "production" in config.stages else "base"
|
|
43
48
|
stage_config = config.stages[prod_stage]
|
|
44
49
|
shell = (
|
|
@@ -55,17 +60,10 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
|
|
|
55
60
|
cmd_copy.command = cmd_spec.command.replace("$", r"\$")
|
|
56
61
|
commands_escaped[cmd_name] = cmd_copy
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
runtime_features = config.runtime.features if config.runtime else []
|
|
60
|
-
features = {
|
|
61
|
-
"display": "display" in runtime_features,
|
|
62
|
-
"gpu": "gpu" in runtime_features,
|
|
63
|
-
"audio": "audio" in runtime_features,
|
|
64
|
-
"aws_credentials": "aws_credentials" in runtime_features,
|
|
65
|
-
}
|
|
63
|
+
features = build_feature_flags(config)
|
|
66
64
|
|
|
67
65
|
# Expand volume variables and apply SELinux labels for production context
|
|
68
|
-
raw_volumes = config.runtime.volumes
|
|
66
|
+
raw_volumes = config.runtime.volumes
|
|
69
67
|
expanded_volumes = expand_volumes_for_script(raw_volumes, workdir)
|
|
70
68
|
expanded_volumes = label_volumes(expanded_volumes)
|
|
71
69
|
|
|
@@ -75,13 +73,13 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
|
|
|
75
73
|
workdir=workdir,
|
|
76
74
|
shell=shell,
|
|
77
75
|
backend=backend,
|
|
78
|
-
privileged=config.runtime.privileged
|
|
79
|
-
network=config.runtime.network_mode
|
|
76
|
+
privileged=config.runtime.privileged,
|
|
77
|
+
network=config.runtime.network_mode,
|
|
80
78
|
features=features,
|
|
81
79
|
volumes=expanded_volumes,
|
|
82
|
-
devices=config.runtime.devices
|
|
80
|
+
devices=config.runtime.devices,
|
|
83
81
|
commands=commands_escaped,
|
|
84
|
-
ipc=config.runtime.ipc
|
|
82
|
+
ipc=config.runtime.ipc,
|
|
85
83
|
)
|
|
86
84
|
|
|
87
85
|
run_script = project_dir / "run.sh"
|
|
@@ -18,7 +18,7 @@ if command -v docker >/dev/null 2>&1; then
|
|
|
18
18
|
elif command -v podman >/dev/null 2>&1; then
|
|
19
19
|
RUNTIME="podman"
|
|
20
20
|
else
|
|
21
|
-
echo "Error: Neither docker nor podman found in PATH"
|
|
21
|
+
echo "Error: Neither docker nor podman found in PATH" >&2
|
|
22
22
|
exit 1
|
|
23
23
|
fi
|
|
24
24
|
{%- else %}
|
|
@@ -292,6 +292,7 @@ run_{{ command_name }}() {
|
|
|
292
292
|
local _manifest=""
|
|
293
293
|
if [[ ${#MANIFEST_LINES[@]} -gt 0 ]]; then
|
|
294
294
|
_manifest=$(mktemp /tmp/cm-manifest-XXXXXX)
|
|
295
|
+
trap 'rm -f "$_manifest"' EXIT
|
|
295
296
|
printf '%s\n' "${MANIFEST_LINES[@]}" >"$_manifest"
|
|
296
297
|
RUN_ARGS+=("-v" "${_manifest}:/run/cm/mounts:ro,z")
|
|
297
298
|
fi
|
|
@@ -27,6 +27,5 @@ src/container_magic/generators/dockerfile.py
|
|
|
27
27
|
src/container_magic/generators/run_script.py
|
|
28
28
|
src/container_magic/registry/__init__.py
|
|
29
29
|
src/container_magic/templates/Dockerfile.j2
|
|
30
|
-
src/container_magic/templates/_macros.j2
|
|
31
30
|
src/container_magic/templates/build.sh.j2
|
|
32
31
|
src/container_magic/templates/run.sh.j2
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
{#- Shared macros for container-magic templates -#}
|
|
2
|
-
|
|
3
|
-
{%- macro symlink_mounts(workspace_name, container_base, workspace_symlinks) -%}
|
|
4
|
-
{% for rel_path in workspace_symlinks %}
|
|
5
|
-
RUN_ARGS+=("-v" "$(pwd)/{{ workspace_name }}/{{ rel_path }}:{{ container_base }}/{{ workspace_name }}/{{ rel_path }}:z")
|
|
6
|
-
{% endfor -%}
|
|
7
|
-
{%- endmacro -%}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/build_script.py
RENAMED
|
File without changes
|
{container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/dockerfile.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|