allow setting args and current_dir

and this is as far as we will get
This commit is contained in:
lda
2026-07-16 18:07:37 +07:00 Verified
parent e1ae88f967
commit b459019085
4 changed files with 60 additions and 7 deletions
+28
View File
@@ -45,6 +45,10 @@ pub struct TerminalConfig {
pub enabled: bool,
#[serde(default = "default_terminal_shell")]
pub shell: PathBuf,
#[serde(default)]
pub args: Vec<String>,
#[serde(default)]
pub current_dir: Option<PathBuf>,
#[serde(default = "default_terminal_max_sessions")]
pub max_sessions: usize,
}
@@ -54,6 +58,8 @@ impl Default for TerminalConfig {
Self {
enabled: false,
shell: default_terminal_shell(),
args: Vec::new(),
current_dir: None,
max_sessions: default_terminal_max_sessions(),
}
}
@@ -249,6 +255,8 @@ mod tests {
terminal: TerminalConfig {
enabled: true,
shell: "/bin/sh".into(),
args: vec!["-l".into()],
current_dir: Some("/tmp".into()),
max_sessions: 2,
},
};
@@ -284,4 +292,24 @@ agent_token = "secret"
);
assert_eq!(config.terminal, TerminalConfig::default());
}
#[test]
fn existing_terminal_config_defaults_optional_command_fields() {
let config: AgentConfig = toml::from_str(
r#"
server_url = "https://example.com"
agent_id = "agent-1"
agent_token = "secret"
[terminal]
enabled = true
shell = "/bin/sh"
max_sessions = 2
"#,
)
.expect("existing terminal config should parse");
assert!(config.terminal.args.is_empty());
assert!(config.terminal.current_dir.is_none());
}
}
+2
View File
@@ -154,6 +154,8 @@ mod tests {
terminal: crate::config::TerminalConfig {
enabled: true,
shell: "/bin/ash".into(),
args: vec!["-l".into()],
current_dir: Some("/root".into()),
max_sessions: 2,
},
};
+9 -1
View File
@@ -215,6 +215,8 @@ async fn run_terminal(
) -> Result<()> {
let terminal = match wakey::wakey_linux::terminal::TerminalPty::spawn(
Path::new(&config.terminal.shell),
&config.terminal.args,
config.terminal.current_dir.as_deref(),
rows,
cols,
) {
@@ -225,7 +227,13 @@ async fn run_terminal(
};
let (mut reader, mut writer, mut child) = terminal.into_parts();
let process_group = child.id();
info!(terminal_id = %terminal_id, shell = %config.terminal.shell.display(), "terminal PTY ready");
info!(
terminal_id = %terminal_id,
program = %config.terminal.shell.display(),
args = ?config.terminal.args,
current_dir = ?config.terminal.current_dir,
"terminal PTY ready"
);
let (relay_input_tx, mut relay_input_rx) = mpsc::channel(RELAY_INPUT_QUEUE);
let mut relay_output: Option<mpsc::Sender<Message>> = None;
+21 -6
View File
@@ -27,8 +27,18 @@ pub struct TerminalWriter {
}
impl TerminalPty {
/// Starts `program` attached to a newly allocated PTY.
pub fn spawn(program: &Path, rows: u16, cols: u16) -> Result<Self> {
/// Starts a configured program attached to a newly allocated PTY.
///
/// Wakey retains control of the PTY streams, terminal environment, and
/// kill-on-drop behavior; callers may only select arguments and a working
/// directory.
pub fn spawn(
program: &Path,
args: &[String],
current_dir: Option<&Path>,
rows: u16,
cols: u16,
) -> Result<Self> {
let (pty, pts) = pty_process::open().context("failed to open PTY")?;
pty.resize(Size::new(rows, cols))
.context("failed to set initial PTY size")?;
@@ -39,10 +49,14 @@ impl TerminalPty {
// The remote frontend is xterm.js regardless of the daemon's own
// environment, so advertise the terminal the child actually receives.
let command = Command::new(program)
let mut command = Command::new(program)
.args(args)
.env("TERM", "xterm-256color")
.env("COLORTERM", "truecolor")
.kill_on_drop(true);
if let Some(current_dir) = current_dir {
command = command.current_dir(current_dir);
}
let child = command
.spawn(pts)
.with_context(|| format!("failed to spawn {} in PTY", program.display()))?;
@@ -116,9 +130,10 @@ mod tests {
#[tokio::test]
#[ignore = "live system check, requires PTY and shell"]
async fn pty_round_trip_and_resize() {
let (mut reader, mut writer, mut child) = TerminalPty::spawn(Path::new("/bin/sh"), 24, 80)
.expect("spawn PTY shell")
.into_parts();
let (mut reader, mut writer, mut child) =
TerminalPty::spawn(Path::new("/bin/sh"), &[], None, 24, 80)
.expect("spawn PTY shell")
.into_parts();
writer.resize(31, 101).expect("resize owned PTY writer");
// Print the size from the parent shell after `stty` exits, so observing