manager: Add os variable since hostname on macos is weird

This commit is contained in:
2024-11-04 17:07:50 +01:00
parent 9001a8f4bd
commit e0d95e3bd0
7 changed files with 318 additions and 212 deletions

View File

@ -3,16 +3,17 @@ use crate::Config;
use async_recursion::async_recursion;
use blueprint::{parse_template, Env, Value};
use futures::future::join_all;
use futures::TryFutureExt;
use std::collections::HashMap;
use std::env;
use std::ffi::OsStr;
use std::io::ErrorKind;
use std::path::PathBuf;
use std::process::Command;
use std::str::from_utf8;
use tokio::fs::{copy, create_dir, read_dir, read_to_string, File};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::join;
use tokio::process::Command;
pub const TEMPLATE_EXTENSION: &str = "tpl";
@ -20,6 +21,7 @@ pub async fn build_tree(cfg: &Config) -> Result<(), Errors> {
let mut env = Env::new();
env.insert("hostname".into(), Value::Str(get_hostname().await));
env.insert("username".into(), Value::Str(get_username()));
env.insert("os".into(), Value::Str(get_operating_system().await));
debug!("trying to read {:?}", cfg.variables_path);
if let Ok(s) = read_to_string(&cfg.variables_path).await {
@ -31,11 +33,7 @@ pub async fn build_tree(cfg: &Config) -> Result<(), Errors> {
let value = match toml_value {
toml::Value::String(s) => Value::Str(s),
toml::Value::Boolean(b) => Value::Bool(b),
_ => {
return Err(InnerError::TypeErr
.with_location(&cfg.variables_path)
.into())
}
_ => return Err(InnerError::Type.with_location(&cfg.variables_path).into()),
};
env.insert(key, value);
@ -170,26 +168,38 @@ fn get_username() -> String {
env::var("USER")
.ok()
.or_else(|| env::var("USERNAME").ok())
.unwrap_or_else(String::new)
.unwrap_or_default()
}
async fn get_hostname() -> String {
async fn read_hostname_file() -> Option<String> {
read_to_string("/etc/hostname").await.ok()
async fn read_hostname_file() -> eyre::Result<String> {
Ok(read_to_string("/etc/hostname").await?)
}
// TODO: should be async
fn run_hostname_cmd() -> Option<String> {
async fn run_hostname_cmd() -> eyre::Result<String> {
Command::new("hostname")
.output()
.ok()
.and_then(|out| from_utf8(&out.stdout).ok().map(str::to_string))
.await
.map_err(Into::into)
.and_then(|out| Ok(from_utf8(&out.stdout).map(str::to_string)?))
}
read_hostname_file()
.or_else(|_| run_hostname_cmd())
.await
.or_else(run_hostname_cmd)
.unwrap_or_else(String::new)
.unwrap_or(String::new())
.trim()
.to_string()
}
async fn get_operating_system() -> String {
Command::new("uname")
.output()
.await
.ok()
.as_ref()
.and_then(|out| from_utf8(&out.stdout).ok())
.unwrap_or("unknown")
.trim()
.to_lowercase()
}

View File

@ -15,16 +15,16 @@ pub struct Error {
#[derive(Debug, Error)]
pub enum InnerError {
#[error("IO Error: {0}")]
IoErr(#[from] io::Error),
Io(#[from] io::Error),
#[error("Failed to parse template file")]
TemplateErr(#[from] blueprint::Error),
Template(#[from] blueprint::Error),
#[error("Failed to parse toml file")]
TomlErr(#[from] toml::de::Error),
Toml(#[from] toml::de::Error),
#[error("Unsupported variable type")]
TypeErr,
Type,
}
impl From<Vec<Error>> for Errors {

View File

@ -10,7 +10,7 @@ use builder::build_tree;
use error::Errors;
use linker::link_tree;
use log::LevelFilter;
use peeker::peek_tree;
use peeker::print_variables;
use std::env;
use std::path::PathBuf;
use structopt::StructOpt;
@ -88,8 +88,8 @@ async fn run() -> Result<(), Errors> {
};
if opt.print_variables {
info!("peeking tree");
peek_tree(&cfg).await?;
info!("scanning tree");
print_variables(&cfg).await?;
} else {
info!("building tree");
build_tree(&cfg).await?;

View File

@ -9,7 +9,8 @@ use std::path::PathBuf;
use tokio::fs::{read_dir, read_to_string};
use tokio::join;
pub async fn peek_tree(cfg: &Config) -> Result<(), Errors> {
/// Iterate over the directory tree and print all variables used in all template files.
pub async fn print_variables(cfg: &Config) -> Result<(), Errors> {
for var in dir(cfg, PathBuf::new()).await? {
println!("{}", var);
}