Skip to content

System Updates

Calculinux uses a dual-layer update strategy combining RAUC for system images and OPKG for packages, with automatic reconciliation to keep everything in sync.

Overview

Calculinux employs an A/B slot update system powered by RAUC (Robust Auto-Update Controller). When you install an update, it writes to the inactive slot, leaving your current system untouched. After reboot, the system switches to the new slot, and the old one becomes your rollback option.

Update Architecture

graph TD
    subgraph base["Read-Only Base Image (RAUC Slot)"]
        kernel[Kernel]
        basepkgs[Base System Packages]
        statusimage[/var/lib/opkg/status.image]
    end

    subgraph overlay["Writable Overlay"]
        userpkgs[User-Installed Packages]
        config[Configuration Files]
        status[/var/lib/opkg/status]
    end

    base -.-> overlay

    style base fill:#e1f5ff,stroke:#0288d1,stroke-width:2px
    style overlay fill:#fff3e0,stroke:#ef6c00,stroke-width:2px

The Calculinux Update Tool (cup)

The calculinux-update package provides the cup command for managing system updates. Two additional internal commands (cup-hook and cup-postreboot) are automatically invoked by the system during the update process—you typically won't need to run these manually.

Installing Updates

Interactive Update

The easiest way to update is interactively:

sudo cup install

This will:

  1. List available channels (if you have multiple enabled)
  2. Show available bundles sorted by date (newest first)
  3. Let you select which bundle to install
  4. Extract bundle metadata (OPKG configuration and package list)
  5. Prefetch packages that will be reinstalled after reboot
  6. Prompt for confirmation before installing

Each RAUC bundle includes metadata about the new system's package configuration, allowing the update tool to prepare everything needed for a smooth transition.

Update Specific Channel

sudo cup install --channel "Release"

Update with Specific Bundle

If you know the bundle name:

sudo cup install --bundle calculinux-bundle-walnascar-20251120.raucb

Non-Interactive Update

For automation or when you're confident:

sudo cup install --bundle <name> --yes

Listing Available Updates

List All Updates

cup list

List Updates from Specific Channel

cup list --channel "Continuous"

Download Without Installing

To download a bundle without installing (useful for offline installation later):

cup download --bundle <name>

By default, bundles are downloaded to /var/cache/calculinux-update/.

Package Reconciliation

Why Reconciliation Matters

Calculinux uses a dual-layer package system:

  • Base layer: System packages baked into the read-only RAUC image
  • Overlay layer: User-installed packages stored in writable storage

When you update the base image, this can create problems:

  1. Duplicate packages: A package you installed is now in the new base image
  2. Missing packages: The new image removed a package your other packages depend on
  3. Version conflicts: Your overlay packages conflict with newer base versions

Automatic Reconciliation

The update process automatically handles these issues:

During Update Installation

When you run sudo cup install, the system:

  1. Extracts bundle metadata - Gets OPKG configuration and package information from the bundle
  2. Plans reconciliation - Identifies duplicates, missing packages, and upgrades needed
  3. Prefetches packages - Downloads packages that will need reinstallation using the new system's package repositories

This metadata-driven approach allows the update to prepare everything needed before installation, enabling offline reconciliation even if network isn't available after reboot.

During RAUC Installation (via cup-hook)

When RAUC installs the new slot:

  1. Removes duplicates - Uninstalls overlay packages now provided by the base
  2. Records the plan - Saves which packages need reinstalling/upgrading
  3. Prepares for reboot - Everything is ready for the post-reboot phase

After Reboot (via cup-postreboot)

When the system boots into the new slot:

  1. Updates package feeds - Runs opkg update
  2. Reinstalls missing packages - Installs packages from the old base now missing
  3. Upgrades overlay packages - Updates all user packages to match new base versions
  4. Uses cached packages - Prefers locally cached .ipk files for offline operation

Checking Reconciliation Status

After an update, check the systemd journal:

journalctl -u calculinux-update-postreboot.service

Look for messages like:

cup-hook: pruned writable status against new image
cup-hook: queued 3 packages for reinstall
cup-hook: queued 5 packages for upgrade

Configuration

Update Channels

Edit /etc/calculinux-update.toml:

[[channels]]
name = "Release"
path = "/update/walnascar/release"
enable = true

[[channels]]
name = "Continuous"
path = "/update/walnascar/continuous"
enable = false

[[channels]]
name = "Builds"
path = "/update/walnascar/pr"
enable = false

Set enable = true to show a channel in cup list.

Skipping Prefetch

In some cases you might want to skip prefetch (though metadata extraction still occurs):

sudo cup install --no-prefetch

Warning

Without prefetch, post-reboot reconciliation requires network access. The bundle metadata will still be validated to ensure compatibility.

Update Process Flow

graph TD
    A[cup install] --> B[Select Bundle]
    B --> C[Extract Bundle Metadata]
    C --> D[Plan Reconciliation]
    D --> E[Prefetch Packages]
    E --> F[Download Bundle]
    F --> G[Confirm Install]
    G --> H[RAUC Install]
    H --> I[cup-hook: Prepare Reconciliation]
    I --> J[System Reboots]
    J --> K[Boot New Slot]
    K --> L[cup-postreboot: Reconcile Packages]
    L --> M[Update Complete]

Troubleshooting

Update Fails to Install

Check RAUC status:

rauc status

View detailed logs:

journalctl -u rauc -e

Packages Not Reconciling After Reboot

Check the post-reboot service:

systemctl status calculinux-update-postreboot.service
journalctl -u calculinux-update-postreboot.service -e

Pending operations are stored in:

  • /var/lib/opkg/opkg-status-hook.pending-reinstalls
  • /var/lib/opkg/opkg-status-hook.pending-upgrades

Prefetch Fails

If bundle metadata extraction or prefetch fails, you have several options:

Check if bundle is corrupted:

# Download again if needed
cup download --bundle <bundle-name>

Skip prefetch (requires network after reboot):

sudo cup install --no-prefetch

Verify OPKG configuration:

cat /etc/opkg/opkg.conf
opkg update

Prefetch failures are usually harmless - the system will simply download packages after reboot instead of using pre-cached versions. However, if bundle metadata extraction fails completely, the bundle may be corrupted and should be re-downloaded.

Rolling Back an Update

RAUC maintains the previous slot as a fallback:

# Mark current slot as bad and reboot to previous
sudo rauc status mark-bad booted
sudo reboot

Or select the other slot in your bootloader (if supported).

Package State After Rollback

After rolling back, some manually installed packages may need to be reinstalled, as the reconciliation system currently only runs during forward updates. A list of your installed packages can help:

# Before updating, save your package list
opkg list-installed > ~/my-packages.txt

# After rollback, reinstall if needed
cat ~/my-packages.txt | awk '{print $1}' | xargs opkg install

Future versions will include automatic rollback detection and reconciliation.

Dry Run

Test the update process without actually installing:

cup install --dry-run

This downloads and prepares but doesn't invoke RAUC.

Best Practices

Before Updating

  1. Check free space: Ensure /var/cache has room for downloads
  2. Backup critical data: Though updates are safe, backups are always good
  3. Note your packages: opkg list-installed > my-packages.txt

After Updating

  1. Check reconciliation: journalctl -u calculinux-update-postreboot.service
  2. Test your applications: Ensure everything still works
  3. Keep previous slot: Don't mark it bad until you're confident

For Development Machines

Use --no-prefetch and ensure network access:

sudo cup install --no-prefetch

Advanced Usage

Testing PR Builds

Enable the Builds channel and install PR bundles:

# Edit /etc/calculinux-update.toml, set Builds enable = true
cup list --channel "Builds"
sudo cup install --channel "Builds" --bundle luckfox-lyra-pr123.raucb

Automated Updates

For kiosk or embedded deployments:

#!/bin/bash
# Update to latest release automatically
BUNDLE=$(cup list --channel "Release" | head -1 | awk '{print $1}')
if [ -n "$BUNDLE" ]; then
    sudo cup install --channel "Release" --bundle "$BUNDLE" --yes
fi

Custom Mirrors

Set mirror_base_url in /etc/calculinux-update.toml:

mirror_base_url = "https://my-mirror.example.com"

For developers working on the update system, see Developer Guide: Calculinux Update