fix(installer): make apt installs noninteractive

This commit is contained in:
Peter Steinberger
2026-04-26 06:23:33 +01:00
parent 58a31b12f7
commit af8648e00e
3 changed files with 62 additions and 16 deletions

View File

@@ -94,6 +94,7 @@ Docs: https://docs.openclaw.ai
- Gateway/update: fail package updates when the restarted managed gateway reports the wrong version, avoiding false-success mixed-version restarts after macOS LaunchAgent updates. Fixes #71835. Thanks @abhinas90 and @jsompis.
- Plugins/runtime deps: surface activated plugin load failures in health and fail package-update restart verification or doctor repair when bundled runtime deps still cannot load, avoiding false-success repairs. (#71883) Thanks @Solvely-Colin.
- Gateway/Linux: include fnm `aliases/default/bin` in generated service PATHs and let doctor accept either modern fnm aliases or the legacy `current/bin` symlink, avoiding false PATH repair prompts. Fixes #68169. Thanks @richard-scott.
- Installer/Linux: run apt installs with noninteractive dpkg and needrestart settings so fresh Ubuntu 24.04 `curl | bash` installs do not hang while installing Node.js, Git, or build tools. Fixes #41146. Thanks @iht76, @alexcarv318, @cs3gallery, @firofame, and @cgdusek.
- WhatsApp: remove ack reactions after a visible reply when `messages.removeAckAfterReply` is enabled, matching other reaction-capable channels. Fixes #26183. Thanks @MrUnforsaken.
- Providers/Z.AI: map OpenClaw thinking controls to Z.AI's `thinking` payload and add opt-in preserved thinking replay via `params.preserveThinking`, so GLM 5.x can keep prior `reasoning_content` when requested. Fixes #58680. Thanks @xuanmingguo.
- Channels/status: keep read-only channel lists on manifest and package metadata by default, loading setup runtime only for explicit fallback callers. Thanks @shakkernerd.

View File

@@ -577,17 +577,31 @@ is_arch_linux() {
return 1
}
apt_get() {
if is_root; then
env DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}" NEEDRESTART_MODE="${NEEDRESTART_MODE:-a}" apt-get "$@"
else
sudo env DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}" NEEDRESTART_MODE="${NEEDRESTART_MODE:-a}" apt-get "$@"
fi
}
apt_get_update() {
apt_get update -qq
}
apt_get_install() {
apt_get install -y -qq \
-o Dpkg::Options::=--force-confdef \
-o Dpkg::Options::=--force-confold \
"$@"
}
install_build_tools_linux() {
require_sudo
if command -v apt-get &> /dev/null; then
if is_root; then
run_quiet_step "Updating package index" apt-get update -qq
run_quiet_step "Installing build tools" apt-get install -y -qq build-essential python3 make g++ cmake
else
run_quiet_step "Updating package index" sudo apt-get update -qq
run_quiet_step "Installing build tools" sudo apt-get install -y -qq build-essential python3 make g++ cmake
fi
run_quiet_step "Updating package index" apt_get_update
run_quiet_step "Installing build tools" apt_get_install build-essential python3 make g++ cmake
return 0
fi
@@ -1446,10 +1460,10 @@ install_node() {
run_quiet_step "Downloading NodeSource setup script" download_file "https://deb.nodesource.com/setup_${NODE_DEFAULT_MAJOR}.x" "$tmp"
if is_root; then
run_quiet_step "Configuring NodeSource repository" bash "$tmp"
run_quiet_step "Installing Node.js" apt-get install -y -qq nodejs
run_quiet_step "Installing Node.js" apt_get_install nodejs
else
run_quiet_step "Configuring NodeSource repository" sudo -E bash "$tmp"
run_quiet_step "Installing Node.js" sudo apt-get install -y -qq nodejs
run_quiet_step "Installing Node.js" apt_get_install nodejs
fi
elif command -v dnf &> /dev/null; then
local tmp
@@ -1536,13 +1550,8 @@ install_git() {
elif [[ "$OS" == "linux" ]]; then
require_sudo
if command -v apt-get &> /dev/null; then
if is_root; then
run_quiet_step "Updating package index" apt-get update -qq
run_quiet_step "Installing Git" apt-get install -y -qq git
else
run_quiet_step "Updating package index" sudo apt-get update -qq
run_quiet_step "Installing Git" sudo apt-get install -y -qq git
fi
run_quiet_step "Updating package index" apt_get_update
run_quiet_step "Installing Git" apt_get_install git
elif command -v pacman &> /dev/null || is_arch_linux; then
if is_root; then
run_quiet_step "Installing Git" pacman -Sy --noconfirm git
@@ -2283,6 +2292,11 @@ main() {
print_gum_status
detect_os_or_die
if [[ "$OS" == "linux" ]]; then
export DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}"
export NEEDRESTART_MODE="${NEEDRESTART_MODE:-a}"
fi
local detected_checkout=""
detected_checkout="$(detect_openclaw_checkout "$PWD" || true)"

View File

@@ -0,0 +1,31 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const SCRIPT_PATH = "scripts/install.sh";
describe("install.sh apt behavior", () => {
const script = readFileSync(SCRIPT_PATH, "utf8");
it("runs apt-get through noninteractive wrappers", () => {
expect(script).toContain("apt_get()");
expect(script).toContain('DEBIAN_FRONTEND="${DEBIAN_FRONTEND:-noninteractive}"');
expect(script).toContain('NEEDRESTART_MODE="${NEEDRESTART_MODE:-a}"');
expect(script).toContain("sudo env DEBIAN_FRONTEND=");
expect(script).toContain("-o Dpkg::Options::=--force-confdef");
expect(script).toContain("-o Dpkg::Options::=--force-confold");
const rawAptInstalls = script
.split("\n")
.filter((line) => /\b(?:sudo\s+)?apt-get\s+install\b/.test(line));
expect(rawAptInstalls).toEqual([]);
});
it("exports noninteractive apt env during Linux startup", () => {
expect(script).toMatch(
/detect_os_or_die\s+if \[\[ "\$OS" == "linux" \]\]; then\s+export DEBIAN_FRONTEND="\$\{DEBIAN_FRONTEND:-noninteractive\}"\s+export NEEDRESTART_MODE="\$\{NEEDRESTART_MODE:-a\}"\s+fi/m,
);
expect(script).toContain(
'run_quiet_step "Configuring NodeSource repository" sudo -E bash "$tmp"',
);
});
});