git.delta.rocks / jrsonnet / refs/commits / d91d16dbe1e7

difftreelog

source

cmds/fleet/src/cmds/tf.rs2.0 KiBsourcehistory
1use std::{collections::BTreeMap, ffi::OsString, path::PathBuf};23use anyhow::{Context, Result};4use clap::Parser;5use fleet_base::host::Config;6use nix_eval::nix_go;7use serde::Deserialize;8use serde_json::Value;9use tempfile::NamedTempFile;10use tokio::{11	fs::{self, create_dir_all},12	process::Command,13};14use tracing::debug;1516#[derive(Deserialize, Debug)]17pub struct TfData {18	// Dummy19	#[allow(dead_code)]20	managed: bool,21	// Host => Data22	#[serde(default)]23	#[serde(skip_serializing_if = "BTreeMap::is_empty")]24	pub hosts: BTreeMap<String, Value>,25}2627#[derive(Parser)]28pub struct Tf {29	args: Vec<OsString>,30}31impl Tf {32	pub async fn run(&self, config: &Config) -> Result<()> {33		let dir = config.directory.join(".fleet/tf/default");34		// TODO: consider postponing fleet init until this step, as it might be35		// highly preferred to extract terraform configuration using multithreaded nix or36		// lazy-trees nix. lazy-trees nix is very fast and perfect for this task.37		{38			debug!("generating terraform configs");39			let system = &config.local_system;40			let config = &config.config_field;41			let data: PathBuf = nix_go!(config.tf({ system })).build("out").await?;42			let data = fs::read(&data).await?;4344			create_dir_all(&dir).await?;4546			let tmp = NamedTempFile::new_in(&dir)?;47			fs::write(tmp.path(), data).await?;48			tmp.persist(dir.join("fleet.tf.json"))?;49		}5051		{52			debug!("running terraform command");53			Command::new("terraform")54				.current_dir(&dir)55				.args(&self.args)56				.status()57				.await?;58		}59		{60			debug!("syncing terraform data");61			let data = Command::new("terraform")62				.current_dir(dir)63				.arg("output")64				.arg("-json")65				.arg("fleet")66				.output()67				.await?;68			let tf_data: TfData = serde_json::from_slice(&data.stdout)69				.context("failed to parse terraform fleet output")?;7071			let mut data = config.data();72			debug!("synchronized done = {tf_data:?}");73			data.extra.insert(74				"terraformHosts".to_owned(),75				serde_json::to_value(tf_data.hosts).expect("should be valid extra"),76			);77		}7879		Ok(())80	}81}