diff --git a/src/docker_data/mod.rs b/src/docker_data/mod.rs index f71a5f7..69e58a6 100644 --- a/src/docker_data/mod.rs +++ b/src/docker_data/mod.rs @@ -448,7 +448,7 @@ impl DockerData { gui_state: Arc>, is_running: Arc, ) { - let args = app_data.lock().args; + let args = app_data.lock().args.clone(); if app_data.lock().get_error().is_none() { let mut inner = Self { app_data, diff --git a/src/main.rs b/src/main.rs index 29db59b..2d6fe97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,17 +17,20 @@ use app_data::AppData; use app_error::AppError; -use bollard::Docker; +use bollard::{Docker, API_DEFAULT_VERSION}; use docker_data::DockerData; use input_handler::InputMessages; use parking_lot::Mutex; use parse_args::CliArgs; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, +use std::{ + process, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, }; use tokio::sync::mpsc::{Receiver, Sender}; -use tracing::{info, Level}; +use tracing::{error, info, Level}; mod app_data; mod app_error; @@ -44,6 +47,7 @@ use crate::docker_data::DockerMessage; const ENTRY_POINT: &str = "/app/oxker"; const ENV_KEY: &str = "OXKER_RUNTIME"; const ENV_VALUE: &str = "container"; +const DOCKER_HOST: &str = "DOCKER_HOST"; /// Enable tracing, only really used in debug mode, for now /// write to file if `-g` is set? @@ -62,6 +66,18 @@ fn check_if_containerised() -> bool { } } +/// Read the optional docker_host path, the cli args take priority over the DOCKER_HOST env +fn read_docker_host(args: &CliArgs) -> Option { + args.host.as_ref().map_or_else( + || { + std::env::vars() + .find(|x| x.0 == DOCKER_HOST) + .map(|(_, val)| val) + }, + |x| Some(x.to_string()), + ) +} + /// Create docker daemon handler, and only spawn up the docker data handler if a ping returns non-error async fn docker_init( app_data: &Arc>, @@ -69,8 +85,13 @@ async fn docker_init( docker_rx: Receiver, gui_state: &Arc>, is_running: &Arc, + host: Option, ) { - if let Ok(docker) = Docker::connect_with_socket_defaults() { + let connection = host.map_or_else(Docker::connect_with_socket_defaults, |host| { + Docker::connect_with_socket(&host, 120, API_DEFAULT_VERSION) + }); + + if let Ok(docker) = connection { if docker.ping().await.is_ok() { let app_data = Arc::clone(app_data); let gui_state = Arc::clone(gui_state); @@ -120,13 +141,25 @@ async fn main() { setup_tracing(); let args = CliArgs::new(); - let app_data = Arc::new(Mutex::new(AppData::default(args))); + let host = read_docker_host(&args); + + //todo if host in arg, use that instead of env? + + let app_data = Arc::new(Mutex::new(AppData::default(args.clone()))); let gui_state = Arc::new(Mutex::new(GuiState::default())); let is_running = Arc::new(AtomicBool::new(true)); let (docker_sx, docker_rx) = tokio::sync::mpsc::channel(32); let (input_sx, input_rx) = tokio::sync::mpsc::channel(32); - docker_init(&app_data, containerised, docker_rx, &gui_state, &is_running).await; + docker_init( + &app_data, + containerised, + docker_rx, + &gui_state, + &is_running, + host, + ) + .await; handler_init(&app_data, &docker_sx, &gui_state, input_rx, &is_running); @@ -134,9 +167,13 @@ async fn main() { Ui::create(app_data, docker_sx, gui_state, is_running, input_sx).await; } else { info!("in debug mode"); + // Debug mode for testing, mostly pointless, doesn't take terminal while is_running.load(Ordering::SeqCst) { - // Debug mode for testing, mostly pointless, doesn't take terminal loop { + if let Some(err) = app_data.lock().get_error() { + error!("{}", err); + process::exit(1); + } docker_sx.send(DockerMessage::Update).await.ok(); tokio::time::sleep(std::time::Duration::from_millis(u64::from( args.docker_interval, diff --git a/src/parse_args/mod.rs b/src/parse_args/mod.rs index d6c823d..7a69053 100644 --- a/src/parse_args/mod.rs +++ b/src/parse_args/mod.rs @@ -3,7 +3,7 @@ use std::process; use clap::Parser; use tracing::error; -#[derive(Parser, Debug, Clone, Copy)] +#[derive(Parser, Debug, Clone)] #[allow(clippy::struct_excessive_bools)] #[command(version, about)] pub struct CliArgs { @@ -19,6 +19,10 @@ pub struct CliArgs { #[clap(short = 'c', conflicts_with = "raw")] pub color: bool, + /// Docker host, defaults to `/var/run/docker.sock` + #[clap(long, short = None)] + pub host: Option, + /// Show raw logs, default is to remove ansi formatting, conflicts with "-c" #[clap(short = 'r', conflicts_with = "color")] pub raw: bool, @@ -46,6 +50,7 @@ impl CliArgs { Self { color: args.color, docker_interval: args.docker_interval, + host: args.host, gui: !args.gui, show_self: !args.show_self, raw: args.raw,