docker-devkit 0.4.1.dev124__py3-none-any.whl → 0.4.2.dev127__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/down.py CHANGED
@@ -10,12 +10,12 @@ from .context_sha import compute_service_shas
10
10
  from .documents import parse_bake
11
11
  from .lifecycle import (
12
12
  enforce_bake_declaration,
13
+ enumerate_profiles,
13
14
  expand_compose_files,
14
15
  load_lifecycle_config,
15
16
  resolve_lock,
16
17
  resolve_manifest,
17
18
  )
18
- from .modes import resolve_auth_mode
19
19
 
20
20
  ENV_FILE = Path(".env")
21
21
 
@@ -44,8 +44,6 @@ def down(
44
44
  if gpu == "auto":
45
45
  gpu = detect_gpu()
46
46
 
47
- resolve_auth_mode(ENV_FILE)
48
-
49
47
  if manifest is not None:
50
48
  os.environ.update(compute_service_shas(root, parse_bake(manifest)))
51
49
 
@@ -55,15 +53,11 @@ def down(
55
53
  raise RuntimeError("No compose files declared; a builds-only repo has no stack to tear down")
56
54
 
57
55
  files_args = " ".join(f"-f {compose_file}" for compose_file in compose_files)
58
- command = (
59
- "docker compose "
60
- f"{files_args} "
61
- f"--project-directory {root} "
62
- "--profile keycloak " # Always include so any keycloak containers from a previous AUTH_MODE=keycloak run get torn down
63
- "--env-file .env "
64
- f"--env-file {lock_file} "
65
- "down --remove-orphans"
66
- )
56
+ # Every profile declared across the assembly, so teardown covers containers from a prior
57
+ # bring-up under a different COMPOSE_PROFILES selection
58
+ compose_prefix = f"docker compose {files_args} --project-directory {root} --env-file .env --env-file {lock_file}"
59
+ profile_flags = "".join(f"--profile {profile} " for profile in enumerate_profiles(compose_prefix))
60
+ command = f"{compose_prefix} {profile_flags}down --remove-orphans"
67
61
 
68
62
  if volumes:
69
63
  command += " -v"
@@ -2,6 +2,8 @@ from __future__ import annotations
2
2
 
3
3
  from pathlib import Path
4
4
 
5
+ from bashrun.bash import bash_output
6
+
5
7
  from .config import LifecycleConfig, load_config
6
8
  from .detect_gpu import Gpu
7
9
 
@@ -48,3 +50,8 @@ def expand_compose_files(config: LifecycleConfig | None, gpu: Gpu, *, include_de
48
50
  if include_dev and config.dev_file is not None:
49
51
  files.append(Path(config.dev_file))
50
52
  return files
53
+
54
+
55
+ def enumerate_profiles(compose_prefix: str) -> list[str]:
56
+ output = bash_output(f"{compose_prefix} config --profiles")
57
+ return [line.strip() for line in output.splitlines() if line.strip()]
docker_devkit/modes.py CHANGED
@@ -1,31 +1,16 @@
1
1
  from os import environ
2
2
  from pathlib import Path
3
- from urllib.parse import urlparse
4
3
 
5
- VALID_AUTH_MODES = ("keycloak", "disabled")
6
- DEFAULT_AUTH_MODE = "keycloak"
7
4
 
8
-
9
- def resolve_auth_mode(env_file: Path) -> str:
5
+ def resolve_compose_profiles(env_file: Path) -> list[str]:
10
6
  file_values = parse_env_file(env_file)
11
- public_url = environ.get("PUBLIC_URL") or file_values.get("PUBLIC_URL")
12
- auth_mode = environ.get("AUTH_MODE") or file_values.get("AUTH_MODE", DEFAULT_AUTH_MODE)
13
-
14
- if not public_url:
15
- raise RuntimeError("PUBLIC_URL is required; set it in .env")
16
- if auth_mode not in VALID_AUTH_MODES:
17
- raise RuntimeError(f"AUTH_MODE={auth_mode!r} is invalid; expected one of {list(VALID_AUTH_MODES)}")
18
-
19
- scheme = urlparse(public_url).scheme
20
- if scheme not in ("http", "https"):
21
- raise RuntimeError(f"PUBLIC_URL={public_url!r} must use http:// or https://")
22
- if scheme == "http" and auth_mode == "keycloak":
23
- raise RuntimeError(
24
- f"AUTH_MODE=keycloak with PUBLIC_URL={public_url!r} is rejected: OAuth credentials must "
25
- f"not flow in cleartext. Use https:// (e.g. via ngrok), or set AUTH_MODE=disabled."
26
- )
27
-
28
- return auth_mode
7
+ raw_profiles = environ.get("COMPOSE_PROFILES") or file_values.get("COMPOSE_PROFILES", "")
8
+ profiles: list[str] = []
9
+ for entry in raw_profiles.split(","):
10
+ profile = entry.strip()
11
+ if profile and profile not in profiles:
12
+ profiles.append(profile)
13
+ return profiles
29
14
 
30
15
 
31
16
  def parse_env_file(path: Path) -> dict[str, str]:
docker_devkit/up.py CHANGED
@@ -11,13 +11,14 @@ from .context_sha import compute_service_shas
11
11
  from .documents import parse_bake
12
12
  from .lifecycle import (
13
13
  enforce_bake_declaration,
14
+ enumerate_profiles,
14
15
  expand_compose_files,
15
16
  load_lifecycle_config,
16
17
  resolve_lock,
17
18
  resolve_manifest,
18
19
  )
19
20
  from .mirror import enforce_mirrored, load_mirror_config
20
- from .modes import parse_env_file, resolve_auth_mode
21
+ from .modes import parse_env_file, resolve_compose_profiles
21
22
 
22
23
  ENV_FILE = Path(".env")
23
24
 
@@ -66,8 +67,6 @@ def up(
66
67
  if gpu == "auto":
67
68
  gpu = detect_gpu()
68
69
 
69
- auth_mode = resolve_auth_mode(ENV_FILE)
70
-
71
70
  mirror_config = load_mirror_config(root)
72
71
  if mirror_config is not None:
73
72
  enforce_mirrored(parse_env_file(lock_file))
@@ -83,10 +82,20 @@ def up(
83
82
  raise RuntimeError("No compose files declared; a builds-only repo has no stack to bring up")
84
83
 
85
84
  files_args = " ".join(f"-f {compose_file}" for compose_file in compose_files)
86
- profile_flag = "--profile keycloak " if auth_mode == "keycloak" else ""
87
- compose_args = f"{files_args} {profile_flag}--project-directory {root} --env-file .env --env-file {lock_file}"
88
-
89
- up_command = f"docker compose {compose_args} up"
85
+ # compose ignores COMPOSE_PROFILES whenever a --profile flag is present, so the selection is
86
+ # resolved here and forwarded as explicit flags
87
+ compose_prefix = f"docker compose {files_args} --project-directory {root} --env-file .env --env-file {lock_file}"
88
+ profiles = resolve_compose_profiles(ENV_FILE)
89
+ if profiles:
90
+ defined = enumerate_profiles(compose_prefix)
91
+ unknown = [profile for profile in profiles if profile not in defined]
92
+ if unknown:
93
+ raise RuntimeError(
94
+ f"COMPOSE_PROFILES selects unknown profile(s) {unknown}; "
95
+ f"profiles defined by the compose files: {defined}"
96
+ )
97
+ profile_flags = "".join(f"--profile {profile} " for profile in profiles)
98
+ up_command = f"{compose_prefix} {profile_flags}up"
90
99
  if not build:
91
100
  # tree-<sha> tags are content-addressed and may not be pushed, so pull only what is missing locally
92
101
  up_command += " --pull missing"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: docker-devkit
3
- Version: 0.4.1.dev124
3
+ Version: 0.4.2.dev127
4
4
  Summary: Docker-stack lifecycle commands (up/down/build) driven by a pyproject-declared compose assembly
5
5
  License-File: LICENSE
6
6
  License-File: NOTICE
@@ -4,18 +4,18 @@ docker_devkit/config.py,sha256=UMAS6yF1E9PIbsRs2TVig9XwSNCvQe5w9eTLUHOPKq0,3112
4
4
  docker_devkit/context_sha.py,sha256=lhCxUcYM98xCdDum3hsFRFw5WYrjvZUSMbOu_7ZmQjE,3041
5
5
  docker_devkit/detect_gpu.py,sha256=C4e3vixvSSJS6xQiMVWp2IdWSAgMr551KrBTuIrkTk4,456
6
6
  docker_devkit/documents.py,sha256=c6jqbBNUKyJOltex-8u536_niWhEL7ScOab_MwZmM9k,2195
7
- docker_devkit/down.py,sha256=WDlq_RBpP84E1-5sp7MtKEhRB9wBOz8Ib59RoviZ8uQ,2179
7
+ docker_devkit/down.py,sha256=c4TtiT5aqIgr4WpyBF4czeHjZ6LJADmu0MlSUwAoKY4,2244
8
8
  docker_devkit/image_refs.py,sha256=dyngpklq8mz4rGzb7gZGg3o3i9q5YO6_DRAC9fBNRfw,5148
9
- docker_devkit/lifecycle.py,sha256=_2ZTn2xpjhDFzdVacA2oog2CvsDujaoc8oqnRnpHtC8,1631
9
+ docker_devkit/lifecycle.py,sha256=sN1wWo5H5wxFMoCI0htqh24tQfp29L1sMN1olPlrPlc,1867
10
10
  docker_devkit/matrix.py,sha256=6NyGL4Ol849dYlcMRzAL2yjFoN6sGkGwVaaxcDm3bG4,4530
11
11
  docker_devkit/mirror.py,sha256=AGL_oQUv68DKXjEFVdD-NQoLbC6w3DZJ7h-lzzvdKwM,2334
12
- docker_devkit/modes.py,sha256=Lwhblzu5Kn7qhfy_QMqE28XuflSIJtCRBYNX7Iq8Qfo,1510
12
+ docker_devkit/modes.py,sha256=UBBDYTEbzFm42BRuPCXQtQrmKJPjX7VlMqPE_WZLu4k,825
13
13
  docker_devkit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
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.1.dev124.dist-info/METADATA,sha256=F_Alz_F3jvIanQMGTCIHfYyg0pRBYW2KnSXcpb9SpW0,540
17
- docker_devkit-0.4.1.dev124.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
18
- docker_devkit-0.4.1.dev124.dist-info/entry_points.txt,sha256=6cAHqlMvuXI00uTJLf73MTqWnLd1-m5sDgJrSyHWv4U,244
19
- docker_devkit-0.4.1.dev124.dist-info/licenses/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
20
- docker_devkit-0.4.1.dev124.dist-info/licenses/NOTICE,sha256=jvglZza3GCdN7v4_TLuXUqX9C_uABlwAKUkcIeKwk_8,26
21
- docker_devkit-0.4.1.dev124.dist-info/RECORD,,
15
+ docker_devkit/up.py,sha256=pbpGf2iciL2f35zxFFe5ApZ1PfE5FQOxkPDjJ5cwFxU,3941
16
+ docker_devkit-0.4.2.dev127.dist-info/METADATA,sha256=Sbogss1YPvfZtdIKLVcWDd1ygQ2OQXvyS5xciKQ0j00,540
17
+ docker_devkit-0.4.2.dev127.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
18
+ docker_devkit-0.4.2.dev127.dist-info/entry_points.txt,sha256=6cAHqlMvuXI00uTJLf73MTqWnLd1-m5sDgJrSyHWv4U,244
19
+ docker_devkit-0.4.2.dev127.dist-info/licenses/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
20
+ docker_devkit-0.4.2.dev127.dist-info/licenses/NOTICE,sha256=jvglZza3GCdN7v4_TLuXUqX9C_uABlwAKUkcIeKwk_8,26
21
+ docker_devkit-0.4.2.dev127.dist-info/RECORD,,