Skip to content

Commit 0e85a6d

Browse files
committed
Merge #219: feat: [#217] Demo slice - Release and Run commands scaffolding
fd53b7f refactor: [#217] Rename run_configuration_tests to run_configure_release_run_tests (Jose Celano) 3ede934 feat: [#217] Add separate E2E validation modules for release and run commands (Jose Celano) 5c14832 docs: [#217] Update Docker-in-Docker ADR with implementation details (Jose Celano) 30a1c3f fix: [#217] Wrap std::env::set_var in unsafe block (Rust 1.81+) (Jose Celano) 862499c feat: [#217] Enable Docker-in-Docker for E2E tests to test run command (Jose Celano) 1643b44 docs: [#217] document Phase 9 manual E2E test issues and resolution (Jose Celano) ed6f480 feat: [#217] wire RunCommandController to RunCommandHandler (Jose Celano) 1921015 feat: [#217] implement Phase 9 - StartServicesStep for run command (Jose Celano) 351e6fe refactor: [#217] Add symmetric logging to release and provision handlers (Jose Celano) 6ef21d2 refactor: [#217] Improve configure handler clarity (Jose Celano) 0ec82fd refactor: [#217] Extract load and validate methods in command handlers (Jose Celano) 419e35b fix(clippy): [#217] Fix clippy linting errors (Jose Celano) 92509c9 refactor(error-handling): [#217] Standardize EnvironmentNotFound error across all handlers (Jose Celano) ca4ee88 refactor(release): [#217] Validate instance IP as precondition for release (Jose Celano) 043560c feat(release): [#217] Complete Phase 8 - Refactor release handler to three-level architecture (Jose Celano) 8a0291a docs: [#217] update phase 6 and 7 documentation with implementation status (Jose Celano) bc32270 feat: [#217] implement phase 6 - release step prepares docker compose files (Jose Celano) 26528f9 test: [#217] add release and run commands to E2E test workflows (Jose Celano) fb529ec feat: [#217] implement state transitions for release and run handlers (Jose Celano) 98aec5d feat: [#217] complete application layer handlers for release and run commands (Jose Celano) 7c113c0 feat: [#217] add release and run steps in application layer (Jose Celano) 2d766df feat: [#217] add release and run command handlers in application layer (Jose Celano) 0791846 feat: [#217] add release and run controllers (wired but empty) (Jose Celano) e97483a refactor: [#217] rename e2e-config-tests to e2e-config-and-release-tests (Jose Celano) ea55f4f feat: [#217] add release and run CLI commands (no-op) (Jose Celano) Pull request description: ## Summary This PR implements the foundational scaffolding for the `release` and `run` commands using a minimal docker-compose deployment with nginx. The goal is to validate the full pipeline (release → run → verify) before adding complexity with the actual Torrust Tracker services. **Issue**: Closes #217 ## Implementation Progress ### Phase Tracking | Phase | Description | Status | |-------|-------------|--------| | **Phase 1** | Presentation Layer - CLI Commands (No-Op) | ✅ Complete | | **Phase 2** | E2E Test Refactoring (Safety Net) | ✅ Complete | | **Phase 3** | Presentation Layer - Controllers | ✅ Complete | | **Phase 4** | Application Layer - Command Handlers (Skeleton) | ✅ Complete | | **Phase 5** | Application Layer - State Transitions | ✅ Complete | | **Phase 6** | Steps Layer - Prepare Compose Files | ✅ Complete | | **Phase 7** | Infrastructure Layer - Docker Compose Template Renderer | ✅ Complete | | **Phase 8** | Steps Layer - Transfer Files to VM | ✅ Complete | | **Phase 9** | Steps Layer - Start Services | ✅ Complete | | **Phase 10** | E2E Test Coverage | ✅ Complete | ### What's Implemented #### CLI Commands - `release` - Release application files to a configured environment - `run` - Run the application stack on a released environment #### State Transitions - `Configured` → `Releasing` → `Released` (release command) - `Released` → `Starting` → `Running` (run command) #### Infrastructure **Docker Compose Template Renderer** - `DockerComposeTemplateRenderer` following the same pattern as `AnsibleTemplateRenderer` and `TofuTemplateRenderer` - Embedded docker-compose.yml template with nginx:alpine demo service - Template extraction via `TemplateManager` (double-indirection pattern) **Release Handler - Three-Level Architecture (Phase 8)** - `ReleaseCommandHandler` refactored to follow Provision Handler patterns - `RenderDockerComposeTemplatesStep` - Renders templates locally - `DeployComposeFilesStep` - Deploys files to VM via Ansible playbook - `ReleaseTraceWriter` - Generates trace files for failure diagnostics - `ReleaseStep` enum and `ReleaseFailureContext` for step tracking - Ansible playbook `deploy-compose-files.yml` for file transfer **Run Handler - Three-Level Architecture (Phase 9)** - `RunCommandHandler` with full step architecture - `StartServicesStep` - Starts Docker Compose services on VM - `RunTraceWriter` - Generates trace files for failure diagnostics - `RunStep` enum and `RunFailureContext` for step tracking - Ansible playbook `start-services.yml.tera` for service management **E2E Test Coverage (Phase 10)** - `RunningServicesValidator` - Remote action to validate running services via SSH - Separate validation modules per command (SRP): - `run_configuration_validation` - Validates configure command (Docker installed) - `run_release_validation` - Validates release command (Compose files deployed) - `run_run_validation` - Validates run command (services running) - Full workflow tested: create → register → configure → release → run → destroy ### Files Changed **Application Layer** - `src/application/command_handlers/release/` - ReleaseCommandHandler (refactored) - `src/application/command_handlers/run/` - RunCommandHandler (fully implemented) - `src/application/steps/application/deploy_compose_files.rs` - DeployComposeFilesStep - `src/application/steps/application/start_services.rs` - StartServicesStep (NEW) - `src/application/steps/rendering/docker_compose_templates.rs` - RenderDockerComposeTemplatesStep **Domain Layer** - `src/domain/environment/state/release_failed.rs` - ReleaseStep enum, ReleaseFailureContext - `src/domain/environment/state/run_failed.rs` - RunStep enum, RunFailureContext (NEW) **Infrastructure Layer** - `src/infrastructure/external_tools/docker_compose/template/renderer/mod.rs` - DockerComposeTemplateRenderer - `src/infrastructure/remote_actions/running_services.rs` - RunningServicesValidator (NEW) - `src/infrastructure/trace/writer/commands/release.rs` - ReleaseTraceWriter - `src/infrastructure/trace/writer/commands/run.rs` - RunTraceWriter (NEW) **Presentation Layer** - `src/presentation/controllers/release/` - Release controller - `src/presentation/controllers/run/` - Run controller **Testing** - `src/testing/e2e/tasks/run_configuration_validation.rs` - Configure command validation - `src/testing/e2e/tasks/run_release_validation.rs` - Release command validation (NEW) - `src/testing/e2e/tasks/run_run_validation.rs` - Run command validation (NEW) - `src/bin/e2e_config_and_release_tests.rs` - Full workflow E2E tests **Templates** - `templates/docker-compose/docker-compose.yml` - nginx:alpine demo service - `templates/ansible/deploy-compose-files.yml` - File deployment playbook - `templates/ansible/start-services.yml.tera` - Service start playbook (NEW) ### Manual E2E Test ```bash # Full workflow verified: cargo run -- create environment --env-file envs/e2e-full.json cargo run -- provision e2e-full cargo run -- configure e2e-full cargo run -- release e2e-full # Verified: docker-compose.yml deployed to VM at /opt/torrust/ cargo run -- run e2e-full # Verified: nginx service running cargo run -- destroy e2e-full ``` ## All Phases Complete ✅ This PR is ready for review. All phases have been implemented: - Full `release` and `run` command implementation - Complete E2E test coverage with separate validation per command - Three-level architecture (Commands → Steps → Actions) consistently applied ## Related Documentation See `docs/issues/217-demo-slice-release-run-commands.md` for detailed implementation plan. ACKs for top commit: josecelano: ACK fd53b7f Tree-SHA512: 0bb61a847cd332a9afdff102783b34c69059975d151de853d0d248882cbcea4ba252dddf3edbfc338ea806a727868e6a2cb838ef10b692bd0471e46608174985
2 parents 2c46b13 + fd53b7f commit 0e85a6d

File tree

91 files changed

+8715
-531
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+8715
-531
lines changed

.cargo/config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
lint = "run --bin linter all"
33
e2e-full = "run --bin e2e-tests-full"
44
e2e-provision = "run --bin e2e-provision-tests"
5-
e2e-config = "run --bin e2e-config-tests"
5+
e2e-config = "run --bin e2e-config-and-release-tests"
66
cov = "llvm-cov"
77
cov-check = "llvm-cov --all-features --workspace --fail-under-lines 70"
88
cov-lcov = "llvm-cov --lcov --output-path=./.coverage/lcov.info"

.github/workflows/test-e2e-config.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ on:
2222
workflow_dispatch: # Allow manual triggering
2323

2424
jobs:
25-
e2e-config-tests:
25+
e2e-config-and-release-tests:
2626
runs-on: ubuntu-latest
2727
timeout-minutes: 45 # Timeout for complete configuration testing with software installation
2828

@@ -62,16 +62,16 @@ jobs:
6262
chmod 600 fixtures/testing_rsa
6363
ls -la fixtures/testing_rsa
6464
65-
- name: Build E2E configuration tests binary
65+
- name: Build E2E configuration and release tests binary
6666
run: |
67-
cargo build --bin e2e-config-tests --release
67+
cargo build --bin e2e-config-and-release-tests --release
6868
69-
- name: Run E2E configuration test
69+
- name: Run E2E configuration and release test
7070
run: |
71-
# Run the E2E configuration test with debug logging for better debugging
72-
echo "🚀 Starting E2E configuration test at $(date)"
73-
cargo run --bin e2e-config-tests
74-
echo "✅ E2E configuration test completed at $(date)"
71+
# Run the E2E configuration and release test with debug logging for better debugging
72+
echo "🚀 Starting E2E configuration and release test at $(date)"
73+
cargo run --bin e2e-config-and-release-tests
74+
echo "✅ E2E configuration and release test completed at $(date)"
7575
env:
7676
# Preserve environment variables for the E2E test
7777
RUST_LOG: debug

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ These principles should guide all development decisions, code reviews, and featu
130130
- **E2E Tests**:
131131
- `cargo run --bin e2e-tests-full` - Comprehensive tests (⚠️ **LOCAL ONLY** - cannot run on GitHub Actions due to network connectivity issues)
132132
- `cargo run --bin e2e-provision-and-destroy-tests` - Infrastructure provisioning and destruction tests (GitHub runner-compatible)
133-
- `cargo run --bin e2e-config-tests` - Software installation and configuration tests (GitHub runner-compatible)
134-
- Pre-commit hook runs the split tests (`e2e-provision-and-destroy-tests` + `e2e-config-tests`) for GitHub Copilot compatibility
133+
- `cargo run --bin e2e-config-and-release-tests` - Software installation, configuration, release, and run workflow tests (GitHub runner-compatible)
134+
- Pre-commit hook runs the split tests (`e2e-provision-and-destroy-tests` + `e2e-config-and-release-tests`) for GitHub Copilot compatibility
135135
- See [`docs/e2e-testing.md`](docs/e2e-testing.md) for detailed information about CI limitations
136136

137137
Follow the project conventions and ensure all checks pass.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ name = "e2e-tests-full"
2525
path = "src/bin/e2e_tests_full.rs"
2626

2727
[[bin]]
28-
name = "e2e-config-tests"
29-
path = "src/bin/e2e_config_tests.rs"
28+
name = "e2e-config-and-release-tests"
29+
path = "src/bin/e2e_config_and_release_tests.rs"
3030

3131
[[bin]]
3232
name = "e2e-provision-and-destroy-tests"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ Use the E2E test binaries to run automated infrastructure tests with hardcoded e
167167
cargo run --bin e2e-tests-full
168168

169169
# Run individual E2E test suites
170-
cargo run --bin e2e-config-tests # Configuration generation and validation tests
170+
cargo run --bin e2e-config-and-release-tests # Configuration, release, and run workflow tests
171171
cargo run --bin e2e-provision-and-destroy-tests # Infrastructure provisioning tests
172172

173173
# Keep the test environment after completion for inspection

docker/provisioned-instance/Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,17 @@ RUN apt-get update && apt-get install -y \
3333
lsb-release \
3434
# APT transport for HTTPS repositories
3535
apt-transport-https \
36+
# iptables for Docker networking
37+
iptables \
3638
# Clean up package cache
3739
&& apt-get clean \
3840
&& rm -rf /var/lib/apt/lists/*
3941

42+
# Install Docker using official installation script
43+
# This installs both Docker daemon and Docker Compose plugin
44+
RUN curl -fsSL https://get.docker.com | sh \
45+
&& rm -rf /var/lib/apt/lists/*
46+
4047
# Configure SSH server
4148
RUN mkdir -p /var/run/sshd \
4249
# Configure SSH for password authentication initially (tests will set up keys later)
@@ -45,7 +52,7 @@ RUN mkdir -p /var/run/sshd \
4552
&& sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
4653

4754
# Create torrust user matching LXD VM configuration
48-
RUN useradd -m -s /bin/bash -G sudo torrust \
55+
RUN useradd -m -s /bin/bash -G sudo,docker torrust \
4956
# Set a simple password for initial SSH access (tests will set up keys later)
5057
&& echo "torrust:torrust123" | chpasswd \
5158
# Configure passwordless sudo

docker/provisioned-instance/supervisord.conf

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,21 @@ logfile_maxbytes=50MB
88
logfile_backups=10
99
loglevel=info
1010

11+
[program:dockerd]
12+
command=/usr/bin/dockerd --host=unix:///var/run/docker.sock --storage-driver=vfs
13+
stdout_logfile=/var/log/supervisor/dockerd.log
14+
stderr_logfile=/var/log/supervisor/dockerd.log
15+
autorestart=true
16+
startretries=3
17+
priority=5
18+
1119
[program:sshd]
1220
command=/usr/sbin/sshd -D
1321
stdout_logfile=/var/log/supervisor/sshd.log
1422
stderr_logfile=/var/log/supervisor/sshd.log
1523
autorestart=true
1624
startretries=3
17-
priority=1
25+
priority=10
1826

1927
[unix_http_server]
2028
file=/var/run/supervisor.sock

docker/ssh-server/Dockerfile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ RUN ssh-keygen -A
2828
# Create test user for SSH authentication
2929
RUN adduser -D -s /bin/sh testuser && \
3030
echo 'testuser:testpass' | chpasswd && \
31-
addgroup testuser wheel
31+
addgroup testuser wheel && \
32+
# Enable passwordless sudo for wheel group (required for deployment testing)
33+
echo '%wheel ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
3234

3335
# Configure SSH daemon
3436
RUN mkdir -p /run/sshd && \

docs/codebase-architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Application initialization and lifecycle management:
209209
**Binary Files:**
210210

211211
-`src/bin/linter.rs` - Code quality linting binary
212-
-`src/bin/e2e-config-tests.rs` - E2E configuration tests
212+
-`src/bin/e2e-config-and-release-tests.rs` - E2E configuration and release tests
213213
-`src/bin/e2e-provision-and-destroy-tests.rs` - E2E provisioning and destruction tests
214214
-`src/bin/e2e-tests-full.rs` - Full E2E test suite
215215

docs/contributing/commit-process.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ This script runs all mandatory checks:
135135
3. **Run tests**: `cargo test`
136136
4. **Test documentation builds**: `cargo doc --no-deps --bins --examples --workspace --all-features`
137137
5. **Run E2E provision and destroy tests**: `cargo run --bin e2e-provision-and-destroy-tests`
138-
6. **Run E2E configuration tests**: `cargo run --bin e2e-config-tests`
138+
6. **Run E2E configuration and release tests**: `cargo run --bin e2e-config-and-release-tests`
139139

140140
**Note**: Code coverage is checked automatically in CI via GitHub Actions, not in the pre-commit script, to keep local commits fast and efficient.
141141

0 commit comments

Comments
 (0)