-
Couldn't load subscription status.
- Fork 0
Description
Overview
Implement the torrust-tracker-deployer create command to create new deployment environments from configuration files. This command initializes environment data, validates configuration, and prepares the environment for provisioning.
Related: Parent Epic #2 - Scaffolding for main app | Roadmap Task 1.5 | Full Specification
Architectural Integration
This command integrates with existing infrastructure:
- Uses existing
Environment::new()withadapters::ssh::SshCredentialstype - Leverages existing
EnvironmentNamevalidation andEnvironmentRepositorypatterns - Follows synchronous command handler patterns from
provision.rs - Repository handles directory creation during
save()for atomicity - Creates
Environment<Created>state that integrates with existing state transitions
Goals
- Add CLI subcommand
createwith mandatory config file - Support JSON configuration format (TOML in separate future issue)
- Validate configuration and convert to domain objects
- Create environment data directory with persistent state
- Set initial environment state to "created"
- Environment name comes from configuration file only
- Support
--working-dirflag for workspace management
CLI Interface
# Create environment from configuration file
torrust-tracker-deployer create environment --env-file ./config/environment.json
# With custom working directory
torrust-tracker-deployer --working-dir /path/to/workspace create environment --env-file ./config/environment.jsonConfiguration File Format (JSON)
{
"environment": {
"name": "production"
},
"ssh_credentials": {
"private_key_path": "~/.ssh/id_rsa",
"public_key_path": "~/.ssh/id_rsa.pub",
"username": "torrust",
"port": 22
}
}Implementation Plan
This EPIC will be implemented as 10 subissues for incremental delivery:
Core MVP (Required - Subissues 1-5)
-
Configuration Infrastructure (#35) - 2-3h
- Domain-layer config value objects (
EnvironmentCreationConfig,SshCredentialsConfig) - Convert to existing domain types (
EnvironmentName,SshCredentials,Username) - JSON Schema validation (optional/can be deferred)
- Domain-layer config value objects (
-
Create Command Implementation (#36) - 3-4h
- Synchronous
CreateCommandfollowing existing patterns - Use
Environment::new()directly (no new methods) - Repository handles directory creation atomically
- Error handling with
.help()methods (tiered help system)
- Synchronous
-
CLI Presentation Layer (#37) - 3-4h
createsubcommand with Figment integration- Configuration parsing and domain object conversion
- User-friendly error presentation
--working-dirflag support
-
E2E Black Box Test (#38) - 3-4h
- True black-box test running production binary
- Test complete workflow with temporary directories
- Verify
--working-dirfunctionality
-
Update E2E Full Tests (#39) - 1-2h
- Update
e2e_tests_full.rsto use CreateCommand - Ensure comprehensive test coverage
- Update
Optional Enhancements (Subissues 6-7)
-
Template System Integration (#40) - 2-3h (Optional)
- Extend existing
TemplateManagerfor config templates - No duplication of existing functionality
- Extend existing
-
Template Generation Support (#41) - 1-2h (Optional, requires feat: [#3] Setup logging for production CLI with configurable options #6)
- Implement
create templatesubcommand - Generate JSON template files
- Implement
Bug Fixes & Documentation (Subissues 8-10)
-
Fix Destroy Command: Handle Created State Gracefully (#50) - 4-5h
- Fix critical bug where destroy command fails for Created state environments
- Skip infrastructure destruction when infrastructure was never provisioned
- No dependencies (but must be completed before Subissue 9)
-
Fix Destroy Command: Add Working Directory Support (#51) - 3-4h (Depends on [Subissue 8/10] Fix Destroy Command: Handle Created State Gracefully #50)
- Add
--working-dirparameter support to destroy command - Maintain consistency with create command's working directory handling
- Add
-
Document Create Environment Command (#52) - 4h
- Add comprehensive user-facing documentation for create environment command
- Update user guide with examples and troubleshooting
Key Architecture Decisions
- Synchronous: All commands are sync (not async) matching existing patterns
- Type Naming:
SshCredentialsConfig(config) vsSshCredentials(adapters/domain) to avoid conflicts - Type Conversion: Config strings → Domain types (
Username,PathBuf) at boundaries - Repository Atomicity: Repository creates directories during
save() - No new methods: Use existing
Environment::new()- nocreate_from_config() - Error Help System: All errors implement
.help()methods - Working Directory:
--working-diravailable in production (not just tests) - MVP Focus: Template generation optional, JSON Schema validation can be deferred
Acceptance Criteria
-
torrust-tracker-deployer create --env-file config.jsonloads JSON configuration - Configuration validation rejects invalid files with clear error messages
- Environment directory
./data/{ENV_NAME}/created (persistent user data) - Build directory
./build/{ENV_NAME}/created as needed (ephemeral) - Environment state set to "created" in persistent storage
- SSH key paths validated (exist and readable)
- Proper help documentation
- All errors follow project guidelines (actionable with
.help()methods)
DDD Layer Organization
- Domain (
src/domain/config/): Configuration value objects, validation rules - Application (
src/application/commands/create/): Delivery-agnostic CreateCommand - Infrastructure (
src/infrastructure/templates/): Template storage (optional) - Presentation (
src/presentation/console/subcommands/create/): Figment parsing, CLI args
Related Documentation
Total Estimated Time: 14-19 hours (MVP: 11-15h, Optional: 3-4h)