backup-docker-to-local 1.3.0__tar.gz → 1.4.0__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. {backup_docker_to_local-1.3.0/src/backup_docker_to_local.egg-info → backup_docker_to_local-1.4.0}/PKG-INFO +1 -1
  2. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/pyproject.toml +1 -1
  3. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0/src/backup_docker_to_local.egg-info}/PKG-INFO +1 -1
  4. backup_docker_to_local-1.4.0/src/baudolo/backup/compose.py +124 -0
  5. backup_docker_to_local-1.3.0/src/baudolo/backup/compose.py +0 -33
  6. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/LICENSE +0 -0
  7. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/README.md +0 -0
  8. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/setup.cfg +0 -0
  9. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/backup_docker_to_local.egg-info/SOURCES.txt +0 -0
  10. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/backup_docker_to_local.egg-info/dependency_links.txt +0 -0
  11. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/backup_docker_to_local.egg-info/entry_points.txt +0 -0
  12. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/backup_docker_to_local.egg-info/requires.txt +0 -0
  13. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/backup_docker_to_local.egg-info/top_level.txt +0 -0
  14. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/__init__.py +0 -0
  15. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/__init__.py +0 -0
  16. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/__main__.py +0 -0
  17. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/app.py +0 -0
  18. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/cli.py +0 -0
  19. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/db.py +0 -0
  20. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/docker.py +0 -0
  21. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/shell.py +0 -0
  22. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/backup/volume.py +0 -0
  23. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/__init__.py +0 -0
  24. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/__main__.py +0 -0
  25. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/db/__init__.py +0 -0
  26. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/db/mariadb.py +0 -0
  27. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/db/postgres.py +0 -0
  28. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/files.py +0 -0
  29. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/paths.py +0 -0
  30. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/restore/run.py +0 -0
  31. {backup_docker_to_local-1.3.0 → backup_docker_to_local-1.4.0}/src/baudolo/seed/__main__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: backup-docker-to-local
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Backup Docker volumes to local with rsync and optional DB dumps.
5
5
  Author: Kevin Veen-Birkenbach
6
6
  License: AGPL-3.0-or-later
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "backup-docker-to-local"
7
- version = "1.3.0"
7
+ version = "1.4.0"
8
8
  description = "Backup Docker volumes to local with rsync and optional DB dumps."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: backup-docker-to-local
3
- Version: 1.3.0
3
+ Version: 1.4.0
4
4
  Summary: Backup Docker volumes to local with rsync and optional DB dumps.
5
5
  Author: Kevin Veen-Birkenbach
6
6
  License: AGPL-3.0-or-later
@@ -0,0 +1,124 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import shutil
5
+ import subprocess
6
+ from pathlib import Path
7
+ from typing import List, Optional
8
+
9
+
10
+ def _detect_env_file(project_dir: Path) -> Optional[Path]:
11
+ """
12
+ Detect Compose env file in a directory.
13
+ Preference (same as Infinito.Nexus wrapper):
14
+ 1) <dir>/.env (file)
15
+ 2) <dir>/.env/env (file) (legacy layout)
16
+ """
17
+ c1 = project_dir / ".env"
18
+ if c1.is_file():
19
+ return c1
20
+
21
+ c2 = project_dir / ".env" / "env"
22
+ if c2.is_file():
23
+ return c2
24
+
25
+ return None
26
+
27
+
28
+ def _detect_compose_files(project_dir: Path) -> List[Path]:
29
+ """
30
+ Detect Compose file stack in a directory (same as Infinito.Nexus wrapper).
31
+ Always requires docker-compose.yml.
32
+ Optionals:
33
+ - docker-compose.override.yml
34
+ - docker-compose.ca.override.yml
35
+ """
36
+ base = project_dir / "docker-compose.yml"
37
+ if not base.is_file():
38
+ raise FileNotFoundError(f"Missing docker-compose.yml in: {project_dir}")
39
+
40
+ files = [base]
41
+
42
+ override = project_dir / "docker-compose.override.yml"
43
+ if override.is_file():
44
+ files.append(override)
45
+
46
+ ca_override = project_dir / "docker-compose.ca.override.yml"
47
+ if ca_override.is_file():
48
+ files.append(ca_override)
49
+
50
+ return files
51
+
52
+
53
+ def _compose_wrapper_path() -> Optional[str]:
54
+ """
55
+ Prefer the Infinito.Nexus compose wrapper if present.
56
+ Equivalent to: `which compose`
57
+ """
58
+ return shutil.which("compose")
59
+
60
+
61
+ def _build_compose_cmd(project_dir: str, passthrough: List[str]) -> List[str]:
62
+ """
63
+ Build the compose command for this project directory.
64
+
65
+ Behavior:
66
+ - If `compose` wrapper exists: use it with --chdir (so it resolves -f/--env-file itself)
67
+ - Else: use `docker compose` and replicate wrapper's file/env detection.
68
+ """
69
+ pdir = Path(project_dir).resolve()
70
+
71
+ wrapper = _compose_wrapper_path()
72
+ if wrapper:
73
+ # Wrapper defaults project name to basename of --chdir.
74
+ # "--" ensures wrapper stops parsing its own args.
75
+ return [wrapper, "--chdir", str(pdir), "--", *passthrough]
76
+
77
+ # Fallback: pure docker compose, but mirror wrapper behavior.
78
+ files = _detect_compose_files(pdir)
79
+ env_file = _detect_env_file(pdir)
80
+
81
+ cmd: List[str] = ["docker", "compose"]
82
+ for f in files:
83
+ cmd += ["-f", str(f)]
84
+ if env_file:
85
+ cmd += ["--env-file", str(env_file)]
86
+
87
+ cmd += passthrough
88
+ return cmd
89
+
90
+
91
+ def hard_restart_docker_services(dir_path: str) -> None:
92
+ print(f"Hard restart compose services in: {dir_path}", flush=True)
93
+
94
+ down_cmd = _build_compose_cmd(dir_path, ["down"])
95
+ up_cmd = _build_compose_cmd(dir_path, ["up", "-d"])
96
+
97
+ print(">>> " + " ".join(down_cmd), flush=True)
98
+ subprocess.run(down_cmd, check=True)
99
+
100
+ print(">>> " + " ".join(up_cmd), flush=True)
101
+ subprocess.run(up_cmd, check=True)
102
+
103
+
104
+ def handle_docker_compose_services(
105
+ parent_directory: str, hard_restart_required: list[str]
106
+ ) -> None:
107
+ for entry in os.scandir(parent_directory):
108
+ if not entry.is_dir():
109
+ continue
110
+
111
+ dir_path = entry.path
112
+ name = os.path.basename(dir_path)
113
+ compose_file = os.path.join(dir_path, "docker-compose.yml")
114
+
115
+ print(f"Checking directory: {dir_path}", flush=True)
116
+ if not os.path.isfile(compose_file):
117
+ print("No docker-compose.yml found. Skipping.", flush=True)
118
+ continue
119
+
120
+ if name in hard_restart_required:
121
+ print(f"{name}: hard restart required.", flush=True)
122
+ hard_restart_docker_services(dir_path)
123
+ else:
124
+ print(f"{name}: no restart required.", flush=True)
@@ -1,33 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import os
4
- import subprocess
5
-
6
-
7
- def hard_restart_docker_services(dir_path: str) -> None:
8
- print(f"Hard restart docker-compose services in: {dir_path}", flush=True)
9
- subprocess.run(["docker-compose", "down"], cwd=dir_path, check=True)
10
- subprocess.run(["docker-compose", "up", "-d"], cwd=dir_path, check=True)
11
-
12
-
13
- def handle_docker_compose_services(
14
- parent_directory: str, hard_restart_required: list[str]
15
- ) -> None:
16
- for entry in os.scandir(parent_directory):
17
- if not entry.is_dir():
18
- continue
19
-
20
- dir_path = entry.path
21
- name = os.path.basename(dir_path)
22
- compose_file = os.path.join(dir_path, "docker-compose.yml")
23
-
24
- print(f"Checking directory: {dir_path}", flush=True)
25
- if not os.path.isfile(compose_file):
26
- print("No docker-compose.yml found. Skipping.", flush=True)
27
- continue
28
-
29
- if name in hard_restart_required:
30
- print(f"{name}: hard restart required.", flush=True)
31
- hard_restart_docker_services(dir_path)
32
- else:
33
- print(f"{name}: no restart required.", flush=True)