183 lines
5.8 KiB
Rust
183 lines
5.8 KiB
Rust
use std::{io::Write, path::PathBuf};
|
|
|
|
use bindings::{
|
|
component::churn_tasks::process::Process, exports::component::churn_tasks::task::Guest,
|
|
};
|
|
use minijinja::{context, Environment};
|
|
|
|
#[allow(warnings)]
|
|
mod bindings;
|
|
|
|
const ALLOY_CONFIG_PATH: &str = "/etc/alloy/config.alloy";
|
|
const ALLOY_CONFIG_FILE: &str = include_str!("../files/config.alloy");
|
|
|
|
struct Component;
|
|
|
|
impl Guest for Component {
|
|
fn id() -> String {
|
|
"grafana/alloy".into()
|
|
}
|
|
|
|
fn should_run() -> bool {
|
|
let output = Process::new().run_process(
|
|
&["systemctl", "is-enabled", "alloy.service"]
|
|
.into_iter()
|
|
.map(|i| i.into())
|
|
.collect::<Vec<String>>(),
|
|
);
|
|
|
|
if !output.contains("enabled") {
|
|
println!("alloy is not enabled");
|
|
return true;
|
|
}
|
|
|
|
let output = Process::new().run_process(
|
|
&["systemctl", "is-active", "alloy.service"]
|
|
.into_iter()
|
|
.map(|i| i.into())
|
|
.collect::<Vec<String>>(),
|
|
);
|
|
|
|
if output.contains("inactive") {
|
|
println!("alloy is inactive");
|
|
return true;
|
|
}
|
|
|
|
match std::fs::read_to_string(ALLOY_CONFIG_PATH) {
|
|
Ok(content) => {
|
|
let process = Process::new();
|
|
let node_name = process.get_variable("node_name");
|
|
let config_file = generate_alloy_file(node_name);
|
|
let is_different = content != config_file;
|
|
if is_different {
|
|
println!("config file was different");
|
|
return true;
|
|
}
|
|
}
|
|
Err(e) => {
|
|
if e.kind() == std::io::ErrorKind::NotFound {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn execute() {
|
|
println!("running alloy installation");
|
|
|
|
let process = Process::new();
|
|
let node_name = process.get_variable("node_name");
|
|
|
|
let output = Process::new().run_process(
|
|
&["systemctl", "is-enabled", "alloy.service"]
|
|
.into_iter()
|
|
.map(|i| i.into())
|
|
.collect::<Vec<String>>(),
|
|
);
|
|
if !output.contains("enabled") {
|
|
install_alloy().expect("to be able to install alloy");
|
|
}
|
|
|
|
let config_file = generate_alloy_file(node_name);
|
|
let restart = match std::fs::read_to_string(ALLOY_CONFIG_PATH) {
|
|
Ok(content) => {
|
|
if content != config_file {
|
|
let mut file = std::fs::File::create(ALLOY_CONFIG_PATH)
|
|
.expect("to be able to create file");
|
|
file.write_all(config_file.as_bytes())
|
|
.expect("to be able to write file");
|
|
file.flush().expect("to be able to flush file");
|
|
true
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
Err(e) => {
|
|
if e.kind() == std::io::ErrorKind::NotFound {
|
|
if let Some(parent) = PathBuf::from(ALLOY_CONFIG_PATH).parent() {
|
|
std::fs::create_dir_all(parent)
|
|
.expect("to be able to create dir for alloy");
|
|
}
|
|
|
|
let mut file = std::fs::File::create(ALLOY_CONFIG_PATH)
|
|
.expect("to be able to create file");
|
|
file.write_all(config_file.as_bytes())
|
|
.expect("to be able to write file");
|
|
file.flush().expect("to be able to flush file");
|
|
|
|
false
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
};
|
|
|
|
if restart {
|
|
restart_alloy().expect("to be able to restart alloy");
|
|
return;
|
|
}
|
|
|
|
run_and_activate_alloy().expect("to be able to active alloy");
|
|
}
|
|
}
|
|
|
|
fn generate_alloy_file(node_name: String) -> String {
|
|
let mut env = Environment::new();
|
|
env.add_template("alloy.config", ALLOY_CONFIG_FILE).unwrap();
|
|
let tmpl = env.get_template("alloy.config").unwrap();
|
|
tmpl.render(context! {node_name => node_name}).unwrap()
|
|
}
|
|
|
|
fn install_alloy() -> Result<(), String> {
|
|
println!("=== installing alloy ===");
|
|
run_command(["apt", "install", "-y", "gpg"])?;
|
|
run_command(["mkdir", "-p", "/etc/apt/keyrings/"])?;
|
|
run_command(["bash", "-c", "wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null"])?;
|
|
run_command(["bash", "-c", "echo \"deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main\" | sudo tee /etc/apt/sources.list.d/grafana.list"])?;
|
|
run_command(["apt-get", "update"])?;
|
|
run_command([
|
|
"apt-get",
|
|
"install",
|
|
"-o Dpkg::Options::=\"--force-confdef\"",
|
|
"-o Dpkg::Options::=\"--force-confold\"",
|
|
"alloy",
|
|
])?;
|
|
println!("=== finished installing alloy ===");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn restart_alloy() -> Result<(), String> {
|
|
println!("=== restarting alloy ===");
|
|
run_command(["systemctl", "restart", "alloy"])?;
|
|
println!("=== finished restarting alloy ===");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn run_and_activate_alloy() -> Result<(), String> {
|
|
println!("=== starting alloy ===");
|
|
run_command(["systemctl", "start", "alloy"])?;
|
|
println!("=== finished starting alloy ===");
|
|
|
|
println!("=== enabling alloy ===");
|
|
run_command(["systemctl", "enable", "alloy"])?;
|
|
println!("=== finished enabling alloy ===");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn run_command(input: impl IntoIterator<Item = impl Into<String>>) -> Result<(), String> {
|
|
let args = input.into_iter().map(|i| i.into()).collect::<Vec<String>>();
|
|
|
|
println!("running {}", args.join(" "));
|
|
let output = Process::new().run_process(&args);
|
|
println!("output: {}", output);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
bindings::export!(Component with_types_in bindings);
|