Atomic Updates
Shanios uses an intelligent multi-layered update system with automatic checking, user notifications, and the shani-deploy tool for atomic system updates. Updates are all-or-nothing — the running system is never touched while an update is being prepared.
Update Process Flow
- Check —
shani-updatetimer runs automatically (15 min after boot, then every 2 hours) and finds a new release - Notify — GUI dialog (yad/zenity/kdialog) prompts for user approval
- Download — R2 CDN primary, SourceForge fallback; resume support via aria2c/wget/curl
- Verify — SHA256 checksum + GPG signature; Btrfs snapshot of old slot taken as backup
- Deploy — New image extracted to inactive slot; UKI generated by
gen-efi; bootloader updated - Reboot — Reboot prompt shown; system boots into updated slot
- Confirm — Boot counters +
mark-boot-successruns after login
If boot fails, the system automatically falls back to the previous slot.
The Full Update Pipeline
Here is every step shani-deploy runs internally, in order.
1. Fetch and Verify
# Download version manifest from R2 CDN (with SourceForge fallback)
# Download image — streamed with resume support
# SHA256 verified after download
# GPG signature verified against known public key (7B927BFFD4A9EAAA8B666B77DE217F3DA8014792)
Nothing is written to the OS subvolumes until both the checksum and signature verify. A corrupted or tampered image never touches your system. If the download is interrupted, it resumes from where it stopped.
2. Snapshot the Inactive Slot
btrfs subvolume snapshot @green @green.$(date +%Y%m%d-%H%M%S)
This snapshot is created before any changes to the inactive slot. If something goes wrong during extraction, this snapshot is your recovery point.
3. Extract the New Image
# Decompress and receive the btrfs send stream
zstd -d --long=31 -T0 shanios-<version>-<profile>.zst -c | btrfs receive /mnt/temp_update
# Swap the candidate slot
btrfs subvolume delete @green
btrfs subvolume snapshot /mnt/temp_update/shanios_base @green
btrfs property set -f -ts @green ro true
btrfs receive reconstructs the subvolume from the send stream. The result is byte-for-byte identical to the subvolume that was snapshotted, signed, and shipped — not a package application or diff, but a complete verified reconstitution of exactly what passed build QA.
4. Generate the UKI
gen-efi generates and signs a new Unified Kernel Image for the updated slot, run inside a chroot of the candidate slot:
gen-efi configure green
The kernel cmdline embedded in the UKI is regenerated from the live disk state — current LUKS UUID, swap offset — and signed with the MOK keypair. The signed UKI is placed in the ESP and the bootloader is updated to set it as the next-boot default.
5. Boot Counting
The new entry gets a +3-0 suffix: 3 tries allowed, 0 done. Each failed boot attempt decrements the tries-left counter. If it reaches zero, systemd-boot automatically falls back to the previous slot's UKI.
If the new slot boots successfully, bless-boot calls bootctl set-good, stopping the countdown. The slot becomes the permanent default.
Before / After
Before update — running @blue:
@blue✅ Active (Booted) — current system@green⏸️ Inactive (Old) — update written hereshani-deploywrites new image into@green, keeps a Btrfs snapshot of old@green- Bootloader updated →
@greenset as next default
After reboot — running @green:
@blue⏸️ Inactive — instant rollback available@green✅ Active (Updated!) — new system runningstartup-checkconfirms success after login
Automatic Rollback
If the updated slot fails to reach multi-user.target within three boot attempts, systemd-boot detects the failure (via boot-count +3-0 decrement) and automatically falls back to the Candidate slot. The user sees the previous system with no data loss.
The boot health pipeline:
mark-boot-in-progress— plants a flag at boot startbless-boot— callsbootctl set-goodearlymark-boot-success— writes/data/boot-okoncemulti-user.targetis reachedcheck-boot-failure(15-minute timer) — records the slot in/data/boot_failureif the system never reached a successful state
Release Channels
shani-deploy supports two release channels:
| Channel | Cadence | Use Case | |---------|---------|----------| | stable | Monthly | Default — recommended for all users | | latest | More frequent | Early access, testing |
For channel switching commands, manual update commands, rollback, and storage management, see System Updates.
Storage Efficiency
The dual-slot architecture is not as expensive on disk as it sounds. Btrfs Copy-on-Write shares unchanged data blocks between @blue and @green — only changed files consume additional space, typically around 18% overhead compared to a single-image system. On top of that, bees continuously deduplicates shared content across all subvolumes. Btrfs zstd compression typically reduces image footprint by a further 30–50%.