redeploy 0.2.43__tar.gz → 0.2.44__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.
- {redeploy-0.2.43 → redeploy-0.2.44}/PKG-INFO +8 -6
- {redeploy-0.2.43 → redeploy-0.2.44}/README.md +5 -5
- {redeploy-0.2.43 → redeploy-0.2.44}/pyproject.toml +2 -1
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/__init__.py +1 -1
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/device_map.py +38 -3
- redeploy-0.2.44/redeploy/integrations/__init__.py +1 -0
- redeploy-0.2.44/redeploy/integrations/op3_bridge.py +74 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/PKG-INFO +8 -6
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/SOURCES.txt +2 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/requires.txt +3 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/exceptions.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/executor.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/handlers.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/progress.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/rollback.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/state.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/state_apply.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/utils/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/apply/utils/run_container_build.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/audit.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/blueprint/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/blueprint/extractor.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/blueprint/generators/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/blueprint/generators/docker_compose.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/blueprint/generators/migration.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/audit.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/blueprint.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/detect.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/devices.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/diagnose.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/diff.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/exec_.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/export.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/hardware.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/import_.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/init.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/inspect.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/patterns.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/plan_apply.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/plugin.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/probe.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/push.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/state.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/status.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/target.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/commands.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/helpers.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/monorepo.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/release.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/version/scanner.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/commands/workflow.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/core.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli/display.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/cli.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/data_sync.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/builtin/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/detector.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/hardware.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/hardware_rules.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/probes.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/remote.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/templates.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/detect/workflow.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/discovery.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl/loader.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl/parser.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/context.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/decorators.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/docker_steps.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/exceptions.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/runner.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/dsl_python/steps.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/fleet.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/config_txt.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/data/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/data/hyperpixel.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/data/official.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/data/waveshare.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/fixes.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/kiosk/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/kiosk/autostart.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/kiosk/browsers.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/kiosk/compositors.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/kiosk/output_profiles.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/panels.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/hardware/raspi_config.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/base.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/docker_compose.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/parsers/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/parsers/compose.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/iac/registry.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/markpact/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/markpact/compiler.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/markpact/models.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/markpact/parser.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/models.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/observe.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/parse.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/patterns.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plan/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plan/planner.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/browser_reload.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/hardware_diagnostic.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/notify.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/process_control.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/plugins/builtin/systemd_reload.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/spec_loader.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/ssh.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/steps.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_audit.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_cli.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_data_sync.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_discovery.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_dsl.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_examples.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_executor.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_fleet.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_git_integration.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_iac.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_manifest.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_markpact_compiler.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_markpact_parser.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_models.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_observe.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_parse.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_patterns.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_planner_edge.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_plugins.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_probes.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_public_api.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_resume.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_spec_loader.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_ssh.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_templates.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_verify.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_version.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_version_changelog.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_version_cli.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_version_manifest.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_version_sources.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/tests/test_workflow.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/verify.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/bump.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/changelog.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/commits.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/diff.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/git_integration.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/git_transaction.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/manifest.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/__init__.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/base.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/json_.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/plain.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/regex.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/toml_.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/sources/yaml_.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version/transaction.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy/version.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/dependency_links.txt +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/entry_points.txt +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/redeploy.egg-info/top_level.txt +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/setup.cfg +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_hardware_config.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_hardware_kiosk.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_hardware_rules.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_iac.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_parse.py +0 -0
- {redeploy-0.2.43 → redeploy-0.2.44}/tests/test_redeploy.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.44
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -22,23 +22,25 @@ Requires-Dist: ruff>=0.4; extra == "dev"
|
|
|
22
22
|
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
23
23
|
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
24
24
|
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
25
|
+
Provides-Extra: op3
|
|
26
|
+
Requires-Dist: op3>=0.1.4; extra == "op3"
|
|
25
27
|
|
|
26
28
|
# redeploy
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
## AI Cost Tracking
|
|
30
32
|
|
|
31
|
-
     
|
|
34
|
+
  
|
|
33
35
|
|
|
34
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
35
|
-
- 👤 **Human dev:** ~$
|
|
36
|
+
- 🤖 **LLM usage:** $7.5000 (65 commits)
|
|
37
|
+
- 👤 **Human dev:** ~$2136 (21.4h @ $100/h, 30min dedup)
|
|
36
38
|
|
|
37
39
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
38
40
|
|
|
39
41
|
---
|
|
40
42
|
|
|
41
|
-
    
|
|
42
44
|
|
|
43
45
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
44
46
|
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
     
|
|
7
|
+
  
|
|
8
8
|
|
|
9
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
10
|
-
- 👤 **Human dev:** ~$
|
|
9
|
+
- 🤖 **LLM usage:** $7.5000 (65 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$2136 (21.4h @ $100/h, 30min dedup)
|
|
11
11
|
|
|
12
12
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
    
|
|
17
17
|
|
|
18
18
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
19
19
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "redeploy"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.44"
|
|
8
8
|
description = "Infrastructure migration toolkit: detect → plan → apply"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -32,6 +32,7 @@ dev = ["pytest>=8.0", "ruff>=0.4",
|
|
|
32
32
|
"costs>=0.1.20",
|
|
33
33
|
"pfix>=0.1.60",
|
|
34
34
|
]
|
|
35
|
+
op3 = ["op3>=0.1.4"]
|
|
35
36
|
|
|
36
37
|
[tool.ruff]
|
|
37
38
|
line-length = 100
|
|
@@ -7,7 +7,7 @@ Public API (stable from 0.2.0, semver guaranteed)::
|
|
|
7
7
|
|
|
8
8
|
Everything not listed in ``__all__`` is internal and may change without notice.
|
|
9
9
|
"""
|
|
10
|
-
__version__ = "0.2.
|
|
10
|
+
__version__ = "0.2.44"
|
|
11
11
|
|
|
12
12
|
# ── Core models ───────────────────────────────────────────────────────────────
|
|
13
13
|
from .models import ( # noqa: F401
|
|
@@ -50,10 +50,16 @@ from rich.table import Table
|
|
|
50
50
|
@click.option("--apply-config", "apply_config", default=None,
|
|
51
51
|
type=click.Path(exists=True, dir_okay=False),
|
|
52
52
|
help="Apply hardware/infra settings from YAML config file to the remote host")
|
|
53
|
+
@click.option(
|
|
54
|
+
"--query", "query_expr",
|
|
55
|
+
default=None,
|
|
56
|
+
metavar="EXPR",
|
|
57
|
+
help="Extract specific values using JMESPath query (e.g. 'hardware.drm_outputs[0].transform', 'host')",
|
|
58
|
+
)
|
|
53
59
|
@click.option("--ssh-key", default=None, type=click.Path(), help="SSH private key path")
|
|
54
60
|
def device_map_cmd(
|
|
55
61
|
host, name, tags, save, out_path, output_fmt,
|
|
56
|
-
no_infra, list_saved, show_file, diff_files, ssh_key, apply_config,
|
|
62
|
+
no_infra, list_saved, show_file, diff_files, ssh_key, apply_config, query_expr,
|
|
57
63
|
):
|
|
58
64
|
"""Generate a full standardized device snapshot (hardware + infra + diagnostics).
|
|
59
65
|
|
|
@@ -105,6 +111,11 @@ def device_map_cmd(
|
|
|
105
111
|
console.print("[red]✗ HOST required (or use --list / --show / --diff)[/red]")
|
|
106
112
|
sys.exit(1)
|
|
107
113
|
|
|
114
|
+
# ── --apply-config ─────────────────────────────────────────────────────────
|
|
115
|
+
if apply_config:
|
|
116
|
+
_apply_config_from_file(console, apply_config, ssh_key)
|
|
117
|
+
return
|
|
118
|
+
|
|
108
119
|
# ── probe ─────────────────────────────────────────────────────────────────
|
|
109
120
|
from ...detect.hardware import probe_hardware
|
|
110
121
|
from ...detect.remote import RemoteProbe
|
|
@@ -195,7 +206,7 @@ def _apply_config_from_file(console, config_path, ssh_key):
|
|
|
195
206
|
import yaml
|
|
196
207
|
import json as _json
|
|
197
208
|
|
|
198
|
-
from ...remote import
|
|
209
|
+
from ...detect.remote import RemoteProbe
|
|
199
210
|
|
|
200
211
|
with open(config_path) as f:
|
|
201
212
|
raw = f.read()
|
|
@@ -214,7 +225,7 @@ def _apply_config_from_file(console, config_path, ssh_key):
|
|
|
214
225
|
console.print(f"[cyan]→ Applying config from {config_path} to {host}[/cyan]")
|
|
215
226
|
|
|
216
227
|
# Connect to remote
|
|
217
|
-
p =
|
|
228
|
+
p = RemoteProbe(host, ssh_key=ssh_key)
|
|
218
229
|
|
|
219
230
|
applied = 0
|
|
220
231
|
|
|
@@ -321,6 +332,30 @@ def _update_kanshi_from_cfg(console, p, dsi_outputs: list):
|
|
|
321
332
|
p.run("pkill -SIGUSR1 kanshi 2>/dev/null || true")
|
|
322
333
|
|
|
323
334
|
|
|
335
|
+
def _execute_query_device_map(console, dm, query_expr, output_fmt):
|
|
336
|
+
"""Execute JMESPath query on DeviceMap model and output result."""
|
|
337
|
+
import jmespath
|
|
338
|
+
import json as _json
|
|
339
|
+
|
|
340
|
+
data = dm.model_dump(mode="json")
|
|
341
|
+
|
|
342
|
+
try:
|
|
343
|
+
result = jmespath.search(query_expr, data)
|
|
344
|
+
except jmespath.exceptions.JMESPathError as e:
|
|
345
|
+
console.print(f"[red]✗ JMESPath error:[/red] {e}")
|
|
346
|
+
sys.exit(1)
|
|
347
|
+
|
|
348
|
+
if result is None:
|
|
349
|
+
console.print("[dim]No match found for query[/dim]")
|
|
350
|
+
return
|
|
351
|
+
|
|
352
|
+
if output_fmt == "json":
|
|
353
|
+
click.echo(_json.dumps(result, indent=2, default=str))
|
|
354
|
+
else:
|
|
355
|
+
import yaml
|
|
356
|
+
click.echo(yaml.safe_dump(result, sort_keys=False, default_flow_style=False))
|
|
357
|
+
|
|
358
|
+
|
|
324
359
|
# ── rendering helpers ─────────────────────────────────────────────────────────
|
|
325
360
|
|
|
326
361
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Redeploy integrations."""
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Bridge between redeploy and op3.
|
|
2
|
+
|
|
3
|
+
All adapters go through here. This module isolates op3 usage so that redeploy
|
|
4
|
+
remains runnable when op3 is not installed.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
from typing import TYPE_CHECKING
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from opstree.probes.context import SSHContext
|
|
13
|
+
from opstree.snapshot.model import Snapshot
|
|
14
|
+
from redeploy.models import InfraState, HardwareInfo
|
|
15
|
+
|
|
16
|
+
OP3_ENABLED_ENV = "REDEPLOY_USE_OP3"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def op3_enabled() -> bool:
|
|
20
|
+
"""Check whether the user wants to use op3."""
|
|
21
|
+
return os.environ.get(OP3_ENABLED_ENV, "0").lower() in ("1", "true", "yes")
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def op3_available() -> bool:
|
|
25
|
+
"""Check whether op3 is installed."""
|
|
26
|
+
try:
|
|
27
|
+
import opstree # noqa: F401
|
|
28
|
+
return True
|
|
29
|
+
except ImportError:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def should_use_op3() -> bool:
|
|
34
|
+
"""Use op3 only when both flag is on and library is available."""
|
|
35
|
+
return op3_enabled() and op3_available()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def make_op3_context_from_ssh_client(ssh_client) -> "SSHContext":
|
|
39
|
+
"""Convert redeploy.SshClient -> opstree.SSHContext."""
|
|
40
|
+
from opstree.probes.context import SSHContext
|
|
41
|
+
|
|
42
|
+
return SSHContext(
|
|
43
|
+
target=ssh_client.target,
|
|
44
|
+
host=ssh_client.host,
|
|
45
|
+
user=ssh_client.user,
|
|
46
|
+
ssh_key=ssh_client.ssh_key,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def snapshot_to_infra_state(snapshot: "Snapshot") -> "InfraState":
|
|
51
|
+
"""Convert opstree.Snapshot -> redeploy.InfraState (backward compat)."""
|
|
52
|
+
from redeploy.models import InfraState
|
|
53
|
+
|
|
54
|
+
runtime_data = snapshot.layer("runtime.container")
|
|
55
|
+
service_data = snapshot.layer("service.containers")
|
|
56
|
+
endpoint_data = snapshot.layer("endpoint.http")
|
|
57
|
+
|
|
58
|
+
# TODO: full mapping once layer schemas stabilise
|
|
59
|
+
return InfraState(
|
|
60
|
+
runtime=runtime_data.data if runtime_data else {},
|
|
61
|
+
services=service_data.data if service_data else {},
|
|
62
|
+
endpoints=endpoint_data.data if endpoint_data else {},
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def snapshot_to_hardware_info(snapshot: "Snapshot") -> "HardwareInfo":
|
|
67
|
+
"""Convert opstree.Snapshot -> redeploy.HardwareInfo."""
|
|
68
|
+
from redeploy.models import HardwareInfo
|
|
69
|
+
|
|
70
|
+
physical = snapshot.layer("physical.display")
|
|
71
|
+
# TODO: expand mapping as op3 layer schema grows
|
|
72
|
+
return HardwareInfo(
|
|
73
|
+
device_model=physical.data.get("model") if physical else None,
|
|
74
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: redeploy
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.44
|
|
4
4
|
Summary: Infrastructure migration toolkit: detect → plan → apply
|
|
5
5
|
Requires-Python: >=3.11
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -22,23 +22,25 @@ Requires-Dist: ruff>=0.4; extra == "dev"
|
|
|
22
22
|
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
23
23
|
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
24
24
|
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
25
|
+
Provides-Extra: op3
|
|
26
|
+
Requires-Dist: op3>=0.1.4; extra == "op3"
|
|
25
27
|
|
|
26
28
|
# redeploy
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
## AI Cost Tracking
|
|
30
32
|
|
|
31
|
-
     
|
|
34
|
+
  
|
|
33
35
|
|
|
34
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
35
|
-
- 👤 **Human dev:** ~$
|
|
36
|
+
- 🤖 **LLM usage:** $7.5000 (65 commits)
|
|
37
|
+
- 👤 **Human dev:** ~$2136 (21.4h @ $100/h, 30min dedup)
|
|
36
38
|
|
|
37
39
|
Generated on 2026-04-21 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
38
40
|
|
|
39
41
|
---
|
|
40
42
|
|
|
41
|
-
    
|
|
42
44
|
|
|
43
45
|
Infrastructure migration and device deploy toolkit — VPS, Raspberry Pi kiosk, Podman Quadlet, k3s.
|
|
44
46
|
|
|
@@ -107,6 +107,8 @@ redeploy/iac/docker_compose.py
|
|
|
107
107
|
redeploy/iac/registry.py
|
|
108
108
|
redeploy/iac/parsers/__init__.py
|
|
109
109
|
redeploy/iac/parsers/compose.py
|
|
110
|
+
redeploy/integrations/__init__.py
|
|
111
|
+
redeploy/integrations/op3_bridge.py
|
|
110
112
|
redeploy/markpact/__init__.py
|
|
111
113
|
redeploy/markpact/compiler.py
|
|
112
114
|
redeploy/markpact/models.py
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|