Commit Graph

73 Commits

Author SHA1 Message Date
Matt Hill
186925065d sdk db backups, wifi ux, release notes, minor copy 2026-03-24 16:39:31 -06:00
Aiden McClelland
53dff95365 revert: remove websocket shutdown signal from RpcContinuations 2026-03-24 11:13:59 -06:00
Aiden McClelland
19fa1cb4e3 fix build 2026-03-23 10:12:15 -06:00
Aiden McClelland
f60a1a9ed0 fix: set backup progress complete atomically with status revert
Move BackupProgress { complete: true } into the same db.mutate() as the
DesiredStatus revert in the backup transition. Previously these were
separate mutations—the status would revert to Running before progress
showed complete, causing a visible gap in the UI.
2026-03-23 01:15:54 -06:00
Aiden McClelland
2aa910a3e8 fix: replace stdio chown with prctl(PR_SET_DUMPABLE) and pipe-wrap
After setuid, the kernel clears the dumpable flag, making /proc/self/
entries owned by root. This broke open("/dev/stderr") for non-root
users inside subcontainers. The previous fix (chowning /proc/self/fd/*)
was dangerous because it chowned whatever file the FD pointed to (could
be the journal socket).

The proper fix is prctl(PR_SET_DUMPABLE, 1) after setuid, which restores
/proc/self/ ownership to the current uid.

Additionally, adds a `pipe-wrap` subcommand that wraps a child process
with piped stdout/stderr, relaying to the original FDs. This ensures all
descendants inherit pipes (which support re-opening via /proc/self/fd/N)
even when the outermost FDs are journal sockets. container-runtime.service
now uses this wrapper.

With pipe-wrap guaranteeing pipe-based FDs, the exec and launch non-TTY
paths no longer need their own pipe+relay threads, eliminating the bug
where exec would hang when a child daemonized (e.g. pg_ctl start).
2026-03-23 01:14:49 -06:00
Aiden McClelland
8d1e11e158 fix: pg_dump/pg_restore permission errors in backup subcontainer
- Pre-create and chown dump file for postgres user before pg_dump
- Chown volume mountpoint to postgres before initdb on restore
- Add --no-privileges to pg_restore to skip GRANT/REVOKE for missing roles
2026-03-23 01:13:20 -06:00
Aiden McClelland
b7e4df44bf wip: subcontainer exec log drain via SCM_RIGHTS (reference only)
Implemented pipe FD handoff from exec to launch via Unix socket +
SCM_RIGHTS for grandchild log capture. Superseded by the simpler
PR_SET_DUMPABLE approach which eliminates the need for pipes entirely.
2026-03-22 23:58:14 -06:00
Aiden McClelland
25aa140174 fix: backup status reporting 2026-03-22 23:55:26 -06:00
Aiden McClelland
cb7618cb34 fix: e2fsck exit codes 1-3 are non-fatal during btrfs conversion
e2fsck returns 1 when errors are corrected and 2 when corrections
require a reboot. These are expected during ext4→btrfs conversion.
Only exit codes >= 4 indicate actual failure. Previously, .invoke()
treated any non-zero exit as an error, causing the conversion to
fail after successful filesystem repairs.
2026-03-21 18:20:55 -06:00
Aiden McClelland
456c5d6725 fix: graceful shutdown for subcontainer daemons
Two issues fixed:

1. Process group cascade: exec-command processes inherited the
   container runtime's process group. When an entrypoint script
   did kill(0, SIGTERM) during shutdown, it signaled ALL processes
   in the group — including other subcontainers' launch wrappers,
   causing their PID namespaces to collapse. Fixed by calling
   setsid() in exec-command's pre_exec to isolate each service
   in its own process group.

2. Unordered daemon termination: removeChild("main") fired
   onLeaveContext callbacks for all Daemon.of() instances
   simultaneously, bypassing Daemons.term()'s reverse-dependency
   ordering. Fixed by having Daemons.build() mark individual
   daemons as managed (suppressing their onLeaveContext) and
   registering a single onLeaveContext that calls the ordered
   Daemons.term(). The term() method is deduplicated so
   system.stop() and onLeaveContext share the same shutdown.
2026-03-21 18:20:50 -06:00
Aiden McClelland
8b65490d0e feat: add progress step for btrfs conversion during setup/init 2026-03-20 19:32:41 -06:00
Aiden McClelland
f5bfbe0465 Revert "fix: RunAction task re-evaluation compared against partial input, not full config"
also apply alternative fix: only re-activate a task that explicitly conflicts with a run action's input

This reverts commit 2999d22d2a.
2026-03-20 16:35:09 -06:00
Aiden McClelland
8bccffcb5c feat: add --arch flag to start-cli registry package download
Use the new flag in the image build recipe to download the tor s9pk
for the target architecture, replacing the standalone download script.
2026-03-20 15:28:45 -06:00
Aiden McClelland
7335e52ab3 fix: daemon lifecycle cleanup and error logging improvements
- Refactor HealthDaemon to use a tracked session (AbortController + awaitable
  promise) instead of fire-and-forget health check loops, preventing health
  checks from running after a service is stopped
- Stop health checks before terminating daemon to avoid false crash reports
  during intentional shutdown
- Guard onExit callbacks with AbortSignal to prevent stale session callbacks
- Add logErrorOnce utility to deduplicate repeated error logging
- Fix SystemForEmbassy.stop() to capture clean promise before deleting ref
- Treat SIGTERM (signal 15) as successful exit in subcontainer sync
- Fix asError to return original Error instead of wrapping in new Error
- Remove unused ExtendedVersion import from Backups.ts
2026-03-20 13:50:57 -06:00
Matt Hill
2a8d8c7154 alpha.22 2026-03-20 08:37:36 -06:00
Matt Hill
56cb3861bc fix build 2026-03-19 18:00:22 -06:00
Matt Hill
2999d22d2a fix: RunAction task re-evaluation compared against partial input, not full config
Bug: After running an action (e.g. bitcoin's autoconfig), update_tasks was
called with the submitted form input — which for task-triggered actions is
filtered to only the task's fields (e.g. {zmqEnabled: true}). Other services'
tasks targeting the same action were then compared against this partial via
is_partial_of, so any task wanting a field NOT in the submission (e.g.
{blocknotify: "curl..."}) would incorrectly become active, even though the
full config still satisfied it.

This caused a cycling bug: running LND's autoconfig (zmqEnabled) would
activate Datum's task (blocknotify), and vice versa, despite the merge
correctly preserving both values in the config.

Fix: After running an action, fetch the full current config via
get_action_input (same as create_task and recheck_tasks already do) and
compare tasks against that.

The one-liner fix would have been to add a get_action_input call in the
RunAction handler. Instead, we extracted eval_action_tasks on
ServiceActorSeed — a single method that both RunAction and recheck_tasks
now call — because the duplication between these two sites is exactly how
this bug happened: recheck_tasks fetched the full config, RunAction didn't,
and they silently diverged.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:43:08 -06:00
Matt Hill
bb745c43cc fix: createTask with undefined input values fails to create task
Bug: Setting a task input property to undefined (e.g. { prune: undefined })
to express "this key should be deleted" resulted in no task being created.
JSON.stringify strips undefined values, so { prune: undefined } serialized
as {}, and is_partial_of({}, any_config) always returns true — meaning
input-not-matches saw a "match" and never activated the task.

Fix (two parts):
- SDK: coerce undefined to null in task input values before serialization,
  so they survive JSON.stringify and reach the Rust backend
- Rust: treat null in a partial as matching a missing key in the full
  config, so tasks correctly deactivate when the key is already absent

Assumption: null and undefined/absent are semantically equivalent for
StartOS config values. Input specs produce concrete values (strings,
numbers, booleans, objects, arrays) — null never appears as a meaningful
distinct-from-absent value in real-world configs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 14:28:04 -06:00
Aiden McClelland
96dcd126db feat: support restoring backups from a different server 2026-03-19 01:07:37 -06:00
Aiden McClelland
3ef99eca87 fix: allow private access to vhost targets on public gateways 2026-03-19 00:41:48 -06:00
Aiden McClelland
292a914307 fix: use shared futures for ACME cert acquisition with 2m timeout 2026-03-19 00:06:34 -06:00
Aiden McClelland
9a58568053 fix: send TLS alerts on handshake timeout and unrecognized SNI 2026-03-19 00:06:25 -06:00
Aiden McClelland
34e01d4223 fix: increase RPC connect timeout from 30s to 60s 2026-03-18 23:49:44 -06:00
Aiden McClelland
427c38f23b feat: add tunnel restart command 2026-03-18 23:49:29 -06:00
Aiden McClelland
d669aa9afb fix: retry BLKRRPART on busy device during OS install 2026-03-18 23:48:49 -06:00
Aiden McClelland
bcdeabfe85 fix: clap CLI definitions and manpage generation
- add #[group(skip)] to all Parser-derived structs
- fix conflicts_with and arg definitions for correct CLI behavior
- refactor bin entry points to support manpage generation
2026-03-18 23:48:13 -06:00
Aiden McClelland
9ed6c1263c fix: derive wifi interface dynamically from gateway info instead of detecting at startup
Remove static wifi_interface/ethernet_interface fields from RpcContextSeed. Instead, look up
the wifi interface from the DB (populated by gateway sync) and check ethernet connectivity
by querying gateway entries. This ensures the wifi manager always uses the correct interface
even if network devices change after boot.
2026-03-18 16:01:41 -06:00
Aiden McClelland
900d86ab83 feat: preserve volumes on failed install + migrate ext4 to btrfs
- COW snapshot (cp --reflink=always) of package volumes before
  install/update; restore on failure, remove on success
- Automatic ext4→btrfs conversion via btrfs-convert during disk attach
  with e2fsck pre-check and post-conversion defrag
- Probe package-data filesystem during setup.disk.list (on both disk
  and partition level) so the UI can warn about ext4 conversion
- Setup wizard preserve-overwrite dialog shows ext4 warning with
  backup acknowledgment checkbox before allowing preserve
2026-03-17 15:11:16 -06:00
Aiden McClelland
873922d9e3 chore: fix mac build 2026-03-16 20:10:51 -06:00
Aiden McClelland
6c9cbebe9c fix: correct argument order in asn1_time_to_system_time
The diff() method computes `compare - self`, not `self - compare`.
The reversed arguments caused all cert expiration times to resolve
to before the unix epoch, making getSslCertificate callbacks fire
immediately and infinitely on every registration.
2026-03-16 20:10:02 -06:00
Aiden McClelland
dd9837b9b2 refactor: convert service callbacks to DbWatch pattern
Convert getServiceInterface, listServiceInterfaces, getSystemSmtp, and
getServiceManifest from manual callback triggers to DbWatchedCallbacks.
getServiceManifest now always returns the installed manifest.
2026-03-16 20:09:10 -06:00
Aiden McClelland
1c1ae11241 chore: bump to v0.4.0-alpha.21 2026-03-16 13:54:59 -06:00
Aiden McClelland
cc6a134a32 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.
2026-03-16 13:40:14 -06:00
Aiden McClelland
3ae24e63e2 perf: add O_DIRECT uploads and stabilize RPC continuation shutdown
Implements DirectIoFile for faster package uploads by bypassing page cache.
Refactors RpcContinuations to support graceful WebSocket shutdown via
broadcast signal, improving stability during daemon restart.
2026-03-16 13:40:13 -06:00
Aiden McClelland
8562e1e19d refactor: change kiosk parameter from Option<bool> to bool
Simplifies the setup API by making kiosk mandatory at the protocol level,
with platform-specific filtering applied at the database layer.
2026-03-16 13:40:13 -06:00
Aiden McClelland
90d8d39adf feat: migrate tor onion keys during v0.3.6a0 to v0.4.0a20 upgrade
Preserves tor service onion addresses by extracting keys from old
database tables and preparing them for inclusion in the new tor service.
2026-03-16 13:40:12 -06:00
Aiden McClelland
a81b1aa5a6 feat: wait for db commit after tunnel add/remove
Add a typed DbWatch at the end of add_tunnel and remove_tunnel that
waits up to 15s for the sync loop to commit the gateway state change
to patch-db before returning.
2026-03-13 12:09:13 -06:00
Aiden McClelland
d8663cd3ae fix: use ip route replace to avoid connectivity gap on gateway changes
Replace the flush+add cycle in apply_policy_routing with ip route
replace for each desired route, then delete stale routes. This
eliminates the window where the per-interface routing table is empty,
which caused temporary connectivity loss on other gateways.
2026-03-13 12:09:13 -06:00
Matt Hill
0fa069126b mok ux, autofill device and pf forms, docss for st, docs for start-sdk 2026-03-12 14:15:45 -06:00
Aiden McClelland
c485edfa12 feat: tunnel TS exports, port forward labels, and db migrations
- Add TS derive and type annotations to all tunnel API param structs
- Export tunnel bindings to a tunnel/ subdirectory with index generation
- Change port forward label from String to Option<String>
- Add TunnelDatabase::init() with default subnet creation
- Add tunnel migration framework with m_00_port_forward_entry migration
  to convert legacy string-only port forwards to the new entry format
2026-03-12 13:39:15 -06:00
Matt Hill
d1444b1175 ST port labels and move logout to settings (#3134)
* chore: update packages (#3132)

* chore: update packages

* start tunnel messaging

* chore: standalone

* pbpaste instead

---------

Co-authored-by: Matt Hill <mattnine@protonmail.com>

* port labels and move logout to settings

* enable-disable forwards

* Fix docs URLs in start-tunnel installer output (#3135)

---------

Co-authored-by: Alex Inkin <alexander@inkin.ru>
Co-authored-by: gStart9 <106188942+gStart9@users.noreply.github.com>
2026-03-12 12:02:38 -06:00
Aiden McClelland
d12b278a84 feat: switch os_install root filesystem from ext4 to btrfs 2026-03-12 11:11:14 -06:00
Aiden McClelland
0070a8e692 refactor: derive OsPartitionInfo from fstab instead of config.yaml
Replace the serialized os_partitions field in ServerConfig with runtime
fstab parsing. OsPartitionInfo::from_fstab() resolves PARTUUID/UUID/LABEL
device specs via blkid and discovers the BIOS boot partition by scanning
for its GPT type GUID via lsblk.

Also removes the efibootmgr-based boot order management (replaced by
GRUB-based USB detection in a subsequent commit) and adds a dedicated
bios: Option<PathBuf> field for the unformatted BIOS boot partition.
2026-03-12 11:10:24 -06:00
Aiden McClelland
effcec7e2e feat: add Secure Boot MOK key enrollment and module signing
Generate DKMS MOK key pair during OS install, sign all unsigned kernel
modules, and enroll the MOK certificate using the user's master password.
On reboot, MokManager prompts the user to complete enrollment. Re-enrolls
on every boot if the key exists but isn't enrolled yet. Adds setup wizard
dialog to inform the user about the MokManager prompt.
2026-03-11 15:18:46 -06:00
Aiden McClelland
10a5bc0280 fix: add restart_again flag to DesiredStatus::Restarting
When a restart is requested while the service is already restarting
(stopped but not yet started), set restart_again so the actor will
perform another stop→start cycle after the current one completes.
2026-03-11 15:18:46 -06:00
Aiden McClelland
90b73dd320 feat: support multiple echoip URLs with fallback
Rename ifconfig_url to echoip_urls and iterate through configured URLs,
falling back to the next one on failure. Reduces timeout per attempt
from 10s to 5s.
2026-03-11 15:18:45 -06:00
Aiden McClelland
00eecf3704 fix: treat all private IPs as private traffic, not just same-subnet
Previously, traffic was only classified as private if the source IP was
in a known interface subnet. This prevented private access from VPNs on
different VLANs. Now all RFC 1918 IPv4 and ULA/link-local IPv6 addresses
are treated as private, and DNS resolution for private domains works for
these sources by returning IPs from all interfaces.
2026-03-11 15:18:43 -06:00
Aiden McClelland
8dd50eb9c0 fix: move unpack progress completion after rename and reformat 2026-03-10 00:14:27 -06:00
Aiden McClelland
73c6696873 refactor: simplify AddPackageSignerParams merge field from Option<bool> to bool 2026-03-10 00:14:26 -06:00
Aiden McClelland
2586f841b8 fix: make unmount idempotent by ignoring "not mounted" errors 2026-03-10 00:14:26 -06:00