From c243696e2ae634099fca91e7ab5614e5c9200f93 Mon Sep 17 00:00:00 2001 From: tmknight Date: Sun, 7 Jan 2024 12:12:39 -0500 Subject: [PATCH 1/5] Set dependencies to current major-minor --- .gitignore | 3 +++ Cargo.lock | 2 +- Cargo.toml | 42 +++++++++++++++++++++--------------------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index b630a4c..38f7476 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ target/ # MSVC Windows builds of rustc generate these, which store debugging information *.pdb + +# IDE +.vscode/ diff --git a/Cargo.lock b/Cargo.lock index 7fd6fdd..f8eddb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,7 +165,7 @@ dependencies = [ [[package]] name = "docker-autoheal" -version = "0.2.0" +version = "0.2.1" dependencies = [ "bollard", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 0d717b4..e0311f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,21 +1,21 @@ -[package] -name = "docker-autoheal" -version = "0.2.1" -authors = ["Travis M Knight "] -license = "MIT" -description = "Monitor and restart unhealthy docker containers" -readme = "README.md" -homepage = "https://github.com/tmknight/docker-autoheal" -edition = "2021" -rust-version = "1.74.1" - -[dependencies] -bollard = "*" -chrono = "*" -futures = "*" -tokio = { version = "*", features = ["full"] } - -[[bin]] -name = "docker-autoheal" -bench = false -test = false +[package] +name = "docker-autoheal" +version = "0.2.1" +authors = ["Travis M Knight "] +license = "MIT" +description = "Monitor and restart unhealthy docker containers" +readme = "README.md" +homepage = "https://github.com/tmknight/docker-autoheal" +edition = "2021" +rust-version = "1.74.1" + +[dependencies] +bollard = "*" +chrono = "0.4.*" +futures = "0.3.*" +tokio = { version = "1.*", features = ["full"] } + +[[bin]] +name = "docker-autoheal" +bench = true +test = true From 7d98b5e592e1fc9cf717ad77d314fc8913284b48 Mon Sep 17 00:00:00 2001 From: tmknight Date: Sun, 7 Jan 2024 13:28:18 -0500 Subject: [PATCH 2/5] Ensure env values return as lowercase; refine logs --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/main.rs | 16 +++++++--------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f8eddb1..7e9abc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,7 +165,7 @@ dependencies = [ [[package]] name = "docker-autoheal" -version = "0.2.1" +version = "0.2.2" dependencies = [ "bollard", "chrono", diff --git a/Cargo.toml b/Cargo.toml index e0311f1..bb84a29 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "docker-autoheal" -version = "0.2.1" +version = "0.2.2" authors = ["Travis M Knight "] license = "MIT" description = "Monitor and restart unhealthy docker containers" diff --git a/src/main.rs b/src/main.rs index 810484d..de8ff6d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,8 +15,8 @@ async fn log_message(msg: &str) { // Return environment variable fn get_env(key: &str, default: &str) -> String { match std::env::var(key) { - Ok(val) => return val, - Err(e) => return default.to_string(), + Ok(val) => return val.to_lowercase(), + Err(e) => return default.to_string().to_lowercase(), } } @@ -78,7 +78,7 @@ async fn main() -> Result<(), Box> { // Build container assessment criteria let mut filters = HashMap::new(); filters.insert("health", vec!["unhealthy"]); - if autoheal_container_label != "ALL" { + if autoheal_container_label != "all" { filters.insert("label", vec![&autoheal_container_label]); } @@ -112,12 +112,10 @@ async fn main() -> Result<(), Box> { // Report what is transpiring let msg0 = format!("Container '{}' ({}) unhealthy", name, id); - // todo - // let msg1 = format!( - // "Restarting '{}' with {}s timeout", - // name, autoheal_default_stop_timeout - // ); - let msg1 = format!("Restarting '{}' now", name); + let msg1 = format!( + "Restarting '{}' with {}s timeout", + name, autoheal_default_stop_timeout + ); log_message(&msg0).await; log_message(&msg1).await; From 94f36faf950a4715258cdc94f356939dc9d42b2f Mon Sep 17 00:00:00 2001 From: tmknight Date: Mon, 8 Jan 2024 10:28:38 -0500 Subject: [PATCH 3/5] v0.2.3 refinements to variables and http connect --- Cargo.lock | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 +- src/main.rs | 57 ++++++++++++++++++++++++------------ 3 files changed, 122 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7e9abc4..f07fa69 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -165,11 +165,12 @@ dependencies = [ [[package]] name = "docker-autoheal" -version = "0.2.2" +version = "0.2.3" dependencies = [ "bollard", "chrono", "futures", + "rustls", "tokio", ] @@ -283,6 +284,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "gimli" version = "0.28.1" @@ -649,12 +661,57 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9d979b3ce68192e42760c7810125eb6cf2ea10efae545a156063e61f314e2a" + +[[package]] +name = "rustls-webpki" +version = "0.102.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4ca26037c909dedb327b48c3327d0ba91d3dd3c4e05dad328f210ffb68e95b" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "ryu" version = "1.0.16" @@ -771,6 +828,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "2.0.46" @@ -942,6 +1011,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -1175,3 +1250,9 @@ name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" diff --git a/Cargo.toml b/Cargo.toml index bb84a29..5460299 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "docker-autoheal" -version = "0.2.2" +version = "0.2.3" authors = ["Travis M Knight "] license = "MIT" description = "Monitor and restart unhealthy docker containers" @@ -13,6 +13,7 @@ rust-version = "1.74.1" bollard = "*" chrono = "0.4.*" futures = "0.3.*" +rustls = "0.22.*" tokio = { version = "1.*", features = ["full"] } [[bin]] diff --git a/src/main.rs b/src/main.rs index de8ff6d..d24db3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use bollard::container::{ListContainersOptions, RestartContainerOptions}; -use bollard::Docker; +use bollard::{Docker, API_DEFAULT_VERSION}; use chrono::prelude::*; use std::collections::HashMap; use std::io::{stdout, Write}; @@ -16,20 +16,28 @@ async fn log_message(msg: &str) { fn get_env(key: &str, default: &str) -> String { match std::env::var(key) { Ok(val) => return val.to_lowercase(), - Err(e) => return default.to_string().to_lowercase(), + Err(_e) => return default.to_string().to_lowercase(), } } #[tokio::main] async fn main() -> Result<(), Box> { - // Autoheal variables - let autoheal_connection_type = get_env("AUTOHEAL_CONNECTION_TYPE", "local"); - let autoheal_container_label = get_env("AUTOHEAL_CONTAINER_LABEL", "autoheal"); - let autoheal_default_stop_timeout = get_env("AUTOHEAL_DEFAULT_STOP_TIMEOUT", "10") - .parse() - .unwrap(); - let autoheal_interval = get_env("AUTOHEAL_INTERVAL", "5").parse().unwrap(); - let autoheal_start_period = get_env("AUTOHEAL_START_PERIOD", "0").parse().unwrap(); + // Autoheal core variables + let autoheal_connection_type: String = get_env("AUTOHEAL_CONNECTION_TYPE", "local"); + let autoheal_container_label: String = get_env("AUTOHEAL_CONTAINER_LABEL", "autoheal"); + let autoheal_stop_timeout: isize = get_env("AUTOHEAL_STOP_TIMEOUT", "10").parse().unwrap(); + let autoheal_interval: u64 = get_env("AUTOHEAL_INTERVAL", "5").parse().unwrap(); + let autoheal_start_delay: u64 = get_env("AUTOHEAL_START_DELAY", "0").parse().unwrap(); + // Autoheal tcp variables + let autoheal_tcp_host: String = get_env("AUTOHEAL_TCP_HOST", "localhost"); + let autoheal_tcp_port: u64 = get_env("AUTOHEAL_TCP_PORT", "2375").parse().unwrap(); + let autoheal_tcp_address: String = autoheal_tcp_host + ":" + &autoheal_tcp_port.to_string(); + let autoheal_tcp_timeout: u64 = get_env("AUTOHEAL_TCP_TIMEOUT", "10").parse().unwrap(); + let autoheal_key_path: String = + get_env("AUTOHEAL_KEY_PATH", "/opt/docker-autoheal/tls/key.pem"); + let autoheal_cert_path: String = + get_env("AUTOHEAL_CERT_PATH", "/opt/docker-autoheal/tls/cert.pem"); + let autoheal_ca_path: String = get_env("AUTOHEAL_CA_PATH", "/opt/docker-autoheal/tls/ca.pem"); // todo // Webhook variables @@ -42,18 +50,29 @@ async fn main() -> Result<(), Box> { match autoheal_connection_type.as_str() { "socket" => { docker_tmp = Some( - #[cfg(unix)] + // #[cfg(unix)] Docker::connect_with_socket_defaults()?, ); } "http" => { - docker_tmp = Some(Docker::connect_with_http_defaults()?); + docker_tmp = Some(Docker::connect_with_http( + &autoheal_tcp_address, + autoheal_tcp_timeout, + API_DEFAULT_VERSION, + )?); } // todo // "ssl" => { // docker_tmp = Some( - // // #[cfg(feature = "ssl")] - // Docker::connect_with_ssl_defaults()?, + // #[cfg(feature = "ssl")] + // Docker::connect_with_ssl( + // autoheal_tcp_address, + // autoheal_tcp_timeout, + // Path::new(autoheal_key_path), + // Path::new(autoheal_cert_path), + // Path::new(autoheal_ca_path), + // API_DEFAULT_VERSION + // )?, // ); // } &_ => { @@ -66,10 +85,10 @@ async fn main() -> Result<(), Box> { let docker = docker_tmp.unwrap(); // Delay start of loop if specified - if autoheal_start_period > 0 { - let msg0 = format!("Delaying evaluation {}s on request", autoheal_start_period); + if autoheal_start_delay > 0 { + let msg0 = format!("Delaying evaluation {}s on request", autoheal_start_delay); log_message(&msg0).await; - std::thread::sleep(Duration::from_secs(autoheal_start_period)); + std::thread::sleep(Duration::from_secs(autoheal_start_delay)); } // Establish loop interval @@ -106,7 +125,7 @@ async fn main() -> Result<(), Box> { if !matches!(state.as_str(), "paused" | "restarting") { // Build restart options let restart_options = Some(RestartContainerOptions { - t: autoheal_default_stop_timeout, + t: autoheal_stop_timeout, ..Default::default() }); @@ -114,7 +133,7 @@ async fn main() -> Result<(), Box> { let msg0 = format!("Container '{}' ({}) unhealthy", name, id); let msg1 = format!( "Restarting '{}' with {}s timeout", - name, autoheal_default_stop_timeout + name, autoheal_stop_timeout ); log_message(&msg0).await; log_message(&msg1).await; From 558d31b8b854878f7b7218ffca09dd26d68af91c Mon Sep 17 00:00:00 2001 From: tmknight Date: Mon, 8 Jan 2024 10:46:27 -0500 Subject: [PATCH 4/5] Update README.md --- README.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 842680e..0defc92 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,21 @@ The `docker-autoheal` binary may be executed via a native OS or via a Docker con ## ENV Defaults -| Variable | Default | Description | -|:---------------------------------:|:--------:|:---------------------------------------------------------------------------------------------------------------------------------:| -| **AUTOHEAL_CONTAINER_LABEL** | autoheal |This is the label (set to `true`) that `docker-autoheal` will monitor and remediate - or set to `all` to simply monitor all containers on the host| -| **AUTOHEAL_DEFAULT_STOP_TIMEOUT** | 10 | Docker waits `n` seconds for a container to stop before killing it during restarts | -| **AUTOHEAL_INTERVAL** | 5 | Check container health every`n` seconds** | -| **AUTOHEAL_START_PERIOD** | 0 | Wait `n` seconds before first health check | +| Variable | Default | Description | +|:----------------------------:|:---------------------:|:--------------------------------------------------------------------------------------------------------------------------------------------------:| +| **AUTOHEAL_CONNECTON_TYPE** | local | This determines how `docker-autheal` connects to Docker (One of: local, socket, http | +| **AUTOHEAL_CONTAINER_LABEL** | autoheal | This is the label (set to `true`) that `docker-autoheal` will monitor and remediate - or set to `all` to simply monitor all containers on the host | +| **AUTOHEAL_STOP_TIMEOUT** | 10 | Docker waits `n` seconds for a container to stop before killing it during restarts | +| **AUTOHEAL_INTERVAL** | 5 | Check container health every`n` seconds** | +| **AUTOHEAL_START_DELAY** | 0 | Wait `n` seconds before first health check | +| **AUTOHEAL_TCP_HOST** | localhost | Address of Docker host | +| **AUTOHEAL_TCP_PORT** | 2375 | Port on which to connect to the Docker host | +| **AUTOHEAL_TCP_TIMEOUT** | 10 | Time in `n` seconds before failing connection attempt | +| +