Skip to content

[EPIC] Implement Create Environment Command #34

@josecelano

Description

@josecelano

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() with adapters::ssh::SshCredentials type
  • Leverages existing EnvironmentName validation and EnvironmentRepository patterns
  • 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 create with 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-dir flag 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.json

Configuration 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)

  1. 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)
  2. Create Command Implementation (#36) - 3-4h

    • Synchronous CreateCommand following existing patterns
    • Use Environment::new() directly (no new methods)
    • Repository handles directory creation atomically
    • Error handling with .help() methods (tiered help system)
  3. CLI Presentation Layer (#37) - 3-4h

    • create subcommand with Figment integration
    • Configuration parsing and domain object conversion
    • User-friendly error presentation
    • --working-dir flag support
  4. E2E Black Box Test (#38) - 3-4h

    • True black-box test running production binary
    • Test complete workflow with temporary directories
    • Verify --working-dir functionality
  5. Update E2E Full Tests (#39) - 1-2h

    • Update e2e_tests_full.rs to use CreateCommand
    • Ensure comprehensive test coverage

Optional Enhancements (Subissues 6-7)

  1. Template System Integration (#40) - 2-3h (Optional)

    • Extend existing TemplateManager for config templates
    • No duplication of existing functionality
  2. Template Generation Support (#41) - 1-2h (Optional, requires feat: [#3] Setup logging for production CLI with configurable options #6)

    • Implement create template subcommand
    • Generate JSON template files

Bug Fixes & Documentation (Subissues 8-10)

  1. 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)
  2. 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-dir parameter support to destroy command
    • Maintain consistency with create command's working directory handling
  3. 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) vs SshCredentials (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() - no create_from_config()
  • Error Help System: All errors implement .help() methods
  • Working Directory: --working-dir available 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.json loads 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)

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions