ALPHA: wire is a tool to deploy nixos systems wire.althaea.zone/
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

CommandArguments builder pattern

+127 -110
+3 -19
wire/lib/src/commands/common.rs
··· 9 9 use crate::{ 10 10 EvalGoal, SubCommandModifiers, 11 11 commands::{ 12 - ChildOutputMode, CommandArguments, Either, WireCommandChip, run_command, 12 + CommandArguments, Either, WireCommandChip, run_command, 13 13 run_command_with_env, 14 14 }, 15 15 errors::HiveLibError, ··· 38 38 ); 39 39 40 40 let child = run_command_with_env( 41 - &CommandArguments { 42 - target: None, 43 - output_mode: ChildOutputMode::Nix, 44 - modifiers, 45 - command_string, 46 - keep_stdin_open: false, 47 - elevated: false, 48 - clobber_lock, 49 - }, 41 + &CommandArguments::new(command_string, modifiers, clobber_lock).nix(), 50 42 HashMap::from([("NIX_SSHOPTS".into(), node.target.create_ssh_opts(modifiers))]), 51 43 )?; 52 44 ··· 103 95 }, 104 96 ); 105 97 106 - let child = run_command(&CommandArguments { 107 - target: None, 108 - output_mode: ChildOutputMode::Nix, 109 - modifiers, 110 - command_string, 111 - keep_stdin_open: false, 112 - elevated: false, 113 - clobber_lock, 114 - })?; 98 + let child = run_command(&CommandArguments::new(command_string, modifiers, clobber_lock).nix())?; 115 99 116 100 child 117 101 .wait_till_success()
+7 -1
wire/lib/src/commands/interactive.rs
··· 69 69 stdout_collection: Arc<Mutex<VecDeque<String>>>, 70 70 completion_status: Arc<CompletionStatus>, 71 71 span: Span, 72 + log_stdout: bool 72 73 } 73 74 74 75 /// the underlying command began ··· 154 155 stdout_collection: stdout_collection.clone(), 155 156 completion_status: completion_status.clone(), 156 157 span: Span::current(), 158 + log_stdout: arguments.log_stdout 157 159 }; 158 160 159 161 std::thread::spawn(move || dynamic_watch_sudo_stdout(arguments)) ··· 394 396 stdout_collection, 395 397 stderr_collection, 396 398 completion_status, 399 + log_stdout, 397 400 .. 398 401 } = arguments; 399 402 ··· 431 434 432 435 if began { 433 436 if let Some(stripped) = line.strip_prefix('#') { 434 - output_mode.trace(&stripped.to_string()); 437 + if log_stdout { 438 + output_mode.trace(&stripped.to_string()); 439 + } 440 + 435 441 let mut queue = stdout_collection.lock().unwrap(); 436 442 queue.push_front(stripped.to_string()); 437 443 continue;
+52 -7
wire/lib/src/commands/mod.rs
··· 38 38 39 39 #[derive(Debug)] 40 40 pub(crate) struct CommandArguments<'t, S: AsRef<str>> { 41 - pub(crate) modifiers: SubCommandModifiers, 42 - pub(crate) target: Option<&'t Target>, 43 - pub(crate) output_mode: ChildOutputMode, 44 - pub(crate) command_string: S, 45 - pub(crate) keep_stdin_open: bool, 46 - pub(crate) elevated: bool, 47 - pub(crate) clobber_lock: Arc<Mutex<()>>, 41 + modifiers: SubCommandModifiers, 42 + target: Option<&'t Target>, 43 + output_mode: ChildOutputMode, 44 + command_string: S, 45 + keep_stdin_open: bool, 46 + elevated: bool, 47 + clobber_lock: Arc<Mutex<()>>, 48 + log_stdout: bool 49 + } 50 + 51 + impl<'a, S: AsRef<str>> CommandArguments<'a, S> { 52 + pub(crate) fn new( 53 + command_string: S, 54 + modifiers: SubCommandModifiers, 55 + clobber_lock: Arc<Mutex<()>>, 56 + ) -> Self { 57 + Self { 58 + command_string, 59 + keep_stdin_open: false, 60 + elevated: false, 61 + log_stdout: false, 62 + target: None, 63 + output_mode: ChildOutputMode::Raw, 64 + modifiers, 65 + clobber_lock, 66 + } 67 + } 68 + 69 + pub(crate) fn on_target(mut self, target: Option<&'a Target>) -> Self { 70 + self.target = target; 71 + self 72 + } 73 + 74 + pub(crate) fn nix(mut self) -> Self { 75 + self.output_mode = ChildOutputMode::Nix; 76 + self 77 + } 78 + 79 + pub(crate) fn keep_stdin_open(mut self) -> Self { 80 + self.keep_stdin_open = true; 81 + self 82 + } 83 + 84 + pub(crate) fn elevated(mut self) -> Self { 85 + self.elevated = true; 86 + self 87 + } 88 + 89 + pub(crate) fn log_stdout(mut self) -> Self { 90 + self.log_stdout = true; 91 + self 92 + } 48 93 } 49 94 50 95 pub(crate) fn run_command<S: AsRef<str>>(
+16 -9
wire/lib/src/commands/noninteractive.rs
··· 7 7 sync::Arc, 8 8 }; 9 9 10 + use crate::{ 11 + SubCommandModifiers, 12 + commands::{ChildOutputMode, CommandArguments, WireCommandChip}, 13 + errors::{CommandError, HiveLibError}, 14 + hive::node::Target, 15 + nix_log::{SubcommandLog, get_errorish_message}, 16 + }; 10 17 use itertools::Itertools; 11 18 use tokio::{ 12 19 io::{AsyncWriteExt, BufReader}, ··· 16 23 }; 17 24 use tracing::{debug, instrument, trace}; 18 25 19 - use crate::{ 20 - SubCommandModifiers, 21 - commands::{ChildOutputMode, CommandArguments, WireCommandChip}, 22 - errors::{CommandError, HiveLibError}, 23 - hive::node::Target, 24 - nix_log::{SubcommandLog, get_errorish_message}, 25 - }; 26 - 27 26 pub(crate) struct NonInteractiveChildChip { 28 27 error_collection: Arc<Mutex<VecDeque<String>>>, 29 28 stdout_collection: Arc<Mutex<VecDeque<String>>>, ··· 95 94 output_mode.clone(), 96 95 error_collection.clone(), 97 96 true, 97 + true 98 98 )); 99 99 joinset.spawn(handle_io( 100 100 stdout_handle, 101 101 output_mode.clone(), 102 102 stdout_collection.clone(), 103 103 false, 104 + arguments.log_stdout 104 105 )); 105 106 106 107 Ok(NonInteractiveChildChip { ··· 151 152 } 152 153 } 153 154 155 + #[instrument(skip_all, name = "log")] 154 156 pub async fn handle_io<R>( 155 157 reader: R, 156 158 output_mode: Arc<ChildOutputMode>, 157 159 collection: Arc<Mutex<VecDeque<String>>>, 158 160 is_error: bool, 161 + should_log: bool 159 162 ) where 160 163 R: tokio::io::AsyncRead + Unpin, 161 164 { 162 165 let mut io_reader = tokio::io::AsyncBufReadExt::lines(BufReader::new(reader)); 163 166 164 167 while let Some(line) = io_reader.next_line().await.unwrap() { 165 - let log = output_mode.trace(&line); 168 + let log = if should_log { 169 + output_mode.trace(&line) 170 + } else { 171 + None 172 + }; 166 173 167 174 if !is_error { 168 175 let mut queue = collection.lock().await;
+2 -11
wire/lib/src/hive/node.rs
··· 11 11 use tracing::{Level, error, event, instrument, trace}; 12 12 13 13 use crate::SubCommandModifiers; 14 - use crate::commands::{ChildOutputMode, CommandArguments, WireCommandChip, run_command_with_env}; 14 + use crate::commands::{CommandArguments, WireCommandChip, run_command_with_env}; 15 15 use crate::errors::NetworkError; 16 16 use crate::hive::HiveLocation; 17 17 use crate::hive::steps::build::Build; ··· 204 204 store ping --store ssh://{}@{}", 205 205 self.target.user, host 206 206 ); 207 - 208 207 let output = run_command_with_env( 209 - &CommandArguments { 210 - target: None, 211 - output_mode: ChildOutputMode::Nix, 212 - modifiers, 213 - command_string, 214 - keep_stdin_open: false, 215 - elevated: false, 216 - clobber_lock, 217 - }, 208 + &CommandArguments::new(command_string, modifiers, clobber_lock).nix().log_stdout(), 218 209 HashMap::from([("NIX_SSHOPTS".into(), self.target.create_ssh_opts(modifiers))]), 219 210 )?; 220 211
+30 -37
wire/lib/src/hive/steps/activate.rs
··· 7 7 8 8 use crate::{ 9 9 HiveLibError, 10 - commands::{ChildOutputMode, CommandArguments, WireCommandChip, run_command}, 10 + commands::{CommandArguments, WireCommandChip, run_command}, 11 11 errors::{ActivationError, NetworkError}, 12 12 hive::node::{Context, ExecuteStep, Goal, SwitchToConfigurationGoal, should_apply_locally}, 13 13 }; ··· 49 49 50 50 let command_string = format!("nix-env -p /nix/var/nix/profiles/system/ --set {built_path}"); 51 51 52 - let child = run_command(&CommandArguments { 53 - target: if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) { 54 - None 55 - } else { 56 - Some(&ctx.node.target) 57 - }, 58 - output_mode: ChildOutputMode::Nix, 59 - modifiers: ctx.modifiers, 60 - command_string, 61 - keep_stdin_open: false, 62 - elevated: true, 63 - clobber_lock: ctx.clobber_lock.clone(), 64 - })?; 52 + let child = run_command( 53 + &CommandArguments::new(command_string, ctx.modifiers, ctx.clobber_lock.clone()) 54 + .nix() 55 + .on_target( 56 + if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) { 57 + None 58 + } else { 59 + Some(&ctx.node.target) 60 + }, 61 + ) 62 + .elevated(), 63 + )?; 65 64 66 65 let _ = child 67 66 .wait_till_success() ··· 105 104 } 106 105 ); 107 106 108 - let child = run_command(&CommandArguments { 109 - target: if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) 110 - { 111 - None 112 - } else { 113 - Some(&ctx.node.target) 114 - }, 115 - output_mode: ChildOutputMode::Raw, 116 - modifiers: ctx.modifiers, 117 - command_string, 118 - keep_stdin_open: false, 119 - elevated: true, 120 - clobber_lock: ctx.clobber_lock.clone(), 121 - })?; 107 + let child = run_command( 108 + &CommandArguments::new(command_string, ctx.modifiers, ctx.clobber_lock.clone()) 109 + .on_target( 110 + if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) 111 + { 112 + None 113 + } else { 114 + Some(&ctx.node.target) 115 + }, 116 + ) 117 + .elevated().log_stdout(), 118 + )?; 122 119 123 120 let result = child.wait_till_success().await; 124 121 ··· 136 133 137 134 warn!("Rebooting {name}!", name = ctx.name); 138 135 139 - let reboot = run_command(&CommandArguments { 140 - target: Some(&ctx.node.target), 141 - output_mode: ChildOutputMode::Nix, 142 - modifiers: ctx.modifiers, 143 - command_string: "reboot now", 144 - keep_stdin_open: false, 145 - elevated: true, 146 - clobber_lock: ctx.clobber_lock.clone(), 147 - })?; 136 + let reboot = run_command( 137 + &CommandArguments::new("reboot now", ctx.modifiers, ctx.clobber_lock.clone()).log_stdout() 138 + .on_target(Some(&ctx.node.target)) 139 + .elevated(), 140 + )?; 148 141 149 142 // consume result, impossible to know if the machine failed to reboot or we 150 143 // simply disconnected
+3 -11
wire/lib/src/hive/steps/build.rs
··· 7 7 8 8 use crate::{ 9 9 HiveLibError, 10 - commands::{ChildOutputMode, CommandArguments, Either, WireCommandChip, run_command_with_env}, 10 + commands::{CommandArguments, Either, WireCommandChip, run_command_with_env}, 11 11 hive::node::{Context, ExecuteStep, Goal}, 12 12 }; 13 13 ··· 35 35 ); 36 36 37 37 let status = run_command_with_env( 38 - &CommandArguments { 39 - target: if ctx.node.build_remotely { 38 + &CommandArguments::new(command_string, ctx.modifiers, ctx.clobber_lock.clone()).on_target(if ctx.node.build_remotely { 40 39 Some(&ctx.node.target) 41 40 } else { 42 41 None 43 - }, 44 - output_mode: ChildOutputMode::Nix, 45 - modifiers: ctx.modifiers, 46 - command_string, 47 - keep_stdin_open: false, 48 - elevated: false, 49 - clobber_lock: ctx.clobber_lock.clone(), 50 - }, 42 + }).nix().log_stdout(), 51 43 std::collections::HashMap::new(), 52 44 )? 53 45 .wait_till_success()
+14 -15
wire/lib/src/hive/steps/keys.rs
··· 24 24 25 25 use crate::HiveLibError; 26 26 use crate::commands::common::push; 27 - use crate::commands::{ChildOutputMode, CommandArguments, WireCommandChip, run_command}; 27 + use crate::commands::{CommandArguments, WireCommandChip, run_command}; 28 28 use crate::errors::KeyError; 29 29 use crate::hive::node::{ 30 30 Context, ExecuteStep, Goal, Push, SwitchToConfigurationGoal, should_apply_locally, ··· 235 235 236 236 let command_string = format!("{agent_directory}/bin/key_agent"); 237 237 238 - let mut child = run_command(&CommandArguments { 239 - target: if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) 240 - { 241 - None 242 - } else { 243 - Some(&ctx.node.target) 244 - }, 245 - output_mode: ChildOutputMode::Raw, 246 - modifiers: ctx.modifiers, 247 - command_string, 248 - keep_stdin_open: true, 249 - elevated: true, 250 - clobber_lock: ctx.clobber_lock.clone(), 251 - })?; 238 + let mut child = run_command( 239 + &CommandArguments::new(command_string, ctx.modifiers, ctx.clobber_lock.clone()) 240 + .on_target( 241 + if should_apply_locally(ctx.node.allow_local_deployment, &ctx.name.to_string()) 242 + { 243 + None 244 + } else { 245 + Some(&ctx.node.target) 246 + }, 247 + ) 248 + .elevated() 249 + .keep_stdin_open().log_stdout(), 250 + )?; 252 251 253 252 let mut writer = SimpleLengthDelimWriter::new(async |data| child.write_stdin(data).await); 254 253