git.delta.rocks / jrsonnet / refs/commits / 353ae3be2d27

difftreelog

source

cmds/fleet/src/main.rs3.5 KiBsourcehistory
1#![feature(try_blocks)]23pub mod cmds;4pub mod command;5pub mod host;6pub mod keys;78mod fleetdata;910use std::ffi::OsString;11use std::time::Duration;1213use anyhow::{bail, Result};14use clap::Parser;1516use cmds::{build_systems::BuildSystems, info::Info, secrets::Secrets};17use host::{Config, FleetOpts};18use indicatif::{ProgressState, ProgressStyle};19use tokio::process::Command;20use tracing::{info, metadata::LevelFilter};21use tracing_indicatif::IndicatifLayer;22use tracing_subscriber::{prelude::*, EnvFilter};2324#[derive(Parser)]25struct Prefetch {}26impl Prefetch {27	async fn run(&self, config: &Config) -> Result<()> {28		let mut prefetch_dir = config.directory.to_path_buf();29		prefetch_dir.push("prefetch");30		if !prefetch_dir.is_dir() {31			info!("nothing to prefetch: no prefetch directory");32			return Ok(());33		}34		for entry in std::fs::read_dir(&prefetch_dir)? {35			let entry = entry?;36			if !entry.metadata()?.is_file() {37				bail!("only files should exist in prefetch directory");38			}39			info!("prefetching {:?}", entry.file_name());40			let mut path = OsString::new();41			path.push("file://");42			path.push(entry.path());43			let status = Command::new("nix-prefetch-url").arg(path).status().await?;44			if !status.success() {45				bail!("failed with {status}");46			}47		}48		Ok(())49	}50}5152#[derive(Parser)]53enum Opts {54	/// Prepare systems for deployments55	BuildSystems(BuildSystems),56	/// Secret management57	#[clap(subcommand)]58	Secrets(Secrets),59	/// Upload prefetch directory to the nix store60	Prefetch(Prefetch),61	/// Config parsing62	Info(Info),63}6465#[derive(Parser)]66#[clap(version = "1.0", author)]67struct RootOpts {68	#[clap(flatten)]69	fleet_opts: FleetOpts,70	#[clap(subcommand)]71	command: Opts,72}7374async fn run_command(config: &Config, command: Opts) -> Result<()> {75	match command {76		Opts::BuildSystems(c) => c.run(config).await?,77		Opts::Secrets(s) => s.run(config).await?,78		Opts::Info(i) => i.run(config).await?,79		Opts::Prefetch(p) => p.run(config).await?,80	};81	Ok(())82}8384#[tokio::main]85async fn main() -> Result<()> {86	let indicatif_layer = IndicatifLayer::new().with_progress_style(87		ProgressStyle::with_template(88			"{color_start}{span_child_prefix} {span_name}{{{span_fields}}}{color_end} {wide_msg} {color_start}{pos:>7}/{len:7}{elapsed}{color_end}",89		)90		.unwrap()91		.with_key(92			"color_start",93			|state: &ProgressState, writer: &mut dyn std::fmt::Write| {94				let elapsed = state.elapsed();9596				if elapsed > Duration::from_secs(60) {97					// Red98					let _ = write!(writer, "\x1b[{}m", 1 + 30);99				} else if elapsed > Duration::from_secs(30) {100					// Yellow101					let _ = write!(writer, "\x1b[{}m", 3 + 30);102				}103			},104		)105		.with_key(106			"color_end",107			|state: &ProgressState, writer: &mut dyn std::fmt::Write| {108				if state.elapsed() > Duration::from_secs(30) {109					let _ = write!(writer, "\x1b[0m");110				}111			},112		),113	);114115	let filter = EnvFilter::from_default_env().add_directive(LevelFilter::INFO.into());116117	tracing_subscriber::registry()118		.with(119			tracing_subscriber::fmt::layer()120				.without_time()121				.with_target(false)122				.with_writer(indicatif_layer.get_stderr_writer())123				.with_filter(filter), // .withou,124		)125		.with(indicatif_layer)126		.init();127	info!("Starting");128	let mut os_args = std::env::args_os();129	let opts = RootOpts::parse_from((&mut os_args).take_while(|v| v != "--"));130	let config = opts.fleet_opts.build(os_args.collect()).await?;131132	match run_command(&config, opts.command).await {133		Ok(()) => {134			config.save()?;135			Ok(())136		}137		Err(e) => {138			let _ = config.save();139			Err(e)140		}141	}142}