added docker image update option
This commit is contained in:
@@ -20,8 +20,10 @@ nvml-wrapper-sys = "0.9.0"
|
||||
anyhow = "1.0.98"
|
||||
|
||||
# Docker .env loading
|
||||
config = "0.13"
|
||||
dotenvy = "0.15"
|
||||
# config = "0.13"
|
||||
|
||||
# Docker API access
|
||||
bollard = "0.16"
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winapi = { version = "0.3", features = ["winuser", "pdh", "ifmib", "iphlpapi", "winerror" ,"wbemcli", "combaseapi"] }
|
||||
|
@@ -1,3 +1,6 @@
|
||||
use crate::serverclientmessage::handle_server_message;
|
||||
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::hardware::HardwareInfo;
|
||||
@@ -7,6 +10,8 @@ use reqwest::{Client, StatusCode};
|
||||
use std::error::Error;
|
||||
use tokio::time::sleep;
|
||||
|
||||
|
||||
|
||||
pub async fn register_with_server(
|
||||
base_url: &str,
|
||||
) -> Result<(i32, String), Box<dyn Error + Send + Sync>> {
|
||||
@@ -154,7 +159,7 @@ pub async fn send_metrics(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn listening_to_server(base_url: &str) -> Result<(), Box<dyn Error + Send + Sync>>{
|
||||
pub async fn listening_to_server(docker: &Docker, base_url: &str) -> Result<(), Box<dyn Error + Send + Sync>>{
|
||||
let url = format!("{}/api/message", base_url);
|
||||
loop {
|
||||
// Replace with your server endpoint
|
||||
@@ -163,7 +168,7 @@ pub async fn listening_to_server(base_url: &str) -> Result<(), Box<dyn Error + S
|
||||
|
||||
if let Ok(resp) = resp {
|
||||
if let Ok(msg) = resp.json::<ServerMessage>().await {
|
||||
handle_message(msg).await;
|
||||
handle_server_message(docker, msg).await;
|
||||
} else {
|
||||
eprintln!("Failed to parse message");
|
||||
}
|
||||
@@ -174,31 +179,4 @@ pub async fn listening_to_server(base_url: &str) -> Result<(), Box<dyn Error + S
|
||||
// Poll every 5 seconds (or use WebSocket for real-time)
|
||||
sleep(Duration::from_secs(5)).await;
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_message(raw: &str) -> ServerMessage {
|
||||
match raw {
|
||||
"restart" => ServerMessage::Restart,
|
||||
msg if msg.starts_with("log:") => ServerMessage::Log(msg[4..].to_string()),
|
||||
msg if msg.starts_with("update:") => ServerMessage::Update(msg[7..].to_string()),
|
||||
_ => ServerMessage::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_message(msg: ServerMessage) {
|
||||
match msg {
|
||||
ServerMessage::Restart => restart_container(),
|
||||
ServerMessage::Update(ver) => update_client(&ver),
|
||||
ServerMessage::Unknown => eprintln!("Unknown message"),
|
||||
}
|
||||
}
|
||||
|
||||
fn restart_container() {
|
||||
println!("Restarting...");
|
||||
std::process::exit(1); // let Docker restart it
|
||||
}
|
||||
|
||||
fn update_client(version: &str) {
|
||||
println!("Updating to version {}", version);
|
||||
}
|
||||
|
||||
}
|
@@ -5,6 +5,7 @@ pub mod api;
|
||||
pub mod hardware;
|
||||
pub mod metrics;
|
||||
pub mod models;
|
||||
pub mod serverclientcomm;
|
||||
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
|
60
WatcherAgent/src/serverclientcomm.rs
Normal file
60
WatcherAgent/src/serverclientcomm.rs
Normal file
@@ -0,0 +1,60 @@
|
||||
use bollard::Docker;
|
||||
use bollard::image::CreateImageOptions;
|
||||
use bollard::container::{RestartContainerOptions};
|
||||
|
||||
pub fn parse_message(raw: &str) -> ServerMessage {
|
||||
match raw {
|
||||
"restart" => ServerMessage::Restart,
|
||||
"update" => ServerMessage::Update,
|
||||
msg if msg.starts_with("log:") => ServerMessage::Log(msg[4..].to_string()),
|
||||
msg if msg.starts_with("update:") => ServerMessage::Update(msg[7..].to_string()),
|
||||
_ => ServerMessage::Unknown,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle_server_message(docker: &Docker, msg: ServerMessage) {
|
||||
match msg {
|
||||
ServerMessage::Update(version) => update_docker_image(docker, &version).await,
|
||||
ServerMessage::Restart => restart_container(docker).await,
|
||||
ServerMessage::Unknown => eprintln!("Unknown message"),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn update_docker_image(docker: &Docker, image: &str) {
|
||||
println!("Updating to {}", image);
|
||||
|
||||
// 1. Pull new image
|
||||
let mut stream = docker.create_image(
|
||||
Some(CreateImageOptions {
|
||||
from_image: image,
|
||||
..Default::default()
|
||||
}),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
|
||||
while let Some(progress) = stream.try_next().await.unwrap_or(None) {
|
||||
if let Some(status) = progress.status {
|
||||
println!("Pull status: {}", status);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Restart the current container
|
||||
if let Ok(container_id) = std::env::var("HOSTNAME") {
|
||||
println!("Restarting container: {}", container_id);
|
||||
docker.restart_container(&container_id, Some(RestartContainerOptions { t: 0 }))
|
||||
.await
|
||||
.unwrap();
|
||||
} else {
|
||||
eprintln!("No container ID found (HOSTNAME not set?)");
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn restart_container(docker: &Docker) {
|
||||
if let Ok(container_id) = std::env::var("HOSTNAME") {
|
||||
println!("Restarting container {}", container_id);
|
||||
docker.restart_container(&container_id, Some(RestartContainerOptions { t: 0 }))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
23
docker-compose.yaml
Normal file
23
docker-compose.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
watcher-agent:
|
||||
image: git.triggermeelmo.com/donpat1to/watcher-agent:development
|
||||
container_name: watcher-agent
|
||||
restart: always
|
||||
privileged: true # Grants full hardware access (use with caution)
|
||||
env_file: .env
|
||||
pid: "host"
|
||||
volumes:
|
||||
# Mount critical system paths for hardware monitoring
|
||||
- /sys:/sys:ro # CPU/GPU temps, sensors
|
||||
- /proc:/proc # Process/CPU stats
|
||||
- /dev:/dev:ro # Disk/GPU device access
|
||||
- /var/run/docker.sock:/var/run/docker.sock # Docker API access
|
||||
- /:/root:ro # Access to for df-command
|
||||
# Application volumes
|
||||
- ./config:/app/config:ro
|
||||
- ./logs:/app/logs
|
||||
network_mode: host # Uses host network (for correct IP/interface detection)
|
||||
healthcheck:
|
||||
test: ["CMD", "/usr/local/bin/WatcherAgent", "healthcheck"]
|
||||
interval: 30s
|
||||
timeout: 3s
|
||||
retries: 3
|
Reference in New Issue
Block a user