-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdocker_compose.rs
More file actions
151 lines (136 loc) · 5 KB
/
Copy pathdocker_compose.rs
File metadata and controls
151 lines (136 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Docker Compose validation remote action
//!
//! This module provides the `DockerComposeValidator` which checks Docker Compose
//! installation and basic functionality on remote instances to ensure the
//! container orchestration tool is properly configured and operational.
//!
//! ## Key Features
//!
//! - Docker Compose plugin installation verification
//! - Version checking and compatibility validation
//! - Basic functionality testing (e.g., docker compose version command)
//! - Comprehensive error reporting for Docker Compose issues
//!
//! ## Validation Process
//!
//! The validator performs multiple checks:
//! - Docker Compose plugin availability and version (using modern plugin syntax)
//! - Integration with Docker engine
//! - Basic command execution functionality
//! - Service orchestration capabilities
//!
//! This ensures that subsequent deployment steps can rely on a working
//! Docker Compose environment for container orchestration.
use std::net::IpAddr;
use tracing::{info, instrument, warn};
use crate::adapters::ssh::SshClient;
use crate::adapters::ssh::SshConfig;
use crate::infrastructure::remote_actions::{RemoteAction, RemoteActionError};
/// Action that validates Docker Compose installation and basic functionality on the server
pub struct DockerComposeValidator {
ssh_client: SshClient,
}
impl DockerComposeValidator {
/// Create a new `DockerComposeValidator` with the specified SSH configuration
///
/// # Arguments
/// * `ssh_config` - SSH connection configuration containing credentials and host IP
#[must_use]
pub fn new(ssh_config: SshConfig) -> Self {
let ssh_client = SshClient::new(ssh_config);
Self { ssh_client }
}
}
impl RemoteAction for DockerComposeValidator {
fn name(&self) -> &'static str {
"docker-compose-validation"
}
#[allow(clippy::too_many_lines)]
#[instrument(
name = "docker_compose_validation",
skip(self),
fields(
action_type = "validation",
component = "docker_compose",
server_ip = %server_ip
)
)]
async fn execute(&self, server_ip: &IpAddr) -> Result<(), RemoteActionError> {
info!(
action = "docker_compose_validation",
"Validating Docker Compose installation"
);
// Check Docker Compose version (using modern plugin syntax)
let compose_version =
self.ssh_client
.execute("docker compose version")
.map_err(|source| RemoteActionError::SshCommandFailed {
action_name: self.name().to_string(),
source,
})?;
let compose_version = compose_version.trim();
info!(
action = "docker_compose_validation",
status = "success",
"Docker Compose installation validated"
);
info!(
action = "docker_compose_validation",
version = compose_version,
"Docker Compose version detected"
);
// Test basic docker-compose functionality with a simple test file (only if Docker is working)
let test_compose_content = r"services:
test:
image: hello-world
";
// Create a temporary test docker-compose.yml file
let create_test_success = self
.ssh_client
.check_command(&format!(
"echo '{test_compose_content}' > /tmp/test-docker-compose.yml"
))
.map_err(|source| RemoteActionError::SshCommandFailed {
action_name: self.name().to_string(),
source,
})?;
if !create_test_success {
warn!(
action = "docker_compose_validation",
check = "test_file_creation",
status = "failed",
"Could not create test docker-compose.yml file"
);
return Ok(()); // Don't fail, just skip the functional test
}
// Validate docker-compose file (using modern plugin syntax)
let validate_success = self
.ssh_client
.check_command("cd /tmp && docker compose -f test-docker-compose.yml config")
.map_err(|source| RemoteActionError::SshCommandFailed {
action_name: self.name().to_string(),
source,
})?;
if validate_success {
info!(
action = "docker_compose_validation",
check = "configuration_validation",
status = "success",
"Docker Compose configuration validation passed"
);
} else {
warn!(
action = "docker_compose_validation",
check = "configuration_validation",
status = "skipped",
"Docker Compose configuration validation skipped"
);
}
// Clean up test file
drop(
self.ssh_client
.check_command("rm -f /tmp/test-docker-compose.yml"),
);
Ok(())
}
}