Compare commits

...

10 Commits

Author SHA1 Message Date
prplV ee64e39c50 readme update 2025-06-17 14:29:36 +03:00
prplV 02f46839bd new ignore 2025-06-17 11:26:35 +03:00
prplV 94ed7af436 another fix 2025-06-06 09:19:59 -04:00
prplV 4eb603afd7 ignore fix 2025-06-06 09:19:33 -04:00
prplV d4e9a2f875 fix metrics 2025-06-06 09:18:43 -04:00
prplV 4133d2f348 hotfix + docker for proxy 2025-06-06 05:31:09 -04:00
Vladislav Drozdov 0634ecd0d3
Merge pull request #15 from prplV/feature/prplV/prc-stat-time
Feature/prpl v/prc stat time
2025-06-05 16:59:21 +03:00
prplV ef8d7e9b4d for unittests pass 2025-06-05 16:52:38 +03:00
prplV 5fabed1e56 finalfinal 2025-06-05 16:27:53 +03:00
prplV 196280f783 final fix 2025-06-05 16:27:22 +03:00
13 changed files with 120 additions and 45 deletions

4
.gitignore vendored
View File

@ -4,4 +4,6 @@
Cargo.lock Cargo.lock
hagent_test.sock hagent_test.sock
release release
*.sock *.sock
*.bak
docker-compose.yml

View File

@ -1,10 +1,20 @@
# noxis-rs # noxis
![Logo](logo.png) ![Logo](logo.png)
### In-container integrating util to handle processes runtime
( with amd64 and riscv64 support )
## Depends on `noxis` - monitoring util with special attention on
1) **Speed**
2) **Multiplatform** execution *(with `amd64` and `riscv64` **support**)*
3) **Smallness** and **Optimization**
It's **main tasks** are
- to manage the processes that occur inside the container or in the target system.
- collect data (metrics);
- monitor the availability of system files necessary for the operation of processes;
- check whether there is a connection between processes and services, where the information comes from or where it is sent.
## Build requirements
- `rustup (>=1.27.1)` - `rustup (>=1.27.1)`
- `gcc-riscv64-unknown-elf` - `gcc-riscv64-unknown-elf`
- `build-essential` - `build-essential`
@ -12,60 +22,70 @@
- `binutils-riscv64-linux-gnu` - `binutils-riscv64-linux-gnu`
## Setting up ## Key items in repo
Download and execute rustup.sh
~~~bash 1) Main daemon `noxis-rs`
2) CLI `noxis-cli`
3) Unix-Socket to Web-Socket **Proxy** for integrations `noxis-proxy`
## Setting up device
Download and execute rustup.sh *(for building)*
~~~ bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
~~~ ~~~
## Building ## Building
1. Clone this repo `runner-rs` 1. Clone `noxis`
~~~bash ~~~ bash
git clone https://github.com/prplV/runner-rs git clone https://github.com/prplV/noxis
~~~ ~~~
2. Enter project's dir and set up toolchain list to compile code for RISC-V and AMD64 2. Enter project's dir and set up toolchain list to compile code for RISC-V or x86_64
~~~bash ~~~ bash
cd runner-rs/ && rustup target add riscv64gc-unknown-linux-gnu && rustup target add x86_64-unknown-linux-gnu cd noxis/ && rustup target add riscv64gc-unknown-linux-gnu && rustup target add x86_64-unknown-linux-gnu
~~~ ~~~
> [!NOTE] > [!NOTE]
> Cargo is configured to build an app for amd64/linux defaultly. RISCV-based compilation is optional. > Cargo is configured to build an apputil for x86_64/linux defaultly. RISCV-based compilation is optional.
3.1. Release build of app for amd64/linux 3.1. Release build of util for x86_64/linux
~~~bash ~~~bash
cargo x86_64 cargo x86_64
~~~ ~~~
3.2. Release build of app for riscv64/linux 3.2. Release build of util for riscv64/linux
~~~bash ~~~bash
cargo riscv64 cargo riscv64
~~~ ~~~
3.3. Release build of app for both (riscv64 and amd64) 3.3. Release build of util for both (riscv64 and x86_64)
~~~bash ~~~bash
cargo unibuild cargo unibuild
~~~ ~~~
## Execution for amd64/linux ## Execution **DAEMON** for x86_64/linux
1) If you work on x86_64/linux machine execute:
~~~bash ~~~bash
./target/x86_64-unknown-linux-gnu/release/runner-rs ./target/x86_64-unknown-linux-gnu/release/noxis-rs
~~~ ~~~
or or
~~~bash ~~~bash
cargo run_x86 cargo run_x86
~~~ ~~~
2) If you work on riscv64/linux machine execute:
## Execution for riscv64/linux
~~~bash ~~~bash
./target/riscv64gc-unknown-linux-gnu/release/runner-rs ./target/riscv64gc-unknown-linux-gnu/release/noxis-rs
~~~ ~~~
or or
> [!CAUTION] > [!CAUTION]

BIN
logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View File

@ -0,0 +1,4 @@
.env
.env.example
README.md
target

19
noxis-proxy/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
FROM rust:latest AS builder
WORKDIR /app
RUN apt update && apt install -y musl-tools
RUN rustup target add x86_64-unknown-linux-musl
COPY . .
RUN cargo build --release --target=x86_64-unknown-linux-musl
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/noxis-proxy /app/noxis-proxy
RUN apk add --no-cache ca-certificates
EXPOSE 7654
ENTRYPOINT ["/app/noxis-proxy"]

View File

@ -0,0 +1,20 @@
services:
noxis-proxy:
container_name: noxis-proxy
image: noxis-proxy:0.1.0
networks:
- noxis-net
environment:
- NOXIS_SOCKET_PATH=./noxis.sock
- NOXIS_PROXY_PORT=7654
- NOXIS_LOG_LEVEL=TRACE
volumes:
- /home/user/diplom_code/noxis-rs/noxis.sock:/app/noxis.sock
ports:
- 7654:7654
restart: always
networks:
noxis-net:
driver: bridge

View File

@ -36,7 +36,7 @@ async fn main() -> anyhow::Result<()> {
.route("/hello", get(hello)) .route("/hello", get(hello))
.with_state(app_state); .with_state(app_state);
let bind = format!("0.0.0.0:{}", std::env::var("NOXIS_PROXY_PORT").unwrap_or_else(|_| String::from("3000"))); let bind = format!("0.0.0.0:{}", std::env::var("NOXIS_PROXY_PORT").unwrap_or_else(|_| String::from("7654")));
tracing::info!("Serving on {}", &bind); tracing::info!("Serving on {}", &bind);
@ -61,23 +61,21 @@ async fn hello(
} }
async fn handle_socket(mut ws: WebSocket, state: AppState) { async fn handle_socket(mut ws: WebSocket, state: AppState) {
// Подключаемся к Unix-сокету
tracing::info!("handle websocket"); tracing::info!("handle websocket");
let mut unix_socket = match UnixStream::connect(&state.socket_path).await {
Ok(socket) => socket,
Err(e) => {
eprintln!("Failed to connect to Unix socket: {}", e);
let _ = ws.send(Message::Text("ERROR: Unix socket connection failed".into())).await;
return;
}
};
// Отправляем сообщения из WS → Unix
let ws_receiver = tokio::spawn(async move { let ws_receiver = tokio::spawn(async move {
while let Some(Ok(msg)) = ws.recv().await { while let Some(Ok(msg)) = ws.recv().await {
let mut unix_socket = match UnixStream::connect(&state.socket_path).await {
Ok(socket) => socket,
Err(e) => {
tracing::error!("Failed to connect to Unix socket: {}", e);
let _ = ws.send(Message::Text("ERROR: Unix socket connection failed".into())).await;
return;
}
};
if let Message::Text(text) = msg { if let Message::Text(text) = msg {
if let Err(e) = unix_socket.write_all(text.as_bytes()).await { if let Err(e) = unix_socket.write_all(text.as_bytes()).await {
eprintln!("Failed to write to Unix socket: {}", e); tracing::error!("Failed to write to Unix socket: {}", e);
break; break;
} }
let mut buf = Vec::new(); let mut buf = Vec::new();
@ -94,5 +92,5 @@ async fn handle_socket(mut ws: WebSocket, state: AppState) {
} }
}); });
let _ = ws_receiver.await; // Дожидаемся завершения задачи let _ = ws_receiver.await;
} }

View File

@ -529,9 +529,9 @@ impl ProcessExtended {
Some(duration) => { Some(duration) => {
format!("{}:{}:{}:{}", format!("{}:{}:{}:{}",
duration.num_days(), duration.num_days(),
duration.num_hours(), duration.num_hours() % 24,
duration.num_minutes(), duration.num_minutes() % 60,
duration.num_seconds() duration.num_seconds() % 60
) )
}, },
None => String::new() None => String::new()

View File

@ -246,7 +246,11 @@ pub mod v2 {
self.name self.name
); );
if let Err(er) = unfreeze_process(&self.name).await { if let Err(er) = unfreeze_process(&self.name).await {
error!("Cannot unfreeze process {} : {}", self.name, er); if er.to_string().contains("already") {
self.state = ProcessState::Pending;
} else {
error!("Cannot unfreeze process {} : {}", self.name, er);
}
} else { } else {
self.state = ProcessState::Pending; self.state = ProcessState::Pending;
info!("Process {} was unfreezed", &self.name); info!("Process {} was unfreezed", &self.name);
@ -264,7 +268,11 @@ pub mod v2 {
info!("{}: New PID - {}", self.name, self.pid); info!("{}: New PID - {}", self.name, self.pid);
} }
Err(er) => { Err(er) => {
error!("Cannot start process {} : {}", self.name, er); if er.to_string().contains("already") {
self.state = ProcessState::Pending;
} else {
error!("Cannot start process {} : {}", self.name, er);
}
} }
} }
} }

View File

@ -49,7 +49,7 @@ pub mod v2 {
ServicesController { ServicesController {
name: String::new(), name: String::new(),
access_url: Arc::from(String::new()), access_url: Arc::from(String::new()),
state: ServiceState::Unavailable, state: ServiceState::Ok,
config: ConnectionQueue::new(), config: ConnectionQueue::new(),
event_registrator: EventHandlers::new(), event_registrator: EventHandlers::new(),
} }

View File

@ -1,5 +1,7 @@
{ {
"dateOfCreation": "1", "dateOfCreation": "1",
"configServer": "", "processes": []
}
,
"processes": [] "processes": []
} }

View File

@ -1,5 +1,7 @@
{ {
"dateOfCreation": "1", "dateOfCreation": "1",
"configServer": "", "processes": []
}
,
"processes": [] "processes": []
} }

View File

@ -1,6 +1,5 @@
{ {
"dateOfCreation": "1721381809103", "dateOfCreation": "1721381809103",
"configServer" : "localhost",
"processes": [ "processes": [
{ {
"name": "temp-process", "name": "temp-process",
@ -12,7 +11,8 @@
"src": "/home/vladislav/web/runner-rs/examples/", "src": "/home/vladislav/web/runner-rs/examples/",
"triggers": { "triggers": {
"onDelete": "hold", "onDelete": "hold",
"onChange": "stop" "onChange": "stop",
"doRestore" : true
} }
} }
], ],