octopize.deploy_tool 3.3.0__tar.gz → 3.5.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 (413) hide show
  1. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/PKG-INFO +45 -5
  2. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/README.md +44 -4
  3. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/pyproject.toml +1 -1
  4. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/__init__.py +1 -1
  5. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/app_root.py +123 -0
  6. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/checks.py +15 -3
  7. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/install_command.py +2 -2
  8. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/migrate_command.py +2 -2
  9. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_users.py +62 -5
  10. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/update_command.py +3 -2
  11. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/configure_command.py +4 -3
  12. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/application/host_paths.py +143 -0
  13. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/application/image_registry_auth.py +201 -0
  14. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/ports.py +59 -0
  15. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/start_command.py +49 -1
  16. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/authentik_migration.py +12 -3
  17. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/authentik_user_types.py +23 -0
  18. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/__init__.py +12 -0
  19. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/start.py +4 -0
  20. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/config_resolver.py +29 -7
  21. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/defaults.yaml +1 -1
  22. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/exceptions.py +19 -0
  23. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/container_identity.py +64 -0
  24. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/container_mounts.py +56 -0
  25. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/docker_client.py +122 -23
  26. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/infra/docker_config_reader.py +60 -0
  27. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/document_step_runner.py +20 -25
  28. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/noop_docker_client.py +13 -0
  29. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/input_gatherer.py +139 -20
  30. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/line_editing.py +56 -0
  31. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/resources/config.example.yaml +11 -2
  32. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/base.py +13 -2
  33. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/email.py +9 -4
  34. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/required.py +2 -0
  35. octopize_deploy_tool-3.5.0/src/octopize_avatar_deploy/templates/.env.template +3 -0
  36. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_api.template +0 -1
  37. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_infra.template +1 -0
  38. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_lifecycle.py +32 -0
  39. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/.env +2 -1
  40. {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_apply_output → octopize_deploy_tool-3.5.0/tests/fixtures/install_render_output}/.env +2 -1
  41. {octopize_deploy_tool-3.3.0/tests/fixtures/update_interactive_diff/expected_render_output → octopize_deploy_tool-3.5.0/tests/fixtures/update_interactive_diff/expected_apply_output}/.env +2 -1
  42. {octopize_deploy_tool-3.3.0/tests/fixtures/install_render_output → octopize_deploy_tool-3.5.0/tests/fixtures/update_interactive_diff/expected_render_output}/.env +2 -1
  43. octopize_deploy_tool-3.5.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +102 -0
  44. octopize_deploy_tool-3.5.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +102 -0
  45. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/fakes.py +44 -0
  46. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_cli_integration.py +44 -0
  47. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_configure_command.py +23 -28
  48. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_install_command.py +141 -1
  49. octopize_deploy_tool-3.5.0/tests/unit/infra/test_container_identity.py +97 -0
  50. octopize_deploy_tool-3.5.0/tests/unit/infra/test_docker_config_reader.py +61 -0
  51. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_document_step_runner.py +40 -22
  52. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_email.py +86 -2
  53. octopize_deploy_tool-3.5.0/tests/unit/steps/test_prompt_text.py +107 -0
  54. octopize_deploy_tool-3.5.0/tests/unit/test_app_root.py +104 -0
  55. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_client.py +68 -0
  56. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migration.py +12 -4
  57. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_config_resolver.py +123 -1
  58. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_create_users.py +139 -6
  59. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_diff_command.py +9 -24
  60. octopize_deploy_tool-3.5.0/tests/unit/test_host_paths.py +129 -0
  61. octopize_deploy_tool-3.5.0/tests/unit/test_image_registry_auth.py +159 -0
  62. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_input_gatherer.py +97 -0
  63. octopize_deploy_tool-3.5.0/tests/unit/test_line_editing.py +84 -0
  64. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_preflight_checks.py +30 -2
  65. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_rich_implementations.py +42 -0
  66. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_start_command.py +116 -1
  67. octopize_deploy_tool-3.3.0/src/octopize_avatar_deploy/templates/.env.template +0 -3
  68. octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_apply_output/.env +0 -101
  69. octopize_deploy_tool-3.3.0/tests/fixtures/update_noninteractive_clean/expected_render_output/.env +0 -101
  70. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/.gitignore +0 -0
  71. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/src/octopize_avatar_deploy/steps/user.py +0 -0
  72. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/generate_env_output_dir_error/output.txt +0 -0
  73. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/help/output.txt +0 -0
  74. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/infra/deployment/deployment-tool/tests/fixtures/missing_subcommand/output.txt +0 -0
  75. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/__init__.py +0 -0
  76. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/_guards.py +0 -0
  77. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/apply_command.py +0 -0
  78. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_env.py +0 -0
  79. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_login.py +0 -0
  80. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/authentik_readiness.py +0 -0
  81. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/client_compatibility_report.py +0 -0
  82. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/subcommand_ports.py +0 -0
  83. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/__init__.py +0 -0
  84. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/authentik_migrate.py +0 -0
  85. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_command.py +0 -0
  86. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/create_self_signed_cert_task.py +0 -0
  87. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/provision_admin.py +0 -0
  88. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/reconcile_blueprint.py +0 -0
  89. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/tasks/registry.py +0 -0
  90. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/commands/verify_command.py +0 -0
  91. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/configure_resume_policy.py +0 -0
  92. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/deployment_markers.py +0 -0
  93. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/deployment_paths.py +0 -0
  94. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/diff_command.py +0 -0
  95. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/legacy_layout.py +0 -0
  96. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/operator_owned_files.py +0 -0
  97. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/polling.py +0 -0
  98. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/render_command.py +0 -0
  99. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/secret_files.py +0 -0
  100. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/stop_command.py +0 -0
  101. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/uninstall_command.py +0 -0
  102. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/application/user_config.py +0 -0
  103. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cert_generator.py +0 -0
  104. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/certificate_verifier.py +0 -0
  105. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/_shared.py +0 -0
  106. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/__init__.py +0 -0
  107. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/apply.py +0 -0
  108. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/configure.py +0 -0
  109. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/diff.py +0 -0
  110. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/install.py +0 -0
  111. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/migrate.py +0 -0
  112. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/render.py +0 -0
  113. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/stop.py +0 -0
  114. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/tasks.py +0 -0
  115. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/uninstall.py +0 -0
  116. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/update.py +0 -0
  117. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli/handlers/verify.py +0 -0
  118. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli_dependencies.py +0 -0
  119. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/cli_test_harness.py +0 -0
  120. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/control_flags.py +0 -0
  121. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/deployment_mode.py +0 -0
  122. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/__init__.py +0 -0
  123. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/client_compatibility.py +0 -0
  124. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/configure_preset.py +0 -0
  125. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_item.py +0 -0
  126. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_item_registry.py +0 -0
  127. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/deployment_state.py +0 -0
  128. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/generation.py +0 -0
  129. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/placement.py +0 -0
  130. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/service_versions.py +0 -0
  131. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/validation.py +0 -0
  132. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/domain/version_id.py +0 -0
  133. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/download_templates.py +0 -0
  134. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/environment.py +0 -0
  135. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/__init__.py +0 -0
  136. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/cert_infra.py +0 -0
  137. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/current_version_resolver.py +0 -0
  138. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/env_file_reader.py +0 -0
  139. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem.py +0 -0
  140. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem_legacy_source.py +0 -0
  141. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/filesystem_user_config_scaffolder.py +0 -0
  142. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/httpx2_http_client.py +0 -0
  143. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/in_memory_state_repository.py +0 -0
  144. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/offline_http_client.py +0 -0
  145. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_defaults_source.py +0 -0
  146. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_template_provider.py +0 -0
  147. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/package_version_provider.py +0 -0
  148. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/preset_loader.py +0 -0
  149. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/system_clock.py +0 -0
  150. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/yaml_config_source.py +0 -0
  151. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/infra/yaml_state_repository.py +0 -0
  152. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/normalizers.py +0 -0
  153. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/output_spec.py +0 -0
  154. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/printer.py +0 -0
  155. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/public_url.py +0 -0
  156. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/renderer.py +0 -0
  157. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/resources/__init__.py +0 -0
  158. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/secret_factory.py +0 -0
  159. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/self_signed_ssl.py +0 -0
  160. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/__init__.py +0 -0
  161. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/authentik.py +0 -0
  162. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/authentik_blueprint.py +0 -0
  163. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/database.py +0 -0
  164. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/logging.py +0 -0
  165. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/nginx.py +0 -0
  166. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/service_urls.py +0 -0
  167. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/storage.py +0 -0
  168. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/telemetry.py +0 -0
  169. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/steps/user.py +0 -0
  170. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/template_provisioning.py +0 -0
  171. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/.template-version +0 -0
  172. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/_env_fragment_web.template +0 -0
  173. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/api.env.template +0 -0
  174. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/branding/favicon.ico +0 -0
  175. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/branding/logo.png +0 -0
  176. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_confirmation.html +0 -0
  177. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_exists.html +0 -0
  178. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_account_invitation.html +0 -0
  179. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_forgotten_password.html +0 -0
  180. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_changed.html +0 -0
  181. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/custom-templates/email_password_reset.html +0 -0
  182. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/octopize-avatar-blueprint.yaml +0 -0
  183. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/authentik/translations.json +0 -0
  184. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/compose.override.yaml.template +0 -0
  185. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/docker-compose.yml.template +0 -0
  186. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/nginx.conf.template +0 -0
  187. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/python_client.env.template +0 -0
  188. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/templates/web.env.template +0 -0
  189. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/tls_types.py +0 -0
  190. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/topology_urls.py +0 -0
  191. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/url_contract.py +0 -0
  192. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/verbosity.py +0 -0
  193. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/src/octopize_avatar_deploy/version_compat.py +0 -0
  194. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/TESTING.md +0 -0
  195. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/__init__.py +0 -0
  196. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/conftest.py +0 -0
  197. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/__init__.py +0 -0
  198. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/conftest.py +0 -0
  199. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_migrate_start_provision_verify.py +0 -0
  200. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/test_update_reapplies_blueprint.py +0 -0
  201. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/e2e/user_disable_revokes_api_key.py +0 -0
  202. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/__init__.py +0 -0
  203. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/apply_help/output.txt +0 -0
  204. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/licenses.csv +0 -0
  205. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/organizations.csv +0 -0
  206. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/authentik_migration/users.csv +0 -0
  207. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/expected/.deployment_states/v1/deployment_state.yaml +0 -0
  208. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/input.yaml +0 -0
  209. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_happy_path/output.txt +0 -0
  210. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/configure_help/output.txt +0 -0
  211. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_help/output.txt +0 -0
  212. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/from/.env +0 -0
  213. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/from/nginx/nginx.conf +0 -0
  214. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/output.txt +0 -0
  215. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/.env +0 -0
  216. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/docker-compose.yml +0 -0
  217. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/diff_integration/to/nginx/nginx.conf +0 -0
  218. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.env +0 -0
  219. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/admin_emails +0 -0
  220. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/authjwt_secret_key +0 -0
  221. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/clevercloud_sso_salt +0 -0
  222. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_password +0 -0
  223. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_admin_user +0 -0
  224. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_name +0 -0
  225. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_password +0 -0
  226. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/db_user +0 -0
  227. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/file_jwt_secret_key +0 -0
  228. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/organization_name +0 -0
  229. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/pepper +0 -0
  230. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/smtp_password +0 -0
  231. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_access_key_id +0 -0
  232. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/e2e/legacy_deployment/.secrets/storage_admin_secret_access_key +0 -0
  233. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/help/output.txt +0 -0
  234. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/.permissions.json +0 -0
  235. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/branding/favicon.ico +0 -0
  236. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/branding/logo.png +0 -0
  237. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  238. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  239. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  240. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  241. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  242. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  243. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  244. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/authentik/translations.json +0 -0
  245. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/docker-compose.yml +0 -0
  246. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_apply_output/nginx/nginx.conf +0 -0
  247. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_help/output.txt +0 -0
  248. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/.permissions.json +0 -0
  249. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/branding/favicon.ico +0 -0
  250. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/branding/logo.png +0 -0
  251. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  252. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  253. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  254. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  255. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  256. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  257. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  258. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/authentik/translations.json +0 -0
  259. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/docker-compose.yml +0 -0
  260. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/install_render_output/nginx/nginx.conf +0 -0
  261. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/migrate_help/output.txt +0 -0
  262. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/missing_subcommand/output.txt +0 -0
  263. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/non_interactive_complete/config.yaml +0 -0
  264. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/non_interactive_no_telemetry/config.yaml +0 -0
  265. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/render_help/output.txt +0 -0
  266. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/start_help/output.txt +0 -0
  267. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/stop_help/output.txt +0 -0
  268. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_authentik_migrate_help/output.txt +0 -0
  269. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_create_self_signed_cert_help/output.txt +0 -0
  270. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_create_users_help/output.txt +0 -0
  271. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_help/output.txt +0 -0
  272. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_provision_admin_help/output.txt +0 -0
  273. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/tasks_reconcile_blueprint_help/output.txt +0 -0
  274. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/uninstall_help/output.txt +0 -0
  275. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_help/output.txt +0 -0
  276. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/base_v1/generated_files/.env +0 -0
  277. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.needs_blueprint_reconcile +0 -0
  278. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/.permissions.json +0 -0
  279. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/favicon.ico +0 -0
  280. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/branding/logo.png +0 -0
  281. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  282. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  283. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  284. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  285. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  286. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  287. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  288. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/authentik/translations.json +0 -0
  289. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/docker-compose.yml +0 -0
  290. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_apply_output/nginx/nginx.conf +0 -0
  291. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/.permissions.json +0 -0
  292. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/favicon.ico +0 -0
  293. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/branding/logo.png +0 -0
  294. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  295. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  296. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  297. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  298. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  299. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  300. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  301. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/authentik/translations.json +0 -0
  302. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/docker-compose.yml +0 -0
  303. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_interactive_diff/expected_render_output/nginx/nginx.conf +0 -0
  304. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/base_v1/generated_files/.env +0 -0
  305. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.needs_blueprint_reconcile +0 -0
  306. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/.permissions.json +0 -0
  307. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/favicon.ico +0 -0
  308. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/branding/logo.png +0 -0
  309. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  310. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_exists.html +0 -0
  311. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_account_invitation.html +0 -0
  312. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  313. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_changed.html +0 -0
  314. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/custom-templates/email_password_reset.html +0 -0
  315. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  316. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/authentik/translations.json +0 -0
  317. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/docker-compose.yml +0 -0
  318. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_apply_output/nginx/nginx.conf +0 -0
  319. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/.permissions.json +0 -0
  320. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/favicon.ico +0 -0
  321. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/branding/logo.png +0 -0
  322. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_confirmation.html +0 -0
  323. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_exists.html +0 -0
  324. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_account_invitation.html +0 -0
  325. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_forgotten_password.html +0 -0
  326. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_changed.html +0 -0
  327. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/custom-templates/email_password_reset.html +0 -0
  328. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/octopize-avatar-blueprint.yaml +0 -0
  329. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/authentik/translations.json +0 -0
  330. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/docker-compose.yml +0 -0
  331. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/update_noninteractive_clean/expected_render_output/nginx/nginx.conf +0 -0
  332. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/fixtures/verify_help/output.txt +0 -0
  333. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/__init__.py +0 -0
  334. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/fixture_dir_comparison.py +0 -0
  335. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/normalization.py +0 -0
  336. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/printers.py +0 -0
  337. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/steps.py +0 -0
  338. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/helpers/tls_fixtures.py +0 -0
  339. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/__init__.py +0 -0
  340. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_authentik_migrate_task.py +0 -0
  341. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_client_compatibility_output.py +0 -0
  342. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_create_self_signed_cert_task.py +0 -0
  343. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_diff_command.py +0 -0
  344. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_legacy_app_root.py +0 -0
  345. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_first_run.py +0 -0
  346. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_relative_tls_paths.py +0 -0
  347. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_migrate_without_tls_keys.py +0 -0
  348. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/integration/test_update_command.py +0 -0
  349. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/test_cli_harness.py +0 -0
  350. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/__init__.py +0 -0
  351. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/conftest.py +0 -0
  352. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_docker_client.py +0 -0
  353. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_filesystem.py +0 -0
  354. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_filesystem_legacy_source.py +0 -0
  355. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_httpx2_http_client.py +0 -0
  356. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_preset_loader.py +0 -0
  357. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_yaml_config_source.py +0 -0
  358. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/infra/test_yaml_deployment_state_repository.py +0 -0
  359. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_authentik.py +0 -0
  360. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_authentik_blueprint.py +0 -0
  361. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_database.py +0 -0
  362. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_logging.py +0 -0
  363. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_nginx.py +0 -0
  364. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_required.py +0 -0
  365. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_service_urls.py +0 -0
  366. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_storage.py +0 -0
  367. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_telemetry.py +0 -0
  368. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/steps/test_user.py +0 -0
  369. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_apply_command.py +0 -0
  370. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_env.py +0 -0
  371. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_login.py +0 -0
  372. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_command.py +0 -0
  373. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_for_docker.py +0 -0
  374. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_migrate_parsers.py +0 -0
  375. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_authentik_readiness.py +0 -0
  376. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_cert_generator.py +0 -0
  377. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_certificate_verifier.py +0 -0
  378. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_cli_verify_ssl.py +0 -0
  379. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_client_compatibility.py +0 -0
  380. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_compare_helpers.py +0 -0
  381. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_config_resolver_consistency.py +0 -0
  382. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_configure_command.py +0 -0
  383. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_create_self_signed_cert_task.py +0 -0
  384. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_deployment_item.py +0 -0
  385. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_docs_command_references.py +0 -0
  386. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_environment.py +0 -0
  387. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_generation.py +0 -0
  388. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_generic_prompt.py +0 -0
  389. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_install_command.py +0 -0
  390. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_migrate_command.py +0 -0
  391. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_normalizers.py +0 -0
  392. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_output_spec.py +0 -0
  393. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_placement.py +0 -0
  394. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_polling.py +0 -0
  395. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_printer.py +0 -0
  396. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_provision_admin.py +0 -0
  397. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_public_url.py +0 -0
  398. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_reconcile_blueprint.py +0 -0
  399. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_render_command.py +0 -0
  400. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_renderer.py +0 -0
  401. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_secret_factory.py +0 -0
  402. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_secret_files.py +0 -0
  403. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_select_authentik_migrate_parser.py +0 -0
  404. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_service_versions.py +0 -0
  405. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_stop_command.py +0 -0
  406. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_task_registry.py +0 -0
  407. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_uninstall_command.py +0 -0
  408. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_update_command.py +0 -0
  409. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_user_config.py +0 -0
  410. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_validation.py +0 -0
  411. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_verify_command.py +0 -0
  412. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_version_id.py +0 -0
  413. {octopize_deploy_tool-3.3.0 → octopize_deploy_tool-3.5.0}/tests/unit/test_version_validation.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: octopize.deploy_tool
3
- Version: 3.3.0
3
+ Version: 3.5.0
4
4
  Summary: Deployment configuration tool for Octopize Avatar platform
5
5
  Project-URL: Homepage, https://octopize.io
6
6
  Project-URL: Documentation, https://docs.octopize.io/docs/deploying/self-hosted/self_installation
@@ -96,9 +96,12 @@ to be up, and `provision-admin` must run before `verify`. Both hold once `start`
96
96
 
97
97
  ## Command reference
98
98
 
99
- `--app-root` defaults to the current directory everywhere it is accepted. Every command and
100
- `tasks` sub-command takes `--verbosity {1,2}`, where `1` is essential (the default) and `2` is
101
- verbose. Every command's `--help` lists its full option set.
99
+ `--app-root` defaults to the current directory everywhere it is accepted, and must be a directory
100
+ the invoking user can read, write and enter — every command refuses a root-owned or otherwise
101
+ inaccessible root up front rather than failing part-way through. It does not have to exist yet, as
102
+ long as its parent is writable. Every command and `tasks` sub-command takes `--verbosity {1,2}`,
103
+ where `1` is essential (the default) and `2` is verbose. Every command's `--help` lists its full
104
+ option set.
102
105
 
103
106
  ### Everyday commands
104
107
 
@@ -279,7 +282,8 @@ answering "keep" for a file is still honoured and still blocks the apply.
279
282
  `migrate` also creates `user_config/` under the new app root, so a migrated deployment is shaped
280
283
  exactly like an installed one and `update --from-config` works the same way on both.
281
284
 
282
- > **Before migrating non-interactively**, make sure the legacy `.env` sets
285
+ > **Before migrating non-interactively**, make sure the legacy `.env` sets `SMTP_HOST` (or pass
286
+ > `USE_AWS_SMTP_PRESET: true`), and sets
283
287
  > `NGINX_SSL_CERTIFICATE_PATH` and `NGINX_SSL_CERTIFICATE_KEY_PATH` to paths that exist.
284
288
  > Otherwise the run falls back to a relative built-in default and keeps it with a warning that
285
289
  > the path is "not usable yet" — the migration completes, but nginx will not start until a
@@ -425,6 +429,9 @@ Two things the example does not tell you:
425
429
  - **`ORGANIZATION_NAME` is missing from it** and is required. A `--non-interactive` run without it
426
430
  stops at `ORGANIZATION_NAME is required but not provided in configuration file`. Add it
427
431
  yourself, as below.
432
+ - **`SMTP_HOST` is required too**, unless you set `USE_AWS_SMTP_PRESET: true` to take the AWS SES
433
+ settings Octopize provides. The example sets it; a `--non-interactive` run with neither stops at
434
+ `'SMTP_HOST' is required and no value was provided`.
428
435
  - **The TLS keys the tool reads are `NGINX_SSL_CERTIFICATE_PATH` and
429
436
  `NGINX_SSL_CERTIFICATE_KEY_PATH`.** Use those spellings.
430
437
 
@@ -515,14 +522,31 @@ docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/
515
522
 
516
523
  ### Start
517
524
 
525
+ `start` pulls the images the deployment needs, and two of them are private. The
526
+ credentials `docker login` writes belong to the Docker _client_, so the login you did on
527
+ the host is invisible to the client in this container: the extra `DOCKER_CONFIG` mount
528
+ below is what gives them to it.
529
+
518
530
  ```bash
519
531
  export CP=$(docker info -f '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
520
532
  docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/docker.sock)" \
521
533
  -v "$(pwd)/avatar:/app-root" -v /var/run/docker.sock:/var/run/docker.sock \
522
534
  -v "$(which docker):/usr/local/bin/docker:ro" -v "$CP:$CP:ro" \
535
+ -e DOCKER_CONFIG=/docker-config -v "$HOME/.docker:/docker-config:ro" \
523
536
  quay.io/octopize/deploy-tool:latest start --app-root /app-root
524
537
  ```
525
538
 
539
+ If the host keeps its registry credentials in a credential helper — a `credsStore` entry
540
+ in `~/.docker/config.json` — that mount carries no usable credential, because the helper
541
+ is a program the container does not have. Write a configuration that holds the token
542
+ itself, and mount that one instead:
543
+
544
+ ```bash
545
+ mkdir -p ~/avatar-registry-login
546
+ DOCKER_CONFIG=~/avatar-registry-login docker login quay.io
547
+ # ... -e DOCKER_CONFIG=/docker-config -v "$HOME/avatar-registry-login:/docker-config:ro"
548
+ ```
549
+
526
550
  ### Stop
527
551
 
528
552
  ```bash
@@ -583,6 +607,11 @@ Notes:
583
607
  by Docker Compose on the _host_, so give the host path even though you are typing it inside a
584
608
  container. The tool detects that it is running in a container, skips the existence check for
585
609
  those paths and prints a notice saying so.
610
+ - **The app root has to come from a mount.** The deployment files are read by the Docker daemon
611
+ on the host, and the tool works out their host path from the container's own mounts, so
612
+ `-v "$(pwd)/avatar:/app-root"` needs no path to match. A directory that belongs to the
613
+ container itself (`/tmp/avatar`, say) is reachable by nothing but the tool, and `start`
614
+ refuses it rather than bring up a stack that cannot read its own secrets.
586
615
  - **Anything outside the app root needs its own mount**: `-v "$(pwd)/config:/input:ro"` with
587
616
  `--from-config /input/config.yaml`, or `-v "$(pwd)/avatar-old:/legacy:ro"` with
588
617
  `--from-legacy /legacy` for `migrate`. Always pass the container-side path.
@@ -647,6 +676,17 @@ under `generated_files/`. Merge them into `.deployment_states/<vX>/generated/` a
647
676
 
648
677
  **`verify` reports "API key not found".** Run `tasks provision-admin` first.
649
678
 
679
+ **An `install` was interrupted with Ctrl+C.** Run `install` again: it reports the incomplete
680
+ configuration and asks `Resume the in-progress configuration (vN)?` Answering `y` continues
681
+ where it stopped, keeping the answers already given; answering `n` starts the questionnaire
682
+ again in a new version slot and leaves the interrupted one on disk. A `--non-interactive` run
683
+ cannot answer, so it stops instead.
684
+
685
+ **`start` reports that an image registry refused the credentials.** The credentials
686
+ `docker login` writes belong to the Docker client, so a `start` run from the deploy-tool
687
+ container does not have the ones you created on the host. The message names the mount to add —
688
+ see [Running via Docker](#running-via-docker).
689
+
650
690
  **Something needs a closer look.** Add `--verbosity 2` for detailed progress and template output.
651
691
 
652
692
  **Starting over.** `uninstall` is the supported teardown: it is confirmation-gated and removes
@@ -63,9 +63,12 @@ to be up, and `provision-admin` must run before `verify`. Both hold once `start`
63
63
 
64
64
  ## Command reference
65
65
 
66
- `--app-root` defaults to the current directory everywhere it is accepted. Every command and
67
- `tasks` sub-command takes `--verbosity {1,2}`, where `1` is essential (the default) and `2` is
68
- verbose. Every command's `--help` lists its full option set.
66
+ `--app-root` defaults to the current directory everywhere it is accepted, and must be a directory
67
+ the invoking user can read, write and enter — every command refuses a root-owned or otherwise
68
+ inaccessible root up front rather than failing part-way through. It does not have to exist yet, as
69
+ long as its parent is writable. Every command and `tasks` sub-command takes `--verbosity {1,2}`,
70
+ where `1` is essential (the default) and `2` is verbose. Every command's `--help` lists its full
71
+ option set.
69
72
 
70
73
  ### Everyday commands
71
74
 
@@ -246,7 +249,8 @@ answering "keep" for a file is still honoured and still blocks the apply.
246
249
  `migrate` also creates `user_config/` under the new app root, so a migrated deployment is shaped
247
250
  exactly like an installed one and `update --from-config` works the same way on both.
248
251
 
249
- > **Before migrating non-interactively**, make sure the legacy `.env` sets
252
+ > **Before migrating non-interactively**, make sure the legacy `.env` sets `SMTP_HOST` (or pass
253
+ > `USE_AWS_SMTP_PRESET: true`), and sets
250
254
  > `NGINX_SSL_CERTIFICATE_PATH` and `NGINX_SSL_CERTIFICATE_KEY_PATH` to paths that exist.
251
255
  > Otherwise the run falls back to a relative built-in default and keeps it with a warning that
252
256
  > the path is "not usable yet" — the migration completes, but nginx will not start until a
@@ -392,6 +396,9 @@ Two things the example does not tell you:
392
396
  - **`ORGANIZATION_NAME` is missing from it** and is required. A `--non-interactive` run without it
393
397
  stops at `ORGANIZATION_NAME is required but not provided in configuration file`. Add it
394
398
  yourself, as below.
399
+ - **`SMTP_HOST` is required too**, unless you set `USE_AWS_SMTP_PRESET: true` to take the AWS SES
400
+ settings Octopize provides. The example sets it; a `--non-interactive` run with neither stops at
401
+ `'SMTP_HOST' is required and no value was provided`.
395
402
  - **The TLS keys the tool reads are `NGINX_SSL_CERTIFICATE_PATH` and
396
403
  `NGINX_SSL_CERTIFICATE_KEY_PATH`.** Use those spellings.
397
404
 
@@ -482,14 +489,31 @@ docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/
482
489
 
483
490
  ### Start
484
491
 
492
+ `start` pulls the images the deployment needs, and two of them are private. The
493
+ credentials `docker login` writes belong to the Docker _client_, so the login you did on
494
+ the host is invisible to the client in this container: the extra `DOCKER_CONFIG` mount
495
+ below is what gives them to it.
496
+
485
497
  ```bash
486
498
  export CP=$(docker info -f '{{range .ClientInfo.Plugins}}{{if eq .Name "compose"}}{{.Path}}{{end}}{{end}}')
487
499
  docker run --rm --user "$(id -u):$(id -g)" --group-add "$(stat -c '%g' /var/run/docker.sock)" \
488
500
  -v "$(pwd)/avatar:/app-root" -v /var/run/docker.sock:/var/run/docker.sock \
489
501
  -v "$(which docker):/usr/local/bin/docker:ro" -v "$CP:$CP:ro" \
502
+ -e DOCKER_CONFIG=/docker-config -v "$HOME/.docker:/docker-config:ro" \
490
503
  quay.io/octopize/deploy-tool:latest start --app-root /app-root
491
504
  ```
492
505
 
506
+ If the host keeps its registry credentials in a credential helper — a `credsStore` entry
507
+ in `~/.docker/config.json` — that mount carries no usable credential, because the helper
508
+ is a program the container does not have. Write a configuration that holds the token
509
+ itself, and mount that one instead:
510
+
511
+ ```bash
512
+ mkdir -p ~/avatar-registry-login
513
+ DOCKER_CONFIG=~/avatar-registry-login docker login quay.io
514
+ # ... -e DOCKER_CONFIG=/docker-config -v "$HOME/avatar-registry-login:/docker-config:ro"
515
+ ```
516
+
493
517
  ### Stop
494
518
 
495
519
  ```bash
@@ -550,6 +574,11 @@ Notes:
550
574
  by Docker Compose on the _host_, so give the host path even though you are typing it inside a
551
575
  container. The tool detects that it is running in a container, skips the existence check for
552
576
  those paths and prints a notice saying so.
577
+ - **The app root has to come from a mount.** The deployment files are read by the Docker daemon
578
+ on the host, and the tool works out their host path from the container's own mounts, so
579
+ `-v "$(pwd)/avatar:/app-root"` needs no path to match. A directory that belongs to the
580
+ container itself (`/tmp/avatar`, say) is reachable by nothing but the tool, and `start`
581
+ refuses it rather than bring up a stack that cannot read its own secrets.
553
582
  - **Anything outside the app root needs its own mount**: `-v "$(pwd)/config:/input:ro"` with
554
583
  `--from-config /input/config.yaml`, or `-v "$(pwd)/avatar-old:/legacy:ro"` with
555
584
  `--from-legacy /legacy` for `migrate`. Always pass the container-side path.
@@ -614,6 +643,17 @@ under `generated_files/`. Merge them into `.deployment_states/<vX>/generated/` a
614
643
 
615
644
  **`verify` reports "API key not found".** Run `tasks provision-admin` first.
616
645
 
646
+ **An `install` was interrupted with Ctrl+C.** Run `install` again: it reports the incomplete
647
+ configuration and asks `Resume the in-progress configuration (vN)?` Answering `y` continues
648
+ where it stopped, keeping the answers already given; answering `n` starts the questionnaire
649
+ again in a new version slot and leaves the interrupted one on disk. A `--non-interactive` run
650
+ cannot answer, so it stops instead.
651
+
652
+ **`start` reports that an image registry refused the credentials.** The credentials
653
+ `docker login` writes belong to the Docker client, so a `start` run from the deploy-tool
654
+ container does not have the ones you created on the host. The message names the mount to add —
655
+ see [Running via Docker](#running-via-docker).
656
+
617
657
  **Something needs a closer look.** Add `--verbosity 2` for detailed progress and template output.
618
658
 
619
659
  **Starting over.** `uninstall` is the supported teardown: it is confirmation-gated and removes
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "octopize.deploy_tool"
7
- version = "3.3.0"
7
+ version = "3.5.0"
8
8
  description = "Deployment configuration tool for Octopize Avatar platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -9,7 +9,7 @@ from .version_compat import (
9
9
  validate_template_version,
10
10
  )
11
11
 
12
- __version__ = "3.3.0"
12
+ __version__ = "3.5.0"
13
13
  __all__ = [
14
14
  "SCRIPT_VERSION",
15
15
  "ConsolePrinter",
@@ -0,0 +1,123 @@
1
+ """Validation of the deployment root supplied on the command line.
2
+
3
+ Every command reads and writes under ``--app-root``: the versioned state
4
+ documents, the rendered versions, ``generated_files/``, the secrets. A path the
5
+ invoking user cannot enter, read or write is a dead end, and the failure
6
+ otherwise surfaces deep inside a command as a bare ``PermissionError`` on some
7
+ individual file — after secrets have already been generated. Checking it at the
8
+ CLI boundary turns that into one actionable message before any work starts.
9
+
10
+ Write access is only demanded of the commands that write: a deployment root left
11
+ read-only can still be stopped, diffed and verified.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import getpass
17
+ import os
18
+ from pathlib import Path
19
+
20
+ from octopize_avatar_deploy.application._guards import CommandError
21
+
22
+ _EXAMPLE_ROOT = "./app/avatar"
23
+
24
+
25
+ class AppRootError(CommandError):
26
+ """Raised when the deployment root cannot be used by the current user."""
27
+
28
+
29
+ def validate_app_root(app_root: Path, *, require_write: bool = True) -> Path:
30
+ """Return *app_root* with ``~`` expanded, once it is usable by this user.
31
+
32
+ A root that does not exist yet is fine — commands create it — provided the
33
+ nearest existing ancestor is a directory this user can write into.
34
+
35
+ Args:
36
+ app_root: The path the operator passed to ``--app-root``.
37
+ require_write: Whether this command writes under the root.
38
+
39
+ Raises:
40
+ AppRootError: If the path (or the directory it would be created in) is
41
+ not a directory, or lacks the access this command needs.
42
+
43
+ """
44
+ expanded = app_root.expanduser()
45
+
46
+ if expanded.is_symlink() and not expanded.exists():
47
+ raise AppRootError(
48
+ f"{expanded} is a broken symlink. Point --app-root at a real directory, "
49
+ f"e.g. {_EXAMPLE_ROOT}."
50
+ )
51
+
52
+ target = expanded
53
+ while not target.exists():
54
+ parent = target.parent
55
+ if parent == target:
56
+ break
57
+ target = parent
58
+
59
+ if not target.is_dir():
60
+ raise AppRootError(
61
+ f"{target} is not a directory. Point --app-root at a directory you own, "
62
+ f"e.g. {_EXAMPLE_ROOT}."
63
+ )
64
+
65
+ missing = [
66
+ label for mode, label in _required_access(require_write) if not os.access(target, mode)
67
+ ]
68
+ if not missing:
69
+ return expanded
70
+
71
+ user = _current_user()
72
+ owner = _owner(target)
73
+ subject = (
74
+ f"Deployment root {expanded}"
75
+ if target == expanded
76
+ else f"{expanded} cannot be created: {target}"
77
+ )
78
+ raise AppRootError(
79
+ f"{subject} is not {_join(missing)} by user {user!r} (owner: {owner!r}).\n"
80
+ f"Point --app-root at a directory your user owns, e.g. {_EXAMPLE_ROOT}, or fix "
81
+ f"this one:\n {_remedy(target, expanded, user, owner)}"
82
+ )
83
+
84
+
85
+ def _required_access(require_write: bool) -> list[tuple[int, str]]:
86
+ """The access modes the command needs, each paired with how to name it."""
87
+ if require_write:
88
+ return [(os.R_OK, "readable"), (os.W_OK, "writable"), (os.X_OK, "traversable")]
89
+ return [(os.R_OK, "readable"), (os.X_OK, "traversable")]
90
+
91
+
92
+ def _remedy(target: Path, expanded: Path, user: str, owner: str) -> str:
93
+ """The one command that gets this user the access they are missing."""
94
+ if owner == user:
95
+ # Already theirs, so the mode bits are what stand in the way.
96
+ return f"chmod u+rwx {target}"
97
+ if target == expanded:
98
+ return f"sudo chown -R {user} {target}"
99
+ return f"sudo install -d -o {user} {expanded}"
100
+
101
+
102
+ def _join(labels: list[str]) -> str:
103
+ if len(labels) == 1:
104
+ return labels[0]
105
+ return f"{', '.join(labels[:-1])} or {labels[-1]}"
106
+
107
+
108
+ def _current_user() -> str:
109
+ try:
110
+ return getpass.getuser()
111
+ except OSError:
112
+ return f"uid {os.getuid()}"
113
+
114
+
115
+ def _owner(path: Path) -> str:
116
+ try:
117
+ return path.owner()
118
+ except (KeyError, NotImplementedError, OSError):
119
+ pass
120
+ try:
121
+ return f"uid {path.stat().st_uid}"
122
+ except OSError:
123
+ return "unknown"
@@ -306,7 +306,9 @@ class DeploymentStateCheck:
306
306
  Handles three cases:
307
307
 
308
308
  - **No state** — nothing to do, continue silently.
309
- - **In-progress** — in interactive mode, offer to resume; in non-interactive mode,
309
+ - **In-progress** — in interactive mode, offer to resume; a declined resume
310
+ continues into a new version slot, because ``install`` is the fresh-install
311
+ command and has no flag that could ask for one. In non-interactive mode,
310
312
  fail by default.
311
313
  - **Completed** — in interactive mode, warn and ask for confirmation;
312
314
  in non-interactive mode, fail by default (destructive fresh install requires
@@ -371,11 +373,21 @@ class DeploymentStateCheck:
371
373
  f"Resume the in-progress configuration ({version_label})?",
372
374
  default=True,
373
375
  key="preflight.deployment_state_check.resume",
376
+ help_text=(
377
+ "Yes continues the interrupted questionnaire: the steps it already "
378
+ f"completed are kept and only the remaining ones are asked.\n"
379
+ "No starts the questionnaire again from the first question, in a new "
380
+ f"version slot. {version_label} stays on disk and is not deployed."
381
+ ),
374
382
  )
375
383
  if resume:
376
384
  return DeploymentStateCheckResult(state="in_progress", aborted=False, resume=True)
377
- # Operator declined to resume — abort so they can decide what to do.
378
- return DeploymentStateCheckResult(state="in_progress", aborted=True, resume=False)
385
+
386
+ self._printer.print(
387
+ f"Starting a fresh configuration in a new version slot. "
388
+ f"The interrupted {version_label} is kept and is not deployed."
389
+ )
390
+ return DeploymentStateCheckResult(state="in_progress", aborted=False, resume=False)
379
391
 
380
392
  def _handle_completed(self) -> DeploymentStateCheckResult:
381
393
  self._printer.print_warning(
@@ -247,8 +247,8 @@ class InstallCommand:
247
247
 
248
248
  self._printer.print_success(
249
249
  f"Install complete. Version {version_label!r} is now deployed to "
250
- f"{apply_result.output_dir}. "
251
- "Run 'start' to bring up the stack."
250
+ f"{apply_result.output_dir}.\n"
251
+ f"Bring up the stack by running 'start' with --app-root {args.app_root}"
252
252
  )
253
253
 
254
254
  # 7. Name the python clients that work with this API version, so the
@@ -378,8 +378,8 @@ class MigrateCommand:
378
378
 
379
379
  self._printer.print_success(
380
380
  f"Migration complete. Version {version_label!r} is now deployed to "
381
- f"{apply_result.output_dir}. "
382
- "Run 'start' to bring up the stack."
381
+ f"{apply_result.output_dir}.\n"
382
+ f"Bring up the stack by running 'start' with --app-root {args.app_root}"
383
383
  )
384
384
 
385
385
  # 6. Name the python clients that work with this API version. A legacy
@@ -21,6 +21,11 @@ from octopize_avatar_deploy.application.authentik_env import (
21
21
  )
22
22
  from octopize_avatar_deploy.application.deployment_paths import DeploymentPaths
23
23
  from octopize_avatar_deploy.application.ports import EnvReader, HttpClient
24
+ from octopize_avatar_deploy.authentik_user_types import (
25
+ EXTERNAL_USER_TYPE,
26
+ INTERNAL_USER_TYPE,
27
+ AuthentikUserType,
28
+ )
24
29
  from octopize_avatar_deploy.cli_dependencies import CliDependencies
25
30
  from octopize_avatar_deploy.domain.validation import ValidationError as _ValidationError
26
31
  from octopize_avatar_deploy.domain.validation import validate_email
@@ -71,6 +76,7 @@ class AuthentikUser:
71
76
  email: str
72
77
  name: str
73
78
  is_active: bool
79
+ user_type: str
74
80
 
75
81
 
76
82
  @dataclass(frozen=True)
@@ -101,6 +107,13 @@ class UserSpec:
101
107
  email: str
102
108
  group: str # Authentik group name
103
109
 
110
+ @property
111
+ def user_type(self) -> AuthentikUserType:
112
+ """The Authentik user type this user needs to exercise its group's rights."""
113
+ if self.group == ADMIN_GROUP_NAME:
114
+ return INTERNAL_USER_TYPE
115
+ return EXTERNAL_USER_TYPE
116
+
104
117
 
105
118
  @dataclass
106
119
  class ProvisionResult:
@@ -170,7 +183,8 @@ class CreateUsersClient(Protocol):
170
183
  """Authentik operations needed by :class:`UserProvisioner`."""
171
184
 
172
185
  def get_user_by_email(self, email: str) -> AuthentikUser | None: ...
173
- def create_user(self, *, email: str) -> AuthentikUser: ...
186
+ def create_user(self, *, email: str, user_type: AuthentikUserType) -> AuthentikUser: ...
187
+ def set_user_type(self, *, user_pk: int, user_type: AuthentikUserType) -> None: ...
174
188
  def get_group_by_name(self, name: str) -> AuthentikGroup | None: ...
175
189
  def add_user_to_group(self, *, user_pk: int, group_pk: str) -> None: ...
176
190
  def get_email_stage_by_name(self, name: str) -> AuthentikEmailStage | None: ...
@@ -218,6 +232,15 @@ class AuthentikHttpClient:
218
232
  return None
219
233
  return resp.body if isinstance(resp.body, dict) else {}
220
234
 
235
+ def _patch(self, path: str, body: dict[str, Any]) -> None:
236
+ url = self._api_url(path)
237
+ try:
238
+ resp = self._http.patch_json(url, body, headers=self._headers)
239
+ except HttpConnectionError as exc:
240
+ raise AuthentikConnectionError(url, exc) from exc
241
+ if resp.status_code >= 400:
242
+ raise AuthentikAPIError(resp.status_code, str(resp.body), url)
243
+
221
244
  def get_user_by_email(self, email: str) -> AuthentikUser | None:
222
245
  resp = self._get("/core/users/", params={"search": email})
223
246
  for user_data in resp.get("results", []):
@@ -225,7 +248,7 @@ class AuthentikHttpClient:
225
248
  return self._parse_user(user_data)
226
249
  return None
227
250
 
228
- def create_user(self, *, email: str) -> AuthentikUser:
251
+ def create_user(self, *, email: str, user_type: AuthentikUserType) -> AuthentikUser:
229
252
  display_name = email.split("@", maxsplit=1)[0]
230
253
  body: dict[str, Any] = {
231
254
  "username": email,
@@ -233,6 +256,7 @@ class AuthentikHttpClient:
233
256
  "name": display_name,
234
257
  "path": "users",
235
258
  "is_active": True,
259
+ "type": user_type,
236
260
  }
237
261
  resp = self._post("/core/users/", body)
238
262
  if resp is None:
@@ -241,6 +265,9 @@ class AuthentikHttpClient:
241
265
  )
242
266
  return self._parse_user(resp)
243
267
 
268
+ def set_user_type(self, *, user_pk: int, user_type: AuthentikUserType) -> None:
269
+ self._patch(f"/core/users/{user_pk}/", {"type": user_type})
270
+
244
271
  def get_group_by_name(self, name: str) -> AuthentikGroup | None:
245
272
  resp = self._get("/core/groups/", params={"name": name})
246
273
  for group_data in resp.get("results", []):
@@ -272,6 +299,7 @@ class AuthentikHttpClient:
272
299
  email=data.get("email", ""),
273
300
  name=data.get("name", ""),
274
301
  is_active=data.get("is_active", True),
302
+ user_type=str(data.get("type", "")),
275
303
  )
276
304
 
277
305
 
@@ -340,11 +368,10 @@ class UserProvisioner:
340
368
  def _provision_one(self, spec: UserSpec, *, send_email: bool) -> ProvisionResult:
341
369
  existing = self._client.get_user_by_email(spec.email)
342
370
  if existing is not None:
343
- self._printer.print(f" {spec.email} — already exists, skipping")
344
- return ProvisionResult(email=spec.email, status="exists")
371
+ return self._reconcile_existing(existing, spec)
345
372
 
346
373
  try:
347
- user = self._client.create_user(email=spec.email)
374
+ user = self._client.create_user(email=spec.email, user_type=spec.user_type)
348
375
  except AuthentikAPIError as exc:
349
376
  self._printer.print_error(f" {spec.email} — failed to create: {exc.detail}")
350
377
  return ProvisionResult(email=spec.email, status="error", detail=exc.detail)
@@ -386,6 +413,36 @@ class UserProvisioner:
386
413
 
387
414
  return ProvisionResult(email=spec.email, status="created")
388
415
 
416
+ def _reconcile_existing(self, user: AuthentikUser, spec: UserSpec) -> ProvisionResult:
417
+ """Leave an existing user alone, except to widen an admin to an internal account.
418
+
419
+ A user is never narrowed back to ``external``: the extra rights an internal
420
+ account carries may have been granted deliberately outside this tool.
421
+ """
422
+ if not (spec.user_type == INTERNAL_USER_TYPE and user.user_type == EXTERNAL_USER_TYPE):
423
+ self._printer.print(f" {spec.email} — already exists, skipping")
424
+ return ProvisionResult(email=spec.email, status="exists")
425
+
426
+ try:
427
+ self._client.set_user_type(user_pk=user.pk, user_type=INTERNAL_USER_TYPE)
428
+ except AuthentikAPIError as exc:
429
+ self._printer.print_error(
430
+ f" {spec.email} — already exists, but failed to convert to an "
431
+ f"internal user: {exc.detail}"
432
+ )
433
+ return ProvisionResult(
434
+ email=spec.email,
435
+ status="error",
436
+ detail=f"Conversion to internal user failed: {exc.detail}",
437
+ )
438
+
439
+ self._printer.print_success(
440
+ f" {spec.email} — already exists, converted to an internal user"
441
+ )
442
+ return ProvisionResult(
443
+ email=spec.email, status="exists", detail="Converted to an internal user"
444
+ )
445
+
389
446
 
390
447
  # ---------------------------------------------------------------------------
391
448
  # Command
@@ -369,8 +369,9 @@ class UpdateCommand:
369
369
 
370
370
  self._printer.print_success(
371
371
  f"Update complete. Version {version_label!r} is now deployed to "
372
- f"{apply_result.output_dir}. "
373
- "Run 'start' to bring up the stack and re-apply the Authentik blueprint."
372
+ f"{apply_result.output_dir}.\n"
373
+ "Bring up the stack and re-apply the Authentik blueprint by running "
374
+ f"'start' with --app-root {args.app_root}"
374
375
  )
375
376
 
376
377
  # 7. Last thing on screen: which python clients still work. The API
@@ -195,8 +195,9 @@ class ConfigureCommand:
195
195
  base_state = DeploymentStateDocument.new(metadata).with_items(preset.items)
196
196
 
197
197
  # 4. Run the configuration pipeline.
198
- # Pass a checkpoint that persists partial state after each step so that
199
- # an interrupted run can be resumed via --resume.
198
+ # Only an interactive run is checkpointed: a non-interactive one is
199
+ # re-runnable from its own inputs, and a partial document it left behind
200
+ # would make the next install ask about a session nobody can answer for.
200
201
  def _checkpoint(partial: DeploymentStateDocument) -> None:
201
202
  self._repository.save(args.app_root, target.version, partial)
202
203
 
@@ -204,7 +205,7 @@ class ConfigureCommand:
204
205
  app_root=args.app_root,
205
206
  base_state=base_state,
206
207
  interactive=args.interactive,
207
- on_checkpoint=_checkpoint,
208
+ on_checkpoint=_checkpoint if args.interactive else None,
208
209
  )
209
210
 
210
211
  # 5. Persist.