Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ echo
read -p "Install systemd service? (y/N) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
cat > /tmp/guestkit-worker.service <<'EOF'
UNIT_TMP="$(mktemp)"
trap 'rm -f "$UNIT_TMP"' EXIT
cat > "$UNIT_TMP" <<EOF
[Unit]
Description=Guestkit Worker Daemon
After=network.target
Expand All @@ -62,7 +64,7 @@ After=network.target
Type=simple
User=nobody
Group=nobody
ExecStart=/usr/local/bin/guestkit-worker daemon --transport http
ExecStart=$INSTALL_DIR/guestkit-worker daemon --transport http
Restart=always
RestartSec=10

Expand All @@ -77,7 +79,7 @@ ReadWritePaths=/tmp/guestkit-worker
WantedBy=multi-user.target
EOF

$SUDO cp /tmp/guestkit-worker.service "$SYSTEMD_DIR/guestkit-worker.service"
$SUDO cp "$UNIT_TMP" "$SYSTEMD_DIR/guestkit-worker.service"
$SUDO systemctl daemon-reload

echo "✓ Systemd service installed"
Expand Down
35 changes: 34 additions & 1 deletion src/agent/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ use base64::{engine::general_purpose::STANDARD, Engine};
use serde_json::{json, Value};
use std::process::{Command, Stdio};

/// Exit code of a finished process. A process killed by a signal has no exit
/// code; report the shell convention 128+signal instead of a generic 1.
fn exit_code(status: &std::process::ExitStatus) -> i64 {
if let Some(c) = status.code() {
return c as i64;
}
#[cfg(unix)]
{
use std::os::unix::process::ExitStatusExt;
if let Some(sig) = status.signal() {
return 128 + sig as i64;
}
}
1
}

/// Run a command synchronously and return exit code + stdout/stderr.
pub fn exec_sync(args: &Value) -> Result<Value, String> {
let path = args
Expand All @@ -27,7 +43,7 @@ pub fn exec_sync(args: &Value) -> Result<Value, String> {

Ok(json!({
"exited": true,
"exitcode": output.status.code().unwrap_or(1),
"exitcode": exit_code(&output.status),
"stdout": String::from_utf8_lossy(&output.stdout),
"stderr": String::from_utf8_lossy(&output.stderr),
}))
Expand All @@ -52,3 +68,20 @@ pub fn exec_sync_qga(args: &Value) -> Result<Value, String> {
}
Ok(ret)
}

#[cfg(all(test, unix))]
mod tests {
use super::*;

#[test]
fn signal_killed_process_reports_128_plus_signal() {
let r = exec_sync(&json!({"path": "/bin/sh", "arg": ["-c", "kill -9 $$"]})).unwrap();
assert_eq!(r["exitcode"], 137);
}

#[test]
fn normal_exit_code_is_preserved() {
let r = exec_sync(&json!({"path": "/bin/sh", "arg": ["-c", "exit 3"]})).unwrap();
assert_eq!(r["exitcode"], 3);
}
}
Loading