Roxora images are built by Armbian's build framework with one extension added. The result is a board that boots Armbian's kernel, device tree, U-Boot and firmware, and runs a stock Ubuntu userspace that updates from the Ubuntu archive.
The build
armbian.refpins one commit of armbian/build. Every image is built from that commit; moving to a newer Armbian is a one-line change that goes through CI like any other.build.shfetches armbian/build at that commit intocache/armbian-build, refuses to run if the checkout is at another commit or has local changes, copiesuserpatches/into it and runs Armbian'scompile.shwith theroxoraextension enabled. It accepts only combinations listed inboards.conf. Every image starts as Armbian's minimal image; a desktop flavor adds Ubuntu's desktop to it (see Desktop flavors).userpatches/extensions/roxora.shis the extension. It uses Armbian's documented extension hooks; Roxora does not carry a fork or patches of armbian/build.verify/verify-image.shchecks every finished image without booting it (see Verification).
Two layers
Armbian's images contain two different things, and Roxora keeps only one of them.
The hardware layer is kept from Armbian. It is what the board needs to boot and to drive its hardware:
- the kernel (
linux-image-*) and its headers (linux-headers-*, installed only where a board needs DKMS), - device trees (
linux-dtb-*), - U-Boot (
linux-u-boot-*), - firmware (
armbian-firmware*), - the hardware-related files of the board support package (BSP): the boot script and its environment, the hook that wraps each initramfs for U-Boot, udev rules and module options for Wi-Fi, Ethernet adapters, video decoders, audio device names and LEDs, and the device tree overlay tool.
The distro layer is removed, or replaced with what Ubuntu ships. It is
everything that changes how the system looks or behaves compared with stock
Ubuntu: the
first-login wizard and armbian-firstrun, armbian-config, Armbian's login
message, logs in RAM and zram swap, Armbian's apt settings, its replacement
base-files, branding, and edits Armbian's build makes to files of Ubuntu
packages.
The full list, file by file, with the reason for each decision, is in
What Roxora keeps from Armbian. The build reads the same
lists as the check:
bsp-remove.list,
rootfs-remove.list and
keep-modified.list.
What the extension does, in order:
- Checks the board, branch, release and flavor against
boards.confand refuses Armbian's own desktop builds (BUILD_DESKTOP). - Sets Armbian options so that some distro-layer parts are never installed:
Ubuntu's own
base-filesand/etc/os-release, no console autologin, time zoneEtc/UTC, no tuning profile, no boot splash, no kernel headers unless a board needs them. - Builds the BSP package with the distro-layer files left out, and with maintainer scripts that keep only the boot-related steps. The package keeps Armbian's name.
- Keeps Armbian from adding the
armbian-configrepository and package. - Installs the apt pin described below, from the first stage of the root filesystem on.
- Purges
fake-ubuntu-advantage-tools, replaces any other Armbian-built package outside the hardware layer with Ubuntu's version, removes files Armbian created outside packages, and reinstalls every Ubuntu package whose files Armbian edited, untildpkg --verifyreports nothing but the files inkeep-modified.list. - Installs cloud-init and unattended-upgrades, seeds the first boot and
creates the default account
roxorawith the passwordroxora, which must be changed at the first login (see FAQ). Automatic security updates are on, as on Ubuntu's server images. - On desktop flavors only: installs Ubuntu's desktop metapackage, hands the network to NetworkManager and seeds the snaps (see Desktop flavors).
- Adds Roxora's apt repository and installs Roxora's packages: the keyring, hwtool (with its GTK app on a desktop) and the wallpapers from the repository, and the release packages of the commit, which own Roxora's apt sources, pins and cloud-init settings from then on (see Roxora's apt repository).
- On UEFI images only: leaves out
linux-dtb, replaces the GRUB settings of Armbian's GRUB support with Roxora's, removes its wallpaper and fonts, leaves out the packages it adds that Ubuntu's server image does not have (efivar,busybox,cloud-initramfs-growroot), and turns off firmware boot entry updates (see UEFI images).
A few Armbian defaults stay because they belong to the boot path or protect
the hardware, and are listed as hardware layer in
What Roxora keeps from Armbian: gzip initramfs compression
(the boot script loads a gzip uInitrd), RESUME=none, sleep states turned
off (suspend and resume are not validated on these boards), the serial console
on ttyS0 at 1500000 baud, and the hostname set to the board name.
Where packages come from
The image keeps both apt sources Armbian writes, and adds Roxora's (see Roxora's apt repository):
/etc/apt/sources.list.d/ubuntu.sources:ports.ubuntu.com, withnoble,noble-updates,noble-securityandnoble-backports./etc/apt/sources.list.d/armbian.sources:apt.armbian.com. It stays, because kernel, device tree, U-Boot and firmware updates come from it.
The Armbian repository is pinned with
roxora-hardware.pref.in,
installed as /etc/apt/preferences.d/roxora-hardware.pref:
Package: linux-image-* linux-dtb-* linux-headers-* linux-u-boot-* armbian-firmware*
Pin: release o=Armbian
Pin-Priority: 500
Package: charsiu
Pin: release o=Armbian
Pin-Priority: 500
Package: *
Pin: release o=Armbian
Pin-Priority: -1For each package apt uses the first record that matches it. The hardware
packages get priority 500, the normal priority, so apt installs and upgrades
them from Armbian. So does charsiu, an LLM runtime for the RK3576 NPU on the
mainline rocket driver that only Armbian's repository publishes; it is not
in the image, but sudo apt install charsiu finds it. Every other package in
the Armbian repository gets -1, so apt never installs or upgrades it from
there.
Which repository the hardware packages come from is set in one file,
hardware-repo.conf: today
apt.armbian.com, with origin Armbian. The pin is rendered from that file,
and verify-image.sh checks the image against it. Moving the hardware
packages to another repository (for example one run by Roxora) is a change to
that file only: the extension then writes that repository's source list and
key in place of Armbian's.
Why the pin is needed: besides its own packages, the Armbian repository
publishes packages under the names of Ubuntu packages, with higher version
numbers. Its noble-utils component carries, for example, base-files (with
Armbian's /etc/os-release), zfsutils-linux and gh. Without the pin, the
next apt upgrade would replace those Ubuntu packages with Armbian's. With
it, they come from the Ubuntu archive.
The BSP package itself (armbian-bsp-cli-*) is not in the hardware patterns.
Roxora builds its own version of it, and an update from Armbian's repository
would bring back the removed files, so it is never upgraded from there.
Roxora's apt repository
roxora-os/apt publishes Roxora's own
packages at https://roxora-os.github.io/apt, one suite per Ubuntu release
(noble, resolute) with one component, main. Its Release files are
signed with Roxora's key (Ed25519, fingerprint
07353CCFAF21725418E3CE4798FC2BE6A9A8952D). Every image has:
-
/etc/apt/sources.list.d/roxora.sources(roxora.sources.in): the URL, the image's Ubuntu release as the suite, andSigned-By: /usr/share/keyrings/roxora-archive-keyring.gpg, the key from theroxora-archive-keyringpackage. -
/etc/apt/preferences.d/roxora.pref(roxora.pref.in):Package: roxora-* Pin: origin "roxora-os.github.io" Pin-Priority: 500 Package: * Pin: origin "roxora-os.github.io" Pin-Priority: -1The records match the host the repository is served from, not a field of its Release file, so nothing but
roxora-*packages can come from there, whatever its index lists. Armbian's -1 record keeps anyroxora-*package of Armbian's repository out.
What the repository carries, and the versions an image installs from it
(roxora-repo.conf):
| Package | What it is | Built by |
|---|---|---|
roxora-archive-keyring |
the repository's key |
roxora-os/apt |
roxora-hwtool, roxora-hwtool-gtk |
hwtool and its GTK app, from hwtool's GitHub releases |
roxora-os/hwtool |
roxora-wallpapers |
the wallpapers, from roxora-os/design at a fixed commit |
roxora-os/apt |
roxora-release |
what every flavor of a release shares |
roxora-os/build, packages/ |
roxora-cli, roxora-desktop-gnome-minimal, roxora-desktop-gnome |
one per flavor |
roxora-os/build |
A new hwtool or Roxora release reaches the repository within the hour (its workflow looks every hour); a published version never changes.
Release packages
The release packages bring an installed system what a release changed in its
image. Their version is the Roxora release, + and the Ubuntu version
(2026.11.5+24.04), so each suite has its own build and a later release is
always the newer package.
roxora-release owns, as configuration files: the source list and pin of
Roxora's repository, the source list of the hardware repository
(armbian.sources, as Armbian's build writes it,
armbian.sources.in) and its
pin (roxora-hardware.pref), and cloud-init's settings (99-roxora.cfg). It
also owns /usr/share/fonts, creates /usr/local/share/fonts (see
Desktop flavors for why both must exist), and depends on
the keyring, hwtool and the wallpapers.
Each flavor package depends on roxora-release of its own version and on
what that flavor's image has in the release: roxora-cli on
NetworkManager (from 2026.11.5 on); the desktop packages on NetworkManager
and the GTK app of hwtool, they recommend Ubuntu's desktop metapackage, and
own 99-roxora-desktop.cfg. One flavor package is installed at a time;
installing another replaces it. The flavor package writes
/usr/lib/roxora-release, linked from /etc/roxora-release:
ROXORA_VERSION=2026.11.5
ROXORA_FLAVOR=cli
ROXORA_UBUNTU_CODENAME=noble
ROXORA_PACKAGE=roxora-cliSteps that apt cannot express run in the packages' maintainer scripts, once, by the version a system comes from, and never against a setting the user changed: on its first installation a desktop package disables systemd-networkd's enablement as the desktop images have it (only where Ubuntu's netplan file makes NetworkManager the renderer; nothing is stopped, it counts from the next boot). Nothing reboots, and nothing repeats the first boot or writes a bootloader.
Configuration files. Images up to 2026.11.4 have Roxora's files without a
package. dpkg takes over a file that is exactly as the package ships it;
for older versions of a file, the package's preinst moves it aside when its
SHA-256 is that of an earlier image
(takeover.list), and puts
it back if the installation fails. A file the user changed stays, and dpkg
asks about it, as about any configuration file. Removing roxora-release
leaves its files in place; purging it removes the sources and pins of both
repositories together, so the system then takes nothing more from either.
The image build runs packages/build.sh
and installs the release packages it writes, with the other packages from
the repository at the versions of roxora-repo.conf. roxora-os/apt runs the
same script at the release's tag to publish them. So a change to the
release packages is built and checked with the images before it reaches any
installed system, and a release's packages reach the repository with the
release, not before. A release tag must carry its version as
ROXORA_RELEASE (release.yml checks).
Images install packages without their recommended packages; apt installs
those on a running system. A release that adds a package to a flavor
package should check what that package recommends: apt full-upgrade
brings it on upgraded systems. The upgrade test (see
Verification) shows it.
Ubuntu release upgrades
From 24.04 to 26.04 with Ubuntu's own release upgrader, as
Installing Roxora says: apt full-upgrade,
then do-release-upgrade, nothing by hand. Not supported yet: it passes in
CI, and has not been run on a board (B9 of
Hardware test). What makes it work:
roxora-releasedepends onubuntu-release-upgrader-core, which Ubuntu's server images have and Roxora's command line images lacked.- The upgrader turns off every apt source it does not know. It reads
/etc/update-manager/release-upgrades.d/*.cfg, and a[ThirdPartyMirrors]section there names archives it moves to the new release like Ubuntu's own (isThirdPartyMirrorin itsDistUpgradeController.py).roxora-releaseshipsroxora.cfgthere (release-upgrades.cfg.in) with Roxora's repository and the hardware repository, and nothing else: other third-party sources are turned off as Ubuntu does. - The upgrader moves only the suite: Armbian's components keep the names
noble-utilsandnoble-desktop. The 26.04roxora-release, which the upgrader installs from Roxora's repository during the upgrade, recognises that edit of the 24.04 package'sarmbian.sources(and ofroxora.sources, and theEnabled: nothe upgrader writes without the configuration) by SHA-256, writes back what the 24.04 package shipped, and dpkg replaces it with the 26.04 file (resolute-utils,resolute-desktop) without asking. - 26.04 has chrony where 24.04 has systemd-timesyncd.
roxora-release26.04 depends onchrony | time-daemon, as Ubuntu'subuntu-minimaldoes: a new image has chrony, an upgraded system keeps timesyncd, as an upgraded Ubuntu server. A plain dependency on chrony made the upgrader and apt keep the release packages back. - 26.04 requires the unified cgroup v2 hierarchy; the upgrader refuses a
system without it. systemd mounts it unless the kernel command line turns
it off, and nothing in Roxora's or Armbian's boot files does
(
verify-image.shchecksboot.cmd,armbianEnv.txtand GRUB's settings, and that the kernel has cgroups). On a board this is B2 of the hardware test. - The hardware layer stays: the upgrader removes none of Armbian's packages
or the BSP package as obsolete, and initramfs-tools stays, whose hook
makes the
uInitrdthe boot script loads (26.04 otherwise uses dracut).
.github/workflows/release-upgrade.yml
(release-upgrade-test.sh) runs the
commands of install.md as written on the previous release's 24.04 ROCK 4D
images (command line, GNOME minimal, GNOME) and RK3576 UEFI command line
image, each first updated as in "Updating to a new Roxora release", in a
chroot, with the upgrader's non-interactive front end. Release packages not
yet published come from a local repository that the test adds to the
upgrader's [ThirdPartyMirrors]. Each result passes
verify-image.sh --upgraded as a 26.04 system, a second
apt full-upgrade has nothing to do, and the UEFI image then boots in QEMU
to the kernel. What an upgraded system has that a new 26.04 image does not,
and why, is in
allowlist-upgraded and
keep-modified-upgraded.
What the chroot cannot show: services do not run, so the upgrader skips its snap steps (on a running desktop it moves the snaps to their 26.04 channels through snapd, as on Ubuntu; in a desktop image that has not booted the 24.04 seed stays and snapd installs it at the first boot), and nothing reboots into 26.04 there.
Boot
There are two kinds of image: board images, which carry U-Boot and boot the way Armbian boots the board, and UEFI images, which carry no bootloader and are started by UEFI firmware already on the board.
Board images: Armbian's boot method, as is
Roxora does not change how the boards boot. For both supported boards Armbian's method is a U-Boot boot script:
- U-Boot loads
/boot/boot.scr, compiled from/boot/boot.cmd. - The script reads
/boot/armbianEnv.txt(device tree file name, overlays, kernel arguments). - It loads
/boot/Image,/boot/uInitrdand/boot/dtb/<fdtfile>, applies overlays from/boot/dtb/rockchip/overlay/and/boot/overlay-user/, and starts the kernel.
/boot/Image, /boot/uInitrd and /boot/dtb are links to the files of the
installed kernel. The kernel and device tree packages update the links, and
the BSP's initramfs hook wraps each new initramfs as uInitrd with
mkimage. There is no boot menu: the board boots the one installed kernel.
Where U-Boot itself lives depends on the board. The image carries U-Boot at 32 KiB, and the CM5-IO starts it from the eMMC or SD card it boots from. The ROCK 4D never boots from the SD card in the first stage: it needs a mainline U-Boot in its SPI NOR flash, which then boots the SD card. Hardware test has the details for both boards.
UEFI images
generic-rk3576-uefi is one image for every RK3576 board that runs UEFI firmware,
for example edk2-rk3576 on the
ROCK 4D (in SPI NOR flash) or the CM5-IO (on eMMC or an SD card). It boots
like other arm64 Ubuntu systems:
- The firmware starts
\EFI\BOOT\BOOTAA64.EFIfrom the image's EFI system partition. That is GRUB, from Ubuntu'sgrub-efi-arm64package. - GRUB reads
/boot/grub/grub.cfg, whichupdate-grubwrites from/etc/default/gruband/etc/default/grub.d/, shows its menu for three seconds and loads/boot/vmlinuz-<version>and/boot/initrd.img-<version>. - The kernel takes the device tree from the firmware (EFI configuration table). GRUB loads none, so the same image works on every board the firmware supports, and the device tree is the one the firmware was built and tested with.
The kernel is the same as on the board images: Armbian's
linux-image-edge-rockchip64, with the rocket NPU driver. Its device tree
files are in /usr/lib/linux-image-<version>/rockchip/; the linux-dtb
package is not installed, because Ubuntu's 10_linux (as of GRUB 2.12)
writes a devicetree line for any /boot/dtb-<version> or /boot/dtb it
finds, and has no setting to turn that off.
The image also carries Armbian's device trees for the SoC on the EFI system
partition, as \dtb\rockchip\<name>.dtb (for example
rk3576-rock-4d.dtb). That is where edk2-rk3576's device tree override
looks: with "Support DTB override & overlays" on, the firmware loads the
file named after its board from the drive it boots from, applies its
fix-ups and passes that instead of its own (see
Installing Roxora).
The kernel hook
zz-roxora-efi-dtb in
/etc/kernel/postinst.d copies the device trees of every kernel that is
installed or updated, and removes those the kernel no longer has, so they
always match the kernel. No overlays are copied: the firmware applies every
overlay in its overlay directory.
Disk layout: GPT, an EFI system partition of 256 MiB (FAT, mounted at
/boot/efi) at 16 MiB, then the root file system. Nothing is written
before the first partition apart from the partition table.
Kernel updates from Armbian's repository run Ubuntu's zz-update-grub
hook, which writes a new grub.cfg. Armbian's kernel package has one name
per branch (linux-image-edge-rockchip64), so an update replaces the
kernel instead of adding one; the menu lists the kernels of the installed
branches, and going back to an older kernel is a package downgrade, as on
the board images. GRUB updates come from the Ubuntu archive; their grub-install
also refreshes \EFI\BOOT\BOOTAA64.EFI. The image sets
grub2/update_nvram to false: GRUB updates write no boot entry into the
firmware, which edk2-rk3576 does not keep from Linux, and its runtime
services fault when Linux tries. The firmware boots the removable-media path
instead.
Roxora's GRUB settings are in
grub.cfg.in, installed as
/etc/default/grub.d/90-roxora.cfg: kernel messages on the SoC's serial
port (ttyS0 at 1500000 baud on RK3576) and the display, and the menu on
the firmware's console. Everything else is Ubuntu's /etc/default/grub.
There is no shim: secure boot is not set up on these boards, and shim's
fallback loader writes boot entries the firmware does not keep.
The image is built by Armbian's own GRUB support (the grub extension) on a
Roxora board file,
generic-rk3576-uefi.conf, which
picks Armbian's rk35xx family for the kernel and sets no U-Boot
(BOOTCONFIG=none). What all UEFI images share is in
board.inc, so a UEFI image for
another SoC is a board file that names its family, SoC and serial console
(see Adding a board).
The hostname is the image name, generic-rk3576-uefi.
Kernel branches
Each board image exists with Armbian's edge kernel (mainline Linux) and
with its vendor kernel (Rockchip's Linux 6.1, the rk35xx family's
vendor branch); boards.conf has a row for each. Everything above holds
for both: the same extension, the same Ubuntu userspace, the same pin. What
differs comes from Armbian:
- The kernel packages are
linux-image-vendor-rk35xxandlinux-dtb-vendor-rk35xx, updated from Armbian's repository like the edge ones. - U-Boot. The ROCK 4D uses mainline U-Boot with either kernel. The CM5-IO
with the vendor kernel uses Rockchip's U-Boot, which the image carries as
two files,
idbloader.imgat 32 KiB andu-boot.itbat 8 MiB, where the mainline build is oneu-boot-rockchip.bin.verify-image.shcompares whichever the installed U-Boot package has with the image. - The serial console of the vendor kernel is
ttyFIQ0. - The GPU. The vendor desktop images use Mesa and panfrost, not Rockchip's
Mali driver or
libmali: Armbian's vendor kernel is built with thepanfrostdriver and without Arm's kbase driver for this GPU (CONFIG_DRM_PANFROST=m, noCONFIG_MALI_BIFROST), so Mesa drives the Mali-G52 as it does on the edge kernel and the desktop flavors need nothing else. The check reads the kernel's configuration from the image and fails a desktop image whose kernel has no panfrost, or has Arm's driver, or that carries alibmali.
The UEFI image has both branches too, command line only for vendor.
Desktop flavors
boards.conf gives every image a flavor. cli is the command line image
described so far. gnome-minimal and gnome are the same image with
Ubuntu's GNOME desktop on top, built in the same run:
./build.sh ... FLAVOR=gnome-minimal. Armbian's desktop support is not
used: it installs Armbian's own desktop package sets and settings, and
Roxora wants what Ubuntu ships.
Packages. After the Ubuntu files are restored, the extension installs one
metapackage with its recommended packages, as apt install does on a
running system: ubuntu-desktop-minimal for gnome-minimal,
ubuntu-desktop for gnome. That brings GDM, GNOME Shell and Ubuntu's
session, NetworkManager, the fonts (Noto CJK among them), the language
tools and, for gnome, LibreOffice and the other applications of a default
Ubuntu installation. Nothing is taken from Armbian's repository: the pin
keeps everything but the hardware layer out.
Snaps. Ubuntu delivers Firefox, the App Center and Thunderbird as snaps;
the firefox and thunderbird packages only install the snap, and skip
that where no snapd runs, as in an image build. The build seeds the snaps
the way Ubuntu's image builds do (livecd-rootfs, ubuntu-image):
snap prepare-image --classic with the store's generic-classic model
writes the snap files and their assertions to /var/lib/snapd/seed, and
snapd installs them from there at the first boot, without a network.
snaps.list names the snaps
and channels, taken from the manifests of Ubuntu's arm64 desktop images;
the build adds the base and content snaps those need today
(snap-closure.py), since
a snap can move to a newer base after Ubuntu made its image. The snaps come
from the store on the day of the build, so two builds can carry different
revisions; after the first boot snapd updates them anyway. Ubuntu's builds
also run snap-preseed, which does part of the first-boot work at build
time; Roxora does not, so the first boot of a desktop image spends a few
minutes installing the seed.
Fonts in snaps. snapd gives a snap the host's fonts through the font directories that exist when it sets the snap up. In a desktop image the fonts are installed when the image is built and the snaps are set up at the first boot, so Firefox sees them.
Network. A command line image runs wired Ethernet with systemd-networkd,
from the netplan file cloud-init writes from the image's seed, as Ubuntu's
server images do. It also has NetworkManager, installed without its
recommended packages, for nmtui and nmcli: Ubuntu's network-manager
package ships
/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf with
unmanaged-devices=*,except:type:wifi,except:type:gsm,except:type:cdma, so
there it manages Wi-Fi and mobile broadband and nothing else. netplan lifts
that only when a netplan file makes NetworkManager the renderer, which no
file of a command line image does. Roxora adds no setting of its own; the
check fails if that default changes.
On a desktop NetworkManager runs every device: ubuntu-settings
ships /usr/lib/netplan/00-network-manager-all.yaml, which makes it
netplan's renderer, as on an installed Ubuntu desktop. So the desktop
flavors differ from cli in two ways. cloud-init writes no network
configuration
(99-roxora-desktop.cfg;
the cli seed's network-config is left out), and systemd-networkd, which
Armbian's build enables, is disabled again. Ubuntu's systemd package does
not enable it either: netplan starts it when a configuration asks for it.
Left enabled, systemd-networkd-wait-online would hold every boot for two
minutes, waiting for links it does not manage.
First login. Ubuntu's preinstalled desktop images create the first user on
the display (oem-config on 24.04, gnome-initial-setup on 26.04). Roxora
keeps the account of the cli image, roxora with an expired password, in
every flavor: a board can then be set up over SSH or the serial console
without a display, and the documentation is the same for all images. GDM
asks for the new password through PAM. cloud-init still does the rest of
the first boot (host keys, growing the root file system, the swap file).
On the desktop flavors roxora is also in the lpadmin and users
groups, as Ubuntu's first desktop user is.
Roxora's own parts are packages from
Roxora's apt repository: roxora-wallpapers, in
every flavor, whose settings override makes Facet the default wallpaper,
roxora-hwtool-gtk, the GTK app of hwtool, and the flavor's release
package (roxora-desktop-gnome-minimal or roxora-desktop-gnome).
The boot is not changed: no boot splash is set up, so kernel messages show until GDM starts.
Verification
verify/verify-image.sh mounts an image read-only (changes go to a
throwaway overlay) and checks:
- every installed package is in Ubuntu's own image, belongs to the
hardware layer, or is on the
allowlist, against the reference
manifests in
verify/reference/: the server image forcli, and with it Ubuntu's desktop images for the desktop flavors; - the pin file is installed unchanged, the Armbian source list is present,
only hardware packages have an Armbian candidate,
base-filescomes from the Ubuntu archive, and a simulatedfull-upgradetakes nothing else from Armbian; - Roxora's repository: its source list, pin and key (fingerprint as in
roxora-repo.conf) and the hardware repository's source list and pin are asroxora-releaseandroxora-archive-keyringship them and owned by them; onlyroxora-*packages have their candidate in Roxora's repository, and a simulatedfull-upgradetakes nothing else from it; - the release packages:
roxora-releaseand the flavor's package at the release ofroxora-repo.conffor the image's Ubuntu release, no other flavor package, and/etc/roxora-releasewith that release and flavor; the keyring, hwtool (and its GTK app on a desktop) and the wallpapers at the versions ofroxora-repo.conf, from Roxora's repository; - none of the removed paths exist,
dpkg --verifyfinds no changed Ubuntu files beyondkeep-modified.list, and/etc/os-releaseis Ubuntu's; - board images: the boot script, environment, kernel,
uInitrd, device tree and the bootloader at 32 KiB are in place and match the installed packages; - UEFI images (those with an EFI system partition): GPT, the EFI system
partition is FAT and mounted at
/boot/efi,\EFI\BOOT\BOOTAA64.EFIis the GRUB imagegrub-installmade,grub.cfgisupdate-grub's and starts the installed kernel and initrd with Roxora's arguments and no device tree, the SoC's device trees on the EFI system partition are the installed kernel's and the kernel hook that keeps them so is in place, there is no U-Boot (package, boot script, or data between 32 KiB and the first partition), GRUB comes from the Ubuntu archive andgrub2/update_nvramis false; - cloud-init is seeded, the
roxoraaccount exists with an expired password, root is locked, there is no autologin, and automatic updates are on; - desktop flavors: GDM is the display manager and the system boots to
graphical.target, without automatic login; NetworkManager is enabled and netplan's renderer, cloud-init writes no network configuration and systemd-networkd is not enabled; the CJK fonts are installed; the default wallpaper in the compiled GNOME settings is Facet; every snap ofsnaps.listis in the seed in its channel, the model isgeneric-classic, andsnap debug validate-seedaccepts the seed. Acliimage must have none of the desktop parts.
The flavor is read from the image (which desktop metapackage is installed); CI also passes the flavor it built, and a mismatch fails.
CI runs it on every image, and its output is published with each release
(see Release contract). It cannot tell whether a
board boots; that is what Hardware test is for. For
UEFI images CI also boots the image in QEMU (arm64 virt machine, Ubuntu's
edk2 build, device tree from the firmware) and checks that the firmware
starts GRUB and GRUB starts the kernel
(qemu-boot.sh). QEMU is not a board, so this
says nothing about the board's hardware.
The upgrade test (.github/workflows/upgrade.yml,
upgrade-test.sh) takes published images of
the previous release (a command line board image, a command line UEFI image
and a desktop image), runs the commands of
Updating to a new Roxora release
in a chroot as they are written, with the release packages of the commit
under test, and checks the result with verify-image.sh --upgraded: the
same checks as for a new image, except that the bootloader on the disk may
be older than an updated U-Boot package. A question from dpkg about a
configuration file fails it. The images have not booted, so it says
nothing about services of a running system.
What Roxora does not do
- No kernel or U-Boot patches of its own. Hardware support is whatever Armbian ships at the pinned commit; hardware fixes are made in Armbian.
- No changes to Armbian's boot method on board images. UEFI images use Armbian's own GRUB support; Roxora only replaces its settings.
- No UEFI firmware in any image. The firmware is installed on the board on its own, from its own project.
- No
armbian-config, and no Roxora replacement for it. Configuration is done the Ubuntu way. - No desktop of its own. The desktop flavors are Ubuntu's GNOME desktop as Ubuntu packages it; there are no other desktops. With the vendor kernel the desktop is the same: Mesa on the kernel's panfrost driver, and no Mali userspace from Rockchip (see FAQ).
- No Debian images. Roxora is Ubuntu only, starting with 24.04 (noble).
- No packages of other projects in its apt repository. Userspace updates come from the Ubuntu archive, hardware updates from Armbian; Roxora's repository carries only Roxora's own packages, and the pin takes nothing else from it.