॥ श्री ॥

Atomic Updates

Concepts 2026-04-27

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

  1. Checkshani-update timer runs automatically (15 min after boot, then every 2 hours) and finds a new release
  2. Notify — GUI dialog (yad/zenity/kdialog) prompts for user approval
  3. Download — R2 CDN primary, SourceForge fallback; resume support via aria2c/wget/curl
  4. Verify — SHA256 checksum + GPG signature; Btrfs snapshot of old slot taken as backup
  5. Deploy — New image extracted to inactive slot; UKI generated by gen-efi; bootloader updated
  6. Reboot — Reboot prompt shown; system boots into updated slot
  7. Confirm — Boot counters + mark-boot-success runs 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 here
  • shani-deploy writes new image into @green, keeps a Btrfs snapshot of old @green
  • Bootloader updated → @green set as next default

After reboot — running @green:

  • @blue ⏸️ Inactive — instant rollback available
  • @green ✅ Active (Updated!) — new system running
  • startup-check confirms 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 start
  • bless-boot — calls bootctl set-good early
  • mark-boot-success — writes /data/boot-ok once multi-user.target is reached
  • check-boot-failure (15-minute timer) — records the slot in /data/boot_failure if 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%.