302 lines
9.9 KiB
Bash
302 lines
9.9 KiB
Bash
#!/bin/bash
|
|
|
|
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"
|
|
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
|
|
|
|
root_pass=''
|
|
root_pass_confirm=''
|
|
|
|
user_realname=''
|
|
user_name=''
|
|
user_pass=''
|
|
user_pass_confirm=''
|
|
|
|
luks_pass=''
|
|
luks_pass_confirm=''
|
|
|
|
stage_status[0]="done"
|
|
stage_func=("true" "root_setup" "user_setup" "hostname_setup" "disk_setup" "install_system")
|
|
|
|
clear
|
|
}
|
|
|
|
menu_select(){
|
|
readyicon=()
|
|
|
|
menu_select=$(dialog --ok-label 'Select' --nocancel --clear --stdout \
|
|
--title 'Installation Menu' \
|
|
--menu 'Select the desired configuration page' 0 0 4 \
|
|
1 "${stage_icon[1]} Setup root user" \
|
|
2 "${stage_icon[2]} Setup default user" \
|
|
3 "${stage_icon[3]} Select installation type and set hostname" \
|
|
4 "${stage_icon[4]} Setup installation disk" \
|
|
5 "${stage_icon[5]} Finish configuring and proceed to installation"
|
|
3>&1 2>&3 3>&-)
|
|
|
|
printf "%s" "${menu_select}"
|
|
}
|
|
|
|
menu_helper(){
|
|
|
|
while [[ ! "${stage_status[5]}" == "done" ]];do
|
|
|
|
for c in {1..5};do
|
|
current_stage=${c}
|
|
prev_stage=$(( "${current_stage}" - 1 ))
|
|
if [[ "${stage_status[${current_stage}]}" == "done" ]];then
|
|
echo "stage ${current_stage} done" >/dev/null
|
|
elif [[ "${stage_status[${prev_stage}]}" == "done" ]];then
|
|
stage_status[${current_stage}]="ready"
|
|
else
|
|
stage_status[${current_stage}]="lock"
|
|
fi
|
|
done
|
|
|
|
for i in {0..5};do
|
|
case "${stage_status[${i}]}" in
|
|
"ready" )
|
|
stage_icon[${i}]=`printf "\xe2\x9d\x8c"`
|
|
;;
|
|
"done" )
|
|
stage_icon[${i}]=`printf "\xe2\x9c\x93"`
|
|
;;
|
|
"lock" )
|
|
stage_icon[${i}]=`printf "\xF0\x9f\x94\x92"`
|
|
;;
|
|
esac
|
|
done
|
|
|
|
menu_opt=`menu_select`
|
|
if [[ ! "${stage_status[${menu_opt}]}" == "lock" ]];then
|
|
"${stage_func[${menu_opt}]}" \
|
|
&& stage_status[${menu_opt}]="done" \
|
|
|| stage_status[${menu_opt}]="ready"
|
|
fi
|
|
|
|
done
|
|
}
|
|
|
|
root_setup(){
|
|
|
|
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]}"
|
|
#validate, return exit code
|
|
validate_pass "${root_pass}" "${root_pass_confirm}" || return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
user_setup(){
|
|
|
|
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]}"
|
|
#validate, return exit code
|
|
validate_username "${user_name}" || return 1
|
|
validate_pass "${validate_pass}" "${validate_pass_confirm}" || return 1
|
|
|
|
return 0
|
|
}
|
|
|
|
hostname_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>&-)
|
|
|
|
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}"`
|
|
return 0
|
|
}
|
|
|
|
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 || return 1
|
|
format_partitions || return 1
|
|
# fi
|
|
# validate, return exit code
|
|
return 0
|
|
}
|
|
|
|
install_system(){
|
|
|
|
#create and mount root
|
|
target_dir="/target"
|
|
mkdir -p "${target_dir}"
|
|
mount -o compress=zstd "/dev/mapper/root_crypt" "${target_dir}"
|
|
# btrfs property set "${target_dir}/" compression zstd
|
|
#create and mount boot
|
|
mkdir -p "${target_dir}/home"
|
|
mount -o compress=zstd "/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 -o compress=zstd "${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
|
|
|
|
for b in {proc,sys,dev,run};do
|
|
mount --make-rslave --rbind "/${b}" "/target/${b}"
|
|
done
|
|
|
|
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=zstd 0 1
|
|
/dev/mapper/home_crypt /home btrfs defaults,compress=zstd 0 1
|
|
/dev/mapper/swap_crypt none swap sw 0 0
|
|
UUID=${boot_uuid} /boot btrfs defaults,compress=zstd 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"
|
|
|
|
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-essentials pogmom-utils pogmom-desktop pogmom-apps linux-image-$(dpkg --print-architecture) firmware-linux"
|
|
#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 "systemctl disable NetworkManager-wait-online.service"
|
|
|
|
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
|
|
run_in_chroot "update-initramfs -c -k all"
|
|
run_in_chroot "update-grub && grub-install --root-directory / ${dest_dev}"
|
|
|
|
return 0
|
|
}
|
|
|
|
finalize(){
|
|
umount -R /target
|
|
#change echo to dialog
|
|
echo "Installation is complete, please remove installation medium and press ENTER to restart or CTRL+C to enter the console."
|
|
read
|
|
reboot
|
|
}
|
|
|