Skip to main content

torrust_tracker_deployer_lib/infrastructure/remote_actions/
mod.rs

1//! Remote actions module (Level 3 of Three-Level Architecture)
2//!
3//! This module provides the lowest-level operations in the three-level architecture,
4//! containing leaf-level actions that directly interact with remote systems via SSH.
5//! These actions are the building blocks used by steps (Level 2) and commands (Level 1).
6//!
7//! ## Execution Context: Inside VM via SSH
8//!
9//! All remote actions in this module execute commands **INSIDE the VM via SSH**.
10//! For external validation (E2E testing from outside the VM), see `external_validators/`.
11//!
12//! **Distinction**:
13//! - **`remote_actions`** (this module): Execute commands inside VM via SSH
14//! - **`external_validators`**: Validate services from outside VM via HTTP
15//!
16//! ## Available Remote Actions
17//!
18//! - `validators::cloud_init` - Cloud-init status checking and validation
19//! - `validators::docker` - Docker installation and service management
20//! - `validators::docker_compose` - Docker Compose installation and validation
21//!
22//! ## Architecture Pattern
23//!
24//! Remote actions follow a consistent pattern:
25//! - Take SSH connection and required parameters
26//! - Execute specific remote operations via SSH
27//! - Provide structured error handling with action context
28//! - Return typed results for use by higher-level components
29//!
30//! These actions are designed to be atomic, testable, and reusable across
31//! different deployment scenarios.
32
33use std::net::IpAddr;
34use thiserror::Error;
35
36use crate::shared::command::CommandError;
37
38pub mod validators;
39
40pub use validators::cloud_init::CloudInitValidator;
41pub use validators::docker::DockerValidator;
42pub use validators::docker_compose::DockerComposeValidator;
43
44/// Errors that can occur during remote action execution
45#[derive(Error, Debug)]
46pub enum RemoteActionError {
47    /// SSH command execution failed
48    #[error("SSH command execution failed during '{action_name}': {source}")]
49    SshCommandFailed {
50        action_name: String,
51        #[source]
52        source: CommandError,
53    },
54
55    /// Action validation failed
56    #[error("Action '{action_name}' validation failed: {message}")]
57    ValidationFailed {
58        action_name: String,
59        message: String,
60    },
61
62    /// Action execution failed with custom error
63    #[error("Action '{action_name}' execution failed: {message}")]
64    ExecutionFailed {
65        action_name: String,
66        message: String,
67    },
68}
69
70/// Trait for remote actions that can be executed on a server via SSH
71///
72/// Remote actions are lightweight scripts that connect to a provisioned
73/// server via SSH to perform various operations such as:
74///
75/// - Validating server state and configuration
76/// - Retrieving server information (hostname, installed packages, etc.)
77/// - Executing maintenance tasks (updates, cleanup, etc.)
78/// - Installing or configuring software components
79#[allow(async_fn_in_trait)]
80pub trait RemoteAction {
81    /// Get the name of this action for logging purposes
82    fn name(&self) -> &'static str;
83
84    /// Execute the action against the specified server
85    ///
86    /// # Arguments
87    /// * `server_ip` - The IP address of the server to execute the action on
88    ///
89    /// # Returns
90    /// * `Ok(())` if the action executes successfully
91    /// * `Err(RemoteActionError)` if the action fails or encounters an error
92    async fn execute(&self, server_ip: &IpAddr) -> Result<(), RemoteActionError>;
93}