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.

cleanup interactive run_command_with_env a bit

+51 -39
+51 -39
wire/lib/src/commands/interactive.rs
··· 6 6 poll::{PollFd, PollFlags, PollTimeout, poll}, 7 7 unistd::{pipe as posix_pipe, read as posix_read, write as posix_write}, 8 8 }; 9 - use portable_pty::{NativePtySystem, PtySize}; 9 + use portable_pty::{CommandBuilder, NativePtySystem, PtyPair, PtySize}; 10 10 use rand::distr::Alphabetic; 11 11 use std::collections::VecDeque; 12 12 use std::fmt::Debug; ··· 113 113 }) 114 114 } 115 115 116 - #[allow(clippy::too_many_lines)] 117 116 #[instrument(level = "trace", skip_all, name = "run", fields(elevated = %arguments.elevated))] 118 117 fn run_command_with_env<S: AsRef<str> + Debug>( 119 118 &mut self, ··· 129 128 130 129 let pty_system = NativePtySystem::default(); 131 130 let pty_pair = portable_pty::PtySystem::openpty(&pty_system, PtySize::default()).unwrap(); 132 - 133 - if let Some(fd) = pty_pair.master.as_raw_fd() { 134 - // convert raw fd to a BorrowedFd 135 - // safe as `fd` is dropped well before `pty_pair.master` 136 - let fd = unsafe { std::os::unix::io::BorrowedFd::borrow_raw(fd) }; 137 - let mut termios = tcgetattr(fd) 138 - .map_err(|x| HiveLibError::CommandError(CommandError::TermAttrs(x)))?; 139 - 140 - termios.local_flags &= !LocalFlags::ECHO; 141 - // Key agent does not work well without canonical mode 142 - termios.local_flags &= !LocalFlags::ICANON; 143 - // Actually quit 144 - termios.local_flags &= !LocalFlags::ISIG; 145 - 146 - tcsetattr(fd, SetArg::TCSANOW, &termios) 147 - .map_err(|x| HiveLibError::CommandError(CommandError::TermAttrs(x)))?; 148 - } 131 + setup_master(&pty_pair)?; 149 132 150 133 let command_string = &format!( 151 134 "echo '{start}' && {command} {flags} {IO_SUBS} && echo '{succeed}' || echo '{failed}'", ··· 161 144 162 145 debug!("{command_string}"); 163 146 164 - let mut command = if let Some(target) = self.target { 165 - let mut command = create_sync_ssh_command(target, self.modifiers)?; 166 - 167 - // force ssh to use our pesudo terminal 168 - command.arg("-tt"); 169 - 170 - command 171 - } else { 172 - let mut command = portable_pty::CommandBuilder::new("sh"); 173 - 174 - command.arg("-c"); 175 - 176 - command 177 - }; 178 - 179 - if arguments.elevated { 180 - command.arg(format!("sudo -u root -- sh -c '{command_string}'")); 181 - } else { 182 - command.arg(command_string); 183 - } 147 + let mut command = build_command(&arguments.command_string, self.target, arguments.elevated, self.modifiers)?; 184 148 185 149 // give command all env vars 186 150 for (key, value) in envs { ··· 274 238 stdout_handle, 275 239 }) 276 240 } 241 + } 242 + 243 + fn setup_master(pty_pair: &PtyPair) -> Result<(), HiveLibError> { 244 + if let Some(fd) = pty_pair.master.as_raw_fd() { 245 + // convert raw fd to a BorrowedFd 246 + // safe as `fd` is dropped well before `pty_pair.master` 247 + let fd = unsafe { std::os::unix::io::BorrowedFd::borrow_raw(fd) }; 248 + let mut termios = tcgetattr(fd) 249 + .map_err(|x| HiveLibError::CommandError(CommandError::TermAttrs(x)))?; 250 + 251 + termios.local_flags &= !LocalFlags::ECHO; 252 + // Key agent does not work well without canonical mode 253 + termios.local_flags &= !LocalFlags::ICANON; 254 + // Actually quit 255 + termios.local_flags &= !LocalFlags::ISIG; 256 + 257 + tcsetattr(fd, SetArg::TCSANOW, &termios) 258 + .map_err(|x| HiveLibError::CommandError(CommandError::TermAttrs(x)))?; 259 + } 260 + 261 + Ok(()) 262 + 263 + } 264 + 265 + fn build_command<S: AsRef<str>>(original_command: &S, target: Option<&Target>, elevated: bool, modifiers: SubCommandModifiers) -> Result<CommandBuilder, HiveLibError> { 266 + let mut command = if let Some(target) = target { 267 + let mut command = create_sync_ssh_command(target, modifiers)?; 268 + 269 + // force ssh to use our pesudo terminal 270 + command.arg("-tt"); 271 + 272 + command 273 + } else { 274 + let mut command = portable_pty::CommandBuilder::new("sh"); 275 + 276 + command.arg("-c"); 277 + 278 + command 279 + }; 280 + 281 + if elevated { 282 + command.arg(format!("sudo -u root -- sh -c '{}'", original_command.as_ref())); 283 + } else { 284 + command.arg(original_command.as_ref()); 285 + } 286 + 287 + Ok(command) 288 + 277 289 } 278 290 279 291 impl CompletionStatus {