torrust_tracker_deployer_lib/application/steps/validation/docker.rs
1//! Docker installation validation step
2//!
3//! This module provides the `ValidateDockerInstallationStep` which validates that
4//! Docker is properly installed and operational on remote hosts. This step ensures
5//! the container runtime is ready for application deployment.
6//!
7//! ## Key Features
8//!
9//! - Docker installation verification via remote validation
10//! - Docker daemon status and functionality checking
11//! - Version compatibility verification
12//! - Integration with SSH-based remote actions
13//!
14//! ## Validation Process
15//!
16//! The step uses the `DockerValidator` remote action to perform comprehensive
17//! checks including Docker version, daemon status, and basic functionality
18//! to ensure the container environment is properly configured.
19
20use tracing::{info, instrument};
21
22use crate::adapters::ssh::SshConfig;
23use crate::infrastructure::remote_actions::{DockerValidator, RemoteAction, RemoteActionError};
24
25/// Step that validates Docker installation on a remote host
26pub struct ValidateDockerInstallationStep {
27 ssh_config: SshConfig,
28}
29
30impl ValidateDockerInstallationStep {
31 #[must_use]
32 pub fn new(ssh_config: SshConfig) -> Self {
33 Self { ssh_config }
34 }
35
36 /// Execute the Docker installation validation step
37 ///
38 /// This will validate that Docker is properly installed and running
39 /// on the remote host by checking the Docker version and daemon status.
40 ///
41 /// # Errors
42 ///
43 /// Returns an error if:
44 /// * SSH connection to the remote host fails
45 /// * Docker validation fails
46 /// * The remote action execution fails for any other reason
47 ///
48 /// # Notes
49 ///
50 /// - In CI environments with network limitations, Docker installation
51 /// validation may be skipped gracefully
52 /// - The validation checks both Docker version and daemon status
53 #[instrument(
54 name = "validate_docker",
55 skip_all,
56 fields(step_type = "validation", component = "docker")
57 )]
58 pub async fn execute(&self) -> Result<(), RemoteActionError> {
59 info!(component = "docker", "Validating Docker installation");
60
61 let docker_validator = DockerValidator::new(self.ssh_config.clone());
62
63 docker_validator.execute(&self.ssh_config.host_ip()).await?;
64
65 Ok(())
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use std::net::{IpAddr, Ipv4Addr};
72 use std::path::PathBuf;
73
74 use crate::adapters::ssh::SshCredentials;
75 use crate::shared::Username;
76
77 use super::*;
78
79 #[test]
80 fn it_should_create_validate_docker_installation_step() {
81 let ssh_credentials = SshCredentials::new(
82 PathBuf::from("test_key"),
83 PathBuf::from("test_key.pub"),
84 Username::new("test_user").unwrap(),
85 );
86 let host_ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1));
87 let ssh_config = SshConfig::with_default_port(ssh_credentials, host_ip);
88
89 let step = ValidateDockerInstallationStep::new(ssh_config);
90
91 // Test that the step can be created successfully
92 assert_eq!(step.ssh_config.host_ip(), host_ip);
93 }
94}