Files
samios/packaging/scripts/samios-installer.sh
T
Sami Ahmed 658a8541e9
SamiOS CI / lint-and-test (push) Successful in 14s
v0.2.0: WSL desktop, branding, GRUB theme, CI, installer, fonts, voice architecture
Major update adding full desktop environment support, complete branding suite,
and project infrastructure:

Desktop (WSL):
- KDE Plasma + SDDM + Dolphin/Konsole/Kate/Firefox setup script
- Windows 11 dark/light color schemes
- PipeWire audio stack
- WSLg-compatible launch script
- SamiOS CLI tool (v0.2.0) with desktop command

Branding:
- Logos: face-on-pyramid with and without text (500px)
- Icons: square + launcher (256/512/1024px) + SVG vector
- Wallpapers: 1920x1080, 4K, clean variant (PIL-generated)
- GRUB theme: full cobalt blue (#1424CE) theme with pyramid background
- SDDM theme: SamiOS login screen configuration
- Branding README with palette, typography, usage guidelines

Fonts:
- Sami Grotesk (Helvetica-like) as default system/UI font
- Sami Sans as secondary
- Full Sami font family support (excluding 7777 personal branding)
- fontconfig rules mapping Helvetica/Arial → Sami Grotesk
- Font policy enforcement in samios CLI

Infrastructure:
- Automated installer (samios-installer.sh): partition, format, pacstrap, bootloader
- PKGBUILD for samios-branding package
- Test suite: shell tests for profiledef, packages, pacman.conf, CLI, font policy
- Makefile: test, lint, check, build, clean targets
- Gitea Actions CI workflow
- Voice integration architecture document (SamiType × SamiOS)
- Updated roadmap reflecting completed phases
2026-08-11 03:39:47 -07:00

446 lines
12 KiB
Bash

#!/bin/bash
# SamiOS Automated Installer
# Partitions disk, formats, pacstraps base system, installs bootloader, creates user
# Usage: samios install [options]
set -e
VERSION="0.2.0"
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'
log() { echo -e "${BLUE}[SamiOS]${NC} $*"; }
ok() { echo -e "${GREEN}${NC} $*"; }
warn() { echo -e "${YELLOW}${NC} $*"; }
err() { echo -e "${RED}${NC} $*" >&2; }
# ============================================================
# Pre-flight checks
# ============================================================
check_root() {
if [ "$(id -u)" -ne 0 ]; then
err "This script must be run as root"
exit 1
fi
}
check_uefi() {
if [ -d /sys/firmware/efi/efivars ]; then
UEFI=true
ok "UEFI mode detected"
else
UEFI=false
ok "BIOS mode detected"
fi
}
detect_disks() {
log "Detecting available disks..."
mapfile -t DISKS < <(lsblk -d -n -p -o NAME | grep -v "loop\|sr\|fd")
echo ""
echo "Available disks:"
for i in "${!DISKS[@]}"; do
SIZE=$(lsblk -d -n -o SIZE "${DISKS[$i]}" 2>/dev/null)
MODEL=$(lsblk -d -n -o MODEL "${DISKS[$i]}" 2>/dev/null)
echo " [$i] ${DISKS[$i]} - ${SIZE} ${MODEL}"
done
echo ""
}
select_disk() {
if [ -n "$TARGET_DISK" ]; then
return
fi
read -p "Select target disk [0-$(( ${#DISKS[@]} - 1 ))]: " DISK_IDX
TARGET_DISK="${DISKS[$DISK_IDX]}"
echo ""
warn "WARNING: This will ERASE ALL DATA on ${TARGET_DISK}"
read -p "Type 'YES' to confirm: " CONFIRM
if [ "$CONFIRM" != "YES" ]; then
err "Installation cancelled"
exit 1
fi
}
# ============================================================
# Partitioning
# ============================================================
partition_disk() {
log "Partitioning ${TARGET_DISK}..."
# Wipe all partition tables
sgdisk --zap-all "$TARGET_DISK"
if [ "$UEFI" = true ]; then
# UEFI: GPT with EFI System Partition + root
sgdisk -n 1:0:+1G -t 1:ef00 -c 1:"EFI System" "$TARGET_DISK"
sgdisk -n 2:0:0 -t 2:8300 -c 2:"SamiOS Root" "$TARGET_DISK"
partprobe "$TARGET_DISK"
sleep 2
# Determine partition names
if [[ "$TARGET_DISK" == *"nvme"* ]] || [[ "$TARGET_DISK" == *"mmcblk"* ]]; then
EFI_PART="${TARGET_DISK}p1"
ROOT_PART="${TARGET_DISK}p2"
else
EFI_PART="${TARGET_DISK}1"
ROOT_PART="${TARGET_DISK}2"
fi
# Format
mkfs.fat -F32 "$EFI_PART"
mkfs.ext4 -F -L samios "$ROOT_PART"
ok "UEFI partitions created"
else
# BIOS: MBR with single root + boot
sgdisk -n 1:0:0 -t 1:8300 -c 1:"SamiOS" "$TARGET_DISK"
partprobe "$TARGET_DISK"
sleep 2
if [[ "$TARGET_DISK" == *"nvme"* ]] || [[ "$TARGET_DISK" == *"mmcblk"* ]]; then
ROOT_PART="${TARGET_DISK}p1"
else
ROOT_PART="${TARGET_DISK}1"
fi
mkfs.ext4 -F -L samios "$ROOT_PART"
ok "BIOS partition created"
fi
}
# ============================================================
# Mount and pacstrap
# ============================================================
mount_and_install() {
log "Mounting filesystems..."
MOUNT_POINT="/mnt"
mount "$ROOT_PART" "$MOUNT_POINT"
if [ "$UEFI" = true ]; then
mkdir -p "$MOUNT_POINT/boot/efi"
mount "$EFI_PART" "$MOUNT_POINT/boot/efi"
fi
log "Installing base system (this takes a few minutes)..."
# Install base system
pacstrap "$MOUNT_POINT" base base-devel linux linux-firmware
# Generate fstab
genfstab -U "$MOUNT_POINT" > "$MOUNT_POINT/etc/fstab"
ok "Base system installed"
}
# ============================================================
# System configuration
# ============================================================
configure_system() {
log "Configuring system..."
MOUNT_POINT="/mnt"
# Hostname
echo "samios" > "$MOUNT_POINT/etc/hostname"
# Hosts
cat > "$MOUNT_POINT/etc/hosts" << 'HOSTS'
127.0.0.1 localhost
::1 localhost
127.0.1.1 samios.localdomain samios
HOSTS
# Timezone
arch-chroot "$MOUNT_POINT" ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
arch-chroot "$MOUNT_POINT" hwclock --systohc
# Locale
sed -i 's/^#en_US.UTF-8/en_US.UTF-8/' "$MOUNT_POINT/etc/locale.gen"
arch-chroot "$MOUNT_POINT" locale-gen
echo "LANG=en_US.UTF-8" > "$MOUNT_POINT/etc/locale.conf"
# Keymap
echo "KEYMAP=us" > "$MOUNT_POINT/etc/vconsole.conf"
# Install essential packages
arch-chroot "$MOUNT_POINT" pacman -S --noconfirm \
networkmanager \
sudo \
grub \
efibootmgr \
os-prober \
nano \
vim \
less \
man-db \
man-pages \
git \
curl \
wget \
bash-completion \
reflector \
openssh
# Enable NetworkManager
arch-chroot "$MOUNT_POINT" systemctl enable NetworkManager
# Enable SSH (optional)
arch-chroot "$MOUNT_POINT" systemctl enable sshd
ok "System configured"
}
# ============================================================
# Bootloader
# ============================================================
install_bootloader() {
log "Installing bootloader..."
MOUNT_POINT="/mnt"
if [ "$UEFI" = true ]; then
arch-chroot "$MOUNT_POINT" grub-install --target=x86_64-efi \
--efi-directory=/boot/efi --bootloader-id=SamiOS
else
arch-chroot "$MOUNT_POINT" grub-install --target=i386-pc "$TARGET_DISK"
fi
# Configure GRUB
arch-chroot "$MOUNT_POINT" grub-mkconfig -o /boot/grub/grub.cfg
ok "Bootloader installed"
}
# ============================================================
# User creation
# ============================================================
create_user() {
log "Creating user account..."
MOUNT_POINT="/mnt"
INTERACTIVE_USER="${INSTALL_USER:-sami}"
if [ -z "$INSTALL_PASSWORD" ]; then
read -s -p "Enter password for ${INTERACTIVE_USER}: " USER_PASS
echo ""
read -s -p "Confirm password: " USER_PASS_CONFIRM
echo ""
if [ "$USER_PASS" != "$USER_PASS_CONFIRM" ]; then
err "Passwords do not match"
exit 1
fi
else
USER_PASS="$INSTALL_PASSWORD"
fi
# Create user
arch-chroot "$MOUNT_POINT" useradd -m -G wheel,storage,power,network -s /bin/bash "$INTERACTIVE_USER"
# Set password
echo "$INTERACTIVE_USER:$USER_PASS" | arch-chroot "$MOUNT_POINT" chpasswd
# Enable sudo for wheel group
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' "$MOUNT_POINT/etc/sudoers"
# Set root password
echo "root:$USER_PASS" | arch-chroot "$MOUNT_POINT" chpasswd
ok "User ${INTERACTIVE_USER} created"
}
# ============================================================
# SamiOS CLI tool
# ============================================================
install_samios_cli() {
log "Installing SamiOS CLI tool..."
MOUNT_POINT="/mnt"
cat > "$MOUNT_POINT/usr/local/bin/samios" << 'SAMIOS_CLI'
#!/bin/bash
set -e
VERSION="0.2.0"
cmd_help() {
cat << EOF
SamiOS CLI v${VERSION}
Commands:
version Show version
status Show system status
update Update system packages
install <pkg> Install a package
remove <pkg> Remove a package
services List running services
fonts Check fonts and policy
help Show this help
EOF
}
cmd_version() {
echo "SamiOS v${VERSION}"
echo "Kernel: $(uname -r)"
echo "Architecture: $(uname -m)"
}
cmd_status() {
echo "=== SamiOS System Status ==="
echo "Version: ${VERSION}"
echo "Hostname: $(hostname)"
echo "Kernel: $(uname -r)"
echo "Uptime: $(uptime -p)"
echo
echo "=== Disk Usage ==="
df -h / | tail -n 1
echo
echo "=== Memory ==="
free -h | grep "Mem:"
echo
echo "=== Network ==="
ip -br addr show | grep -v "lo" 2>/dev/null
}
cmd_update() { sudo pacman -Syu --noconfirm; }
cmd_install() { [ -z "$1" ] && echo "Usage: samios install <package>" && exit 1; sudo pacman -S --noconfirm "$1"; }
cmd_remove() { [ -z "$1" ] && echo "Usage: samios remove <package>" && exit 1; sudo pacman -R --noconfirm "$1"; }
cmd_services() { systemctl list-units --type=service --state=running; }
cmd_fonts() {
echo "=== Installed Fonts ==="
fc-list | wc -l
echo "fonts installed"
echo
echo "=== Font Policy ==="
echo "Excluded: fonts with '7777' in name (personal branding)"
if fc-list | grep -iq "7777"; then
echo "WARNING: Found 7777 fonts:"
fc-list | grep -i "7777"
else
echo "OK: No forbidden fonts"
fi
}
case "${1:-}" in
version) cmd_version ;;
status) cmd_status ;;
update) cmd_update ;;
install) shift; cmd_install "$@" ;;
remove) shift; cmd_remove "$@" ;;
services) cmd_services ;;
fonts) cmd_fonts ;;
help|--help|-h|"") cmd_help ;;
*) echo "Unknown: $1"; exit 1 ;;
esac
SAMIOS_CLI
chmod +x "$MOUNT_POINT/usr/local/bin/samios"
# MOTD
cat > "$MOUNT_POINT/etc/motd" << 'MOTD'
___ ___ ___ ___ ___
/\ \ /\__\ /\ \ /\__\ /\ \
/::\ \ /::| | /::\ \ /:/ / /::\ \
/:/\:\ \ /:|:| | /:/\:\ \ /:/ / /:/\:\ \
/:\ \:\ \ /:/|:| |__ /::\~\:\ \ /:/ / ___ /::\~\:\ \
/:/\:\ \:\__\/:/ |:| /\__\ /:/\:\ \:\__\ /:/__/ /\__\ /:/\:\ \:\__\
\/__\:\/:/ /\/ |:|/:/ / \/_|::\/:/ / \:\ \ /:/ / \:\~\:\ \/__/
\::/ / |:/:/ / |:|::/ / \:\ /:/ / \:\ \:\__\
/:/ / |::/ / |:|\/__/ \:\/:/ / \:\ \/__/
/:/ / /:/ / |:| | \::/ / \:\__\
\/__/ \/__/ \|__| \/__/ \/__/
Welcome to SamiOS! Type 'samios help' to get started.
MOTD
# Bashrc welcome
cat > "$MOUNT_POINT/etc/bash.bashrc" << 'BASHRC'
# SamiOS system-wide bashrc
export PS1='\[\033[01;34m\]sami\[\033[01;34m\]@samios\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
alias ls='ls --color=auto'
alias ll='ls -la'
alias la='ls -A'
alias l='ls -CF'
alias update='sudo pacman -Syu'
alias install='sudo pacman -S'
alias remove='sudo pacman -R'
# SamiOS CLI in PATH
export PATH="/usr/local/bin:$PATH"
BASHRC
ok "SamiOS CLI and configs installed"
}
# ============================================================
# Cleanup and finish
# ============================================================
finish_install() {
log "Finalizing installation..."
MOUNT_POINT="/mnt"
# Unmount
umount -R "$MOUNT_POINT"
echo ""
echo "============================================"
echo " SamiOS Installation Complete! "
echo "============================================"
echo ""
echo " Disk: $TARGET_DISK"
echo " User: ${INSTALL_USER:-sami}"
echo " Bootloader: $([ "$UEFI" = true ] && echo "GRUB (UEFI)" || echo "GRUB (BIOS)")"
echo ""
echo " Next steps:"
echo " 1. Reboot: systemctl reboot"
echo " 2. Log in as ${INSTALL_USER:-sami}"
echo " 3. Run: samios status"
echo " 4. Install desktop: samios install plasma"
echo ""
}
# ============================================================
# Main
# ============================================================
main() {
echo ""
echo "============================================"
echo " SamiOS Installer v${VERSION} "
echo "============================================"
echo ""
check_root
check_uefi
detect_disks
select_disk
partition_disk
mount_and_install
configure_system
install_bootloader
create_user
install_samios_cli
finish_install
}
# Parse args
while [ $# -gt 0 ]; do
case "$1" in
--disk) TARGET_DISK="$2"; shift 2 ;;
--user) INSTALL_USER="$2"; shift 2 ;;
--password) INSTALL_PASSWORD="$2"; shift 2 ;;
--help|-h) echo "Usage: samios install [--disk /dev/sdX] [--user username] [--password pass]"; exit 0 ;;
*) shift ;;
esac
done
main