greentic-operator 0.4.43

Greentic operator CLI for local dev and demo orchestration.
Documentation
use std::path::{Path, PathBuf};

use std::hash::{Hash, Hasher};
use std::str::FromStr;

use super::runner::{ProcessStatus, ServiceState, log_path, pid_path};

const NATS_CONTAINER_PREFIX: &str = "greentic-operator-nats";

pub fn start_nats(root: &Path) -> anyhow::Result<ServiceState> {
    start_nats_with_log(root, None)
}

pub fn start_nats_with_log(
    root: &Path,
    log_path_override: Option<PathBuf>,
) -> anyhow::Result<ServiceState> {
    let port = nats_port(root);
    let pid = pid_path(root, "nats");
    let log = log_path_override.unwrap_or_else(|| log_path(root, "nats"));
    let container = container_name(root);
    let args = vec![
        "run".to_string(),
        "--rm".to_string(),
        "--name".to_string(),
        container,
        "-p".to_string(),
        format!("{port}:{port}"),
        "nats:2".to_string(),
        "-js".to_string(),
    ];
    super::runner::start_process("docker", &args, &[], &pid, &log, Some(root))
}

pub fn stop_nats(root: &Path) -> anyhow::Result<ServiceState> {
    let pid = pid_path(root, "nats");
    super::runner::stop_process(&pid)
}

pub fn nats_status(root: &Path) -> anyhow::Result<ProcessStatus> {
    let pid = pid_path(root, "nats");
    super::runner::process_status(&pid)
}

pub fn tail_nats_logs(root: &Path) -> anyhow::Result<()> {
    let log = log_path(root, "nats");
    super::runner::tail_log(&log)
}

pub fn nats_url(root: &Path) -> String {
    format!("nats://127.0.0.1:{}", nats_port(root))
}

fn container_name(root: &Path) -> String {
    let mut hasher = std::collections::hash_map::DefaultHasher::new();
    let mut identity = root.to_path_buf();
    if let Ok(canonical) = root.canonicalize() {
        identity = canonical;
    }
    identity.to_string_lossy().hash(&mut hasher);
    let hash = hasher.finish();
    format!("{NATS_CONTAINER_PREFIX}-{hash:08x}")
}

fn nats_port(root: &Path) -> u16 {
    if let Ok(value) = std::env::var("GREENTIC_OPERATOR_NATS_PORT")
        && let Ok(port) = u16::from_str(&value)
    {
        return port;
    }
    let mut hasher = std::collections::hash_map::DefaultHasher::new();
    let mut identity = root.to_path_buf();
    if let Ok(canonical) = root.canonicalize() {
        identity = canonical;
    }
    identity.to_string_lossy().hash(&mut hasher);
    let hash = hasher.finish();
    4222 + (hash % 1000) as u16
}