bg-coolify-migrate 2.2.0__tar.gz → 2.2.2__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.
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/CHANGELOG.md +26 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/PKG-INFO +3 -3
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/README.MD +2 -2
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/__init__.py +1 -1
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/resources.py +25 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/steps.py +19 -11
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_api_resources.py +51 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_engine_steps.py +40 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/.gitignore +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/LICENSE +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/README.template.MD +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/SECURITY.template.MD +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/architecture.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/cli.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/configuration.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/index.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/installation.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/quickstart.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/safety.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/server-migration.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/troubleshooting.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/docs/why.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/pyproject.toml +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/client.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/fields.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/cli.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/docker.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/quiesce.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/dns/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/dns/extract.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/dns/gate.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/dns/resolve.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/compose.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/drift.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/images.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/kinds.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/manifest.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/naming.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/plan.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/statemachine.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/compensations.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/context.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/executor.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/keys.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/planner.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/runner.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/errors.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/journal/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/journal/store.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/observability/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/observability/logging_setup.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/py.typed +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/appkey.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/fencing.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/inventory.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/runner.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/statemachine.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/steps.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/settings/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/settings/base.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/partition.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/rsync.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/ssh.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/verify.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/console.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/dashboard.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/report.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/run_report.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/server_report.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/wizard.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/conftest.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/README.md +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/bootstrap.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/conftest.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/docker-compose.yml +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/prepare.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/runner.Dockerfile +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_all_engines.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_compose_service.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_drift_gate.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_label_contract.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_multi_resource.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_real_migration.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/e2e/test_rollback.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/integration/__init__.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/integration/docker-compose.yml +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/integration/prepare.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/integration/test_real_transfer.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_api_client.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_api_fields.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_cli.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_discovery.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_dns.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_compose.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_drift.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_images.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_kinds.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_manifest.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_naming.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_plan.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_domain_statemachine.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_engine.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_engine_context.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_engine_planner.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_engine_wiring.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_journal.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_observability.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_packaging.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_server_migration.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_transfer.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_ui.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_ui_run.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_ui_wizard.py +0 -0
- {bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/test_verify_collect.py +0 -0
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## v2.2.2 (2026-07-16)
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
- **engine**: Do not abort quiesce on a resource with no volumes
|
|
9
|
+
([`03e580e`](https://github.com/bauer-group/IP-CoolifyMigration/commit/03e580e0bee3eb0d6d831c57063b4e1bb742b265))
|
|
10
|
+
|
|
11
|
+
### Documentation
|
|
12
|
+
|
|
13
|
+
- Update README.MD [automated]
|
|
14
|
+
([`3a298d5`](https://github.com/bauer-group/IP-CoolifyMigration/commit/3a298d5fa2cc1e388e486f87455c27ae883000fe))
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## v2.2.1 (2026-07-16)
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **api**: Rebuild the git URL when recreating a public app
|
|
22
|
+
([`467c53d`](https://github.com/bauer-group/IP-CoolifyMigration/commit/467c53d4c13ca5e49693ac507fed051f868bc6e2))
|
|
23
|
+
|
|
24
|
+
### Documentation
|
|
25
|
+
|
|
26
|
+
- Update README.MD [automated]
|
|
27
|
+
([`a41bdca`](https://github.com/bauer-group/IP-CoolifyMigration/commit/a41bdca77c9a13912c9acf750a51c494802ac6bb))
|
|
28
|
+
|
|
29
|
+
|
|
4
30
|
## v2.2.0 (2026-07-16)
|
|
5
31
|
|
|
6
32
|
### Documentation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bg-coolify-migrate
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: BAUER GROUP Coolify migration toolkit — failsafe, resumable project and instance migration with byte-exact volume mirroring
|
|
5
5
|
Project-URL: Homepage, https://github.com/bauer-group/IP-CoolifyMigration
|
|
6
6
|
Project-URL: Source, https://github.com/bauer-group/IP-CoolifyMigration
|
|
@@ -55,7 +55,7 @@ Requires-Dist: mkdocstrings[python]>=0.26.0; extra == 'docs'
|
|
|
55
55
|
Description-Content-Type: text/markdown
|
|
56
56
|
|
|
57
57
|
<!-- AUTO-GENERATED FILE. DO NOT EDIT. Edit docs/README.template.MD instead. -->
|
|
58
|
-
<!-- Generated on 2026-07-16
|
|
58
|
+
<!-- Generated on 2026-07-16 17:04:54 UTC -->
|
|
59
59
|
|
|
60
60
|
# BAUER GROUP - Coolify Migration Toolkit
|
|
61
61
|
|
|
@@ -78,7 +78,7 @@ external orchestrator has none of those constraints. That is what this is.
|
|
|
78
78
|
|
|
79
79
|
## Repository Information
|
|
80
80
|
|
|
81
|
-
- **Version:** v2.1
|
|
81
|
+
- **Version:** v2.2.1
|
|
82
82
|
- **Repository:** bauer-group/IP-CoolifyMigration
|
|
83
83
|
- **Branch:** main
|
|
84
84
|
- **Architecture:** Pure-logic cores with thin IO shells; saga engine with a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!-- AUTO-GENERATED FILE. DO NOT EDIT. Edit docs/README.template.MD instead. -->
|
|
2
|
-
<!-- Generated on 2026-07-16
|
|
2
|
+
<!-- Generated on 2026-07-16 17:04:54 UTC -->
|
|
3
3
|
|
|
4
4
|
# BAUER GROUP - Coolify Migration Toolkit
|
|
5
5
|
|
|
@@ -22,7 +22,7 @@ external orchestrator has none of those constraints. That is what this is.
|
|
|
22
22
|
|
|
23
23
|
## Repository Information
|
|
24
24
|
|
|
25
|
-
- **Version:** v2.1
|
|
25
|
+
- **Version:** v2.2.1
|
|
26
26
|
- **Repository:** bauer-group/IP-CoolifyMigration
|
|
27
27
|
- **Branch:** main
|
|
28
28
|
- **Architecture:** Pure-logic cores with thin IO shells; saga engine with a
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/resources.py
RENAMED
|
@@ -223,6 +223,27 @@ async def create_service(
|
|
|
223
223
|
return str(uuid)
|
|
224
224
|
|
|
225
225
|
|
|
226
|
+
_GIT_URL_PREFIXES = ("https://", "http://", "git://", "git@")
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def _public_git_url(git_repository: str) -> str:
|
|
230
|
+
"""A full git URL for the ``/applications/public`` route.
|
|
231
|
+
|
|
232
|
+
Coolify stores a PUBLIC app's repo as the short ``owner/repo`` form: on create
|
|
233
|
+
it parses the URL and keeps only the path (``ApplicationsController`` does
|
|
234
|
+
``git_repository = segment(1)/segment(2)`` and sets the default GitHub source).
|
|
235
|
+
But the same endpoint validates ``git_repository`` with ``ValidGitRepositoryUrl``
|
|
236
|
+
— it must be a full URL. So a public app that GETs back as ``owner/repo`` is
|
|
237
|
+
rejected on re-create with "must start with https://…". We rebuild the
|
|
238
|
+
github.com URL (Coolify's default public source); anything already a URL is left
|
|
239
|
+
untouched. The private-github-app / deploy-key routes accept the short form, so
|
|
240
|
+
this is only for ``public``.
|
|
241
|
+
"""
|
|
242
|
+
if git_repository.startswith(_GIT_URL_PREFIXES):
|
|
243
|
+
return git_repository
|
|
244
|
+
return f"https://github.com/{git_repository.strip('/')}"
|
|
245
|
+
|
|
246
|
+
|
|
226
247
|
async def create_application(
|
|
227
248
|
api: CoolifyClient, snapshot: ResourceSnapshot, placement: Placement, source: dict[str, Any]
|
|
228
249
|
) -> str:
|
|
@@ -234,6 +255,10 @@ async def create_application(
|
|
|
234
255
|
body["name"] = snapshot.name
|
|
235
256
|
body["instant_deploy"] = False
|
|
236
257
|
|
|
258
|
+
# Public git apps come back short (owner/repo) but the public route needs a URL.
|
|
259
|
+
if segment == "public" and body.get("git_repository"):
|
|
260
|
+
body["git_repository"] = _public_git_url(str(body["git_repository"]))
|
|
261
|
+
|
|
237
262
|
# The FQDN is decided by the DNS gate and the finalize policy, not carried
|
|
238
263
|
# over. coolify-mover copies it verbatim, producing two resources that claim
|
|
239
264
|
# the same hostname.
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/steps.py
RENAMED
|
@@ -289,17 +289,25 @@ async def _capture_mounts(ctx: MigrationContext) -> None:
|
|
|
289
289
|
name=snapshot.name,
|
|
290
290
|
)
|
|
291
291
|
if not containers:
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"
|
|
301
|
-
|
|
302
|
-
|
|
292
|
+
# No containers is only a problem when there is data to copy. The plan's
|
|
293
|
+
# manifest is the signal: if it found volumes, a running stack is the ONLY
|
|
294
|
+
# chance to capture them, so refuse (silently copying nothing for a
|
|
295
|
+
# stateful resource is the failure we exist to prevent). If it found none
|
|
296
|
+
# — a stateless/rebuilt resource, or one that is simply stopped — there is
|
|
297
|
+
# nothing to capture, so carry on and let it be recreated on the target.
|
|
298
|
+
if resource.manifest.to_migrate:
|
|
299
|
+
raise PreflightError(
|
|
300
|
+
f"{snapshot.name}: has volumes to migrate but no running containers "
|
|
301
|
+
f"on {ctx.plan.source_server.name}",
|
|
302
|
+
hint=(
|
|
303
|
+
"Coolify removes containers when it stops them, so a running "
|
|
304
|
+
"stack is the only chance to see what its volumes mounted. Start "
|
|
305
|
+
"the resource, then migrate. If it IS running, its containers may "
|
|
306
|
+
"not carry the labels we filter on."
|
|
307
|
+
),
|
|
308
|
+
)
|
|
309
|
+
log.info("quiesce.no_containers_no_volumes", resource=snapshot.name)
|
|
310
|
+
continue
|
|
303
311
|
mounts = await inspect_all_mounts(ctx.source_host, containers)
|
|
304
312
|
ctx.pre_stop_mounts[snapshot.uuid] = mounts
|
|
305
313
|
log.info(
|
|
@@ -355,6 +355,57 @@ class TestCreateApplication:
|
|
|
355
355
|
with pytest.raises(UnsupportedResource, match="missing required field"):
|
|
356
356
|
await create_resource(api, snapshot, _placement(), {})
|
|
357
357
|
|
|
358
|
+
async def test_public_short_repo_is_rebuilt_into_a_github_url(
|
|
359
|
+
self, api: CoolifyClient, respx_mock: respx.Router
|
|
360
|
+
) -> None:
|
|
361
|
+
# Coolify stores a public app's repo as owner/repo, but the public create
|
|
362
|
+
# route validates git_repository as a URL (422 otherwise). Reconstruct it.
|
|
363
|
+
import json
|
|
364
|
+
|
|
365
|
+
route = respx_mock.post(f"{BASE}/applications/public").mock(
|
|
366
|
+
return_value=httpx.Response(201, json={"uuid": "a2"})
|
|
367
|
+
)
|
|
368
|
+
snapshot = ResourceSnapshot(
|
|
369
|
+
uuid="a1",
|
|
370
|
+
name="bentopdf",
|
|
371
|
+
collection="applications",
|
|
372
|
+
kind=ResourceKind.APP_GIT_BUILD,
|
|
373
|
+
git_repository="alam00000/bentopdf",
|
|
374
|
+
git_branch="main",
|
|
375
|
+
git_auth=GitAuth.PUBLIC,
|
|
376
|
+
)
|
|
377
|
+
await create_resource(
|
|
378
|
+
api,
|
|
379
|
+
snapshot,
|
|
380
|
+
_placement(),
|
|
381
|
+
{
|
|
382
|
+
"git_repository": "alam00000/bentopdf",
|
|
383
|
+
"git_branch": "main",
|
|
384
|
+
"build_pack": "nixpacks",
|
|
385
|
+
},
|
|
386
|
+
)
|
|
387
|
+
body = json.loads(route.calls[0].request.read())
|
|
388
|
+
assert body["git_repository"] == "https://github.com/alam00000/bentopdf"
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
class TestPublicGitUrl:
|
|
392
|
+
def test_short_form_becomes_a_github_url(self) -> None:
|
|
393
|
+
from bg_coolify_migrate.api.resources import _public_git_url
|
|
394
|
+
|
|
395
|
+
assert _public_git_url("alam00000/bentopdf") == "https://github.com/alam00000/bentopdf"
|
|
396
|
+
assert _public_git_url("/owner/repo/") == "https://github.com/owner/repo"
|
|
397
|
+
|
|
398
|
+
def test_a_real_url_is_left_untouched(self) -> None:
|
|
399
|
+
from bg_coolify_migrate.api.resources import _public_git_url
|
|
400
|
+
|
|
401
|
+
for url in (
|
|
402
|
+
"https://github.com/o/r",
|
|
403
|
+
"http://example.com/o/r",
|
|
404
|
+
"git://example.com/o/r",
|
|
405
|
+
"git@github.com:o/r.git",
|
|
406
|
+
):
|
|
407
|
+
assert _public_git_url(url) == url
|
|
408
|
+
|
|
358
409
|
|
|
359
410
|
class TestCopyEnvs:
|
|
360
411
|
async def test_bulk_upsert_overwrites_generated_secrets(
|
|
@@ -119,6 +119,46 @@ async def ctx(tmp_path: Path): # type: ignore[no-untyped-def]
|
|
|
119
119
|
await api.aclose()
|
|
120
120
|
|
|
121
121
|
|
|
122
|
+
class TestCaptureMounts:
|
|
123
|
+
"""The 'no containers' guard protects stateful resources from silently copying
|
|
124
|
+
nothing - but a stateless / no-volume resource must migrate, not abort."""
|
|
125
|
+
|
|
126
|
+
async def test_refuses_when_there_are_volumes_but_no_containers(
|
|
127
|
+
self, ctx: MigrationContext
|
|
128
|
+
) -> None:
|
|
129
|
+
# Default ctx: a COPY_DATA resource with a volume, source `docker ps` empty.
|
|
130
|
+
from bg_coolify_migrate.engine.steps import _capture_mounts
|
|
131
|
+
|
|
132
|
+
with pytest.raises(PreflightError, match="has volumes to migrate"):
|
|
133
|
+
await _capture_mounts(ctx)
|
|
134
|
+
|
|
135
|
+
async def test_proceeds_when_a_no_volume_resource_has_no_containers(
|
|
136
|
+
self, ctx: MigrationContext
|
|
137
|
+
) -> None:
|
|
138
|
+
# A rebuild app with no volumes and no running containers must NOT abort -
|
|
139
|
+
# there is nothing to capture; it is recreated (rebuilt) on the target.
|
|
140
|
+
from bg_coolify_migrate.engine.steps import _capture_mounts
|
|
141
|
+
|
|
142
|
+
ctx.plan = _plan(
|
|
143
|
+
resources=(
|
|
144
|
+
ResourcePlan(
|
|
145
|
+
snapshot=_snapshot(
|
|
146
|
+
name="alam00000/bentopdf",
|
|
147
|
+
collection="applications",
|
|
148
|
+
kind=ResourceKind.APP_GIT_BUILD,
|
|
149
|
+
engine=None,
|
|
150
|
+
image=None,
|
|
151
|
+
builds=True,
|
|
152
|
+
),
|
|
153
|
+
strategy=Strategy.REBUILD,
|
|
154
|
+
manifest=VolumeManifest(), # no volumes to migrate
|
|
155
|
+
),
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
await _capture_mounts(ctx) # no raise
|
|
159
|
+
assert ctx.pre_stop_mounts == {} # nothing captured, nothing lost
|
|
160
|
+
|
|
161
|
+
|
|
122
162
|
class TestPreflight:
|
|
123
163
|
async def test_passes_a_healthy_setup(
|
|
124
164
|
self, ctx: MigrationContext, respx_mock: respx.Router
|
|
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
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/api/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/docker.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/discovery/quiesce.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/dns/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/compose.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/drift.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/images.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/kinds.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/manifest.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/naming.py
RENAMED
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/domain/statemachine.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/compensations.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/context.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/executor.py
RENAMED
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/planner.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/engine/runner.py
RENAMED
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/journal/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/journal/store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/appkey.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/fencing.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/inventory.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/runner.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/statemachine.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/server/steps.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/settings/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/settings/base.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/__init__.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/partition.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/rsync.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/ssh.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/transfer/verify.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/dashboard.py
RENAMED
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/run_report.py
RENAMED
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/src/bg_coolify_migrate/ui/server_report.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{bg_coolify_migrate-2.2.0 → bg_coolify_migrate-2.2.2}/tests/integration/test_real_transfer.py
RENAMED
|
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
|
|
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
|