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

difftreelog

feat test/boot/switch actions

Yaroslav Bolyukin2020-11-30parent: #8aa3354.patch.diff
in: trunk

1 file changed

modifiedsrc/cmds/build_systems.rsdiffbeforeafterboth
before · src/cmds/build_systems.rs
1use std::process::Command;23use crate::{4	command::CommandExt,5	db::{keys::list_hosts, secret::SecretDb, Db, DbData},6	nix::SYSTEMS_ATTRIBUTE,7};8use anyhow::Result;9use clap::Clap;10use log::{info, warn};1112#[derive(Clap)]13pub struct BuildSystems {14	/// Hosts to skip15	#[clap(long, number_of_values = 1)]16	skip: Vec<String>,17	#[clap(subcommand)]18	subcommand: Option<Subcommand>,19}2021#[derive(Clap)]22enum Subcommand {23	/// Switch to built system until reboot24	Test,25	/// Switch to built system after reboot26	Boot,27	/// test + boot28	Switch,29}3031impl BuildSystems {32	pub fn run(self) -> Result<()> {33		let db = Db::new(".fleet")?;34		let hosts = list_hosts()?;35		let data = SecretDb::open(&db)?.generate_nix_data()?;3637		for host in hosts.iter() {38			if self.skip.contains(host) {39				warn!("Skipping host {}", host);40				continue;41			}42			info!("Building host {}", host);43			let built = tempfile::tempdir()?;44			Command::new("nix")45				.inherit_stdio()46				.arg("build")47				.arg(format!(48					"{}.{}.config.system.build.toplevel",49					SYSTEMS_ATTRIBUTE, host,50				))51				.arg("--no-link")52				.arg("--out-link")53				.arg(built.path())54				.arg("--impure")55				.env("SECRET_DATA", data.clone())56				.run()?;57			info!("Uploading system closure");58			let full_path = std::fs::canonicalize(built.path())?;59			info!("{:?}", full_path);60			Command::new("nix")61				.inherit_stdio()62				.arg("copy")63				.arg(full_path)64				.arg("--to")65				.arg(format!("ssh://root@{}", host))66				.run()?;67			match self.subcommand {68				Some(Subcommand::Test) => {69					info!("Setting system to test")70				}71				Some(Subcommand::Boot) => {72					info!("Setting system to switch on boot")73				}74				Some(Subcommand::Switch) => {75					info!("Switching to configuration")76				}77				_ => {}78			}79		}80		Ok(())81	}82}
after · src/cmds/build_systems.rs
1use std::process::Command;23use crate::{4	command::CommandExt,5	db::{keys::list_hosts, secret::SecretDb, Db, DbData},6	nix::SYSTEMS_ATTRIBUTE,7};8use anyhow::Result;9use clap::Clap;10use log::{info, warn};1112#[derive(Clap)]13pub struct BuildSystems {14	/// Hosts to skip15	#[clap(long, number_of_values = 1)]16	skip: Vec<String>,17	/// Host, which should be threaten as localhost18	#[clap(long, env = "FLEET_LOCALHOST")]19	localhost: Option<String>,20	#[clap(subcommand)]21	subcommand: Option<Subcommand>,22}2324#[derive(Clap)]25enum Subcommand {26	/// Switch to built system until reboot27	Test,28	/// Switch to built system after reboot29	Boot,30	/// test + boot31	Switch,32}33impl Subcommand {34	fn should_switch_profile(&self) -> bool {35		matches!(self, Self::Test | Self::Switch)36	}37	fn name(&self) -> &'static str {38		match self {39			Self::Test => "test",40			Self::Boot => "boot",41			Self::Switch => "switch",42		}43	}44}4546impl BuildSystems {47	pub fn run(self) -> Result<()> {48		let db = Db::new(".fleet")?;49		let hosts = list_hosts()?;50		let data = SecretDb::open(&db)?.generate_nix_data()?;5152		for host in hosts.iter() {53			if self.skip.contains(host) {54				warn!("Skipping host {}", host);55				continue;56			}57			let is_local = Some(host) == self.localhost.as_ref();58			info!("Building host {}", host);59			let built = {60				let dir = tempfile::tempdir()?;61				dir.path().to_owned()62			};6364			Command::new("nix")65				.args(&["build", "--impure", "--no-link", "--out-link"])66				.arg(&built)67				.arg(format!(68					"{}.{}.config.system.build.toplevel",69					SYSTEMS_ATTRIBUTE, host,70				))71				.env("SECRET_DATA", data.clone())72				.inherit_stdio()73				.run()?;74			let built = std::fs::canonicalize(built)?;75			info!("Built closure: {:?}", built);76			if !is_local {77				info!("Uploading system closure");78				Command::new("nix")79					.args(&["copy", "--to"])80					.arg(format!("ssh://root@{}", host))81					.arg(&built)82					.inherit_stdio()83					.run()?;84			}85			if let Some(subcommand) = &self.subcommand {86				if subcommand.should_switch_profile() {87					info!("Switching generation");88					if !is_local {89						Command::ssh_on(host, "nix-env")90					} else {91						Command::new("nix-env")92					}93					.args(&["-p", "/nix/var/nix/profiles/system", "--set"])94					.arg(&built)95					.inherit_stdio()96					.run()?;97				}98				info!("Executing activation script");99				let mut switch_script = built.clone();100				switch_script.push("bin");101				switch_script.push("switch-to-configuration");102				info!("{:?}", switch_script);103				if !is_local {104					Command::ssh_on(host, "sudo")105				} else {106					Command::new("sudo")107				}108				.arg(switch_script)109				.arg(subcommand.name())110				.inherit_stdio()111				.run()?;112			}113		}114		Ok(())115	}116}