#!/usr/bin/env bash # Runs inside the Docker container (aarch64). # Produces /dist/orionos-arm64.iso using archiso's "releng" profile as a base. set -euo pipefail DIST="${DIST:-/dist}" WORK=/tmp/orionos-work PROFILE=/tmp/orionos-profile SRC=/orionos echo "════════════════════════════════════════" echo " OrionOS ARM64 ISO Builder" echo "════════════════════════════════════════" # ── 1. Start from archiso's releng profile ──────────────────────────── echo ">>> Copying archiso releng profile..." cp -r /usr/share/archiso/configs/releng "$PROFILE" # ── 2. Package list — ARM64 (no syslinux, no Intel GPU, no broadcom-wl) cat > "$PROFILE/packages.aarch64" <<'PKGS' base linux-aarch64 linux-firmware mkinitcpio grub efibootmgr xorg-server xorg-xinit xorg-xrandr xorg-xset xorg-xsetroot xterm alacritty ttf-dejavu ttf-liberation noto-fonts libxft fontconfig imlib2 xf86-video-fbdev xf86-video-vesa mesa xf86-input-libinput spice-vdagent alsa-utils alsa-firmware pipewire pipewire-alsa pipewire-pulse wireplumber networkmanager networkmanager-openvpn thunar gvfs gvfs-smb tumbler ffmpegthumbnailer file-roller mousepad feh picom xbindkeys arandr pavucontrol brightnessctl dunst network-manager-applet polkit-gnome xdg-user-dirs xdg-utils shared-mime-info desktop-file-utils adwaita-icon-theme gnome-themes-extra hicolor-icon-theme firefox mpv evince viewnior xscreensaver xfce4-power-manager bluez blueman xclip scrot parcellite papirus-icon-theme pacman-contrib zip unzip p7zip wget curl man-db noto-fonts-emoji playerctl xorg-xkill rsync arch-install-scripts htop nano git sudo bash-completion fastfetch plymouth PKGS # Remove the x86_64 package list so archiso doesn't get confused rm -f "$PROFILE/packages.x86_64" # ── 3. airootfs overlay — files that land in the live system ───────── AIROOTFS="$PROFILE/airootfs" # ── Ship our own archiso mkinitcpio hooks ──────────────────────────── mkdir -p "$AIROOTFS/usr/lib/initcpio/hooks" mkdir -p "$AIROOTFS/usr/lib/initcpio/install" cat > "$AIROOTFS/usr/lib/initcpio/hooks/archiso" <<'HOOK' run_hook() { export mount_handler="archiso_mount_handler" } archiso_mount_handler() { local _newroot="${1}" local _dev _sfs _i [ -z "${archisobasedir}" ] && archisobasedir="arch" if [ -z "${archisolabel}" ]; then echo "ERROR: archisolabel not set" return 1 fi _i=0 while [ "${_i}" -lt 30 ]; do _dev=$(blkid --match-token LABEL="${archisolabel}" --output device 2>/dev/null | head -1) [ -n "${_dev}" ] && break sleep 1 _i=$((_i + 1)) done if [ -z "${_dev}" ]; then echo "ERROR: archiso: cannot find device with label '${archisolabel}'" return 1 fi mkdir -p /run/archiso/bootmnt mount -r "${_dev}" /run/archiso/bootmnt # aarch64 squashfs path _sfs="/run/archiso/bootmnt/${archisobasedir}/aarch64/airootfs.sfs" mkdir -p /run/archiso/airootfs mount -r -t squashfs "${_sfs}" /run/archiso/airootfs mkdir -p /run/archiso/cowspace mount -t tmpfs -o "size=75%,mode=0755" tmpfs /run/archiso/cowspace mkdir -p /run/archiso/cowspace/upper /run/archiso/cowspace/work mount -t overlay overlay \ -o "lowerdir=/run/archiso/airootfs,upperdir=/run/archiso/cowspace/upper,workdir=/run/archiso/cowspace/work" \ "${_newroot}" } HOOK cat > "$AIROOTFS/usr/lib/initcpio/install/archiso" <<'INSTALL' build() { add_runscript add_binary blkid add_binary sleep add_module squashfs add_module overlay add_module iso9660 add_module vfat add_dir /run/archiso/bootmnt add_dir /run/archiso/airootfs add_dir /run/archiso/cowspace } help() { echo "Mounts the archiso squashfs for live boot." } INSTALL mkdir -p "$AIROOTFS/etc/mkinitcpio.conf.d" cat > "$AIROOTFS/etc/mkinitcpio.conf.d/archiso.conf" <<'MKCONF' MODULES=() BINARIES=() FILES=() HOOKS=(base udev plymouth archiso block filesystems keyboard) MKCONF cat > "$AIROOTFS/etc/hostname" <<'EOF' orionos EOF mkdir -p "$AIROOTFS/etc/sudoers.d" echo "%wheel ALL=(ALL) ALL" > "$AIROOTFS/etc/sudoers.d/wheel" # ── 4. Install OrionOS binaries ───────────────────────────────────────── echo ">>> Installing OrionOS binaries..." mkdir -p "$AIROOTFS/usr/local/bin" install -m755 "$SRC/wm/orionwm" "$AIROOTFS/usr/local/bin/orionwm" install -m755 "$SRC/deskbar/oriondeskbar" "$AIROOTFS/usr/local/bin/oriondeskbar" install -m755 "$SRC/launcher/orionlauncher" "$AIROOTFS/usr/local/bin/orionlauncher" install -m755 "$SRC/themes/orionwallpaper" "$AIROOTFS/usr/local/bin/orionwallpaper" install -m755 "$SRC/nebula/nebula" "$AIROOTFS/usr/local/bin/nebula" install -m755 "$SRC/orionpkg/orionpkg" "$AIROOTFS/usr/local/bin/orionpkg" install -m755 "$SRC/installer/orioninstall" "$AIROOTFS/usr/local/bin/orioninstall" if [[ -f "$SRC/installer/orioninstall-gui" ]]; then install -m755 "$SRC/installer/orioninstall-gui" "$AIROOTFS/usr/local/bin/orioninstall-gui" fi if [[ -f "$SRC/rigel/rigel" ]]; then install -m755 "$SRC/rigel/rigel" "$AIROOTFS/usr/local/bin/rigel" fi if [[ -f "$SRC/quill/quill" ]]; then install -m755 "$SRC/quill/quill" "$AIROOTFS/usr/local/bin/quill" fi if [[ -f "$SRC/lens/lens" ]]; then install -m755 "$SRC/lens/lens" "$AIROOTFS/usr/local/bin/lens" fi # ── 5. GTK theme ────────────────────────────────────────────────────── echo ">>> Installing GTK theme..." mkdir -p "$AIROOTFS/usr/share/themes" cp -r "$SRC/themes/OrionOS" "$AIROOTFS/usr/share/themes/" # ── 6. picom config ─────────────────────────────────────────────────── mkdir -p "$AIROOTFS/etc/orionos" install -m644 "$SRC/themes/picom.conf" "$AIROOTFS/etc/orionos/picom.conf" # ── 7. Default wallpaper ────────────────────────────────────────────── echo ">>> Generating default wallpaper..." mkdir -p "$AIROOTFS/usr/share/orionos/wallpapers" if convert -size 1920x1080 gradient:"#1E3A5A-#0E1A28" \ "$AIROOTFS/usr/share/orionos/wallpapers/orionos-default.png" 2>/dev/null; then echo " Wallpaper generated." else echo " (ImageMagick unavailable — wallpaper skipped)" fi # ── 8. User skeleton ────────────────────────────────────────────────── echo ">>> Writing user skeleton..." SKEL="$AIROOTFS/etc/skel" mkdir -p "$SKEL/.config/gtk-3.0" cat > "$SKEL/.xinitrc" <<'XINITRC' #!/bin/sh [ -f "$HOME/.Xresources" ] && xrdb -merge "$HOME/.Xresources" xset r rate 250 30 xrandr --dpi 96 # SPICE clipboard agent (UTM copy-paste between host and VM) spice-vdagent & orionwallpaper xdg-user-dirs-update 2>/dev/null || true export GTK_THEME=OrionOS mkdir -p "$HOME/.config/gtk-3.0" cat > "$HOME/.config/gtk-3.0/settings.ini" < "$HOME/.gtkrc-2.0" < "$SKEL/.xbindkeysrc" <<'XBK' "orionlauncher" Mod1 + F1 "nebula" super + s "brightnessctl set 10%-" XF86MonBrightnessDown "brightnessctl set +10%" XF86MonBrightnessUp "pactl set-sink-mute @DEFAULT_SINK@ toggle" XF86AudioMute "pactl set-sink-volume @DEFAULT_SINK@ -5%" XF86AudioLowerVolume "pactl set-sink-volume @DEFAULT_SINK@ +5%" XF86AudioRaiseVolume XBK mkdir -p "$AIROOTFS/etc/fonts" cat > "$AIROOTFS/etc/fonts/local.conf" <<'FONTS' true true hintslight rgb lcddefault sans-serif DejaVu SansNoto Color Emoji monospace DejaVu Sans Mono FONTS cat > "$SKEL/.Xresources" <<'XRES' XTerm*faceName: DejaVu Sans Mono XTerm*faceSize: 11 XTerm*renderFont: true XTerm*antialias: true XTerm*background: #0E1520 XTerm*foreground: #C8D4E8 XTerm*cursorColor: #4A90D9 XTerm*scrollBar: false XTerm*saveLines: 4096 XTerm*metaSendsEscape: true XTerm*utf8: 2 XTerm*color0: #1A1E2A XTerm*color1: #CC4444 XTerm*color2: #44AA66 XTerm*color3: #BBAA22 XTerm*color4: #4488CC XTerm*color5: #8844CC XTerm*color6: #44AACC XTerm*color7: #C8D4E8 XTerm*color8: #3A4050 XTerm*color9: #FF6666 XTerm*color10: #66CC88 XTerm*color11: #DDCC44 XTerm*color12: #66AAFF XTerm*color13: #AA66FF XTerm*color14: #66CCEE XTerm*color15: #EEF4FF XRES mkdir -p "$SKEL/.config/alacritty" cat > "$SKEL/.config/alacritty/alacritty.toml" <<'ALACRITTY' [window] padding = { x = 10, y = 8 } decorations = "none" opacity = 0.96 title = "Terminal" [font] normal = { family = "DejaVu Sans Mono", style = "Regular" } bold = { family = "DejaVu Sans Mono", style = "Bold" } size = 11.0 [colors.primary] background = "#0E1520" foreground = "#C8D4E8" [colors.cursor] text = "#0E1520" cursor = "#4A90D9" [colors.normal] black = "#1A1E2A" red = "#CC4444" green = "#44AA66" yellow = "#BBAA22" blue = "#4488CC" magenta = "#8844CC" cyan = "#44AACC" white = "#C8D4E8" [colors.bright] black = "#3A4050" red = "#FF6666" green = "#66CC88" yellow = "#DDCC44" blue = "#66AAFF" magenta = "#AA66FF" cyan = "#66CCEE" white = "#EEF4FF" [colors.selection] background = "#2060A0" text = "#F0F4FF" [scrolling] history = 10000 [cursor] style = { shape = "Block", blinking = "On" } blink_interval = 500 ALACRITTY mkdir -p "$SKEL/.config/dunst" cat > "$SKEL/.config/dunst/dunstrc" <<'DUNST' [global] font = Sans 10 geometry = "300x5-20+46" transparency = 0 frame_color = "#2A3A5A" frame_width = 1 separator_color = "#2A3A5A" sort = yes indicate_hidden = yes shrink = no markup = full format = "%s\n%b" alignment = left word_wrap = yes padding = 10 horizontal_padding = 10 max_icon_size = 32 sticky_history = yes history_length = 20 browser = firefox [urgency_low] background = "#1C2230" foreground = "#A0B8D0" timeout = 5 [urgency_normal] background = "#1E3050" foreground = "#D0E0F0" timeout = 8 [urgency_critical] background = "#5A1010" foreground = "#FFD0D0" frame_color = "#AA2020" timeout = 0 DUNST cat > "$SKEL/.config/gtk-3.0/settings.ini" <<'GTK3' [Settings] gtk-theme-name=OrionOS gtk-font-name=Sans 10 gtk-icon-theme-name=Adwaita gtk-cursor-theme-name=DMZ-White GTK3 # ── Plymouth dark navy boot splash ─────────────────────────────────── echo ">>> Creating Plymouth theme..." PLYM="$AIROOTFS/usr/share/plymouth/themes/orionos" mkdir -p "$PLYM" cat > "$PLYM/orionos.plymouth" <<'PLYMDEF' [Plymouth Theme] Name=OrionOS Description=OrionOS dark navy boot splash ModuleName=script [script] ImageDir=/usr/share/plymouth/themes/orionos ScriptFile=/usr/share/plymouth/themes/orionos/orionos.script PLYMDEF cat > "$PLYM/orionos.script" <<'PLYMSCRIPT' W = Window.GetWidth(); H = Window.GetHeight(); Window.SetBackgroundTopColor(0.067, 0.082, 0.125); Window.SetBackgroundBottomColor(0.040, 0.055, 0.090); logo = Image("logo.png"); logo_sprite = Sprite(logo); logo_sprite.SetPosition( Math.Int((W - logo.GetWidth()) / 2), Math.Int(H * 0.40 - logo.GetHeight() / 2), 1 ); BAR_W = Math.Int(Math.Min(W * 0.42, 440)); BAR_H = 4; bar_x = Math.Int((W - BAR_W) / 2); bar_y = Math.Int(H * 0.72); bar_bg = Image("bar_bg.png").Scale(BAR_W, BAR_H); bar_bg_sprite = Sprite(bar_bg); bar_bg_sprite.SetPosition(bar_x, bar_y, 2); bar_fill_sprite = Sprite(); bar_fill_sprite.SetPosition(bar_x, bar_y, 3); fun boot_progress_callback(time, progress) { fill_w = Math.Int(BAR_W * progress); if (fill_w < 2) fill_w = 2; bar_fill = Image("bar_fg.png").Scale(fill_w, BAR_H); bar_fill_sprite.SetImage(bar_fill); } Plymouth.SetBootProgressFunction(boot_progress_callback); PLYMSCRIPT if command -v convert &>/dev/null; then convert -size 340x90 xc:none \ -font DejaVu-Sans-Bold -pointsize 62 \ -fill "#90BBEE" -gravity center \ -annotate 0 "OrionOS" \ "$PLYM/logo.png" 2>/dev/null || true convert -size 1x1 xc:"#1C2840" "$PLYM/bar_bg.png" 2>/dev/null || true convert -size 1x1 xc:"#1E58A8" "$PLYM/bar_fg.png" 2>/dev/null || true fi # ── VirtIO / QEMU display config (UTM) ──────────────────────────────── mkdir -p "$AIROOTFS/etc/X11/xorg.conf.d" cat > "$AIROOTFS/etc/X11/xorg.conf.d/20-virtio.conf" <<'VIRTIO' Section "Device" Identifier "VirtIO GPU" Driver "modesetting" Option "AccelMethod" "none" EndSection VIRTIO cat > "$AIROOTFS/etc/X11/xorg.conf.d/40-libinput.conf" <<'TOUCHPAD' Section "InputClass" Identifier "Touchpad" MatchIsTouchpad "on" Driver "libinput" Option "Tapping" "on" Option "NaturalScrolling" "true" Option "ScrollMethod" "twofinger" EndSection TOUCHPAD cat > "$AIROOTFS/etc/X11/xorg.conf.d/10-keyboard.conf" <<'KEYBOARD' Section "InputClass" Identifier "All Keyboards" MatchIsKeyboard "on" Driver "libinput" Option "XkbLayout" "us" Option "XkbOptions" "terminate:ctrl_alt_bksp" EndSection KEYBOARD # ── 9. profiledef.sh — aarch64, EFI only ───────────────────────────── cat > "$PROFILE/profiledef.sh" <<'PROFILEDEF' #!/usr/bin/env bash iso_name="orionos-arm64" iso_label="ORIONOS_ARM64_$(date +%Y%m)" iso_publisher="OrionOS Project" iso_application="OrionOS — BeOS-inspired Linux Desktop (ARM64)" iso_version="0.2" install_dir="arch" buildmodes=('iso') bootmodes=('uefi.systemd-boot') arch="aarch64" pacman_conf="pacman.conf" airootfs_image_type="squashfs" airootfs_image_tool_options=('-comp' 'zstd' '-Xcompression-level' '5' '-b' '1M') bootstrap_tarball_compression=('zstd' '-c' '-T0' '--auto-threads=logical' '--long' '-19') file_permissions=( ["/etc/shadow"]="0:0:400" ["/etc/skel/.xinitrc"]="0:0:755" ["/root/customize_airootfs.sh"]="0:0:755" ["/usr/local/bin/orionwm"]="0:0:755" ["/usr/local/bin/oriondeskbar"]="0:0:755" ["/usr/local/bin/orionlauncher"]="0:0:755" ["/usr/local/bin/orionwallpaper"]="0:0:755" ["/usr/local/bin/nebula"]="0:0:755" ["/usr/local/bin/orionpkg"]="0:0:755" ["/usr/local/bin/orioninstall"]="0:0:755" ) PROFILEDEF # ── 10. EFI boot loader (aarch64 kernel paths) ─────────────────────── mkdir -p "$PROFILE/efiboot/loader/entries" cat > "$PROFILE/efiboot/loader/loader.conf" <<'LOADER' default orionos.conf timeout 5 editor no LOADER cat > "$PROFILE/efiboot/loader/entries/orionos.conf" <<'ENTRY' title OrionOS ARM64 linux /arch/boot/aarch64/vmlinuz-linux-aarch64 initrd /arch/boot/aarch64/initramfs-linux-aarch64.img options archisobasedir=arch archisolabel=%ARCHISO_LABEL% quiet splash loglevel=3 ENTRY # ── 11. Auto-login ──────────────────────────────────────────────────── mkdir -p "$AIROOTFS/etc/systemd/system/getty@tty1.service.d" cat > "$AIROOTFS/etc/systemd/system/getty@tty1.service.d/autologin.conf" <<'AUTOLOGIN' [Service] ExecStart= ExecStart=-/sbin/agetty --autologin orion --noclear %I $TERM AUTOLOGIN cat > "$SKEL/.bash_profile" <<'BASH_PROFILE' if [[ -z $DISPLAY && $XDG_VTNR -eq 1 ]]; then startx 2>&1 | tee /tmp/x-session.log fi BASH_PROFILE # ── 12. customize_airootfs.sh ──────────────────────────────────────── cat > "$PROFILE/airootfs/root/customize_airootfs.sh" <<'CUSTOMIZE' #!/usr/bin/env bash set -euo pipefail sed -i 's/#en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen locale-gen echo "LANG=en_US.UTF-8" > /etc/locale.conf ln -sf /usr/share/zoneinfo/UTC /etc/localtime useradd -m -G wheel,audio,video,storage,input -s /bin/bash orion 2>/dev/null || true echo "orion:orionos" | chpasswd echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel chmod 440 /etc/sudoers.d/wheel systemctl enable NetworkManager systemctl enable spice-vdagentd 2>/dev/null || true systemctl enable bluetooth 2>/dev/null || true systemctl enable fstrim.timer 2>/dev/null || true update-desktop-database 2>/dev/null || true fc-cache -f 2>/dev/null || true plymouth-set-default-theme orionos 2>/dev/null || true mkinitcpio -P 2>&1 | tail -5 || true mkdir -p /etc/skel cat > /etc/skel/.xscreensaver <<'SS' mode: blank timeout: 0:10:00 lock: True lockTimeout: 0:00:00 dpmsEnabled: True dpmsStandby: 0:10:00 dpmsSuspend: 0:20:00 dpmsOff: 0:30:00 SS cp -r /etc/skel/. /home/orion/ 2>/dev/null || true chown -R orion:orion /home/orion chmod +x /usr/local/bin/orionwm \ /usr/local/bin/oriondeskbar \ /usr/local/bin/orionlauncher \ /usr/local/bin/orionwallpaper \ /usr/local/bin/orioninstall 2>/dev/null || true [ -f /usr/local/bin/orioninstall-gui ] && chmod +x /usr/local/bin/orioninstall-gui echo "OrionOS ARM64 customization complete." CUSTOMIZE chmod 755 "$PROFILE/airootfs/root/customize_airootfs.sh" # ── 13. Build the ISO ───────────────────────────────────────────────── echo ">>> Building ARM64 ISO (this takes 5-15 minutes)..." mkdir -p "$DIST" "$WORK" mkarchiso -v \ -w "$WORK" \ -o "$DIST" \ "$PROFILE" echo "" echo "════════════════════════════════════════" echo " Build complete!" find "$DIST" -name "*.iso" -exec echo " ISO: {}" \; echo "════════════════════════════════════════"