forked from torrust/torrust-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtracker_container.rs
More file actions
130 lines (104 loc) · 4.15 KB
/
tracker_container.rs
File metadata and controls
130 lines (104 loc) · 4.15 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
use std::time::Duration;
use rand::distr::Alphanumeric;
use rand::RngExt;
use super::docker::{RunOptions, RunningContainer};
use super::logs_parser::RunningServices;
use crate::console::ci::e2e::docker::Docker;
#[derive(Debug)]
pub struct TrackerContainer {
pub image: String,
pub name: String,
pub running: Option<RunningContainer>,
}
impl Drop for TrackerContainer {
/// Ensures that the temporary container is removed when the
/// struct goes out of scope.
fn drop(&mut self) {
tracing::info!("Dropping tracker container: {}", self.name);
if Docker::container_exist(&self.name) {
let _unused = Docker::remove(&self.name);
}
}
}
impl TrackerContainer {
#[must_use]
pub fn new(tag: &str, container_name_prefix: &str) -> Self {
Self {
image: tag.to_owned(),
name: Self::generate_random_container_name(container_name_prefix),
running: None,
}
}
/// # Panics
///
/// Will panic if it can't build the docker image.
pub fn build_image(&self) {
tracing::info!("Building tracker container image with tag: {} ...", self.image);
Docker::build("./Containerfile", &self.image).expect("A tracker local docker image should be built");
}
/// # Panics
///
/// Will panic if it can't run the container.
pub fn run(&mut self, options: &RunOptions) {
tracing::info!("Running docker tracker image: {} ...", self.name);
let container = Docker::run(&self.image, &self.name, options).expect("A tracker local docker image should be running");
tracing::info!("Waiting for the container {} to be healthy ...", self.name);
let is_healthy = Docker::wait_until_is_healthy(&self.name, Duration::from_secs(10));
assert!(is_healthy, "Unhealthy tracker container: {}", &self.name);
tracing::info!("Container {} is healthy ...", &self.name);
self.running = Some(container);
self.assert_there_are_no_panics_in_logs();
}
/// # Panics
///
/// Will panic if it can't get the logs from the running container.
#[must_use]
pub fn running_services(&self) -> RunningServices {
let logs = Docker::logs(&self.name).expect("Logs should be captured from running container");
tracing::info!("Parsing running services from logs. Logs :\n{logs}");
RunningServices::parse_from_logs(&logs)
}
/// # Panics
///
/// Will panic if it can't stop the container.
pub fn stop(&mut self) {
match &self.running {
Some(container) => {
tracing::info!("Stopping docker tracker container: {} ...", self.name);
Docker::stop(container).expect("Container should be stopped");
self.assert_there_are_no_panics_in_logs();
}
None => {
if Docker::is_container_running(&self.name) {
tracing::error!("Tracker container {} was started manually", self.name);
} else {
tracing::info!("Docker tracker container is not running: {} ...", self.name);
}
}
}
self.running = None;
}
/// # Panics
///
/// Will panic if it can't remove the container.
pub fn remove(&self) {
if let Some(_running_container) = &self.running {
tracing::error!("Can't remove running container: {} ...", self.name);
} else {
tracing::info!("Removing docker tracker container: {} ...", self.name);
Docker::remove(&self.name).expect("Container should be removed");
}
}
fn generate_random_container_name(prefix: &str) -> String {
let rand_string: String = rand::rng().sample_iter(&Alphanumeric).take(20).map(char::from).collect();
format!("{prefix}{rand_string}")
}
fn assert_there_are_no_panics_in_logs(&self) {
let logs = Docker::logs(&self.name).expect("Logs should be captured from running container");
assert!(
!(logs.contains(" panicked at ") || logs.contains("RUST_BACKTRACE=1")),
"{}",
format!("Panics found is logs:\n{logs}")
);
}
}