docker-stack 2.0.4__tar.gz → 2.0.6__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.
Files changed (31) hide show
  1. {docker_stack-2.0.4 → docker_stack-2.0.6}/PKG-INFO +1 -1
  2. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/cli.py +12 -5
  3. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/PKG-INFO +1 -1
  4. {docker_stack-2.0.4 → docker_stack-2.0.6}/setup.py +1 -1
  5. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_docker_stack.py +31 -4
  6. {docker_stack-2.0.4 → docker_stack-2.0.6}/README.md +0 -0
  7. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/__init__.py +0 -0
  8. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/command_runner.py +0 -0
  9. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/compose.py +0 -0
  10. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/docker_objects.py +0 -0
  11. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/envsubst.py +0 -0
  12. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/envsubst_merge.py +0 -0
  13. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/helpers.py +0 -0
  14. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/login.py +0 -0
  15. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/manager_api.py +0 -0
  16. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/markers.py +0 -0
  17. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/merge_conf.py +0 -0
  18. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/registry.py +0 -0
  19. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack/url_parser.py +0 -0
  20. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/SOURCES.txt +0 -0
  21. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/dependency_links.txt +0 -0
  22. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/entry_points.txt +0 -0
  23. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/requires.txt +0 -0
  24. {docker_stack-2.0.4 → docker_stack-2.0.6}/docker_stack.egg-info/top_level.txt +0 -0
  25. {docker_stack-2.0.4 → docker_stack-2.0.6}/pyproject.toml +0 -0
  26. {docker_stack-2.0.4 → docker_stack-2.0.6}/setup.cfg +0 -0
  27. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_docker_objects.py +0 -0
  28. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_load_env.py +0 -0
  29. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_login.py +0 -0
  30. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_manager_api.py +0 -0
  31. {docker_stack-2.0.4 → docker_stack-2.0.6}/tests/test_node_ls.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docker-stack
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: CLI for deploying and managing Docker stacks.
5
5
  Home-page: https://github.com/mesudip/docker-stack
6
6
  Author: Sudip Bhattarai
@@ -329,12 +329,13 @@ class DockerStack:
329
329
  docker_object_name = docker_object_name_for(name, explicit_name=explicit_name)
330
330
 
331
331
  if manager_client and stack:
332
+ manager_object_name = explicit_name or name
332
333
  label_map = normalize_labels(labels)
333
334
  if manager.object_type == "config":
334
335
  response = manager_client.resolve_config(
335
336
  stack=stack,
336
337
  namespace=namespace,
337
- name=docker_object_name,
338
+ name=manager_object_name,
338
339
  content=data,
339
340
  labels=label_map,
340
341
  )
@@ -342,7 +343,7 @@ class DockerStack:
342
343
  response = manager_client.resolve_secret(
343
344
  stack=stack,
344
345
  namespace=namespace,
345
- name=docker_object_name,
346
+ name=manager_object_name,
346
347
  content=None if is_generated_secret else data,
347
348
  generate=generate_options if is_generated_secret else None,
348
349
  labels=label_map,
@@ -432,6 +433,12 @@ class DockerStack:
432
433
  @staticmethod
433
434
  def _version_sort_key(raw: str):
434
435
  return int(raw) if raw.isdigit() else raw
436
+ @staticmethod
437
+ def _display_stack_name(raw: str) -> str:
438
+ value = raw.strip()
439
+ if value.startswith("default--"):
440
+ return value[len("default--"):]
441
+ return value
435
442
 
436
443
  def _print_stack_listing(self, stack_versions: Dict[str, List[str]]) -> None:
437
444
  max_stack_name_length = max(len(stack) for stack in stack_versions) if stack_versions else 10
@@ -461,7 +468,7 @@ class DockerStack:
461
468
  try:
462
469
  payload = client.list_stacks()
463
470
  stack_versions = {
464
- str(item.get("stack")): [
471
+ self._display_stack_name(str(item.get("stack"))): [
465
472
  str(version)
466
473
  for version in (
467
474
  item.get("versions")
@@ -487,7 +494,7 @@ class DockerStack:
487
494
  parts = line.split("\t")
488
495
  if len(parts) == 3 and "mesudip.stack.name" in parts[2]:
489
496
  labels = {k: v for k, v in (label.split("=") for label in parts[2].split(",") if "=" in label)}
490
- stack_name = labels.get("mesudip.stack.name")
497
+ stack_name = self._display_stack_name(labels.get("mesudip.stack.name", "")) or None
491
498
  version = labels.get("mesudip.object.version", "unknown")
492
499
 
493
500
  if stack_name:
@@ -558,7 +565,7 @@ class DockerStack:
558
565
  parts = line.split("\t")
559
566
  if len(parts) == 2 and "mesudip.stack.name" in parts[1]:
560
567
  labels = {k: v for k, v in (label.split("=") for label in parts[1].split(",") if "=" in label)}
561
- stack = labels.get("mesudip.stack.name")
568
+ stack = self._display_stack_name(labels.get("mesudip.stack.name", "")) or None
562
569
  version = labels.get("mesudip.object.version", "unknown")
563
570
  tag = labels.get("mesudip.stack.tag", "")
564
571
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: docker-stack
3
- Version: 2.0.4
3
+ Version: 2.0.6
4
4
  Summary: CLI for deploying and managing Docker stacks.
5
5
  Home-page: https://github.com/mesudip/docker-stack
6
6
  Author: Sudip Bhattarai
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="docker-stack",
5
- version="2.0.4",
5
+ version="2.0.6",
6
6
  description="CLI for deploying and managing Docker stacks.",
7
7
  long_description=open("README.md").read(), # You can include a README file to describe your package
8
8
  long_description_content_type="text/markdown",
@@ -229,7 +229,7 @@ def test_process_x_content_uses_manager_resolve_apis(monkeypatch):
229
229
  {
230
230
  "stack": "govtool",
231
231
  "namespace": "default",
232
- "name": "govtool_app.conf",
232
+ "name": "app.conf",
233
233
  "content": "hello",
234
234
  "labels": {},
235
235
  }
@@ -238,7 +238,7 @@ def test_process_x_content_uses_manager_resolve_apis(monkeypatch):
238
238
  {
239
239
  "stack": "govtool",
240
240
  "namespace": "default",
241
- "name": "govtool_app-secret",
241
+ "name": "app-secret",
242
242
  "content": None,
243
243
  "generate": {
244
244
  "length": 24,
@@ -250,8 +250,8 @@ def test_process_x_content_uses_manager_resolve_apis(monkeypatch):
250
250
  "return_generated_value": True,
251
251
  }
252
252
  ]
253
- assert processed_configs == {"app.conf": {"name": "govtool_app.conf_v2", "external": True}}
254
- assert processed_secrets == {"app-secret": {"name": "govtool_app-secret", "external": True}}
253
+ assert processed_configs == {"app.conf": {"name": "app.conf_v2", "external": True}}
254
+ assert processed_secrets == {"app-secret": {"name": "app-secret", "external": True}}
255
255
  assert docker.stack.generated_secrets == {"app-secret": "generated-from-manager"}
256
256
 
257
257
 
@@ -295,6 +295,33 @@ def test_rm_enqueues_stack_remove_command():
295
295
  assert docker.stack.commands[-1].command == ["docker", "stack", "rm", "govtool"]
296
296
 
297
297
 
298
+ def test_default_namespace_stack_names_are_normalized_in_output(monkeypatch, capsys):
299
+ inspect_payloads = {
300
+ ("docker", "config", "ls", "--format", "{{.ID}} {{.Name}} {{.Labels}}"):
301
+ "cfg1 default--team-a mesudip.stack.name=default--team-a,mesudip.object.version=1",
302
+ ("docker", "config", "ls", "--format", "{{.Name}} {{.Labels}}"):
303
+ "default--team-a mesudip.stack.name=default--team-a,mesudip.object.version=1,mesudip.stack.tag=stable",
304
+ ("docker", "config", "inspect", "team-a"):
305
+ json.dumps([{"Spec": {"Data": base64.b64encode(b"services:\n api:\n image: busybox\n").decode("utf-8")}}]),
306
+ }
307
+
308
+ def fake_run_cli_command(command, **kwargs):
309
+ key = tuple(command)
310
+ if key not in inspect_payloads:
311
+ raise AssertionError(f"Unexpected command: {command}")
312
+ return inspect_payloads[key]
313
+
314
+ monkeypatch.setattr("docker_stack.cli.run_cli_command", fake_run_cli_command)
315
+ monkeypatch.setattr("docker_stack.cli.discover_manager_client", lambda *_args, **_kwargs: None)
316
+
317
+ docker = Docker()
318
+ assert docker.stack.ls() == {"team-a": ["1"]}
319
+ assert docker.stack.versions("team-a") == [("1", "stable")]
320
+ output = capsys.readouterr().out
321
+ assert "default--team-a" not in output
322
+ assert "team-a" in output
323
+
324
+
298
325
  def test_filtered_agent_outputs_still_render(monkeypatch, capsys):
299
326
  inspect_payloads = {
300
327
  ("docker", "config", "ls", "--format", "{{.ID}}\t{{.Name}}\t{{.Labels}}"): "\n".join(
File without changes
File without changes