From 21d1606886558983ad705a77680a930127a050ec Mon Sep 17 00:00:00 2001 From: Penelope Gwen Date: Thu, 12 Dec 2024 01:39:04 -0800 Subject: [PATCH] first commit --- .gitignore | 3 + build.sh | 24 ++ live-build/auto/build | 6 + live-build/auto/clean | 9 + live-build/auto/config | 14 + .../root/.bashrc | 20 + .../config/package-lists/live.list.chroot | 18 + package.sh | 6 + scripts/lib/.functions.swp | Bin 0 -> 1024 bytes scripts/lib/functions | 364 ++++++++++++++++++ scripts/setup.sh | 33 ++ 11 files changed, 497 insertions(+) create mode 100644 .gitignore create mode 100755 build.sh create mode 100755 live-build/auto/build create mode 100755 live-build/auto/clean create mode 100755 live-build/auto/config create mode 100755 live-build/config/includes.chroot_after_packages/root/.bashrc create mode 100644 live-build/config/package-lists/live.list.chroot create mode 100755 package.sh create mode 100644 scripts/lib/.functions.swp create mode 100644 scripts/lib/functions create mode 100755 scripts/setup.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c3e5918 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +output/ +live-build/cache/ +live-build/config/hooks/ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..57e1ed0 --- /dev/null +++ b/build.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +START_DIR=`pwd` +SCRIPT_ROOT=`realpath "$(dirname ${0})"` + +cd "${SCRIPT_ROOT}/live-build/" + +sudo lb clean +sudo lb config +sudo lb build + +cd "${SCRIPT_ROOT}/" + +build_date=`date +%Y-%m-%d_%H%M%S` + +mkdir -p "${SCRIPT_ROOT}/output/${build_date}/" + +find "${SCRIPT_ROOT}/live-build" -maxdepth 1 -name 'SapphicLinux*' -exec mv {} "${SCRIPT_ROOT}/output/${build_date}/" \; + +cd "${SCRIPT_ROOT}/live-build/" +sudo lb clean +cd "${SCRIPT_ROOT}/" + +cd "${START_DIR}" diff --git a/live-build/auto/build b/live-build/auto/build new file mode 100755 index 0000000..c124ee4 --- /dev/null +++ b/live-build/auto/build @@ -0,0 +1,6 @@ +#!/bin/sh + +set -e + +rsync -aSH ../scripts/ ./config/includes.chroot_after_packages/root/installer/ +lb build noauto "${@}" 2>&1 | tee SapphicLinux_build_$(date +%Y-%m-%d_%H%M).log diff --git a/live-build/auto/clean b/live-build/auto/clean new file mode 100755 index 0000000..a7d9002 --- /dev/null +++ b/live-build/auto/clean @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +rm -rf config/includes.chroot_after_packages/root/installer +rm -f config/binary config/bootstrap config/chroot config/common config/source + +lb clean noauto "${@}" + diff --git a/live-build/auto/config b/live-build/auto/config new file mode 100755 index 0000000..332cf91 --- /dev/null +++ b/live-build/auto/config @@ -0,0 +1,14 @@ +#!/bin/sh + +set -e + +lb config noauto \ + --archive-areas "main contrib non-free-firmware" \ + --architectures amd64 \ + --bootappend-live "boot=live components hostname=sapphic-installer username=root" \ + --distribution bookworm \ + --debian-installer none \ + --debian-installer-gui false \ + --hdd-label SapphicLinux \ + --image-name SapphicLinux \ + "${@}" diff --git a/live-build/config/includes.chroot_after_packages/root/.bashrc b/live-build/config/includes.chroot_after_packages/root/.bashrc new file mode 100755 index 0000000..3658c8d --- /dev/null +++ b/live-build/config/includes.chroot_after_packages/root/.bashrc @@ -0,0 +1,20 @@ +# ~/.bashrc: executed by bash(1) for non-login shells. + +# Note: PS1 and umask are already set in /etc/profile. You should not +# need this unless you want different defaults for root. +# PS1='${debian_chroot:+($debian_chroot)}\h:\w\$ ' +# umask 022 + +# You may uncomment the following lines if you want `ls' to be colorized: +# export LS_OPTIONS='--color=auto' +# eval "$(dircolors)" +# alias ls='ls $LS_OPTIONS' +# alias ll='ls $LS_OPTIONS -l' +# alias l='ls $LS_OPTIONS -lA' +# +# Some more alias to avoid making mistakes: +# alias rm='rm -i' +# alias cp='cp -i' +# alias mv='mv -i' +./installer/setup.sh +#mv ./install*.log /target/boot/ diff --git a/live-build/config/package-lists/live.list.chroot b/live-build/config/package-lists/live.list.chroot new file mode 100644 index 0000000..c1db29d --- /dev/null +++ b/live-build/config/package-lists/live.list.chroot @@ -0,0 +1,18 @@ +live-boot +live-config +live-config-systemd +systemd-sysv +parted +debootstrap +cryptsetup +dosfstools +debconf-utils +rsync +network-manager +bc +dialog +imagemagick +btrfs-progs +tmux +curl +gpg diff --git a/package.sh b/package.sh new file mode 100755 index 0000000..b1f7738 --- /dev/null +++ b/package.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +SCRIPT_ROOT=`dirname ${0}` +package_date=`date +%Y-%m-%d_%H%M%S` + +tar -pczf "${SCRIPT_ROOT}/../sapphic_${package_date}.tar.gz" --exclude="${SCRIPT_ROOT}/live-build/cache" --exclude="${SCRIPT_ROOT}/output" "${SCRIPT_ROOT}" diff --git a/scripts/lib/.functions.swp b/scripts/lib/.functions.swp new file mode 100644 index 0000000000000000000000000000000000000000..d0e4a4485b2e6ee6bc3572dc989c3e1060bb284f GIT binary patch literal 1024 zcmYc?$V<%2SFq4CVn6|jclj9#Qu9)C@(WT?B(QK`>U48b^YY8`bxRD*($S0q>nctz m$}A`;*3ZdI(oZYROD@UG&nw1a-l))M2#kgRO+p|P-BbW(V;CR+ literal 0 HcmV?d00001 diff --git a/scripts/lib/functions b/scripts/lib/functions new file mode 100644 index 0000000..39557c1 --- /dev/null +++ b/scripts/lib/functions @@ -0,0 +1,364 @@ +#!/bin/bash + +run_in_chroot(){ + chroot '/target/' /bin/bash -c "${1}" +} + +prepare_install(){ + echo -n "Checking network..." + if ! ping -c 4 deb.debian.org &>/dev/null;then + tmux popup -h 75% -w 75% -E "nmtui-connect" + fi + clear + echo -n "Waiting on network" + while ! timeout 1 ping -c 1 deb.debian.org &> /dev/null;do + printf "%c" "." + sleep 1 + done + clear +} + +menu(){ + + menu_select=$(dialog --ok-label 'Menu' --nocancel --clear --stdout \ + --title 'Device Type' \ + --menu 'Select the desired configuration page' 0 0 4 \ + root_setup 'Setup root user' \ + user_setup 'Setup default user' \ + device_type_setup 'Select installation type' \ + hostname_setup 'Set hostname' \ + partition_setup 'Partition disk' \ + 3>&1 2>&3 3>&-) + +} + +root_setup(){ + root_pass='' + root_pass_confirm='' + + root_info=$(dialog --ok-label 'Submit' --nocancel --clear --stdout \ + --title "Root Setup" \ + --form "Please enter the following information for the root user" \ + 0 0 0 \ + "Password:" 1 1 "$root_pass" 1 25 40 0 \ + "Password (confirm):" 2 1 "$root_pass_confirm" 2 25 40 0 \ + 3>&1 2>&3 3>&-) + root_info_array=(${root_info}) + root_pass="${root_info_array[0]}" + root_pass_confirm="${root_info_array[1]}" + +} + +user_setup(){ + user_realname='' + user_name='' + user_pass='' + user_pass_confirm='' + + user_realname=$(dialog --ok-label 'Submit' --nocancel --stdout --clear \ + --title 'Default User Full Name' \ + --inputbox 'Enter default user`s Full Name' 10 30 \ + 3>&1 2>&3 3>&-) + + user_info=$(dialog --ok-label 'Submit' --nocancel --clear --stdout \ + --title 'Default User' \ + --form 'Please enter the following information for the default user' \ + 0 0 3 \ + 'Username:' 1 1 "$user_name" 1 25 40 0 \ + 'Password:' 2 1 "$user_pass" 2 25 40 0 \ + 'Password (confirm):' 3 1 "$user_pass_confirm" 3 25 40 0 \ + 3>&1 2>&3 3>&-) + user_info_array=(${user_info}) + user_name="${user_info_array[0]}" + user_pass="${user_info_array[1]}" + user_pass_confirm="${user_info_array[2]}" + +} + +device_type_setup(){ + device_type=$(dialog --ok-label 'Submit' --nocancel --clear --stdout \ + --title 'Device Type' \ + --menu 'Please select the device type to use for the installation' 0 0 4 \ + user 'single-user desktop environment' \ + common 'multi-user desktop environment' \ + server 'headless environment intended for remote access' \ + kiosk 'public desktop environment' \ + 3>&1 2>&3 3>&-) +} + +sanitize_hostname(){ + printf "%s" "${1}" | tr -dc '\-[:alnum:]\n\r' | tr '[:upper:]' '[:lower:]' +} + +hostname_setup(){ + if [ "${device_type}" = "user" ];then + sys_role="${user_name}" + else + sys_role="${device_type}" + fi + + sys_manufacturer=`dmidecode -s system-manufacturer` + sys_model=`dmidecode -s system-product-name` + sys_serialno=`dmidecode -s system-serial-number` + + dest_hostname=`printf "%s-%s%s-%s" "${sys_role}" "${sys_manufacturer}" "${sys_model}" "${sys_serialno}"` + dest_hostname=`sanitize_hostname "${dest_hostname}"` + dest_hostname=$(dialog --ok-label 'Submit' --nocancel --clear --stdout \ + --title 'Hostname' \ + --inputbox 'Customize the hostname below' 0 0 "${dest_hostname}" \ + 3>&1 2>&3 3>&-) + dest_hostname=`sanitize_hostname "${dest_hostname}"` +} + +automatic_partitioner(){ + device_menu=() + for blk_device in $(lsblk -no PATH --nodeps); do + device_menu+=("$(lsblk -no PATH --nodeps ${blk_device})") + device_menu+=("$(lsblk -no MODEL,SIZE --nodeps ${blk_device})") + done + dest_dev=$(dialog --ok-label "Submit" --nocancel --stdout \ + --menu 'Select Install Destination' \ + 20 0 20 \ + "${device_menu[@]}" \ + 3>&1 2>&3 3>&-) + + root_gb=$(dialog --ok-label 'Submit' --nocancel --clear --stdout \ + --title "Root Partition Size" \ + --rangebox "Please set the root partition size in GB" \ + 0 0 10 2000 100 \ + 3>&1 2>&3 3>&-) + + if [[ ${dest_dev} = *[0-9] ]];then + part_sep="p" + else + part_sep="" + fi + efi_part="${dest_dev}${part_sep}1" + boot_part="${dest_dev}${part_sep}2" + swap_part="${dest_dev}${part_sep}3" + root_part="${dest_dev}${part_sep}4" + home_part="${dest_dev}${part_sep}5" + + luks_pass='' + luks_pass_confirm='' + + luks_info=$(dialog --ok-label 'Submit' --nocancel --stdout \ + --title "luks Setup" \ + --form "Please enter the following information for luks encryption" \ + 0 0 0 \ + "Password:" 1 1 "$luks_pass" 1 25 40 0 \ + "Password (confirm):" 2 1 "$luks_pass_confirm" 2 25 40 0 \ + 3>&1 2>&3 3>&-) + luks_info_array=(${luks_info}) + luks_pass="${luks_info_array[0]}" + luks_pass_confirm="${luks_info_array[1]}" + +#new gpt label + parted "${dest_dev}" mklabel gpt --script --fix +#efi + parted "${dest_dev}" mkpart efi fat32 0MB 256MB --script --fix --align optimal +#boot + parted "${dest_dev}" mkpart boot btrfs 256MB 768MB --script --fix --align optimal +#swap + mem_mb=`grep MemTotal /proc/meminfo | awk '{print $2 "/1024"}' | bc` + swap_end=`printf "768+%s\n" "${mem_mb}" | bc` + parted "${dest_dev}" mkpart swap linux-swap 768MB "${swap_end}MB" --script --fix --align optimal +#root + root_mb=`printf "%s*1024\n" "${root_gb}" | bc` + root_end=`printf "%s+%s\n" "${swap_end}" "${root_mb}" | bc` + parted "${dest_dev}" mkpart root btrfs "${swap_end}MB" "${root_end}MB" --script --fix --align optimal +#home + parted "${dest_dev}" mkpart home btrfs "${root_end}MB" 100% --script --fix --align optimal +} + +#manual_partitioner(){ +# target_dev='' +# until [ "${target_dev}" == 'done' ];do +# device_menu=() +# for blk_device in $(lsblk -no PATH --nodeps); do +# device_menu+=("$(lsblk -no PATH --nodeps ${blk_device})") +# device_menu+=("$(lsblk -no MODEL,SIZE --nodeps ${blk_device})") +# done +# device_menu+=("done") +# device_menu+=("Proceed to selecting disks") +# target_dev=`dialog --menu 'Select Install Destination' 20 0 20 "${device_menu[@]}" 2>&1 >/dev/tty` +# tmux popup -h 75% -w 75% -E "cfdisk ${target_dev}" +# done +# for blk_parts in $(lsblk -rno PATH,TYPE | grep -v 'disk$\|crypt$' | awk '{ print $1 } '); do +# device_menu+=("$(lsblk -rno PATH --nodeps ${blk_device})") +# device_menu+=("$(lsblk -rno MODEL,SIZE --nodeps ${blk_device})") +# done +#} + +disk_setup(){ +# partition_method=$(dialog --ok-label 'Submit' --nocancel --stdout \ +# --title 'Partition Method' \ +# --menu 'Please select the partition method to use for the installation' 0 0 4 \ +# manual 'Manually partition installation' \ +# automatic "Use recommended partitioning scheme [DESTRUCTIVE]" \ +# 3>&1 2>&3 3>&-) + +# if [ "${partition_method}" == "manual" ];then +# manual_partitioner +# elif [ "${partition_method}" == "automatic" ] + automatic_partitioner +# fi +} + +encrypt_partition(){ + echo -n "${3}" | cryptsetup luksFormat "${1}" - + echo -n "${3}" | cryptsetup luksOpen "${1}" "${2}_crypt" - +} + +get_part_uuid(){ + lsblk -drno UUID "${1}" +} + +format_partitions(){ +#efi partition + mkfs.vfat "${efi_part}" +#boot partition + mkfs.btrfs -f "${boot_part}" -L boot +#swap partition + encrypt_partition "${swap_part}" swap "${luks_pass}" + mkswap /dev/mapper/swap_crypt +#root partition + encrypt_partition "${root_part}" root "${luks_pass}" + mkfs.btrfs /dev/mapper/root_crypt -L root +#home partition + encrypt_partition "${home_part}" home "${luks_pass}" + mkfs.btrfs /dev/mapper/home_crypt -L home + + get_uuids +} + +get_uuids(){ +#get uuids + efi_uuid=`get_part_uuid "${efi_part}"` + boot_uuid=`get_part_uuid "${boot_part}"` + swap_luks_uuid=`get_part_uuid "${swap_part}"` + root_luks_uuid=`get_part_uuid "${root_part}"` + home_luks_uuid=`get_part_uuid "${home_part}"` +} + +create_filesystem(){ + +#create and mount root + target_dir="/target" + mkdir -p "${target_dir}" + mount "/dev/mapper/root_crypt" "${target_dir}" +# btrfs property set "${target_dir}/" compression zstd +#create and mount boot + mkdir -p "${target_dir}/home" + mount "/dev/mapper/home_crypt" "${target_dir}/home" +# btrfs property set "${target_dir}/home/" compression zstd +#create and mount boot + mkdir -p "${target_dir}/boot" + mount "${boot_part}" "${target_dir}/boot" +# btrfs property set "${target_dir}/boot/" compression zstd +#create and mount efi + mkdir -p "${target_dir}/boot/efi" + mount "${efi_part}" "${target_dir}/boot/efi" +#install base system + debootstrap --arch "$(dpkg --print-architecture)" unstable "${target_dir}" https://deb.debian.org/debian + +mkdir '/target/etc/crypttab.d' +for k in {home,swap};do + keyfile_path="/target/etc/crypttab.d/${k}_key" + openssl genrsa -out "${keyfile_path}" 4096 + chmod -v 0400 "${keyfile_path}" + chown root:root "${keyfile_path}" + case "${k}" in + swap) + keyfile_device="${swap_part}" + ;; + home) + keyfile_device="${home_part}" + ;; + esac + echo -n "${luks_pass}" | cryptsetup luksAddKey "${keyfile_device}" "${keyfile_path}" - +done + +#crypttab for luks-encrypted partitions + cat > "${target_dir}/etc/crypttab" << EOF +root_crypt UUID=${root_luks_uuid} none luks,discard +swap_crypt UUID=${swap_luks_uuid} /etc/crypttab.d/swap_key luks,swap,discard +home_crypt UUID=${home_luks_uuid} /etc/crypttab.d/home_key luks,discard +EOF + +#fstab for filesystem mounts + cat > "${target_dir}/etc/fstab" << EOF +/dev/mapper/root_crypt / btrfs defaults,compress 0 1 +/dev/mapper/home_crypt /home btrfs defaults,compress 0 1 +/dev/mapper/swap_crypt none swap sw 0 0 +UUID=${boot_uuid} /boot btrfs defaults,compress 0 2 +UUID=${efi_uuid} /boot/efi vfat umask=0077 0 1 +EOF + +#configure apt + cat > "${target_dir}/etc/apt/sources.list" << EOF +deb https://deb.debian.org/debian/ unstable main contrib non-free non-free-firmware +deb-src https://deb.debian.org/debian/ unstable main contrib non-free non-free-firmware +EOF + + curl -fsSL 'https://apt.pogmom.me/public.gpg' | gpg --dearmor -o "${target_dir}/usr/share/keyrings/pogmom.gpg" + mkdir -p "${target_dir}/etc/apt/sources.list.d" + echo "deb [signed-by=/usr/share/keyrings/pogmom.gpg] https://apt.pogmom.me/ unstable main" | tee "${target_dir}/etc/apt/sources.list.d/pogmom.list" + +} + +prepare_chroot(){ + for b in {proc,sys,dev,run};do + mount --make-rslave --rbind "/${b}" "/target/${b}" + done + + run_in_chroot "apt-get update" + echo "America/Los_Angeles" > /target/etc/timezone +# run_in_chroot "DEBIAN_FRONTEND=noninteractive apt-get install -y btrfs-progs locales passwd zram-tools rsync network-manager curl linux-image-amd64 firmware-linux grub-efi grub-pc-bin cryptsetup-initramfs systemd-cryptsetup" + run_in_chroot "DEBIAN_FRONTEND=noninteractive apt-get install -y pogmom-utils pogmom-desktop pogmom-apps linux-image-amd64 firmware-linux grub-efi grub-pc-bin cryptsetup-initramfs systemd-cryptsetup" +#TODO: split pogmom-utils into pogmom-utils and pogmom-essential + case "$(hostnamectl chassis)" in + laptop) + chassis_packages="tlp" + ;; + esac + run_in_chroot "DEBIAN_FRONTEND=noninteractive apt-get install -y ${chassis_packages} isenkram --no-install-recommends" + run_in_chroot "DEBIAN_FRONTEND=noninteractive isenkram-autoinstall-firmware" + +# drop files into the root filesystem +# rsync -aSH "${SCRIPT_ROOT}"/payload/ /target/ +# do stuff with the payload + +#zswap +# echo -e 'ALGO=zstd\nPERCENT=60' | tee -a /target/etc/default/zramswap #zstd is unavailable in kernel 6.12 + echo -e 'ALGO=lzo\nPERCENT=60' | tee -a /target/etc/default/zramswap + +#hostname + echo "${dest_hostname}" > /target/etc/hostname + cat > /target/etc/hosts << EOF +127.0.0.1 localhost +127.0.1.1 ${dest_hostname} +EOF + + run_in_chroot "timedatectl set-local-rtc 0" + + run_in_chroot "dpkg-reconfigure tzdata locales keyboard-configuration" + date > /target/root/install_date + + run_in_chroot "echo \"root:${root_pass}\" | chpasswd" + run_in_chroot "useradd -c \"${user_realname}\" -m ${user_name}" + run_in_chroot "echo \"${user_name}:${user_pass}\" | chpasswd" + run_in_chroot "usermod -aG sudo ${user_name}" + perl -i -pe 's/(GRUB_CMDLINE_LINUX_DEFAULT)="(.*)"/$1="$2 rd.luks.uuid='"${root_luks_uuid}"'"/' /target/etc/default/grub + root_kernel_version=`run_in_chroot "uname -r"` + run_in_chroot "update-initramfs -c -k all" + run_in_chroot "update-grub && grub-install --root-directory / ${dest_dev}" +} + +finalize(){ + umount -R /target + echo "Installation is complete, please remove installation medium and press ENTER to restart or CTRL+C to enter the console." + read + reboot +} + diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000..1572c81 --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +SCRIPT_ROOT=`dirname "${0}"` + +#if [ -f "${SCRIPT_ROOT}/install_started" ];then +# exit 1 +#else +# touch "${SCRIPT_ROOT}/install_started" +#fi + +source ${SCRIPT_ROOT}/lib/functions + +prepare_install + +#collect_info #break into smaller functions, move luks out, validate inputs + +root_setup + +user_setup + +device_type_setup + +hostname_setup + +disk_setup + +format_partitions + +create_filesystem + +prepare_chroot + +finalize