0.1.0
commit
e232cf29ca
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.86"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.36"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "runner-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.203"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.203"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.118"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.68"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "runner-rs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0.203", features = ["derive"] }
|
||||||
|
serde_json = "1.0.118"
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
hostname=$1
|
||||||
|
port=$2
|
||||||
|
|
||||||
|
if nc -z -w1 $hostname $port > /dev/null 2>&1; then
|
||||||
|
echo "Service $hostname:$port is running"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Service $hostname:$port is unreachable"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"processes" : [{
|
||||||
|
"name" : "web-server",
|
||||||
|
"path" : "/home/vladislav/web/web-server",
|
||||||
|
"dependencies" : {
|
||||||
|
"files" : [
|
||||||
|
{
|
||||||
|
"filename" : "control-file",
|
||||||
|
"src" : "/home/vladislav/web/"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "config-file",
|
||||||
|
"src" : "/home/vladislav/web/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services" : [{
|
||||||
|
"hostname" : "ya.ru",
|
||||||
|
"port" : 443
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,130 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::{self, error};
|
||||||
|
use std::fs;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
enum CustomError {
|
||||||
|
Fatal,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Processes {
|
||||||
|
#[serde(default)]
|
||||||
|
processes : Vec<TrackingProcess>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct TrackingProcess {
|
||||||
|
name : String,
|
||||||
|
path : String,
|
||||||
|
dependencies: Dependencies,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Dependencies {
|
||||||
|
#[serde(default)]
|
||||||
|
files : Vec<Files>,
|
||||||
|
#[serde(default)]
|
||||||
|
services: Vec<Services>,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Files {
|
||||||
|
filename : String,
|
||||||
|
src : String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Services {
|
||||||
|
hostname : String,
|
||||||
|
port : u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let processes = load_processes("settings.json");
|
||||||
|
let mut error_counter = 0;
|
||||||
|
|
||||||
|
if processes.processes.len() == 0 {
|
||||||
|
eprintln!("Error: Processes list is null, runner-rs initialization is stopped");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processes.processes.iter().for_each(|proc| {
|
||||||
|
println!("\nProcess '{}' on stage:\n{}\nDepends on {} file(s), {} service(s)\n",
|
||||||
|
proc.name,
|
||||||
|
proc.path,
|
||||||
|
proc.dependencies.files.len(),
|
||||||
|
proc.dependencies.services.len());
|
||||||
|
|
||||||
|
proc.dependencies.files.iter().for_each(|file| {
|
||||||
|
if let Err(_) = check_file(&file.filename, &file.src) {
|
||||||
|
println!("Error: Process {} cannot run without file {}{}", proc.name, file.src, file.filename);
|
||||||
|
error_counter += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
proc.dependencies.services.iter().for_each(|ser| {
|
||||||
|
if let Err(_) = check_service(&ser.hostname, &ser.port) {
|
||||||
|
println!("Error: Process {} cannot run while service {}:{} is down", proc.name, ser.hostname, ser.port);
|
||||||
|
error_counter += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error_counter > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match start_process(&proc.name, &proc.path) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Success!");
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
println!("Error: Cannot run process");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
fn load_processes(json_filename: &str) -> Processes{
|
||||||
|
let read = fs::read_to_string(json_filename).expect(format!("Missing '{}' file. Cannot start runner", json_filename).as_str());
|
||||||
|
serde_json::from_str::<Processes>(&read).expect(format!("Parsing error in '{}' file. Cannot start runner", json_filename).as_str())
|
||||||
|
}
|
||||||
|
fn start_process(name: &str, path: &str) -> Result<(), CustomError> {
|
||||||
|
let runsh = format!("{}{}", path, "/run.sh");
|
||||||
|
let mut command = Command::new("bash");
|
||||||
|
command.arg(runsh);
|
||||||
|
|
||||||
|
match command.spawn() {
|
||||||
|
Ok(mut child) => {
|
||||||
|
println!("Process {} is running now!", name);
|
||||||
|
child.wait();
|
||||||
|
return Ok(());
|
||||||
|
},
|
||||||
|
Err(_) => return Err(CustomError::Fatal),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn check_file(filename: &str, path: &str) -> Result<(), CustomError> {
|
||||||
|
let fileconcat = format!("{}{}", path, filename);
|
||||||
|
let path = Path::new(&fileconcat);
|
||||||
|
if path.exists() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CustomError::Fatal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn check_service(host: &str, port: &u32) -> Result<(), CustomError> {
|
||||||
|
let mut command = Command::new("bash");
|
||||||
|
command.args(["service-checker.sh", host, &port.to_string()]);
|
||||||
|
|
||||||
|
match command.output() {
|
||||||
|
Ok(output) => {
|
||||||
|
if (output.status.success()) {
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
return Err(CustomError::Fatal);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(_) => {
|
||||||
|
return Err(CustomError::Fatal);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue