mkinitcpio runs during pacstrap (kernel install) before customize_airootfs.sh, so the initramfs gets the Arch default spinner theme. Add mkinitcpio -P after plymouth-set-default-theme so the orionos theme is baked into the final initramfs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
824 lines
25 KiB
Bash
Executable File
824 lines
25 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# Runs inside the Docker container.
|
||
# Produces /dist/orionos.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 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 — trim releng defaults, add what we need ─────────
|
||
cat > "$PROFILE/packages.x86_64" <<'PKGS'
|
||
base
|
||
linux
|
||
linux-firmware
|
||
mkinitcpio
|
||
archiso
|
||
grub
|
||
efibootmgr
|
||
syslinux
|
||
xorg-server
|
||
xorg-xinit
|
||
xorg-xrandr
|
||
xorg-xset
|
||
xorg-xsetroot
|
||
xterm
|
||
alacritty
|
||
ttf-dejavu
|
||
ttf-liberation
|
||
noto-fonts
|
||
libxft
|
||
fontconfig
|
||
xf86-video-intel
|
||
xf86-video-vesa
|
||
mesa
|
||
xf86-input-libinput
|
||
alsa-utils
|
||
alsa-firmware
|
||
sof-firmware
|
||
pipewire
|
||
pipewire-alsa
|
||
pipewire-pulse
|
||
wireplumber
|
||
networkmanager
|
||
networkmanager-openvpn
|
||
broadcom-wl
|
||
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
|
||
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
|
||
|
||
# ── 3. airootfs overlay — files that land in the live system ─────────
|
||
AIROOTFS="$PROFILE/airootfs"
|
||
|
||
# ── Ship our own archiso mkinitcpio hooks ────────────────────────────
|
||
# Archiso v78+ removed the mkinitcpio hook binaries from the package.
|
||
# We provide them ourselves so the live initramfs can mount the squashfs.
|
||
mkdir -p "$AIROOTFS/usr/lib/initcpio/hooks"
|
||
mkdir -p "$AIROOTFS/usr/lib/initcpio/install"
|
||
|
||
# -- archiso hook (runtime: mounts squashfs and sets up overlay) ------
|
||
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
|
||
|
||
# Wait up to 30 s for the USB/CD device to appear
|
||
_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
|
||
|
||
# Mount the boot medium (ISO/USB)
|
||
mkdir -p /run/archiso/bootmnt
|
||
mount -r "${_dev}" /run/archiso/bootmnt
|
||
|
||
# Mount the squashfs
|
||
_sfs="/run/archiso/bootmnt/${archisobasedir}/x86_64/airootfs.sfs"
|
||
mkdir -p /run/archiso/airootfs
|
||
mount -r -t squashfs "${_sfs}" /run/archiso/airootfs
|
||
|
||
# Writable tmpfs overlay (so the live session can write)
|
||
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
|
||
|
||
# Overlay squashfs (ro) + tmpfs (rw) → new root
|
||
mount -t overlay overlay \
|
||
-o "lowerdir=/run/archiso/airootfs,upperdir=/run/archiso/cowspace/upper,workdir=/run/archiso/cowspace/work" \
|
||
"${_newroot}"
|
||
}
|
||
HOOK
|
||
|
||
# -- archiso install script (build-time: adds binaries/modules to initramfs)
|
||
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
|
||
|
||
# Override the releng archiso.conf — drop memdisk/pxe hooks (memdiskfind
|
||
# is no longer shipped by syslinux), keep only what we actually provide.
|
||
mkdir -p "$AIROOTFS/etc/mkinitcpio.conf.d"
|
||
cat > "$AIROOTFS/etc/mkinitcpio.conf.d/archiso.conf" <<'MKCONF'
|
||
MODULES=()
|
||
BINARIES=()
|
||
FILES=()
|
||
HOOKS=(base udev plymouth microcode archiso block filesystems keyboard)
|
||
MKCONF
|
||
echo ">>> Live initramfs HOOKS: base udev microcode archiso block filesystems keyboard"
|
||
|
||
# passwd / shadow / group
|
||
cat > "$AIROOTFS/etc/hostname" <<'EOF'
|
||
orionos
|
||
EOF
|
||
|
||
# Create 'orion' user in the live environment
|
||
mkdir -p "$AIROOTFS/etc/sudoers.d"
|
||
echo "%wheel ALL=(ALL) ALL" > "$AIROOTFS/etc/sudoers.d/wheel"
|
||
|
||
# ── 3b. OnlyOffice — create a local pacman repo so mkarchiso can find it
|
||
if [[ -f /onlyoffice.pkg.tar.zst ]]; then
|
||
echo ">>> Setting up local OnlyOffice repo..."
|
||
mkdir -p /orionos-local-repo
|
||
cp /onlyoffice.pkg.tar.zst /orionos-local-repo/
|
||
OO_PKG="$(find /orionos-local-repo -name '*.pkg.tar.zst' | head -1)"
|
||
repo-add /orionos-local-repo/orionos-local.db.tar.gz "$OO_PKG"
|
||
|
||
# Prepend [orionos-local] to the profile's pacman.conf
|
||
sed -i 's/^\[core\]/[orionos-local]\nSigLevel = Never\nServer = file:\/\/\/orionos-local-repo\n\n[core]/' \
|
||
"$PROFILE/pacman.conf"
|
||
|
||
echo "onlyoffice-bin" >> "$PROFILE/packages.x86_64"
|
||
echo ">>> OnlyOffice repo ready."
|
||
else
|
||
echo ">>> OnlyOffice build not available — skipping."
|
||
fi
|
||
|
||
# ── 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/installer/orioninstall" "$AIROOTFS/usr/local/bin/orioninstall"
|
||
# GUI installer (compiled binary; falls back gracefully if not built)
|
||
if [[ -f "$SRC/installer/orioninstall-gui" ]]; then
|
||
install -m755 "$SRC/installer/orioninstall-gui" "$AIROOTFS/usr/local/bin/orioninstall-gui"
|
||
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 in container — wallpaper skipped, solid color will be used)"
|
||
fi
|
||
|
||
# ── 8. User skeleton (.xinitrc, GTK config, xbindkeys) ───────────────
|
||
echo ">>> Writing user skeleton..."
|
||
SKEL="$AIROOTFS/etc/skel"
|
||
mkdir -p "$SKEL/.config/gtk-3.0"
|
||
|
||
cat > "$SKEL/.xinitrc" <<'XINITRC'
|
||
#!/bin/sh
|
||
# OrionOS session startup
|
||
|
||
# Merge X resources if present
|
||
[ -f "$HOME/.Xresources" ] && xrdb -merge "$HOME/.Xresources"
|
||
|
||
# Key repeat: 250ms delay, 30/s rate — comfortable for typing
|
||
xset r rate 250 30
|
||
|
||
# HiDPI hint for GTK/Qt (96 DPI default; bump to 144 for HiDPI Macs)
|
||
xrandr --dpi 96
|
||
|
||
# Wallpaper
|
||
orionwallpaper
|
||
|
||
# Create standard user directories (Desktop, Downloads, Pictures…)
|
||
xdg-user-dirs-update 2>/dev/null || true
|
||
|
||
# GTK theme
|
||
export GTK_THEME=OrionOS
|
||
mkdir -p "$HOME/.config/gtk-3.0"
|
||
cat > "$HOME/.config/gtk-3.0/settings.ini" <<EOF
|
||
[Settings]
|
||
gtk-theme-name=OrionOS
|
||
gtk-font-name=Sans 10
|
||
gtk-icon-theme-name=Adwaita
|
||
gtk-cursor-theme-name=Adwaita
|
||
EOF
|
||
cat > "$HOME/.gtkrc-2.0" <<EOF
|
||
include "/usr/share/themes/OrionOS/gtk-2.0/gtkrc"
|
||
EOF
|
||
|
||
# Audio session (pipewire + wireplumber)
|
||
pipewire &
|
||
pipewire-pulse &
|
||
wireplumber &
|
||
|
||
# Privilege escalation agent (needed for Thunar mounts, package managers, etc.)
|
||
/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 &
|
||
|
||
# Notifications
|
||
dunst &
|
||
|
||
# Network manager tray applet
|
||
nm-applet &
|
||
|
||
# Compositor
|
||
picom --config /etc/orionos/picom.conf &
|
||
|
||
# Clipboard sync: keep PRIMARY and CLIPBOARD selections in sync
|
||
if command -v xclip &>/dev/null; then
|
||
while true; do
|
||
xclip -o -sel primary 2>/dev/null | xclip -i -sel clipboard 2>/dev/null || true
|
||
sleep 1
|
||
done &
|
||
fi
|
||
|
||
# Screen locker daemon (locks after idle timeout)
|
||
xscreensaver -no-splash &
|
||
|
||
# Power management (handles suspend, battery alerts, lid close)
|
||
xfce4-power-manager &
|
||
|
||
# Global hotkeys
|
||
xbindkeys &
|
||
|
||
# Deskbar
|
||
oriondeskbar &
|
||
|
||
# Window manager (must be last — controls the session)
|
||
exec orionwm
|
||
XINITRC
|
||
chmod 755 "$SKEL/.xinitrc"
|
||
|
||
cat > "$SKEL/.xbindkeysrc" <<'XBK'
|
||
# App launcher
|
||
"orionlauncher"
|
||
Mod1 + F1
|
||
|
||
# Brightness (Mac Fn+F1/F2, also mapped as XF86 keys)
|
||
"brightnessctl set 10%-"
|
||
XF86MonBrightnessDown
|
||
"brightnessctl set +10%"
|
||
XF86MonBrightnessUp
|
||
|
||
# Volume (Mac Fn+F10/F11/F12)
|
||
"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
|
||
|
||
# ── Font antialiasing (system-wide) ──────────────────────────────────
|
||
mkdir -p "$AIROOTFS/etc/fonts"
|
||
cat > "$AIROOTFS/etc/fonts/local.conf" <<'FONTS'
|
||
<?xml version="1.0"?>
|
||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||
<fontconfig>
|
||
<match target="font">
|
||
<edit name="antialias" mode="assign"><bool>true</bool></edit>
|
||
<edit name="hinting" mode="assign"><bool>true</bool></edit>
|
||
<edit name="hintstyle" mode="assign"><const>hintslight</const></edit>
|
||
<edit name="rgba" mode="assign"><const>rgb</const></edit>
|
||
<edit name="lcdfilter" mode="assign"><const>lcddefault</const></edit>
|
||
</match>
|
||
<!-- Prefer noto for emoji -->
|
||
<alias>
|
||
<family>serif</family>
|
||
<prefer><family>DejaVu Serif</family><family>Noto Color Emoji</family></prefer>
|
||
</alias>
|
||
<alias>
|
||
<family>sans-serif</family>
|
||
<prefer><family>DejaVu Sans</family><family>Noto Color Emoji</family></prefer>
|
||
</alias>
|
||
<alias>
|
||
<family>monospace</family>
|
||
<prefer><family>DejaVu Sans Mono</family></prefer>
|
||
</alias>
|
||
</fontconfig>
|
||
FONTS
|
||
|
||
# ── .Xresources — nice dark xterm ────────────────────────────────────
|
||
cat > "$SKEL/.Xresources" <<'XRES'
|
||
! OrionOS dark terminal theme
|
||
XTerm*faceName: DejaVu Sans Mono
|
||
XTerm*faceSize: 11
|
||
XTerm*renderFont: true
|
||
XTerm*antialias: true
|
||
XTerm*background: #0E1520
|
||
XTerm*foreground: #C8D4E8
|
||
XTerm*cursorColor: #4A90D9
|
||
XTerm*pointerColor: #4A90D9
|
||
XTerm*selectBackground: #2060A0
|
||
XTerm*selectForeground: #F0F4FF
|
||
XTerm*scrollBar: false
|
||
XTerm*saveLines: 4096
|
||
XTerm*bellIsUrgent: true
|
||
XTerm*metaSendsEscape: true
|
||
XTerm*utf8: 2
|
||
! Colors: dark background with readable palette
|
||
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
|
||
! Urxvt (same palette, in case rxvt-unicode is used)
|
||
URxvt*font: xft:DejaVu Sans Mono:size=11
|
||
URxvt*background: #0E1520
|
||
URxvt*foreground: #C8D4E8
|
||
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
|
||
line_height = 0
|
||
markup = full
|
||
format = "<b>%s</b>\n%b"
|
||
alignment = left
|
||
show_age_threshold = 60
|
||
word_wrap = yes
|
||
ignore_newline = no
|
||
stack_duplicates = true
|
||
hide_duplicate_count = false
|
||
padding = 10
|
||
horizontal_padding = 10
|
||
max_icon_size = 32
|
||
sticky_history = yes
|
||
history_length = 20
|
||
dmenu = /usr/bin/dmenu -p dunst
|
||
browser = firefox
|
||
always_run_script = true
|
||
title = Dunst
|
||
class = Dunst
|
||
|
||
[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'
|
||
# OrionOS Plymouth boot splash — dark navy + accent blue progress bar
|
||
|
||
W = Window.GetWidth();
|
||
H = Window.GetHeight();
|
||
|
||
# Solid dark navy background
|
||
Window.SetBackgroundTopColor(0.067, 0.082, 0.125);
|
||
Window.SetBackgroundBottomColor(0.040, 0.055, 0.090);
|
||
|
||
# Logo (centered, upper third of screen)
|
||
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
|
||
);
|
||
|
||
# Progress bar
|
||
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 background track (dark blue-grey)
|
||
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 (accent blue, grows with progress)
|
||
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
|
||
|
||
# Generate PNG assets (ImageMagick is used above for the wallpaper)
|
||
if command -v convert &>/dev/null; then
|
||
# Logo: "OrionOS" in accent blue on transparent background
|
||
convert -size 340x90 xc:none \
|
||
-font DejaVu-Sans-Bold -pointsize 62 \
|
||
-fill "#90BBEE" -gravity center \
|
||
-annotate 0 "OrionOS" \
|
||
"$PLYM/logo.png" 2>/dev/null \
|
||
&& echo " Plymouth logo generated." \
|
||
|| echo " Plymouth logo generation failed (non-fatal)."
|
||
# 1×1 pixel images — scaled at runtime by the script
|
||
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
|
||
else
|
||
echo " ImageMagick not available — Plymouth PNGs skipped."
|
||
fi
|
||
|
||
# ── Mac hardware: libinput touchpad config ────────────────────────────
|
||
mkdir -p "$AIROOTFS/etc/X11/xorg.conf.d"
|
||
cat > "$AIROOTFS/etc/X11/xorg.conf.d/40-libinput.conf" <<'TOUCHPAD'
|
||
Section "InputClass"
|
||
Identifier "Apple Trackpad"
|
||
MatchIsTouchpad "on"
|
||
Driver "libinput"
|
||
Option "Tapping" "on"
|
||
Option "TappingButtonMap" "lrm"
|
||
Option "NaturalScrolling" "true"
|
||
Option "ScrollMethod" "twofinger"
|
||
Option "DisableWhileTyping" "true"
|
||
Option "ClickMethod" "clickfinger"
|
||
Option "AccelProfile" "adaptive"
|
||
Option "AccelSpeed" "0.3"
|
||
EndSection
|
||
TOUCHPAD
|
||
|
||
# ── Keyboard: US layout, Ctrl+Alt+Backspace to kill X ────────────────
|
||
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
|
||
|
||
# ── Mac: load broadcom-wl at boot ─────────────────────────────────────
|
||
mkdir -p "$AIROOTFS/etc/modules-load.d"
|
||
echo "wl" > "$AIROOTFS/etc/modules-load.d/broadcom-wl.conf"
|
||
|
||
# Blacklist conflicting Broadcom modules
|
||
mkdir -p "$AIROOTFS/etc/modprobe.d"
|
||
cat > "$AIROOTFS/etc/modprobe.d/broadcom-wl.conf" <<'MODPROBE'
|
||
blacklist b43
|
||
blacklist b43legacy
|
||
blacklist ssb
|
||
blacklist bcm43xx
|
||
blacklist brcm80211
|
||
blacklist brcmfmac
|
||
blacklist brcmsmac
|
||
blacklist bcma
|
||
MODPROBE
|
||
|
||
# Let X auto-detect the GPU via the modesetting driver (kernel DRM/KMS).
|
||
# Forcing a specific driver (intel/amdgpu/etc.) breaks VMs and cross-hardware boots.
|
||
|
||
# ── 9. profiledef.sh — archiso metadata ──────────────────────────────
|
||
cat > "$PROFILE/profiledef.sh" <<'PROFILEDEF'
|
||
#!/usr/bin/env bash
|
||
iso_name="orionos"
|
||
iso_label="ORIONOS_$(date +%Y%m)"
|
||
iso_publisher="OrionOS Project"
|
||
iso_application="OrionOS — BeOS-inspired Linux Desktop"
|
||
iso_version="0.2"
|
||
install_dir="arch"
|
||
buildmodes=('iso')
|
||
# Support both UEFI (systemd-boot) and legacy BIOS (syslinux) hardware
|
||
bootmodes=(
|
||
'bios.syslinux'
|
||
'uefi.systemd-boot'
|
||
)
|
||
arch="x86_64"
|
||
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/orioninstall"]="0:0:755"
|
||
)
|
||
PROFILEDEF
|
||
|
||
# ── 10. Boot loader configs ───────────────────────────────────────────
|
||
|
||
# systemd-boot entry (UEFI)
|
||
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
|
||
linux /arch/boot/x86_64/vmlinuz-linux
|
||
initrd /arch/boot/x86_64/initramfs-linux.img
|
||
options archisobasedir=arch archisolabel=%ARCHISO_LABEL% quiet splash loglevel=3
|
||
ENTRY
|
||
|
||
|
||
# ── 10. Auto-login to tty1 and startx ────────────────────────────────
|
||
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
|
||
|
||
# bash_profile: startx automatically on tty1 (no exec — keep shell on failure)
|
||
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
|
||
|
||
# ── 11. customize_airootfs.sh — runs inside the chroot ───────────────
|
||
cat > "$PROFILE/airootfs/root/customize_airootfs.sh" <<'CUSTOMIZE'
|
||
#!/usr/bin/env bash
|
||
set -euo pipefail
|
||
|
||
# Locale
|
||
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
|
||
|
||
# Timezone
|
||
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
|
||
|
||
# Create user 'orion' (live session user)
|
||
useradd -m -G wheel,audio,video,storage,input -s /bin/bash orion 2>/dev/null || true
|
||
echo "orion:orionos" | chpasswd
|
||
|
||
# sudoers
|
||
echo "%wheel ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/wheel
|
||
chmod 440 /etc/sudoers.d/wheel
|
||
|
||
# Enable services
|
||
systemctl enable NetworkManager
|
||
systemctl enable bluetooth 2>/dev/null || true
|
||
systemctl enable fstrim.timer 2>/dev/null || true
|
||
|
||
# MIME / default app associations
|
||
if command -v xdg-mime &>/dev/null; then
|
||
# Run as the orion user (xdg-mime needs $HOME)
|
||
sudo -u orion HOME=/home/orion XDG_DATA_HOME=/home/orion/.local/share \
|
||
xdg-mime default firefox.desktop x-scheme-handler/http \
|
||
x-scheme-handler/https \
|
||
text/html 2>/dev/null || true
|
||
sudo -u orion HOME=/home/orion XDG_DATA_HOME=/home/orion/.local/share \
|
||
xdg-mime default evince.desktop application/pdf 2>/dev/null || true
|
||
sudo -u orion HOME=/home/orion XDG_DATA_HOME=/home/orion/.local/share \
|
||
xdg-mime default viewnior.desktop image/jpeg image/png \
|
||
image/gif image/webp 2>/dev/null || true
|
||
sudo -u orion HOME=/home/orion XDG_DATA_HOME=/home/orion/.local/share \
|
||
xdg-mime default mpv.desktop video/mp4 video/mkv \
|
||
audio/mpeg audio/flac 2>/dev/null || true
|
||
sudo -u orion HOME=/home/orion XDG_DATA_HOME=/home/orion/.local/share \
|
||
xdg-mime default mousepad.desktop text/plain 2>/dev/null || true
|
||
fi
|
||
update-desktop-database 2>/dev/null || true
|
||
|
||
# Fontconfig cache
|
||
fc-cache -f 2>/dev/null || true
|
||
|
||
# Plymouth: set default theme and rebuild initramfs so the theme is baked in.
|
||
# mkinitcpio already ran during pacstrap (kernel install) before this chroot
|
||
# script executes, so we must rebuild here or the Arch default theme is used.
|
||
plymouth-set-default-theme orionos 2>/dev/null || true
|
||
mkinitcpio -P 2>&1 | tail -5 || true
|
||
|
||
# xscreensaver config (screen lock)
|
||
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
|
||
|
||
# Copy skeleton to orion's home (ensure xinitrc is present)
|
||
cp -r /etc/skel/. /home/orion/ 2>/dev/null || true
|
||
chown -R orion:orion /home/orion
|
||
|
||
# Ensure OrionOS binaries are executable (permissions can be lost through squashfs build)
|
||
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 customization complete."
|
||
CUSTOMIZE
|
||
chmod 755 "$PROFILE/airootfs/root/customize_airootfs.sh"
|
||
|
||
# ── 12. Build the ISO ─────────────────────────────────────────────────
|
||
echo ">>> Building 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 "════════════════════════════════════════"
|