diff options
author | bill-auger <mr.j.spam.me@gmail.com> | 2020-03-27 20:53:45 -0400 |
---|---|---|
committer | bill-auger <mr.j.spam.me@gmail.com> | 2022-05-01 23:58:14 -0400 |
commit | 5faac3e6a166a12a3a0cbb50be21a73632725651 (patch) | |
tree | f3118df3aecf2dc9f9f6013102f1c1d664599f53 /configs/profile/root-image/root/.session/install/install.sh | |
parent | 640513f18fec15f24fedf43eb8e86dfae6530637 (diff) |
consolidate install wizards into unified implementation
this is admitedly a huge change, nearly a total re-write
the original scripts were very brittle and redundant
even without functional changes, a DRY refactoring
would have been nearly as massive
the functional changes for rubustness, were also quite significant
it would not have been feasibe to break them down
* consolidated all per-init and per-language scripts sets into one
* extracted translatable strings into separate file
* remvoed confusing main menu, in favor of sequential prompts
* better error handling and logging
* added cfdisk support for CLI ISOs (GUI ISO still launches gparted)
* ensure that all target partitions are formatted
Diffstat (limited to 'configs/profile/root-image/root/.session/install/install.sh')
-rwxr-xr-x | configs/profile/root-image/root/.session/install/install.sh | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/configs/profile/root-image/root/.session/install/install.sh b/configs/profile/root-image/root/.session/install/install.sh new file mode 100755 index 0000000..7858ea3 --- /dev/null +++ b/configs/profile/root-image/root/.session/install/install.sh @@ -0,0 +1,299 @@ +#!/bin/bash + +source $(cd $(dirname ${BASH_SOURCE[0]}) ; pwd)/../session-common.sh.inc + + +readonly PACCONF_NONSYSTEMD_REGEX='N ; s|^#\[nonsystemd\].*#Include|\[nonsystemd\]\nInclude|' +readonly PACCONF_SYSTEMD_REGEX='N ; s|^\[nonsystemd\].*Include|#\[nonsystemd\]\n#Include|' +readonly ONLINE_CHECK_URL=https://repo.parabola.nu/check_network_status.txt +readonly GRUB_THEME_SED_CMD='s|^#GRUB_THEME=.*|GRUB_THEME=/boot/grub/themes/parabola-laf/theme.txt|' + + +Init() +{ + echo "${TR[internet-${TR_KEY}]} ...." + local has_isorepo=$( [[ ! -d /isorepo ]] && echo 1 || echo 0 ) + local is_online=$( curl ${ONLINE_CHECK_URL} &> /dev/null && echo 1 || echo 0 ) + + if [[ ${has_isorepo} && ${is_online} ]] ; then SetStateVar 'INSTALL' 'prompt' ; + elif [[ ${has_isorepo} ]] ; then SetStateVar 'INSTALL' 'offline' ; + else SetStateVar 'INSTALL' 'online' ; + fi + +DbgDlg "has_isorepo=$has_isorepo is_online=$is_online install=$install" +} + +InitKeyring() +{ + if [[ "$(GetStateVar 'KEYRING')" != 'ready' ]] + then pacman -Sy archlinux-keyring archlinux32-keyring parabola-keyring --noconfirm + pacman-key --populate archlinux archlinux32 parabola + pacman-key --refresh-keys + SetStateVar 'KEYRING' 'ready' + fi +} + +Partition() +{ + umount /mnt &> /dev/null || true + + # prompt for disk device + local hd_devices=$(ls /dev/sd?) + local hdds=() + local hd_device + local capacity + local hdd + for hd_device in ${hd_devices} + do capacity=$(fdisk --list /dev/sda | head --lines=1 | sed 's|.*: \([^,]*\),.*|\1|') + hdds+=( "${hd_device}" "${capacity}" off ) + done + hdd=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --radiolist "${TR[hdd-${TR_KEY}]}" 20 70 50 "${hdds[@]}" ) + [[ -n "${hdd}" ]] && SetStateVar 'HDD' ${hdd} || exit + + # prompt for partitioner + local part_method=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --menu "${TR[part-${TR_KEY}]}" 20 70 50 \ + 'auto' "${TR[part_auto-${TR_KEY}]}" \ + 'manual' "${TR[part_man-${TR_KEY}]}" ) + [[ -n "${part_method}" ]] || exit + + # partitioning + local root_part + case ${part_method} in + 'auto') + # create partition table + parted -s ${device} -- mklabel msdos + + # create partitions + parted -s ${hdd} -- mkpart primary 1MiB 1000MiB + parted -s ${hdd} -- mkpart primary 1000MiB -1s + parted -s ${hdd} -- set 2 boot on + + # format partitions + (echo t ; echo 1 ; echo 82 ; echo w) | fdisk ${hdd} + mkswap ${hdd}1 + mkfs.ext4 ${hdd}2 + + root_part=${hdd}2 + ;; + 'manual') + if which gparted &> /dev/null ; then gparted ${hdd} ; + elif which cfdisk &> /dev/null ; then cfdisk ${hdd} ; fi ; + + # prompt for root partition + local partitions=() + local partition + for partition in $(ls ${hdd}?) + do capacity=$(df --human-readable --output=size ${partition} | tail --lines=1 | tr -d ' ') + partitions+=( "${partition}" "${capacity}" off ) + done + root_part=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --radiolist "${TR[mount_root-${TR_KEY}]}" 20 70 50 \ + ${partitions[@]} ) + [[ -n "${root_part}" ]] || exit + + # prompt to mount additional partitions + local other=0 + local boot_part + local home_part + while [[ "${other}" != 3 ]] + do other=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" --cancel-label "None" \ + --menu "${TR[mount_other-${TR_KEY}]}" 20 70 50 \ + 1 "/boot" 2 "/home" 3 "Done" ) + case $other in + 1) boot_part=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --radiolist "${TR[mount_boot-${TR_KEY}]}" 20 70 50 \ + ${partitions[@]} ) + umount /mnt/boot &> /dev/null || true + mkdir /mnt/boot &> /dev/null || true + ;; + 2) home_part=$( WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --radiolist "${TR[mount_home-${TR_KEY}]}" 20 70 50 \ + ${partitions[@]} ) + umount /mnt/home &> /dev/null || true + mkdir /mnt/home &> /dev/null || true + ;; + *) other=3 + ;; + esac + done + ;; + *) exit ;; + esac + + # format unformatted partitions and mount partitions + for partition in ${root_part} ${boot_part} ${home_part} + do ! blkid ${partition} | grep ' TYPE="' &> /dev/null && \ + WizardDlg "${TR[dlg_part-${TR_KEY}]}" \ + --yesno "${partition} ${TR[format-${TR_KEY}]}" 20 70 && \ + mkfs.ext4 ${partition} + blkid ${partition} | grep ' TYPE="' > /dev/null || exit + done + mount ${root_part} /mnt + mount ${boot_part} /mnt/boot || [[ -z "${boot_part}" ]] + mount ${home_part} /mnt/home || [[ -z "${home_part}" ]] +} + +NoticeCustomize() { WizardDlg "" --msgbox "${TR[notice_customize-${TR_KEY}]}" 20 70 ; } + +SelectDefaults() +{ + if WizardDlg "${TR[dlg_defaults-${TR_KEY}]}" --yesno "${TR[defaults-${TR_KEY}]}" 20 70 + then SetStateVar 'BASE' 'base parabola-base' + SetStateVar 'INIT' 'openrc' + fi +} + +SelectBase() +{ + if [[ -n "$(SetStateVar 'BASE')" && -n "$(GetStateVar 'INIT')" ]] ; then return 0 ; fi ; + + # prompt for base package set + local base=$( WizardDlg "${TR[dlg_base-${TR_KEY}]}" \ + --radiolist "${TR[base-${TR_KEY}]}" 20 70 50 \ + 'core' "${TR[base_mini-${TR_KEY}]}" 'off' \ + 'posix' "${TR[base_posix-${TR_KEY}]}" 'on' ) + local base_packages=( 'base' $( [[ "${base}" == 'posix' ]] && echo 'parabola-base' || : ) ) + [[ -n "${base}" ]] && SetStateVar 'BASE' ${base_packages} || exit + + # prompt for init-system + local init=$( WizardDlg "${TR[dlg_base-${TR_KEY}]}" \ + --radiolist "${TR[init-${TR_KEY}]}" 20 70 50 \ + 'openrc' "${TR[init_openrc-${TR_KEY}]}" 'off' \ + 'systemd' "${TR[init_systemd-${TR_KEY}]}" 'on' ) + [[ -n "${init}" ]] && SetStateVar 'INIT' ${init} || exit + + # prompt for local vs remote package repos if possible + local install=$(GetStateVar 'INSTALL') + local install=$( [[ "${install}" == 'prompt' ]] && \ + WizardDlg "${TR[dlg_base-${TR_KEY}]}" \ + --radiolist "${TR[install-${TR_KEY}]}" 20 70 50 \ + 'offline' "${TR[install_offline-${TR_KEY}]}" 'on' \ + 'online' "${TR[install_online-${TR_KEY}]}" 'off' ) + [[ -n "${install}" ]] && SetStateVar 'INSTALL' ${install} || exit +} + +InstallBase() +{ + local conf_regex=$( [[ "${init}" == 'openrc' ]] && echo "$PACCONF_NONSYSTEMD_REGEX" || \ + echo "$PACCONF_SYSTEMD_REGEX" ) + local install=$(GetStateVar 'INSTALL') + local base_packages=$(GetStateVar 'BASE') + + sed -i "$conf_regex" /etc/pacman-${install}.conf + cp /etc/pacman-${install}.conf /etc/pacman.conf + + # install standard packages + pacstrap /mnt base ${base_packages[@]} +} + +ConfigChroot() +{ + genfstab -p /mnt >> /mnt/etc/fstab + cp "${SESSION_STATE_FILE}" /mnt/root/ + cp "${SESSION_INCLUDE_FILE}" /mnt/root/ + cp "${CHROOT_ENVIRONMENT_FILE}" /mnt/root/ + chmod +x /mnt/root/${CHROOT_ENVIRONMENT_FILENAME} + arch-chroot /mnt /root/${CHROOT_ENVIRONMENT_FILENAME} + rm /mnt/root/${CHROOT_ENVIRONMENT_FILENAME} +} + +NoticeOptional() { WizardDlg "" --msgbox "${TR[notice_optional-${TR_KEY}]}" 20 70 ; } + +InstallGrub() +{ + # prompt to install GRUB + local grub=$( WizardDlg "${TR[dlg_grub-${TR_KEY}]}" \ + --radiolist "${TR[grub-${TR_KEY}]}" 20 70 50 \ + 'yes' "${TR[yes-${TR_KEY}]}" 'on' \ + 'no' "${TR[no-${TR_KEY}]}" 'off' ) + [[ -n "${grub}" ]] || exit + [[ "${grub}" == 'yes' ]] || return + + pacstrap /mnt grub grub2-theme-gnuaxiom + + # enable Parabola theme for grub + sed -i "$GRUB_THEME_SED_CMD" /mnt/etc/default/grub +} + +InstallWmDe() +{ + # prompt to install a graphical environment + local desktop=$( WizardDlg "${TR[dlg_wmde-${TR_KEY}]}" \ + --radiolist "${TR[gui-${TR_KEY}]}" 20 70 50 \ + 'yes' "${TR[yes-${TR_KEY}]}" 'on' \ + 'no' "${TR[no-${TR_KEY}]}" 'off' ) + + # prompt for WM/DE + local wmde=$( [[ "${desktop}" == 'no' ]] && echo 'cli' || \ + WizardDlg "${TR[dlg_wmde-${TR_KEY}]}" \ + --radiolist "${TR[wmde-${TR_KEY}]}" 20 70 50 \ + 'cli' "${TR[wmde_cli-${TR_KEY}]}" 'off' \ + 'lxde' "${TR[wmde_lxde-${TR_KEY}]}" 'on' \ + 'mate' "${TR[wmde_mate-${TR_KEY}]}" 'off' ) + [[ -n "${wmde}" ]] && SetStateVar 'WMDE' ${wmde} || exit + + # install graphical packages + [[ "${wmde}" != 'cli' ]] && pacstrap /mnt parabola-desktop-${wmde} # TODO: parabola-desktop NYI + + # enable services + cp "${CHROOT_SERVICES_FILE}" /mnt/root/ + chmod +x /mnt/root/${CHROOT_SERVICES_FILENAME} + arch-chroot /mnt /root/${CHROOT_SERVICES_FILENAME} + rm /mnt/root/${CHROOT_SERVICES_FILENAME} +} + +CreateUser() +{ + # prompt to create an unprivileged user login + local user=$( WizardDlg "${TR[dlg_user-${TR_KEY}]}" \ + --radiolist "${TR[user-${TR_KEY}]}" 20 70 50 \ + 'yes' "${TR[yes-${TR_KEY}]}" 'on' \ + 'no' "${TR[no-${TR_KEY}]}" 'off' ) + [[ -n "${user}" ]] || exit + [[ "${user}" == 'yes' ]] || return + + # create unprivileged user login + cp "${CHROOT_LOGIN_FILE}" /mnt/root/ + chmod +x /mnt/root/${CHROOT_LOGIN_FILENAME} + arch-chroot /mnt /root/${CHROOT_LOGIN_FILENAME} + rm /mnt/root/${CHROOT_LOGIN_FILENAME} +} + +Cleanup() +{ + # clean-up + arch-chroot /mnt pacman -R dialog --noconfirm &> /dev/null || true + rm /mnt/root/${SESSION_STATE_FILENAME} &> /dev/null || true + rm /mnt/root/${SESSION_INCLUDE_FILENAME} &> /dev/null || true + rm /mnt/root/${CHROOT_ENVIRONMENT_FILENAME} &> /dev/null || true + rm /mnt/root/${CHROOT_LOGIN_FILENAME} &> /dev/null || true + rm /mnt/root/${CHROOT_SERVICES_FILENAME} &> /dev/null || true + umount /mnt/boot &> /dev/null || true + umount /mnt/home &> /dev/null || true + umount /mnt &> /dev/null || true +} + + +## main entry ## + +set -o errexit -o errtrace +trap 'trap - ERR ; clear ; LogError() { : ; } ; Cleanup ;' EXIT INT TERM +trap 'trap - EXIT INT TERM ; clear ; LogError "${FUNCNAME[0]}" ${LINENO} ;' ERR + +Init # Check for isorepo existence and internet connection +InitKeyring # Initialize the pacman keyring +Partition # Partition and mount target disks +NoticeCustomize # Explain that the next choices are mandatory but interchangeable +SelectDefaults # Choose to install the standard system, or to customize +SelectBase # Select base system +InstallBase # Install base system +ConfigChroot # Generate fstab and configure system in-chroot (non-interactive) +NoticeOptional # Explain that the next choices are optional +InstallGrub # Install grub +InstallWmDe # Install GUI packages and configure services in-chroot +CreateUser # Create unpriviledged login user in-chroot +Cleanup # Remove helper scripts from the chroot and un-mount target disks + +exit |