14 Commits

Author SHA1 Message Date
6fd275802c removed unneccessary conditions for if statement
All checks were successful
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 4s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 6s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m10s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 2m43s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 3m32s
Rust Cross-Platform Build / Build and Push Docker Image (push) Successful in 2m2s
Rust Cross-Platform Build / Workflow Summary (push) Successful in 2s
Rust Cross-Platform Build / Create Tag (push) Successful in 5s
2025-09-26 13:20:26 +02:00
9018adf998 removed unused env
All checks were successful
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 5s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 5s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m12s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 2m46s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 3m33s
Rust Cross-Platform Build / Build and Push Docker Image (push) Successful in 2m3s
Rust Cross-Platform Build / Create Tag (push) Has been skipped
Rust Cross-Platform Build / Workflow Summary (push) Successful in 2s
2025-09-26 11:40:02 +02:00
3124697f10 removed unused env 2025-09-26 11:39:05 +02:00
30382fedef changed secrets to AUTOMATION_*
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Has been cancelled
Rust Cross-Platform Build / Run Tests (push) Has been cancelled
Rust Cross-Platform Build / Set Tag Name (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been cancelled
Rust Cross-Platform Build / Create Tag (push) Has been cancelled
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
2025-09-26 11:16:38 +02:00
8910155524 removed setup_rust
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Has been cancelled
Rust Cross-Platform Build / Run Tests (push) Has been cancelled
Rust Cross-Platform Build / Set Tag Name (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been cancelled
Rust Cross-Platform Build / Create Tag (push) Has been cancelled
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
2025-09-26 11:15:30 +02:00
7a68df41ac removed redundant and unvalid conditions
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Has been cancelled
Rust Cross-Platform Build / Setup Rust Toolchain (push) Has been cancelled
Rust Cross-Platform Build / Run Tests (push) Has been cancelled
Rust Cross-Platform Build / Set Tag Name (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Has been cancelled
Rust Cross-Platform Build / Build and Push Docker Image (push) Has been cancelled
Rust Cross-Platform Build / Create Tag (push) Has been cancelled
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
2025-09-26 02:06:25 +02:00
60ce51cd82 depends on docker-build
Some checks failed
Rust Cross-Platform Build / Create Tag (push) Blocked by required conditions
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 4s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 4s
Rust Cross-Platform Build / Setup Rust Toolchain (push) Successful in 23s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m0s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 1m26s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 2m6s
Rust Cross-Platform Build / Build and Push Docker Image (push) Successful in 1m50s
Rust Cross-Platform Build / Workflow Summary (push) Has been cancelled
2025-09-26 01:53:41 +02:00
54fca8b1d3 added docker secrets
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 4s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 4s
Rust Cross-Platform Build / Setup Rust Toolchain (push) Successful in 23s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m4s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 2m37s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 3m16s
Rust Cross-Platform Build / Build and Push Docker Image (push) Successful in 1m54s
Rust Cross-Platform Build / Workflow Summary (push) Successful in 1s
Rust Cross-Platform Build / Create Tag (push) Failing after 12m40s
2025-09-26 00:15:29 +02:00
aa876d9e5d added newer action version for login
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 5s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 4s
Rust Cross-Platform Build / Setup Rust Toolchain (push) Successful in 23s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m6s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 2m35s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 3m25s
Rust Cross-Platform Build / Create Tag (push) Successful in 4s
Rust Cross-Platform Build / Build and Push Docker Image (push) Failing after 2m11s
Rust Cross-Platform Build / Workflow Summary (push) Successful in 1s
2025-09-26 00:00:24 +02:00
88625ff986 added docker api for restart and client updat
Some checks failed
Rust Cross-Platform Build / Detect Rust Project (push) Successful in 5s
Rust Cross-Platform Build / Set Tag Name (push) Successful in 4s
Rust Cross-Platform Build / Setup Rust Toolchain (push) Successful in 23s
Rust Cross-Platform Build / Run Tests (push) Successful in 1m0s
Rust Cross-Platform Build / Build (x86_64-unknown-linux-gnu) (push) Successful in 2m25s
Rust Cross-Platform Build / Build (x86_64-pc-windows-gnu) (push) Successful in 3m2s
Rust Cross-Platform Build / Create Tag (push) Successful in 5s
Rust Cross-Platform Build / Build and Push Docker Image (push) Failing after 12s
Rust Cross-Platform Build / Workflow Summary (push) Successful in 1s
2025-09-25 22:02:11 +02:00
428be53fff added docker api for restart and client updat 2025-09-25 22:02:00 +02:00
83cb815e76 added docker image update option 2025-09-23 23:27:13 +02:00
755617c86f removed loggin option for client 2025-09-23 21:28:19 +02:00
314bf8c327 added server comm 2025-09-21 01:40:32 +02:00
7 changed files with 143 additions and 29 deletions

View File

@@ -9,11 +9,8 @@ on:
branches: [ "development", "main" ] branches: [ "development", "main" ]
env: env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
REGISTRY: git.triggermeelmo.com REGISTRY: git.triggermeelmo.com
IMAGE_NAME: donpat1to/watcher-agent IMAGE_NAME: donpat1to/watcher-agent
TAG: ${{ github.ref == 'refs/heads/main' && 'latest' || github.ref == 'refs/heads/development' && 'development' || github.ref_type == 'tag' && github.ref_name || 'pr' }}
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@@ -54,24 +51,9 @@ jobs:
exit 1 exit 1
fi fi
setup-rust:
name: Setup Rust Toolchain
needs: detect-project
if: ${{ !failure() && !cancelled() }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
targets: x86_64-unknown-linux-gnu, x86_64-pc-windows-gnu
components: rustfmt, clippy
test: test:
name: Run Tests name: Run Tests
needs: [detect-project, setup-rust] needs: [detect-project]
if: ${{ !failure() && !cancelled() }} if: ${{ !failure() && !cancelled() }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -134,7 +116,7 @@ jobs:
# audit: # audit:
# name: Security Audit # name: Security Audit
# needs: [detect-project, setup-rust] # needs: [detect-project]
# if: ${{ !failure() && !cancelled() }} # if: ${{ !failure() && !cancelled() }}
# runs-on: ubuntu-latest # runs-on: ubuntu-latest
# steps: # steps:
@@ -154,7 +136,7 @@ jobs:
build: build:
name: Build (${{ matrix.target }}) name: Build (${{ matrix.target }})
needs: [detect-project, setup-rust, test, audit] needs: [detect-project, test]
if: ${{ !failure() && !cancelled() }} if: ${{ !failure() && !cancelled() }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@@ -227,14 +209,14 @@ jobs:
path: dist/ path: dist/
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
- name: Login to Docker Registry - name: Login to Docker Registry
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ secrets.DOCKER_USERNAME }} username: ${{ secrets.AUTOMATION_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }} password: ${{ secrets.AUTOMATION_PASSWORD }}
- name: Build Docker image - name: Build Docker image
uses: docker/build-push-action@v4 uses: docker/build-push-action@v4
@@ -250,8 +232,10 @@ jobs:
tag: tag:
name: Create Tag name: Create Tag
needs: [build, set-tag] needs: [docker-build, build, set-tag]
if: github.event_name == 'push' if: |
github.event_name == 'push' &&
needs.docker-build.result == 'success'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

View File

@@ -20,8 +20,11 @@ nvml-wrapper-sys = "0.9.0"
anyhow = "1.0.98" anyhow = "1.0.98"
# Docker .env loading # Docker .env loading
config = "0.13" # config = "0.13"
dotenvy = "0.15"
# Docker API access
bollard = "0.19"
futures-util = "0.3"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["winuser", "pdh", "ifmib", "iphlpapi", "winerror" ,"wbemcli", "combaseapi"] } winapi = { version = "0.3", features = ["winuser", "pdh", "ifmib", "iphlpapi", "winerror" ,"wbemcli", "combaseapi"] }

View File

@@ -1,3 +1,5 @@
use crate::serverclientcomm::handle_server_message;
use std::time::Duration; use std::time::Duration;
use crate::hardware::HardwareInfo; use crate::hardware::HardwareInfo;
@@ -7,6 +9,9 @@ use reqwest::{Client, StatusCode};
use std::error::Error; use std::error::Error;
use tokio::time::sleep; use tokio::time::sleep;
use bollard::Docker;
use crate::models::ServerMessage;
pub async fn register_with_server( pub async fn register_with_server(
base_url: &str, base_url: &str,
) -> Result<(i32, String), Box<dyn Error + Send + Sync>> { ) -> Result<(i32, String), Box<dyn Error + Send + Sync>> {
@@ -153,3 +158,25 @@ pub async fn send_metrics(
Ok(()) Ok(())
} }
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
let resp = reqwest::get(&url)
.await;
if let Ok(resp) = resp {
if let Ok(msg) = resp.json::<ServerMessage>().await {
handle_server_message(docker, msg).await;
} else {
eprintln!("Failed to parse message");
}
} else {
eprintln!("Failed to reach server");
}
// Poll every 5 seconds (or use WebSocket for real-time)
sleep(Duration::from_secs(5)).await;
}
}

View File

@@ -5,6 +5,7 @@ pub mod api;
pub mod hardware; pub mod hardware;
pub mod metrics; pub mod metrics;
pub mod models; pub mod models;
pub mod serverclientcomm;
use std::env; use std::env;
use std::error::Error; use std::error::Error;

View File

@@ -72,3 +72,12 @@ pub struct HardwareDto {
pub ram_size: f64, pub ram_size: f64,
pub ip_address: String, pub ip_address: String,
} }
#[derive(Debug, Deserialize)]
#[serde(tag = "command", content = "data")]
pub enum ServerMessage {
Update(String),
Restart,
#[serde(other)]
Unknown,
}

View File

@@ -0,0 +1,67 @@
use crate::models::ServerMessage;
use bollard::Docker;
use bollard::query_parameters::CreateImageOptions;
use bollard::query_parameters::RestartContainerOptions;
use futures_util::StreamExt;
pub fn parse_message(raw: &str) -> ServerMessage {
match raw {
"restart" => ServerMessage::Restart,
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: Some(image.to_string()),
..Default::default()
}),
None,
None,
);
// Use the stream with proper trait bounds
while let Some(result) = StreamExt::next(&mut stream).await {
match result {
Ok(progress) => {
if let Some(status) = progress.status {
println!("Pull status: {}", status);
}
}
Err(e) => {
eprintln!("Error pulling image: {}", e);
break;
}
}
}
// 2. Restart the current container
restart_container(docker).await;
}
pub async fn restart_container(docker: &Docker) {
if let Ok(container_id) = std::env::var("HOSTNAME") {
println!("Restarting container {}", container_id);
if let Err(e) = docker.restart_container(&container_id, Some(RestartContainerOptions { signal: None, t: Some(0) }))
.await
{
eprintln!("Failed to restart container: {}", e);
}
} else {
eprintln!("No container ID found (HOSTNAME not set?)");
}
}

23
docker-compose.yaml Normal file
View 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