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

difftreelog

feat fleet tf now executes terraform by itself

Yaroslav Bolyukin2024-09-01parent: #87c4900.patch.diff
in: trunk

3 files changed

modifiedcmds/fleet/src/cmds/tf.rsdiffbeforeafterboth
1use std::{1use std::{
2 collections::{BTreeMap, HashMap},2 collections::{BTreeMap, HashMap},
3 ffi::OsString,
3 path::PathBuf,4 path::PathBuf,
4};5};
56
6use anyhow::{bail, Context, Result};7use anyhow::{Context, Result};
7use clap::Parser;8use clap::Parser;
8use fleet_base::host::Config;9use fleet_base::host::Config;
9use nix_eval::nix_go;10use nix_eval::nix_go;
10use serde::Deserialize;11use serde::Deserialize;
11use serde_json::Value;12use serde_json::Value;
13use tempfile::NamedTempFile;
12use tokio::{fs::copy, process::Command};14use tokio::{
15 fs::{self, create_dir_all},
16 process::Command,
17};
18use tracing::debug;
1319
14#[derive(Deserialize)]20#[derive(Deserialize, Debug)]
15pub struct TfData {21pub struct TfData {
16 // Dummy22 // Dummy
17 #[allow(dead_code)]23 #[allow(dead_code)]
23}29}
2430
25#[derive(Parser)]31#[derive(Parser)]
26pub enum Tf {32pub struct Tf {
27 /// Generate fleet.tf.json file for running terraform.33 args: Vec<OsString>,
28 Generate,
29 /// Fetch data from terraform to fleet.
30 Refresh,
31}34}
32impl Tf {35impl Tf {
33 pub async fn run(&self, config: &Config) -> Result<()> {36 pub async fn run(&self, config: &Config) -> Result<()> {
34 match self {37 let dir = config.directory.join(".fleet/tf/default");
35 Tf::Generate => {38 // TODO: consider postponing fleet init until this step, as it might be
39 // highly preferred to extract terraform configuration using multithreaded nix or
40 // lazy-trees nix. lazy-trees nix is very fast and perfect for this task.
41 {
42 debug!("generating terraform configs");
36 let system = &config.local_system;43 let system = &config.local_system;
37 let config = &config.config_field;44 let config = &config.config_field;
38 let data: HashMap<String, PathBuf> = nix_go!(config.tf({ system })).build().await?;45 let data: HashMap<String, PathBuf> = nix_go!(config.tf({ system })).build().await?;
39 let data = &data["out"];46 let data = &data["out"];
4047 let data = fs::read(&data).await?;
48
49 create_dir_all(&dir).await?;
50
51 let tmp = NamedTempFile::new_in(&dir)?;
52 fs::write(tmp.path(), data).await?;
53 tmp.persist(dir.join("fleet.tf.json"))?;
54 }
55
56 {
57 debug!("running terraform command");
41 copy(data, "fleet.tf.json").await?;58 Command::new("terraform")
42 }59 .current_dir(&dir)
43 Tf::Refresh => {60 .args(&self.args)
61 .status()
44 let cmd = Command::new("terraform").arg("refresh").status().await?;62 .await?;
45 if !cmd.success() {63 }
64 {
46 bail!("terraform refresh failed")65 debug!("syncing terraform data");
47 }
48
49 let data = Command::new("terraform")66 let data = Command::new("terraform")
50 .arg("output")67 .current_dir(dir)
51 .arg("-json")68 .arg("output")
52 .arg("fleet")69 .arg("-json")
53 .output()70 .arg("fleet")
54 .await?;71 .output()
72 .await?;
55 let tf_data: TfData = serde_json::from_slice(&data.stdout)73 let tf_data: TfData = serde_json::from_slice(&data.stdout)
56 .context("failed to parse terraform fleet output")?;74 .context("failed to parse terraform fleet output")?;
5775
58 let mut data = config.data();76 let mut data = config.data();
77 debug!("synchronized done = {tf_data:?}");
59 data.extra.insert(78 data.extra.insert(
60 "terraformHosts".to_owned(),79 "terraformHosts".to_owned(),
61 serde_json::to_value(tf_data.hosts).expect("should be valid extra"),80 serde_json::to_value(tf_data.hosts).expect("should be valid extra"),
62 );81 );
63 }82 }
64 }
6583
66 Ok(())84 Ok(())
67 }85 }
modifiedcmds/fleet/src/main.rsdiffbeforeafterboth
82 #[clap(hide(true))]82 #[clap(hide(true))]
83 Complete(Complete),83 Complete(Complete),
84 /// Compile and evaluate terranix configuration84 /// Compile and evaluate terranix configuration
85 #[clap(subcommand)]
86 Tf(Tf),85 Tf(Tf),
87}86}
8887
addedcmds/terraform-provider-fleet/Cargo.tomldiffbeforeafterboth

no changes