From cc6a134a32a54ca0c7e97995ee6cf4a58cd9e772 Mon Sep 17 00:00:00 2001 From: Aiden McClelland Date: Mon, 16 Mar 2026 13:39:52 -0600 Subject: [PATCH] chore: enable debug features and improve graceful shutdown for unstable builds Adds stack overflow backtraces, debug info compilation, and SSH password auth for development. Reduces shutdown timeouts from 60s to 100ms for faster iteration. Fixes race condition in NetService cleanup. --- build/image-recipe/build.sh | 5 +++++ .../usr/lib/startos/scripts/init_resize.sh | 8 +++++--- core/build/build-cli.sh | 4 ++++ core/build/build-registrybox.sh | 4 ++++ core/build/build-start-container.sh | 4 ++++ core/build/build-startbox.sh | 4 ++++ core/build/build-tunnelbox.sh | 4 ++++ core/locales/i18n.yaml | 7 +++++++ core/src/backup/backup_bulk.rs | 9 +++++++++ core/src/bins/mod.rs | 5 +++++ core/src/bins/startd.rs | 2 +- core/src/net/net_controller.rs | 2 +- core/src/net/web_server.rs | 2 +- web/package-lock.json | 20 ++----------------- 14 files changed, 56 insertions(+), 24 deletions(-) diff --git a/build/image-recipe/build.sh b/build/image-recipe/build.sh index e35b21b9a..c2367dbfa 100755 --- a/build/image-recipe/build.sh +++ b/build/image-recipe/build.sh @@ -131,6 +131,11 @@ ff02::1 ip6-allnodes ff02::2 ip6-allrouters EOT +if [[ "${IB_OS_ENV}" =~ (^|-)dev($|-) ]]; then + mkdir -p config/includes.chroot/etc/ssh/sshd_config.d + echo "PasswordAuthentication yes" > config/includes.chroot/etc/ssh/sshd_config.d/dev-password-auth.conf +fi + # Installer marker file (used by installed GRUB to detect the live USB) mkdir -p config/includes.binary touch config/includes.binary/.startos-installer diff --git a/build/image-recipe/raspberrypi/img/usr/lib/startos/scripts/init_resize.sh b/build/image-recipe/raspberrypi/img/usr/lib/startos/scripts/init_resize.sh index faa796c7b..67e0629df 100755 --- a/build/image-recipe/raspberrypi/img/usr/lib/startos/scripts/init_resize.sh +++ b/build/image-recipe/raspberrypi/img/usr/lib/startos/scripts/init_resize.sh @@ -58,6 +58,11 @@ check_variables () { main () { get_variables + # Fix GPT backup header first — the image was built with a tight root + # partition, so the backup GPT is not at the end of the SD card. parted + # will prompt interactively if this isn't fixed before we use it. + sgdisk -e "$ROOT_DEV" 2>/dev/null || true + if ! check_variables; then return 1 fi @@ -74,9 +79,6 @@ main () { fi fi - # Fix GPT backup header to reflect new partition layout - sgdisk -e "$ROOT_DEV" 2>/dev/null || true - mount / -o remount,rw btrfs filesystem resize max /media/startos/root diff --git a/core/build/build-cli.sh b/core/build/build-cli.sh index d809a189f..889c5a766 100755 --- a/core/build/build-cli.sh +++ b/core/build/build-cli.sh @@ -67,6 +67,10 @@ if [[ "${ENVIRONMENT:-}" =~ (^|-)console($|-) ]]; then RUSTFLAGS="--cfg tokio_unstable" fi +if [[ "${ENVIRONMENT:-}" =~ (^|-)unstable($|-) ]]; then + RUSTFLAGS="$RUSTFLAGS -C debuginfo=1" +fi + echo "FEATURES=\"$FEATURES\"" echo "RUSTFLAGS=\"$RUSTFLAGS\"" rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-cli --target=$TARGET diff --git a/core/build/build-registrybox.sh b/core/build/build-registrybox.sh index 263a3ae6d..1d70895e3 100755 --- a/core/build/build-registrybox.sh +++ b/core/build/build-registrybox.sh @@ -38,6 +38,10 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then RUSTFLAGS="--cfg tokio_unstable" fi +if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then + RUSTFLAGS="$RUSTFLAGS -C debuginfo=1" +fi + echo "FEATURES=\"$FEATURES\"" echo "RUSTFLAGS=\"$RUSTFLAGS\"" rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin registrybox --target=$RUST_ARCH-unknown-linux-musl diff --git a/core/build/build-start-container.sh b/core/build/build-start-container.sh index d5a56549e..12f47063b 100755 --- a/core/build/build-start-container.sh +++ b/core/build/build-start-container.sh @@ -38,6 +38,10 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then RUSTFLAGS="--cfg tokio_unstable" fi +if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then + RUSTFLAGS="$RUSTFLAGS -C debuginfo=1" +fi + echo "FEATURES=\"$FEATURES\"" echo "RUSTFLAGS=\"$RUSTFLAGS\"" rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin start-container --target=$RUST_ARCH-unknown-linux-musl diff --git a/core/build/build-startbox.sh b/core/build/build-startbox.sh index 5a6df1771..86907e2db 100755 --- a/core/build/build-startbox.sh +++ b/core/build/build-startbox.sh @@ -38,6 +38,10 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then RUSTFLAGS="--cfg tokio_unstable" fi +if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then + RUSTFLAGS="$RUSTFLAGS -C debuginfo=1" +fi + echo "FEATURES=\"$FEATURES\"" echo "RUSTFLAGS=\"$RUSTFLAGS\"" rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin startbox --target=$RUST_ARCH-unknown-linux-musl diff --git a/core/build/build-tunnelbox.sh b/core/build/build-tunnelbox.sh index 181af3644..1326a2422 100755 --- a/core/build/build-tunnelbox.sh +++ b/core/build/build-tunnelbox.sh @@ -38,6 +38,10 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then RUSTFLAGS="--cfg tokio_unstable" fi +if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then + RUSTFLAGS="$RUSTFLAGS -C debuginfo=1" +fi + echo "FEATURES=\"$FEATURES\"" echo "RUSTFLAGS=\"$RUSTFLAGS\"" rust-zig-builder cargo zigbuild --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features=$FEATURES --locked --bin tunnelbox --target=$RUST_ARCH-unknown-linux-musl diff --git a/core/locales/i18n.yaml b/core/locales/i18n.yaml index 0b7a688a2..94d1225a2 100644 --- a/core/locales/i18n.yaml +++ b/core/locales/i18n.yaml @@ -1255,6 +1255,13 @@ backup.bulk.leaked-reference: fr_FR: "référence fuitée vers BackupMountGuard" pl_PL: "wyciekła referencja do BackupMountGuard" +backup.bulk.service-not-ready: + en_US: "Cannot create a backup of a service that is still initializing or in an error state" + de_DE: "Es kann keine Sicherung eines Dienstes erstellt werden, der noch initialisiert wird oder sich im Fehlerzustand befindet" + es_ES: "No se puede crear una copia de seguridad de un servicio que aún se está inicializando o está en estado de error" + fr_FR: "Impossible de créer une sauvegarde d'un service encore en cours d'initialisation ou en état d'erreur" + pl_PL: "Nie można utworzyć kopii zapasowej usługi, która jest jeszcze inicjalizowana lub znajduje się w stanie błędu" + # backup/restore.rs backup.restore.package-error: en_US: "Error restoring package %{id}: %{error}" diff --git a/core/src/backup/backup_bulk.rs b/core/src/backup/backup_bulk.rs index 4c95bcad9..cb70a77a1 100644 --- a/core/src/backup/backup_bulk.rs +++ b/core/src/backup/backup_bulk.rs @@ -300,6 +300,15 @@ async fn perform_backup( error: backup_result, }, ); + } else { + backup_report.insert( + id.clone(), + PackageBackupReport { + error: Some( + t!("backup.bulk.service-not-ready").to_string(), + ), + }, + ); } } diff --git a/core/src/bins/mod.rs b/core/src/bins/mod.rs index 2b1959db7..f790bf5c1 100644 --- a/core/src/bins/mod.rs +++ b/core/src/bins/mod.rs @@ -149,6 +149,11 @@ impl MultiExecutable { } pub fn execute(&self) { + #[cfg(feature = "backtrace-on-stack-overflow")] + unsafe { + backtrace_on_stack_overflow::enable() + }; + set_locale_from_env(); let mut popped = Vec::with_capacity(2); diff --git a/core/src/bins/startd.rs b/core/src/bins/startd.rs index 314d3dc7a..487170b82 100644 --- a/core/src/bins/startd.rs +++ b/core/src/bins/startd.rs @@ -190,7 +190,7 @@ pub fn main(args: impl IntoIterator) { } } }); - rt.shutdown_timeout(Duration::from_secs(60)); + rt.shutdown_timeout(Duration::from_millis(100)); res }; diff --git a/core/src/net/net_controller.rs b/core/src/net/net_controller.rs index 529b8824a..c48c7c9c6 100644 --- a/core/src/net/net_controller.rs +++ b/core/src/net/net_controller.rs @@ -820,7 +820,6 @@ impl NetService { break; } } - self.shutdown = true; Ok(()) } @@ -832,6 +831,7 @@ impl NetService { impl Drop for NetService { fn drop(&mut self) { if !self.shutdown { + self.shutdown = true; let svc = std::mem::replace(self, Self::dummy()); tokio::spawn(async move { svc.remove_all().await.log_err() }); } diff --git a/core/src/net/web_server.rs b/core/src/net/web_server.rs index 8ffe9deaa..eed7cf37c 100644 --- a/core/src/net/web_server.rs +++ b/core/src/net/web_server.rs @@ -509,7 +509,7 @@ where drop(queue_cell.replace(None)); if !runner.is_empty() { - tokio::time::timeout(Duration::from_secs(60), runner) + tokio::time::timeout(Duration::from_millis(100), runner) .await .log_err(); } diff --git a/web/package-lock.json b/web/package-lock.json index 11eb53ecc..fb07bd64b 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -836,6 +836,7 @@ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -8322,6 +8323,7 @@ "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", @@ -12524,24 +12526,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", - "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "dev": true, - "license": "ISC", - "optional": true, - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yargs": { "version": "18.0.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz",