break setup into functions

This commit is contained in:
Tobias Powalowski 2022-03-21 22:25:15 +01:00
parent f03ba7bdd7
commit 2dace79d54
35 changed files with 4507 additions and 4454 deletions

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/container_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/container.sh
_ARCHBOOT="archboot-arm"
_KEYRING="archlinuxarm"
[[ -z "${1}" ]] && _usage

View file

@ -1,8 +1,8 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/container_functions
source /usr/lib/archboot/repository_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/container.sh
source /usr/lib/archboot/repository.sh
_ARCHBOOT="archboot-arm"
[[ -d "${1}" ]] || (echo "Create directory ${1} ..."; mkdir "${1}")
_REPODIR="$(mktemp -d "${1}"/repository.XXX)"

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/iso_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/iso.sh
[[ -z "${1}" ]] && _usage
_parameters "$@"
_root_check

View file

@ -2,8 +2,8 @@
# created by Tobias Powalowski <tpowa@archlinux.org>
_ARCH="aarch64"
source /etc/archboot/defaults
source /usr/lib/archboot/functions
source /usr/lib/archboot/container_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/container.sh
_LATEST_ARM64="http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz"
_KEYRING="archlinuxarm"

View file

@ -2,8 +2,8 @@
# created by Tobias Powalowski <tpowa@archlinux.org>
_ARCH="aarch64"
_ARCHBOOT="archboot-arm"
source /usr/lib/archboot/functions
source /usr/lib/archboot/release_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/release.sh
[[ -z "${1}" ]] && _usage
_root_check
echo "Start release creation in $1 ..."

View file

@ -1,7 +1,7 @@
#! /bin/bash
_ARCH="aarch64"
source /usr/lib/archboot/functions
source /usr/lib/archboot/server_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/server.sh
_root_check
_update_aarch64_pacman_chroot || exit 1
_update_source

View file

@ -1,6 +1,6 @@
#!/bin/bash
source /usr/lib/archboot/functions
source /usr/lib/archboot/bootloader_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/bootloader.sh
_SHIM=$(mktemp -d shim.XXX)
_SHIM32=$(mktemp -d shim32.XXX)
_SHIMAA64=$(mktemp -d shimaa64.XXX)

View file

@ -1,5 +1,5 @@
#!/bin/bash
source /usr/lib/archboot/installer_common_functions
. /usr/lib/archboot/installer/common.sh
DESTDIR="${1}"
usage() {

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
. /usr/lib/archboot/common.sh
_D_SCRIPTS=""
_L_COMPLETE=""
_L_INSTALL_COMPLETE=""
@ -8,6 +8,8 @@ _G_RELEASE=""
_CONFIG="/etc/archboot/${_RUNNING_ARCH}-update_installer.conf"
_W_DIR="/archboot"
_INSTALLER_SOURCE="https://gitlab.archlinux.org/tpowa/archboot/-/raw/master"
_LIB_PATH="/usr/lib/archboot"
_INST_PATH="${_LIB_PATH}/installer"
kver() {
# get kernel version from installed kernel
@ -72,10 +74,23 @@ if [[ "${_D_SCRIPTS}" == "1" ]]; then
wget -q "$_INSTALLER_SOURCE/usr/bin/archboot-${_RUNNING_ARCH}-release.sh?inline=false" -O "/usr/bin/archboot-${_RUNNING_ARCH}-release.sh" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/bin/archboot-binary-check.sh?inline=false" -O /usr/bin/archboot-binary-check.sh >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/bin/archboot-update-installer.sh?inline=false" -O /usr/bin/update-installer.sh >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/lib/archboot/functions?inline=false" -O "/usr/lib/archboot/functions" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/lib/archboot/container_functions?inline=false" -O "/usr/lib/archboot/container_functions" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/lib/archboot/release_functions?inline=false" -O "/usr/lib/archboot/release_functions" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE/usr/lib/archboot/iso_functions?inline=false" -O "/usr/lib/archboot/iso_functions" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_LIB_PATH}/common.sh?inline=false" -O "${_LIB_PATH}/common.sh" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_LIB_PATH}/container.sh?inline=false" -O "${_LIB_PATH}/container.sh" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_LIB_PATH}/release.sh?inline=false" -O "${_LIB_PATH}/release.sh" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_LIB_PATH}/iso.sh?inline=false" -O "${_LIB_PATH}/iso.sh" >/dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/autoconfiguration.sh?inline=false" -O "${_INST_PATH}/autoconfiguration.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/autoprepare.sh?inline=false" -O "${_INST_PATH}/autoprepare.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/base.sh?inline=false" -O "${_INST_PATH}/base.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/blockdevices.sh?inline=false" -O "${_INST_PATH}/blockdevices.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/bootloader.sh?inline=false" -O "${_INST_PATH}/bootloader.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/btrfs.sh?inline=false" -O "${_INST_PATH}/btrfs.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/common.sh?inline=false" -O "${_INST_PATH}/common.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/configuration.sh?inline=false" -O "${_INST_PATH}/configuration.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/mountpoints.sh?inline=false" -O "${_INST_PATH}/mountpoints.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/network.sh?inline=false" -O "${_INST_PATH}/network.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/pacman.sh?inline=false" -O "${_INST_PATH}/pacman.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/partition.sh?inline=false" -O "${_INST_PATH}/partition.sh" > /dev/null 2>&1
wget -q "$_INSTALLER_SOURCE${_INST_PATH}/storage.sh?inline=false" -O "${_INST_PATH}/storage.sh" > /dev/null 2>&1
echo "Finished: Downloading scripts done."
exit 0
fi
@ -131,7 +146,7 @@ if [[ "${_L_COMPLETE}" == "1" || "${_L_INSTALL_COMPLETE}" == "1" ]]; then
echo " This will need some time ..."
# add fix for mkinitcpio 31, remove when 32 is released
cp "${_W_DIR}"/usr/share/archboot/patches/31-mkinitcpio.fixed "${_W_DIR}"/usr/bin/mkinitcpio
cp "${_W_DIR}"/usr/share/archboot/patches/31-initcpio.functions.fixed "${_W_DIR}"/usr/lib/initcpio/functions
cp "${_W_DIR}"/usr/share/archboot/patches/31-initcpio.functions.fixed "${_W_DIR}"/usr/lib/initcpio/common.sh
kver
# write initramfs to /tmp
systemd-nspawn -q -D "${_W_DIR}" /bin/bash -c "umount /tmp; mkinitcpio -k ${_HWKVER} -c ${_CONFIG} -d /tmp/" >/dev/tty7 2>&1 || exit 1

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/container_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/container.sh
_CACHEDIR="${1}/var/cache/pacman/pkg"
_ARCHBOOT="archboot"
_KEYRING="archlinux"

View file

@ -1,8 +1,8 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/container_functions
source /usr/lib/archboot/repository_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/container.sh
source /usr/lib/archboot/repository.sh
_ARCHBOOT="archboot"
[[ -d "${1}" ]] || (echo "Create directory ${1} ..."; mkdir "${1}")
_REPODIR="$(mktemp -d "${1}"/repository.XXX)"

View file

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# created by Tobias Powalowski <tpowa@archlinux.org>
source /usr/lib/archboot/functions
source /usr/lib/archboot/iso_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/iso.sh
[[ -z "${1}" ]] && _usage
_parameters "$@"
_root_check

View file

@ -2,8 +2,8 @@
# created by Tobias Powalowski <tpowa@archlinux.org>
_ARCH="x86_64"
_ARCHBOOT="archboot"
source /usr/lib/archboot/functions
source /usr/lib/archboot/release_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/release.sh
[[ -z "${1}" ]] && _usage
_root_check
_x86_64_check

View file

@ -1,7 +1,7 @@
#! /bin/bash
_ARCH="x86_64"
source /usr/lib/archboot/functions
source /usr/lib/archboot/server_functions
source /usr/lib/archboot/common.sh
source /usr/lib/archboot/server.sh
_root_check
_update_source
_x86_64_pacman_use_default || exit 1

View file

@ -0,0 +1,189 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# auto_fstab()
# preprocess fstab file
# comments out old fields and inserts new ones
# according to partitioning/formatting stage
#
auto_fstab(){
# Modify fstab
if [[ "${S_MKFS}" = "1" || "${S_MKFSAUTO}" = "1" ]]; then
if [[ -f /tmp/.device-names ]]; then
sort /tmp/.device-names >>"${DESTDIR}"/etc/fstab
fi
if [[ -f /tmp/.fstab ]]; then
# clean fstab first from entries
sed -i -e '/^\#/!d' "${DESTDIR}"/etc/fstab
sort /tmp/.fstab >>"${DESTDIR}"/etc/fstab
fi
fi
}
# auto_ssd()
# add udev rule for ssd disks using the deadline scheduler by default
# add sysctl file for swaps
auto_ssd () {
[[ ! -f ${DESTDIR}/etc/udev/rules.d/60-ioschedulers.rules ]] && cp /etc/udev/rules.d/60-ioschedulers.rules "${DESTDIR}"/etc/udev/rules.d/60-ioschedulers.rules
[[ ! -f ${DESTDIR}/etc/sysctl.d/99-sysctl.conf ]] && cp /etc/sysctl.d/99-sysctl.conf "${DESTDIR}"/etc/sysctl.d/99-sysctl.conf
}
# auto_mdadm()
# add mdadm setup to existing /etc/mdadm.conf
auto_mdadm()
{
if [[ -e ${DESTDIR}/etc/mdadm.conf ]]; then
if grep -q ^md /proc/mdstat 2>/dev/null; then
DIALOG --infobox "Adding raid setup to ${DESTDIR}/etc/mdadm.conf ..." 4 40
mdadm -Ds >> "${DESTDIR}"/etc/mdadm.conf
fi
fi
}
# auto_network()
# configures network on host system according to installer
# settings if user wishes to do so
#
auto_network()
{
# exit if network wasn't configured in installer
if [[ ${S_NET} -eq 0 ]]; then
return 1
fi
# copy netctl profiles
[[ -d ${DESTDIR}/etc/netctl ]] && cp /etc/netctl/* "${DESTDIR}"/etc/netctl/ 2>/dev/null
# enable netctl profiles
for i in $(echo /etc/netctl/*); do
[[ -f $i ]] && chroot "${DESTDIR}" /usr/bin/netctl enable "$(basename "${i}")"
done
# copy proxy settings
if [[ "${PROXY_HTTP}" != "" ]]; then
echo "export http_proxy=${PROXY_HTTP}" >> "${DESTDIR}"/etc/profile.d/proxy.sh;
chmod a+x "${DESTDIR}"/etc/profile.d/proxy.sh
fi
if [[ "${PROXY_FTP}" != "" ]]; then
echo "export ftp_proxy=${PROXY_FTP}" >> "${DESTDIR}"/etc/profile.d/proxy.sh;
chmod a+x "${DESTDIR}"/etc/profile.d/proxy.sh
fi
}
# Pacman signature check is enabled by default
# add gnupg pacman files to installed system
# in order to have a working pacman on installed system
auto_pacman()
{
if ! [[ -d ${DESTDIR}/etc/pacman.d/gnupg ]]; then
DO_PACMAN_GPG=""
DIALOG --yesno "Would you like to copy pacman's GPG files to installed system?\nDuring boot pacman GPG entropy was generated by haveged,\nif you need your own entropy answer NO." 0 0 && DO_PACMAN_GPG="yes"
if [[ "${DO_PACMAN_GPG}" = "yes" ]]; then
DIALOG --infobox "Copy /etc/pacman.d/gnupg directory to ${DESTDIR}/etc/pacman.d/gnupg ..." 0 0
cp -ar /etc/pacman.d/gnupg "${DESTDIR}"/etc/pacman.d 2>&1
fi
fi
}
# If [testing] repository was enabled during installation,
# enable it on installed system too!
auto_testing()
{
if [[ "${DOTESTING}" == "yes" ]]; then
sed -i -e '/^#\[testing\]/ { n ; s/^#// }' "${DESTDIR}"/etc/pacman.conf
sed -i -e '/^#\[community-testing\]/ { n ; s/^#// }' "${DESTDIR}"/etc/pacman.conf
sed -i -e 's:^#\[testing\]:\[testing\]:g' -e 's:^#\[community-testing\]:\[community-testing\]:g' "${DESTDIR}"/etc/pacman.conf
fi
}
auto_hwdetect() {
HWDETECT=""
FBPARAMETER=""
HWPARAMETER=""
HWDETECTMODULES=""
HWDETECTHOOKS=""
HWKVER=""
DIALOG --yesno "PRECONFIGURATION?\n-----------------\n\nDo you want to use 'hwdetect' for:\n'/etc/mkinitcpio.conf'?\n\nThis ensures consistent ordering of your storage disk / usb controllers.\n\nIt is recommended to say 'YES' here." 18 70 && HWDETECT="yes"
if [[ "${HWDETECT}" = "yes" ]]; then
# check on framebuffer modules and kms FBPARAMETER
grep -q "^radeon" /proc/modules && FBPARAMETER="--ati-kms"
grep -q "^amdgpu" /proc/modules && FBPARAMETER="--amd-kms"
grep -q "^i915" /proc/modules && FBPARAMETER="--intel-kms"
grep -q "^nouveau" /proc/modules && FBPARAMETER="--nvidia-kms"
# check on nfs,dmraid and keymap HWPARAMETER
# check on used keymap, if not us keyboard layout
! grep -q '^KEYMAP="us"' "${DESTDIR}"/etc/vconsole.conf && HWPARAMETER="${HWPARAMETER} --keymap"
# check on nfs
if lsmod | grep -q ^nfs; then
DIALOG --defaultno --yesno "Setup detected nfs driver...\nDo you need support for booting from nfs shares?" 0 0 && HWPARAMETER="${HWPARAMETER} --nfs"
fi
# check on dmraid
if [[ -e ${DESTDIR}/lib/initcpio/hooks/dmraid ]]; then
if ! dmraid -r | grep ^no; then
HWPARAMETER="${HWPARAMETER} --dmraid"
fi
fi
# get kernel version
offset=$(hexdump -s 526 -n 2 -e '"%0d"' "${DESTDIR}/boot/${VMLINUZ}")
read -r HWKVER _ < <(dd if="${DESTDIR}/boot/${VMLINUZ}" bs=1 count=127 skip=$(( offset + 0x200 )) 2>/dev/null)
# arrange MODULES for mkinitcpio.conf
HWDETECTMODULES="$(hwdetect --kernel_directory="${DESTDIR}" --kernel_version="${HWKVER}" --hostcontroller --filesystem ${FBPARAMETER})"
# arrange HOOKS for mkinitcpio.conf
HWDETECTHOOKS="$(hwdetect --kernel_directory="${DESTDIR}" --kernel_version="${HWKVER}" --rootdevice="${PART_ROOT}" --hooks-dir="${DESTDIR}"/usr/lib/initcpio/install "${HWPARAMETER}" --hooks)"
# change mkinitcpio.conf
[[ -n "${HWDETECTMODULES}" ]] && sed -i -e "s/^MODULES=.*/${HWDETECTMODULES}/g" "${DESTDIR}"/etc/mkinitcpio.conf
[[ -n "${HWDETECTHOOKS}" ]] && sed -i -e "s/^HOOKS=.*/${HWDETECTHOOKS}/g" "${DESTDIR}"/etc/mkinitcpio.conf
fi
}
auto_parameters() {
if [[ ! -f ${DESTDIR}/etc/vconsole.conf ]]; then
: >"${DESTDIR}"/etc/vconsole.conf
if [[ -s /tmp/.keymap ]]; then
DIALOG --infobox "Setting the keymap: $(sed -e 's/\..*//g' /tmp/.keymap) in vconsole.conf ..." 0 0
echo KEYMAP="$(sed -e 's/\..*//g' /tmp/.keymap)" >> "${DESTDIR}"/etc/vconsole.conf
fi
if [[ -s /tmp/.font ]]; then
DIALOG --infobox "Setting the consolefont: $(sed -e 's/\..*//g'/tmp/.font) in vconsole.conf ..." 0 0
echo FONT="$(sed -e 's/\..*//g' /tmp/.font)" >> "${DESTDIR}"/etc/vconsole.conf
fi
fi
}
auto_luks() {
# remove root device from crypttab
if [[ -e /tmp/.crypttab && "$(grep -v '^#' "${DESTDIR}"/etc/crypttab)" = "" ]]; then
# add to temp crypttab
sed -i -e "/^$(basename "${PART_ROOT}") /d" /tmp/.crypttab
cat /tmp/.crypttab >> "${DESTDIR}"/etc/crypttab
chmod 600 /tmp/passphrase-* 2>/dev/null
cp /tmp/passphrase-* "${DESTDIR}"/etc/ 2>/dev/null
fi
}
auto_timesetting() {
if [[ -e /etc/localtime && ! -e "${DESTDIR}"/etc/localtime ]]; then
cp -a /etc/localtime "${DESTDIR}"/etc/localtime
fi
if [[ ! -f "${DESTDIR}"/etc/adjtime ]]; then
echo "0.0 0 0.0" > "${DESTDIR}"/etc/adjtime
echo "0" >> "${DESTDIR}"/etc/adjtime
[[ -s /tmp/.hardwareclock ]] && cat /tmp/.hardwareclock >>"${DESTDIR}"/etc/adjtime
fi
}
auto_pacman_mirror() {
# /etc/pacman.d/mirrorlist
# add installer-selected mirror to the top of the mirrorlist
if [[ "${SYNC_URL}" != "" ]]; then
#shellcheck disable=SC2027,SC2086
awk "BEGIN { printf(\"# Mirror used during installation\nServer = "${SYNC_URL}"\n\n\") } 1 " "${DESTDIR}"/etc/pacman.d/mirrorlist > /tmp/inst-mirrorlist
mv /tmp/inst-mirrorlist "${DESTDIR}/etc/pacman.d/mirrorlist"
fi
}
auto_system_files () {
if [[ ! -f ${DESTDIR}/etc/hostname ]]; then
echo "myhostname" > "${DESTDIR}"/etc/hostname
fi
if [[ ! -f ${DESTDIR}/etc/locale.conf ]]; then
echo "LANG=C.UTF-8" > "${DESTDIR}"/etc/locale.conf
echo "LC_COLLATE=C" >> "${DESTDIR}"/etc/locale.conf
fi
}

View file

@ -0,0 +1,341 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
autoprepare() {
# check on encrypted devices, else weird things can happen!
_stopluks
# check on raid devices, else weird things can happen during partitioning!
_stopmd
# check on lvm devices, else weird things can happen during partitioning!
_stoplvm
NAME_SCHEME_PARAMETER_RUN=""
# switch for mbr usage
set_guid
: >/tmp/.device-names
DISCS=$(blockdevices)
if [[ "$(echo "${DISCS}" | wc -w)" -gt 1 ]]; then
DIALOG --cr-wrap --msgbox "Available Disks:\n\n$(_getavaildisks)\n" 0 0
#shellcheck disable=SC2046
DIALOG --menu "Select the storage drive to use" 14 55 7 $(blockdevices _) 2>"${ANSWER}" || return 1
DISC=$(cat ${ANSWER})
else
DISC="${DISCS}"
if [[ "${DISC}" = "" ]]; then
DIALOG --msgbox "ERROR: Setup cannot find available disk device, please use normal installation routine for partitioning and mounting devices." 0 0
return 1
fi
fi
BOOT_PART_SIZE=""
GUID_PART_SIZE=""
UEFISYS_PART_SIZE=""
DEFAULTFS=""
_UEFISYS_BOOTPART=""
UEFISYS_MOUNTPOINT=""
UEFISYS_PART_SET=""
BOOT_PART_SET=""
SWAP_PART_SET=""
ROOT_PART_SET=""
CHOSEN_FS=""
# get just the disk size in 1000*1000 MB
DISC_SIZE="$(($(${_LSBLK} SIZE -d -b "${DISC}")/1000000))"
if [[ "${DISC_SIZE}" = "" ]]; then
DIALOG --msgbox "ERROR: Setup cannot detect size of your device, please use normal installation routine for partitioning and mounting devices." 0 0
return 1
fi
if [[ "${GUIDPARAMETER}" = "yes" ]]; then
DIALOG --inputbox "Enter the mountpoint of your UEFI SYSTEM PARTITION (Default is /boot) : " 0 0 "/boot" 2>"${ANSWER}" || return 1
UEFISYS_MOUNTPOINT="$(cat ${ANSWER})"
fi
if [[ "${UEFISYS_MOUNTPOINT}" == "/boot" ]]; then
DIALOG --msgbox "You have chosen to use /boot as the UEFISYS Mountpoint. The minimum partition size is 260 MiB and only FAT32 FS is supported" 0 0
_UEFISYS_BOOTPART="1"
fi
while [[ "${DEFAULTFS}" = "" ]]; do
FSOPTS=""
[[ "$(which mkfs.ext2 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext2 Ext2"
[[ "$(which mkfs.ext3 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext3 Ext3"
[[ "$(which mkfs.ext4 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext4 Ext4"
[[ "$(which mkfs.btrfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} btrfs Btrfs"
[[ "$(which mkfs.nilfs2 2>/dev/null)" ]] && FSOPTS="${FSOPTS} nilfs2 Nilfs2"
[[ "$(which mkfs.f2fs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} f2fs F2FS"
[[ "$(which mkfs.xfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} xfs XFS"
[[ "$(which mkfs.jfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} jfs JFS"
# create 1 MB bios_grub partition for grub BIOS GPT support
if [[ "${GUIDPARAMETER}" = "yes" ]]; then
GUID_PART_SIZE="2"
GPT_BIOS_GRUB_PART_SIZE="${GUID_PART_SIZE}"
_PART_NUM="1"
_GPT_BIOS_GRUB_PART_NUM="${_PART_NUM}"
DISC_SIZE="$((DISC_SIZE-GUID_PART_SIZE))"
fi
if [[ "${GUIDPARAMETER}" = "yes" ]]; then
if [[ "${_UEFISYS_BOOTPART}" == "1" ]]; then
while [[ "${UEFISYS_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your /boot partition,\nMinimum value is 260.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "1024" 2>${ANSWER} || return 1
UEFISYS_PART_SIZE="$(cat ${ANSWER})"
if [[ "${UEFISYS_PART_SIZE}" = "" ]]; then
DIALOG --msgbox "ERROR: You have entered a invalid size, please enter again." 0 0
else
if [[ "${UEFISYS_PART_SIZE}" -ge "${DISC_SIZE}" || "${UEFISYS_PART_SIZE}" -lt "260" || "${UEFISYS_PART_SIZE}" = "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
BOOT_PART_SET=1
UEFISYS_PART_SET=1
_PART_NUM="$((_PART_NUM+1))"
_UEFISYS_PART_NUM="${_PART_NUM}"
fi
fi
done
else
while [[ "${UEFISYS_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your UEFI SYSTEM PARTITION,\nMinimum value is 260.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "1024" 2>${ANSWER} || return 1
UEFISYS_PART_SIZE="$(cat ${ANSWER})"
if [[ "${UEFISYS_PART_SIZE}" = "" ]]; then
DIALOG --msgbox "ERROR: You have entered a invalid size, please enter again." 0 0
else
if [[ "${UEFISYS_PART_SIZE}" -ge "${DISC_SIZE}" || "${UEFISYS_PART_SIZE}" -lt "260" || "${UEFISYS_PART_SIZE}" = "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
UEFISYS_PART_SET=1
_PART_NUM="$((_PART_NUM+1))"
_UEFISYS_PART_NUM="${_PART_NUM}"
fi
fi
done
fi
DISC_SIZE="$((DISC_SIZE-UEFISYS_PART_SIZE))"
while [[ "${BOOT_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your /boot partition,\nMinimum value is 16.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "512" 2>${ANSWER} || return 1
BOOT_PART_SIZE="$(cat ${ANSWER})"
if [[ "${BOOT_PART_SIZE}" = "" ]]; then
DIALOG --msgbox "ERROR: You have entered a invalid size, please enter again." 0 0
else
if [[ "${BOOT_PART_SIZE}" -ge "${DISC_SIZE}" || "${BOOT_PART_SIZE}" -lt "16" || "${BOOT_PART_SIZE}" = "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
BOOT_PART_SET=1
_PART_NUM="$((_UEFISYS_PART_NUM+1))"
_BOOT_PART_NUM="${_PART_NUM}"
DISC_SIZE="$((DISC_SIZE-BOOT_PART_SIZE))"
fi
fi
done
else
while [[ "${BOOT_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your /boot partition,\nMinimum value is 16.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "512" 2>${ANSWER} || return 1
BOOT_PART_SIZE="$(cat ${ANSWER})"
if [[ "${BOOT_PART_SIZE}" = "" ]]; then
DIALOG --msgbox "ERROR: You have entered a invalid size, please enter again." 0 0
else
if [[ "${BOOT_PART_SIZE}" -ge "${DISC_SIZE}" || "${BOOT_PART_SIZE}" -lt "16" || "${BOOT_PART_SIZE}" = "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
BOOT_PART_SET=1
_PART_NUM="1"
_BOOT_PART_NUM="${_PART_NUM}"
DISC_SIZE="$((DISC_SIZE-BOOT_PART_SIZE))"
fi
fi
done
fi
SWAP_SIZE="256"
[[ "${DISC_SIZE}" -lt "256" ]] && SWAP_SIZE="${DISC_SIZE}"
while [[ "${SWAP_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your swap partition,\nMinimum value is > 0.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "${SWAP_SIZE}" 2>"${ANSWER}" || return 1
SWAP_PART_SIZE=$(cat ${ANSWER})
if [[ "${SWAP_PART_SIZE}" = "" || "${SWAP_PART_SIZE}" = "0" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
if [[ "${SWAP_PART_SIZE}" -ge "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered a too large size, please enter again." 0 0
else
SWAP_PART_SET=1
_PART_NUM="$((_PART_NUM+1))"
_SWAP_PART_NUM="${_PART_NUM}"
fi
fi
done
while [[ "${CHOSEN_FS}" = "" ]]; do
#shellcheck disable=SC2086
DIALOG --menu "Select a filesystem for / and /home:" 16 45 9 ${FSOPTS} 2>${ANSWER} || return 1
FSTYPE=$(cat ${ANSWER})
DIALOG --yesno "${FSTYPE} will be used for / and /home. Is this OK?" 0 0 && CHOSEN_FS=1
done
# / and /home are subvolumes on btrfs
if ! [[ "${FSTYPE}" = "btrfs" ]]; then
DISC_SIZE="$((DISC_SIZE-SWAP_PART_SIZE))"
ROOT_SIZE="7500"
[[ "${DISC_SIZE}" -lt "7500" ]] && ROOT_SIZE="${DISC_SIZE}"
while [[ "${ROOT_PART_SET}" = "" ]]; do
DIALOG --inputbox "Enter the size (MB) of your / partition\nMinimum value is 2000,\nthe /home partition will use the remaining space.\n\nDisk space left: ${DISC_SIZE} MB" 10 65 "${ROOT_SIZE}" 2>"${ANSWER}" || return 1
ROOT_PART_SIZE=$(cat ${ANSWER})
if [[ "${ROOT_PART_SIZE}" = "" || "${ROOT_PART_SIZE}" = "0" || "${ROOT_PART_SIZE}" -lt "2000" ]]; then
DIALOG --msgbox "ERROR: You have entered an invalid size, please enter again." 0 0
else
if [[ "${ROOT_PART_SIZE}" -ge "${DISC_SIZE}" ]]; then
DIALOG --msgbox "ERROR: You have entered a too large size, please enter again." 0 0
else
DIALOG --yesno "$((DISC_SIZE-ROOT_PART_SIZE)) MB will be used for your /home partition. Is this OK?" 0 0 && ROOT_PART_SET=1
fi
fi
done
fi
_PART_NUM="$((_PART_NUM+1))"
_ROOT_PART_NUM="${_PART_NUM}"
if ! [[ "${FSTYPE}" = "btrfs" ]]; then
_PART_NUM="$((_PART_NUM+1))"
fi
_HOME_PART_NUM="${_PART_NUM}"
DEFAULTFS=1
done
DIALOG --defaultno --yesno "${DISC} will be COMPLETELY ERASED! Are you absolutely sure?" 0 0 \
|| return 1
DEVICE=${DISC}
# validate DEVICE
if [[ ! -b "${DEVICE}" ]]; then
DIALOG --msgbox "Device '${DEVICE}' is not valid" 0 0
return 1
fi
# validate DEST
if [[ ! -d "${DESTDIR}" ]]; then
DIALOG --msgbox "Destination directory '${DESTDIR}' is not valid" 0 0
return 1
fi
[[ -e /tmp/.fstab ]] && rm -f /tmp/.fstab
# disable swap and all mounted partitions, umount / last!
_umountall
# we assume a /dev/sdX,/dev/vdX or /dev/nvmeXnY format
if [[ "${GUIDPARAMETER}" == "yes" ]]; then
# GPT (GUID) is supported only by 'parted' or 'sgdisk'
printk off
DIALOG --infobox "Partitioning ${DEVICE}" 0 0
# clean partition table to avoid issues!
sgdisk --zap "${DEVICE}" &>/dev/null
# clear all magic strings/signatures - mdadm, lvm, partition tables etc.
dd if=/dev/zero of="${DEVICE}" bs=512 count=2048 &>/dev/null
wipefs -a "${DEVICE}" &>/dev/null
# create fresh GPT
sgdisk --clear "${DEVICE}" &>/dev/null
# create actual partitions
sgdisk --set-alignment="2048" --new=${_GPT_BIOS_GRUB_PART_NUM}:0:+${GPT_BIOS_GRUB_PART_SIZE}M --typecode=${_GPT_BIOS_GRUB_PART_NUM}:EF02 --change-name=${_GPT_BIOS_GRUB_PART_NUM}:BIOS_GRUB "${DEVICE}" > ${LOG}
sgdisk --set-alignment="2048" --new=${_UEFISYS_PART_NUM}:0:+"${UEFISYS_PART_SIZE}"M --typecode=${_UEFISYS_PART_NUM}:EF00 --change-name=${_UEFISYS_PART_NUM}:UEFI_SYSTEM "${DEVICE}" > ${LOG}
if [[ "${_UEFISYS_BOOTPART}" == "1" ]]; then
sgdisk --attributes=${_UEFISYS_PART_NUM}:set:2 "${DEVICE}" > ${LOG}
else
sgdisk --set-alignment="2048" --new=${_BOOT_PART_NUM}:0:+"${BOOT_PART_SIZE}"M --typecode=${_BOOT_PART_NUM}:8300 --attributes=${_BOOT_PART_NUM}:set:2 --change-name=${_BOOT_PART_NUM}:ARCHLINUX_BOOT "${DEVICE}" > ${LOG}
fi
sgdisk --set-alignment="2048" --new=${_SWAP_PART_NUM}:0:+"${SWAP_PART_SIZE}"M --typecode=${_SWAP_PART_NUM}:8200 --change-name=${_SWAP_PART_NUM}:ARCHLINUX_SWAP "${DEVICE}" > ${LOG}
if [[ "${FSTYPE}" = "btrfs" ]]; then
sgdisk --set-alignment="2048" --new=${_ROOT_PART_NUM}:0:0 --typecode=${_ROOT_PART_NUM}:8300 --change-name=${_ROOT_PART_NUM}:ARCHLINUX_ROOT "${DEVICE}" > ${LOG}
else
sgdisk --set-alignment="2048" --new=${_ROOT_PART_NUM}:0:+"${ROOT_PART_SIZE}"M --typecode=${_ROOT_PART_NUM}:8300 --change-name=${_ROOT_PART_NUM}:ARCHLINUX_ROOT "${DEVICE}" > ${LOG}
sgdisk --set-alignment="2048" --new=${_HOME_PART_NUM}:0:0 --typecode=${_HOME_PART_NUM}:8302 --change-name=${_HOME_PART_NUM}:ARCHLINUX_HOME "${DEVICE}" > ${LOG}
fi
sgdisk --print "${DEVICE}" > ${LOG}
else
# start at sector 1 for 4k drive compatibility and correct alignment
printk off
DIALOG --infobox "Partitioning ${DEVICE}" 0 0
# clean partitiontable to avoid issues!
dd if=/dev/zero of="${DEVICE}" bs=512 count=2048 >/dev/null 2>&1
wipefs -a "${DEVICE}" &>/dev/null
# create DOS MBR with parted
parted -a optimal -s "${DEVICE}" unit MiB mktable msdos >/dev/null 2>&1
parted -a optimal -s "${DEVICE}" unit MiB mkpart primary 1 $((GUID_PART_SIZE+BOOT_PART_SIZE)) >${LOG}
parted -a optimal -s "${DEVICE}" unit MiB set 1 boot on >${LOG}
parted -a optimal -s "${DEVICE}" unit MiB mkpart primary $((GUID_PART_SIZE+BOOT_PART_SIZE)) $((GUID_PART_SIZE+BOOT_PART_SIZE+SWAP_PART_SIZE)) >${LOG}
# $(sgdisk -E ${DEVICE}) | grep ^[0-9] as end of last partition to keep the possibilty to convert to GPT later, instead of 100%
if [[ "${FSTYPE}" = "btrfs" ]]; then
parted -a optimal -s "${DEVICE}" unit MiB mkpart primary $((GUID_PART_SIZE+BOOT_PART_SIZE+SWAP_PART_SIZE)) "$(sgdisk -E "${DEVICE}" | grep "^[0-9]")S" >${LOG}
else
parted -a optimal -s "${DEVICE}" unit MiB mkpart primary $((GUID_PART_SIZE+BOOT_PART_SIZE+SWAP_PART_SIZE)) $((GUID_PART_SIZE+BOOT_PART_SIZE+SWAP_PART_SIZE+ROOT_PART_SIZE)) >${LOG}
parted -a optimal -s "${DEVICE}" unit MiB mkpart primary $((GUID_PART_SIZE+BOOT_PART_SIZE+SWAP_PART_SIZE+ROOT_PART_SIZE)) "$(sgdisk -E "${DEVICE}" | grep "^[0-9]")S" >${LOG}
fi
fi
#shellcheck disable=SC2181
if [[ $? -gt 0 ]]; then
DIALOG --msgbox "Error partitioning ${DEVICE} (see ${LOG} for details)" 0 0
printk on
return 1
fi
# reread partitiontable for kernel
partprobe "${DEVICE}"
printk on
## wait until /dev initialized correct devices
udevadm settle
if [[ "${NAME_SCHEME_PARAMETER_RUN}" == "" ]]; then
set_device_name_scheme || return 1
fi
## FSSPECS - default filesystem specs (the + is bootable flag)
## <partnum>:<mountpoint>:<partsize>:<fstype>[:<fsoptions>][:+]:labelname
## The partitions in FSSPECS list should be listed in the "mountpoint" order.
## Make sure the "root" partition is defined first in the FSSPECS list
_FSSPEC_ROOT_PART="${_ROOT_PART_NUM}:/:${FSTYPE}::ROOT_ARCH"
_FSSPEC_HOME_PART="${_HOME_PART_NUM}:/home:${FSTYPE}::HOME_ARCH"
_FSSPEC_SWAP_PART="${_SWAP_PART_NUM}:swap:swap::SWAP_ARCH"
_FSSPEC_BOOT_PART="${_BOOT_PART_NUM}:/boot:ext2::BOOT_ARCH"
_FSSPEC_UEFISYS_PART="${_UEFISYS_PART_NUM}:${UEFISYS_MOUNTPOINT}:vfat:-F32:EFISYS"
if [[ "${GUIDPARAMETER}" == "yes" ]]; then
if [[ "${_UEFISYS_BOOTPART}" == "1" ]]; then
FSSPECS="${_FSSPEC_ROOT_PART} ${_FSSPEC_UEFISYS_PART} ${_FSSPEC_HOME_PART} ${_FSSPEC_SWAP_PART}"
else
FSSPECS="${_FSSPEC_ROOT_PART} ${_FSSPEC_BOOT_PART} ${_FSSPEC_UEFISYS_PART} ${_FSSPEC_HOME_PART} ${_FSSPEC_SWAP_PART}"
fi
else
FSSPECS="${_FSSPEC_ROOT_PART} ${_FSSPEC_BOOT_PART} ${_FSSPEC_HOME_PART} ${_FSSPEC_SWAP_PART}"
fi
## make and mount filesystems
for fsspec in ${FSSPECS}; do
DOMKFS="yes"
PART="${DEVICE}$(echo "${fsspec}" | tr -d ' ' | cut -f1 -d:)"
# Add check on nvme controller: Uses /dev/nvme0n1pX name scheme
echo "${DEVICE}" | grep -q "nvme" && PART="${DEVICE}p$(echo "${fsspec}" | tr -d ' ' | cut -f1 -d:)"
MP="$(echo "${fsspec}" | tr -d ' ' | cut -f2 -d:)"
FSTYPE="$(echo "${fsspec}" | tr -d ' ' | cut -f3 -d:)"
FS_OPTIONS="$(echo "${fsspec}" | tr -d ' ' | cut -f4 -d:)"
[[ "${FS_OPTIONS}" == "" ]] && FS_OPTIONS="NONE"
LABEL_NAME="$(echo "${fsspec}" | tr -d ' ' | cut -f5 -d:)"
BTRFS_DEVICES="${PART}"
if [[ "${FSTYPE}" = "btrfs" ]]; then
BTRFS_COMPRESS="compress=lzo"
[[ "${MP}" = "/" ]] && BTRFS_SUBVOLUME="root"
[[ "${MP}" = "/home" ]] && BTRFS_SUBVOLUME="home" && DOMKFS="no"
DOSUBVOLUME="yes"
else
BTRFS_COMPRESS="NONE"
BTRFS_SUBVOLUME="NONE"
DOSUBVOLUME="no"
fi
BTRFS_LEVEL="NONE"
if ! [[ "${FSTYPE}" = "swap" ]]; then
DIALOG --infobox "Creating ${FSTYPE} on ${PART}\nwith FSLABEL ${LABEL_NAME} ,\nmounting to ${DESTDIR}${MP}" 0 0
else
DIALOG --infobox "Creating and activating swapspace on ${PART}" 0 0
fi
_mkfs "${DOMKFS}" "${PART}" "${FSTYPE}" "${DESTDIR}" "${MP}" "${LABEL_NAME}" "${FS_OPTIONS}" "${BTRFS_DEVICES}" ${BTRFS_LEVEL} ${BTRFS_SUBVOLUME} ${DOSUBVOLUME} ${BTRFS_COMPRESS} || return 1
sleep 1
done
DIALOG --msgbox "Auto-prepare was successful" 0 0
S_MKFSAUTO=1
}

View file

@ -0,0 +1,33 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
set_title() {
if [[ -e "${LOCAL_DB}" ]]; then
TITLE="Arch Linux Installation (Local mode) --> wiki.archlinux.org/title/Archboot"
else
TITLE="Arch Linux Installation (Online mode) --> wiki.archlinux.org/title/Archboot"
fi
}
# DIALOG()
# an el-cheapo dialog wrapper
#
# parameters: see dialog(1)
# returns: whatever dialog did
DIALOG() {
dialog --backtitle "${TITLE}" --aspect 15 "$@"
return $?
}
printk()
{
case ${1} in
"on") echo 4 >/proc/sys/kernel/printk ;;
"off") echo 0 >/proc/sys/kernel/printk ;;
esac
}
getdest() {
[[ "${DESTDIR}" ]] && return 0
DIALOG --inputbox "Enter the destination directory where your target system is mounted" 8 65 "${DESTDIR}" 2>${ANSWER} || return 1
DESTDIR=$(cat ${ANSWER})
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,282 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# scan and update btrfs devices
btrfs_scan() {
btrfs device scan >/dev/null 2>&1
}
# mount btrfs for checks
mount_btrfs() {
btrfs_scan
BTRFSMP="$(mktemp -d /tmp/brtfsmp.XXXX)"
mount "${PART}" "${BTRFSMP}"
}
# unmount btrfs after checks done
umount_btrfs() {
umount "${BTRFSMP}"
rm -r "${BTRFSMP}"
}
# Set BTRFS_DEVICES on detected btrfs devices
find_btrfs_raid_devices() {
btrfs_scan
if [[ "${DETECT_CREATE_FILESYSTEM}" = "no" && "${FSTYPE}" = "btrfs" ]]; then
for i in $(btrfs filesystem show "${PART}" | cut -d " " -f 11); do
BTRFS_DEVICES="${BTRFS_DEVICES}#${i}"
done
fi
}
find_btrfs_raid_bootloader_devices() {
btrfs_scan
BTRFS_COUNT=1
if [[ "$(${_LSBLK} FSTYPE "${bootdev}")" = "btrfs" ]]; then
BTRFS_DEVICES=""
for i in $(btrfs filesystem show "${bootdev}" | cut -d " " -f 11); do
BTRFS_DEVICES="${BTRFS_DEVICES}#${i}"
BTRFS_COUNT=$((BTRFS_COUNT+1))
done
fi
}
# find btrfs subvolume
find_btrfs_subvolume() {
if [[ "${DETECT_CREATE_FILESYSTEM}" = "no" ]]; then
# existing btrfs subvolumes
mount_btrfs
for i in $(btrfs subvolume list "${BTRFSMP}" | cut -d " " -f 9); do
echo "${i}"
[[ "${1}" ]] && echo "${1}"
done
umount_btrfs
fi
}
find_btrfs_bootloader_subvolume() {
if [[ "$(${_LSBLK} FSTYPE "${bootdev}")" = "btrfs" ]]; then
BTRFS_SUBVOLUMES=""
PART="${bootdev}"
mount_btrfs
for i in $(btrfs subvolume list "${BTRFSMP}" | cut -d " " -f 7); do
BTRFS_SUBVOLUMES="${BTRFS_SUBVOLUMES}#${i}"
done
umount_btrfs
fi
}
# subvolumes already in use
subvolumes_in_use() {
SUBVOLUME_IN_USE=""
while read -r i; do
echo "${i}" | grep -q ":btrfs:" && SUBVOLUME_IN_USE="${SUBVOLUME_IN_USE} $(echo "${i}" | cut -d: -f 9)"
done < /tmp/.parts
}
# do not ask for btrfs filesystem creation, if already prepared for creation!
check_btrfs_filesystem_creation() {
DETECT_CREATE_FILESYSTEM="no"
SKIP_FILESYSTEM="no"
SKIP_ASK_SUBVOLUME="no"
#shellcheck disable=SC2013
for i in $(grep "${PART}[:#]" /tmp/.parts); do
if echo "${i}" | grep -q ":btrfs:"; then
FSTYPE="btrfs"
SKIP_FILESYSTEM="yes"
# check on filesystem creation, skip subvolume asking then!
echo "${i}" | cut -d: -f 4 | grep -q yes && DETECT_CREATE_FILESYSTEM="yes"
[[ "${DETECT_CREATE_FILESYSTEM}" = "yes" ]] && SKIP_ASK_SUBVOLUME="yes"
fi
done
}
# remove devices with no subvolume from list and generate raid device list
btrfs_parts() {
if [[ -s /tmp/.btrfs-devices ]]; then
BTRFS_DEVICES=""
while read -r i; do
BTRFS_DEVICES="${BTRFS_DEVICES}#${i}"
# remove device if no subvolume is used!
[[ "${BTRFS_SUBVOLUME}" = "NONE" ]] && PARTS="${PARTS//${i}\ _/}"
done < /tmp/.btrfs-devices
else
[[ "${BTRFS_SUBVOLUME}" = "NONE" ]] && PARTS="${PARTS//${PART}\ _/}"
fi
}
# choose raid level to use on btrfs device
btrfs_raid_level() {
BTRFS_RAIDLEVELS="NONE - raid0 - raid1 - raid5 - raid6 - raid10 - single -"
BTRFS_RAID_FINISH=""
BTRFS_LEVEL=""
BTRFS_DEVICE="${PART}"
: >/tmp/.btrfs-devices
DIALOG --msgbox "BTRFS DATA RAID OPTIONS:\n\nRAID5/6 are for testing purpose. Use with extreme care!\n\nIf you don't need this feature select NONE." 0 0
while [[ "${BTRFS_RAID_FINISH}" != "DONE" ]]; do
#shellcheck disable=SC2086
DIALOG --menu "Select the raid data level you want to use" 21 50 9 ${BTRFS_RAIDLEVELS} 2>${ANSWER} || return 1
BTRFS_LEVEL=$(cat ${ANSWER})
if [[ "${BTRFS_LEVEL}" = "NONE" ]]; then
echo "${BTRFS_DEVICE}" >>/tmp/.btrfs-devices
break
else
# take selected device as 1st device, add additional devices in part below.
select_btrfs_raid_devices
fi
done
}
# select btrfs raid devices
select_btrfs_raid_devices () {
# show all devices with sizes
# DIALOG --msgbox "DISKS:\n$(_getavaildisks)\n\nPARTITIONS:\n$(_getavailpartitions)" 0 0
# select the second device to use, no missing option available!
: >/tmp/.btrfs-devices
BTRFS_PART="${BTRFS_DEVICE}"
BTRFS_PARTS="${PARTS}"
echo "${BTRFS_PART}" >>/tmp/.btrfs-devices
BTRFS_PARTS="${BTRFS_PARTS//${BTRFS_PART}\ _/}"
RAIDNUMBER=2
#shellcheck disable=SC2086
DIALOG --menu "Select device ${RAIDNUMBER}" 21 50 13 ${BTRFS_PARTS} 2>${ANSWER} || return 1
BTRFS_PART=$(cat ${ANSWER})
echo "${BTRFS_PART}" >>/tmp/.btrfs-devices
while [[ "${BTRFS_PART}" != "DONE" ]]; do
BTRFS_DONE=""
RAIDNUMBER=$((RAIDNUMBER + 1))
# RAID5 needs 3 devices
# RAID6, RAID10 need 4 devices!
[[ "${RAIDNUMBER}" -ge 3 && ! "${BTRFS_LEVEL}" = "raid10" && ! "${BTRFS_LEVEL}" = "raid6" && ! "${BTRFS_LEVEL}" = "raid5" ]] && BTRFS_DONE="DONE _"
[[ "${RAIDNUMBER}" -ge 4 && "${BTRFS_LEVEL}" = "raid5" ]] && BTRFS_DONE="DONE _"
[[ "${RAIDNUMBER}" -ge 5 && "${BTRFS_LEVEL}" = "raid10" || "${BTRFS_LEVEL}" = "raid6" ]] && BTRFS_DONE="DONE _"
# clean loop from used partition and options
BTRFS_PARTS="${BTRFS_PARTS//${BTRFS_PART}\ _/}"
# add more devices
#shellcheck disable=SC2086
DIALOG --menu "Select device ${RAIDNUMBER}" 21 50 13 ${BTRFS_PARTS} ${BTRFS_DONE} 2>${ANSWER} || return 1
BTRFS_PART=$(cat ${ANSWER})
[[ "${BTRFS_PART}" = "DONE" ]] && break
echo "${BTRFS_PART}" >>/tmp/.btrfs-devices
done
# final step ask if everything is ok?
#shellcheck disable=SC2028
DIALOG --yesno "Would you like to create btrfs raid data like this?\n\nLEVEL:\n${BTRFS_LEVEL}\n\nDEVICES:\n$(while read -r i; do echo "${i}\n"; done </tmp/.btrfs-devices)" 0 0 && BTRFS_RAID_FINISH="DONE"
}
# prepare new btrfs device
prepare_btrfs() {
btrfs_raid_level || return 1
prepare_btrfs_subvolume || return 1
}
# prepare btrfs subvolume
prepare_btrfs_subvolume() {
DOSUBVOLUME="no"
BTRFS_SUBVOLUME="NONE"
if [[ "${SKIP_ASK_SUBVOLUME}" = "no" ]]; then
DIALOG --defaultno --yesno "Would you like to create a new subvolume on ${PART}?" 0 0 && DOSUBVOLUME="yes"
else
DOSUBVOLUME="yes"
fi
if [[ "${DOSUBVOLUME}" = "yes" ]]; then
BTRFS_SUBVOLUME="NONE"
while [[ "${BTRFS_SUBVOLUME}" = "NONE" ]]; do
DIALOG --inputbox "Enter the SUBVOLUME name for the device, keep it short\nand use no spaces or special\ncharacters." 10 65 2>${ANSWER} || return 1
BTRFS_SUBVOLUME=$(cat ${ANSWER})
check_btrfs_subvolume
done
else
BTRFS_SUBVOLUME="NONE"
fi
}
# check btrfs subvolume
check_btrfs_subvolume(){
[[ "${DOMKFS}" = "yes" && "${FSTYPE}" = "btrfs" ]] && DETECT_CREATE_FILESYSTEM="yes"
if [[ "${DETECT_CREATE_FILESYSTEM}" = "no" ]]; then
mount_btrfs
for i in $(btrfs subvolume list "${BTRFSMP}" | cut -d " " -f 7); do
if echo "${i}" | grep -q "${BTRFS_SUBVOLUME}"; then
DIALOG --msgbox "ERROR: You have defined 2 identical SUBVOLUME names or an empty name! Please enter another name." 8 65
BTRFS_SUBVOLUME="NONE"
fi
done
umount_btrfs
else
subvolumes_in_use
if echo "${SUBVOLUME_IN_USE}" | grep -Eq "${BTRFS_SUBVOLUME}"; then
DIALOG --msgbox "ERROR: You have defined 2 identical SUBVOLUME names or an empty name! Please enter another name." 8 65
BTRFS_SUBVOLUME="NONE"
fi
fi
}
# create btrfs subvolume
create_btrfs_subvolume() {
mount_btrfs
btrfs subvolume create "${BTRFSMP}"/"${_btrfssubvolume}" >${LOG}
# change permission from 700 to 755
# to avoid warnings during package installation
chmod 755 "${BTRFSMP}"/"${_btrfssubvolume}"
umount_btrfs
}
# choose btrfs subvolume from list
choose_btrfs_subvolume () {
BTRFS_SUBVOLUME="NONE"
SUBVOLUMES_DETECTED="no"
SUBVOLUMES=$(find_btrfs_subvolume _)
# check if subvolumes are present
[[ -n "${SUBVOLUMES}" ]] && SUBVOLUMES_DETECTED="yes"
subvolumes_in_use
for i in ${SUBVOLUME_IN_USE}; do
SUBVOLUMES=${SUBVOLUMES//${i}\ _/}
done
if [[ -n "${SUBVOLUMES}" ]]; then
#shellcheck disable=SC2086
DIALOG --menu "Select the subvolume to mount" 21 50 13 ${SUBVOLUMES} 2>${ANSWER} || return 1
BTRFS_SUBVOLUME=$(cat ${ANSWER})
else
if [[ "${SUBVOLUMES_DETECTED}" = "yes" ]]; then
DIALOG --msgbox "ERROR: All subvolumes of the device are already in use. Switching to create a new one now." 8 65
SKIP_ASK_SUBVOLUME=yes
prepare_btrfs_subvolume || return 1
fi
fi
}
# btrfs subvolume menu
btrfs_subvolume() {
FILESYSTEM_FINISH=""
if [[ "${FSTYPE}" = "btrfs" && "${DOMKFS}" = "no" ]]; then
if [[ "${ASK_MOUNTPOINTS}" = "1" ]]; then
# create subvolume if requested
# choose btrfs subvolume if present
prepare_btrfs_subvolume || return 1
if [[ "${BTRFS_SUBVOLUME}" = "NONE" ]]; then
choose_btrfs_subvolume || return 1
fi
else
# use device if no subvolume is present
choose_btrfs_subvolume || return 1
fi
btrfs_compress
fi
FILESYSTEM_FINISH="yes"
}
# ask for btrfs compress option
btrfs_compress() {
BTRFS_COMPRESS="NONE"
BTRFS_COMPRESSLEVELS="lzo - zlib - zstd -"
if [[ "${BTRFS_SUBVOLUME}" = "NONE" ]]; then
DIALOG --yesno "Would you like to compress the data on ${PART}?" 0 0 && BTRFS_COMPRESS="compress"
else
DIALOG --yesno "Would you like to compress the data on ${PART} subvolume=${BTRFS_SUBVOLUME}?" 0 0 && BTRFS_COMPRESS="compress"
fi
if [[ "${BTRFS_COMPRESS}" = "compress" ]]; then
#shellcheck disable=SC2086
DIALOG --menu "Select the compression method you want to use" 21 50 9 ${BTRFS_COMPRESSLEVELS} 2>${ANSWER} || return 1
BTRFS_COMPRESS="compress=$(cat ${ANSWER})"
fi
}

View file

@ -0,0 +1,84 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# geteditor()
# prompts the user to choose an editor
# sets EDITOR global variable
#
geteditor() {
if ! [[ "${EDITOR}" ]]; then
DIALOG --menu "Select a Text Editor to Use" 10 35 3 \
"1" "nano (easier)" \
"2" "vi" 2>${ANSWER} || return 1
case $(cat ${ANSWER}) in
"1") EDITOR="nano" ;;
"2") EDITOR="vi" ;;
esac
fi
}
set_mkinitcpio() {
DIALOG --msgbox "The mkinitcpio.conf file controls which modules will be placed into the initramfs for your system's kernel.\n\n- Non US keymap users should add 'keymap' to HOOKS= array\n- If you install under VMWARE add 'BusLogic' to MODULES= array\n- raid, lvm2, encrypt are not enabled by default\n- 2 or more disk controllers, please specify the correct module\n loading order in MODULES= array \n\nMost of you will not need to change anything in this file." 18 70
HOOK_ERROR=""
${EDITOR} "${DESTDIR}""${FILE}"
#shellcheck disable=SC2013
for i in $(grep ^HOOKS "${DESTDIR}"/etc/mkinitcpio.conf | sed -e 's/"//g' -e 's/HOOKS=\(//g' -e 's/\)//g'); do
[[ -e ${DESTDIR}/usr/lib/initcpio/install/${i} ]] || HOOK_ERROR=1
done
if [[ "${HOOK_ERROR}" = "1" ]]; then
DIALOG --msgbox "ERROR: Detected error in 'HOOKS=' line, please correct HOOKS= in /etc/mkinitcpio.conf!" 18 70
fi
}
set_locale() {
# enable glibc locales from locale.conf
#shellcheck disable=SC2013
for i in $(grep "^LANG" "${DESTDIR}"/etc/locale.conf | sed -e 's/.*=//g' -e's/\..*//g'); do
sed -i -e "s/^#${i}/${i}/g" "${DESTDIR}"/etc/locale.gen
done
${EDITOR} "${DESTDIR}""${FILE}"
}
set_password() {
PASSWORD=""
while [[ "${PASSWORD}" = "" ]]; do
DIALOG --insecure --passwordbox "Enter root password:" 0 0 2>${ANSWER} || return 1
PASS=$(cat ${ANSWER})
DIALOG --insecure --passwordbox "Retype root password:" 0 0 2>${ANSWER} || return 1
PASS2=$(cat ${ANSWER})
if [[ "${PASS}" = "${PASS2}" ]]; then
PASSWORD=${PASS}
echo "${PASSWORD}" > /tmp/.password
echo "${PASSWORD}" >> /tmp/.password
PASSWORD=/tmp/.password
else
DIALOG --msgbox "Password didn't match, please enter again." 0 0
fi
done
chroot "${DESTDIR}" passwd root < /tmp/.password
rm /tmp/.password
}
# run_mkinitcpio()
# runs mkinitcpio on the target system, displays output
#
run_mkinitcpio() {
chroot_mount
# all mkinitcpio output goes to /tmp/mkinitcpio.log, which we tail into a dialog
( \
touch /tmp/setup-mkinitcpio-running
echo "Initramfs progress ..." > /tmp/initramfs.log; echo >> /tmp/mkinitcpio.log
if [[ "${RUNNING_ARCH}" == "aarch64" ]]; then
chroot "${DESTDIR}" /usr/bin/mkinitcpio -p ${KERNELPKG}-"${RUNNING_ARCH}" >>/tmp/mkinitcpio.log 2>&1
else
chroot "${DESTDIR}" /usr/bin/mkinitcpio -p ${KERNELPKG} >>/tmp/mkinitcpio.log 2>&1
fi
echo >> /tmp/mkinitcpio.log
rm -f /tmp/setup-mkinitcpio-running
) &
sleep 2
dialog --backtitle "${TITLE}" --title "Rebuilding initramfs images ..." --no-kill --tailboxbg "/tmp/mkinitcpio.log" 18 70
while [[ -f /tmp/setup-mkinitcpio-running ]]; do
/usr/bin/true
done
chroot_umount
}

View file

@ -0,0 +1,432 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# destdir_mounts()
# check if PART_ROOT is set and if something is mounted on ${DESTDIR}
destdir_mounts(){
# Don't ask for filesystem and create new filesystems
ASK_MOUNTPOINTS=""
PART_ROOT=""
# check if something is mounted on ${DESTDIR}
PART_ROOT="$(mount | grep "${DESTDIR} " | cut -d' ' -f 1)"
# Run mountpoints, if nothing is mounted on ${DESTDIR}
if [[ "${PART_ROOT}" = "" ]]; then
DIALOG --msgbox "Setup couldn't detect mounted partition(s) in ${DESTDIR}, please set mountpoints first." 0 0
detect_uefi_boot
mountpoints || return 1
fi
}
# values that are needed for fs creation
clear_fs_values() {
: >/tmp/.btrfs-devices
DOMKFS="no"
LABEL_NAME=""
FS_OPTIONS=""
BTRFS_DEVICES=""
BTRFS_LEVEL=""
BTRFS_SUBVOLUME=""
DOSUBVOLUME=""
BTRFS_COMPRESS=""
}
# add ssd mount options
ssd_optimization() {
# ext4, jfs, xfs, btrfs, nilfs2, f2fs have ssd mount option support
ssd_mount_options=""
if echo "${_fstype}" | grep -Eq 'ext4|jfs|btrfs|xfs|nilfs2|f2fs'; then
# check all underlying devices on ssd
for i in $(${_LSBLK} NAME,TYPE "${_device}" -s | grep "disk$" | cut -d' ' -f 1); do
# check for ssd
if [[ "$(cat /sys/block/"$(basename "${i}")"/queue/rotational)" == "0" ]]; then
ssd_mount_options="noatime"
fi
done
fi
}
select_filesystem() {
FILESYSTEM_FINISH=""
# don't allow vfat as / filesystem, it will not work!
FSOPTS=""
[[ "$(which mkfs.ext2 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext2 Ext2"
[[ "$(which mkfs.ext3 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext3 Ext3"
[[ "$(which mkfs.ext4 2>/dev/null)" ]] && FSOPTS="${FSOPTS} ext4 Ext4"
[[ "$(which mkfs.btrfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} btrfs Btrfs"
[[ "$(which mkfs.nilfs2 2>/dev/null)" ]] && FSOPTS="${FSOPTS} nilfs2 Nilfs2"
[[ "$(which mkfs.f2fs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} f2fs F2FS"
[[ "$(which mkfs.xfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} xfs XFS"
[[ "$(which mkfs.jfs 2>/dev/null)" ]] && FSOPTS="${FSOPTS} jfs JFS"
[[ "$(which mkfs.vfat 2>/dev/null)" && "${DO_ROOT}" = "DONE" ]] && FSOPTS="${FSOPTS} vfat FAT32"
#shellcheck disable=SC2086
DIALOG --menu "Select a filesystem for ${PART}" 21 50 13 ${FSOPTS} 2>${ANSWER} || return 1
FSTYPE=$(cat ${ANSWER})
}
enter_mountpoint() {
FILESYSTEM_FINISH=""
MP=""
while [[ "${MP}" = "" ]]; do
DIALOG --inputbox "Enter the mountpoint for ${PART}" 8 65 "/boot" 2>${ANSWER} || return 1
MP=$(cat ${ANSWER})
if grep ":${MP}:" /tmp/.parts; then
DIALOG --msgbox "ERROR: You have defined 2 identical mountpoints! Please select another mountpoint." 8 65
MP=""
fi
done
}
# set sane values for paramaters, if not already set
check_mkfs_values() {
# Set values, to not confuse mkfs call!
[[ "${FS_OPTIONS}" = "" ]] && FS_OPTIONS="NONE"
[[ "${BTRFS_DEVICES}" = "" ]] && BTRFS_DEVICES="NONE"
[[ "${BTRFS_LEVEL}" = "" ]] && BTRFS_LEVEL="NONE"
[[ "${BTRFS_SUBVOLUME}" = "" ]] && BTRFS_SUBVOLUME="NONE"
[[ "${DOSUBVOLUME}" = "" ]] && DOSUBVOLUME="no"
[[ "${LABEL_NAME}" = "" && -n "$(${_LSBLK} LABEL "${PART}")" ]] && LABEL_NAME="$(${_LSBLK} LABEL "${PART}")"
[[ "${LABEL_NAME}" = "" ]] && LABEL_NAME="NONE"
}
create_filesystem() {
FILESYSTEM_FINISH=""
LABEL_NAME=""
FS_OPTIONS=""
BTRFS_DEVICES=""
BTRFS_LEVEL=""
DIALOG --yesno "Would you like to create a filesystem on ${PART}?\n\n(This will overwrite existing data!)" 0 0 && DOMKFS="yes"
if [[ "${DOMKFS}" = "yes" ]]; then
while [[ "${LABEL_NAME}" = "" ]]; do
DIALOG --inputbox "Enter the LABEL name for the device, keep it short\n(not more than 12 characters) and use no spaces or special\ncharacters." 10 65 \
"$(${_LSBLK} LABEL "${PART}")" 2>${ANSWER} || return 1
LABEL_NAME=$(cat ${ANSWER})
if grep ":${LABEL_NAME}$" /tmp/.parts; then
DIALOG --msgbox "ERROR: You have defined 2 identical LABEL names! Please enter another name." 8 65
LABEL_NAME=""
fi
done
if [[ "${FSTYPE}" = "btrfs" ]]; then
prepare_btrfs || return 1
btrfs_compress
fi
DIALOG --inputbox "Enter additional options to the filesystem creation utility.\nUse this field only, if the defaults are not matching your needs,\nelse just leave it empty." 10 70 2>${ANSWER} || return 1
FS_OPTIONS=$(cat ${ANSWER})
fi
FILESYSTEM_FINISH="yes"
}
mountpoints() {
NAME_SCHEME_PARAMETER_RUN=""
while [[ "${PARTFINISH}" != "DONE" ]]; do
activate_special_devices
: >/tmp/.device-names
: >/tmp/.fstab
: >/tmp/.parts
#
# Select mountpoints
#
DIALOG --cr-wrap --msgbox "Available partitions:\n\n$(_getavailpartitions)\n" 0 0
PARTS=$(findpartitions _)
DO_SWAP=""
while [[ "${DO_SWAP}" != "DONE" ]]; do
FSTYPE="swap"
#shellcheck disable=SC2086
DIALOG --menu "Select the partition to use as swap" 21 50 13 NONE - ${PARTS} 2>${ANSWER} || return 1
PART=$(cat ${ANSWER})
if [[ "${PART}" != "NONE" ]]; then
clear_fs_values
if [[ "${ASK_MOUNTPOINTS}" = "1" ]]; then
create_filesystem
else
FILESYSTEM_FINISH="yes"
fi
else
FILESYSTEM_FINISH="yes"
fi
[[ "${FILESYSTEM_FINISH}" = "yes" ]] && DO_SWAP=DONE
done
check_mkfs_values
if [[ "${PART}" != "NONE" ]]; then
PARTS="${PARTS//${PART}\ _/}"
echo "${PART}:swap:swap:${DOMKFS}:${LABEL_NAME}:${FS_OPTIONS}:${BTRFS_DEVICES}:${BTRFS_LEVEL}:${BTRFS_SUBVOLUME}:${DOSUBVOLUME}:${BTRFS_COMPRESS}" >>/tmp/.parts
fi
DO_ROOT=""
while [[ "${DO_ROOT}" != "DONE" ]]; do
#shellcheck disable=SC2086
DIALOG --menu "Select the partition to mount as /" 21 50 13 ${PARTS} 2>${ANSWER} || return 1
PART=$(cat ${ANSWER})
PART_ROOT=${PART}
# Select root filesystem type
FSTYPE="$(${_LSBLK} FSTYPE "${PART}")"
# clear values first!
clear_fs_values
check_btrfs_filesystem_creation
if [[ "${ASK_MOUNTPOINTS}" = "1" && "${SKIP_FILESYSTEM}" = "no" ]]; then
select_filesystem && create_filesystem && btrfs_subvolume
else
btrfs_subvolume
fi
[[ "${FILESYSTEM_FINISH}" = "yes" ]] && DO_ROOT=DONE
done
find_btrfs_raid_devices
btrfs_parts
check_mkfs_values
echo "${PART}:${FSTYPE}:/:${DOMKFS}:${LABEL_NAME}:${FS_OPTIONS}:${BTRFS_DEVICES}:${BTRFS_LEVEL}:${BTRFS_SUBVOLUME}:${DOSUBVOLUME}:${BTRFS_COMPRESS}" >>/tmp/.parts
! [[ "${FSTYPE}" = "btrfs" ]] && PARTS="${PARTS//${PART}\ _/}"
#
# Additional partitions
#
while [[ "${PART}" != "DONE" ]]; do
DO_ADDITIONAL=""
while [[ "${DO_ADDITIONAL}" != "DONE" ]]; do
#shellcheck disable=SC2086
DIALOG --menu "Select any additional partitions to mount under your new root (select DONE when finished)" 21 52 13 ${PARTS} DONE _ 2>${ANSWER} || return 1
PART=$(cat ${ANSWER})
if [[ "${PART}" != "DONE" ]]; then
FSTYPE="$(${_LSBLK} FSTYPE "${PART}")"
# clear values first!
clear_fs_values
check_btrfs_filesystem_creation
# Select a filesystem type
if [[ "${ASK_MOUNTPOINTS}" = "1" && "${SKIP_FILESYSTEM}" = "no" ]]; then
enter_mountpoint && select_filesystem && create_filesystem && btrfs_subvolume
else
enter_mountpoint
btrfs_subvolume
fi
else
FILESYSTEM_FINISH="yes"
fi
[[ "${FILESYSTEM_FINISH}" = "yes" ]] && DO_ADDITIONAL="DONE"
done
if [[ "${PART}" != "DONE" ]]; then
find_btrfs_raid_devices
btrfs_parts
check_mkfs_values
echo "${PART}:${FSTYPE}:${MP}:${DOMKFS}:${LABEL_NAME}:${FS_OPTIONS}:${BTRFS_DEVICES}:${BTRFS_LEVEL}:${BTRFS_SUBVOLUME}:${DOSUBVOLUME}:${BTRFS_COMPRESS}" >>/tmp/.parts
! [[ "${FSTYPE}" = "btrfs" ]] && PARTS="${PARTS//${PART}\ _/}"
fi
done
#shellcheck disable=SC2028
DIALOG --yesno "Would you like to create and mount the filesytems like this?\n\nSyntax\n------\nDEVICE:TYPE:MOUNTPOINT:FORMAT:LABEL:FSOPTIONS:BTRFS_DETAILS\n\n$(while read -r i;do echo "${i}\n" | sed -e 's, ,#,g';done </tmp/.parts)" 0 0 && PARTFINISH="DONE"
done
# disable swap and all mounted partitions
_umountall
if [[ "${NAME_SCHEME_PARAMETER_RUN}" = "" ]]; then
set_device_name_scheme || return 1
fi
printk off
while read -r line; do
PART=$(echo "${line}" | cut -d: -f 1)
FSTYPE=$(echo "${line}" | cut -d: -f 2)
MP=$(echo "${line}" | cut -d: -f 3)
DOMKFS=$(echo "${line}" | cut -d: -f 4)
LABEL_NAME=$(echo "${line}" | cut -d: -f 5)
FS_OPTIONS=$(echo "${line}" | cut -d: -f 6)
BTRFS_DEVICES=$(echo "${line}" | cut -d: -f 7)
BTRFS_LEVEL=$(echo "${line}" | cut -d: -f 8)
BTRFS_SUBVOLUME=$(echo "${line}" | cut -d: -f 9)
DOSUBVOLUME=$(echo "${line}" | cut -d: -f 10)
BTRFS_COMPRESS=$(echo "${line}" | cut -d: -f 11)
if [[ "${DOMKFS}" = "yes" ]]; then
if [[ "${FSTYPE}" = "swap" ]]; then
DIALOG --infobox "Creating and activating swapspace on ${PART}" 0 0
else
DIALOG --infobox "Creating ${FSTYPE} on ${PART},\nmounting to ${DESTDIR}${MP}" 0 0
fi
_mkfs yes "${PART}" "${FSTYPE}" "${DESTDIR}" "${MP}" "${LABEL_NAME}" "${FS_OPTIONS}" "${BTRFS_DEVICES}" "${BTRFS_LEVEL}" "${BTRFS_SUBVOLUME}" "${DOSUBVOLUME}" "${BTRFS_COMPRESS}" || return 1
else
if [[ "${FSTYPE}" = "swap" ]]; then
DIALOG --infobox "Activating swapspace on ${PART}" 0 0
else
DIALOG --infobox "Mounting ${FSTYPE} on ${PART} to ${DESTDIR}${MP}" 0 0
fi
_mkfs no "${PART}" "${FSTYPE}" "${DESTDIR}" "${MP}" "${LABEL_NAME}" "${FS_OPTIONS}" "${BTRFS_DEVICES}" "${BTRFS_LEVEL}" "${BTRFS_SUBVOLUME}" "${DOSUBVOLUME}" "${BTRFS_COMPRESS}" || return 1
fi
sleep 1
done < /tmp/.parts
printk on
DIALOG --msgbox "Partitions were successfully mounted." 0 0
NEXTITEM="5"
S_MKFS=1
}
# _mkfs()
# Create and mount filesystems in our destination system directory.
#
# args:
# domk: Whether to make the filesystem or use what is already there
# device: Device filesystem is on
# fstype: type of filesystem located at the device (or what to create)
# dest: Mounting location for the destination system
# mountpoint: Mount point inside the destination system, e.g. '/boot'
# returns: 1 on failure
_mkfs() {
local _domk=${1}
local _device=${2}
local _fstype=${3}
local _dest=${4}
local _mountpoint=${5}
local _labelname=${6}
local _fsoptions=${7}
local _btrfsdevices="${8//#/\ }"
local _btrfslevel=${9}
local _btrfssubvolume=${10}
local _dosubvolume=${11}
local _btrfscompress=${12}
# correct empty entries
[[ "${_fsoptions}" = "NONE" ]] && _fsoptions=""
[[ "${_btrfscompress}" = "NONE" ]] && _btrfscompress=""
[[ "${_btrfssubvolume}" = "NONE" ]] && _btrfssubvolume=""
# add btrfs raid level, if needed
[[ ! "${_btrfslevel}" = "NONE" && "${_fstype}" = "btrfs" ]] && _fsoptions="${_fsoptions} -m ${_btrfslevel} -d ${_btrfslevel}"
# add btrfs options, minimum requirement linux 3.14 -O no-holes
[[ "${_fstype}" = "btrfs" ]] && _fsoptions="${_fsoptions} -O no-holes"
# we have two main cases: "swap" and everything else.
if [[ "${_fstype}" = "swap" ]]; then
swapoff "${_device}" >/dev/null 2>&1
if [[ "${_domk}" = "yes" ]]; then
mkswap -L "${_labelname}" "${_device}" >${LOG} 2>&1
#shellcheck disable=SC2181
if [[ $? != 0 ]]; then
DIALOG --msgbox "Error creating swap: mkswap ${_device}" 0 0
return 1
fi
fi
swapon "${_device}" >${LOG} 2>&1
#shellcheck disable=SC2181
if [[ $? != 0 ]]; then
DIALOG --msgbox "Error activating swap: swapon ${_device}" 0 0
return 1
fi
else
# make sure the fstype is one we can handle
local knownfs=0
for fs in xfs jfs ext2 ext3 ext4 f2fs btrfs nilfs2 ntfs3 vfat; do
[[ "${_fstype}" = "${fs}" ]] && knownfs=1 && break
done
if [[ ${knownfs} -eq 0 ]]; then
DIALOG --msgbox "unknown fstype ${_fstype} for ${_device}" 0 0
return 1
fi
# if we were tasked to create the filesystem, do so
if [[ "${_domk}" = "yes" ]]; then
local ret
#shellcheck disable=SC2086
case ${_fstype} in
xfs) mkfs.xfs ${_fsoptions} -L "${_labelname}" -f ${_device} >${LOG} 2>&1; ret=$? ;;
jfs) yes | mkfs.jfs ${_fsoptions} -L "${_labelname}" ${_device} >${LOG} 2>&1; ret=$? ;;
ext2) mkfs.ext2 -F -L ${_fsoptions} "${_labelname}" ${_device} >${LOG} 2>&1; ret=$? ;;
ext3) mke2fs -F ${_fsoptions} -L "${_labelname}" -t ext3 ${_device} >${LOG} 2>&1; ret=$? ;;
ext4) mke2fs -F ${_fsoptions} -L "${_labelname}" -t ext4 ${_device} >${LOG} 2>&1; ret=$? ;;
f2fs) mkfs.f2fs ${_fsoptions} -l "${_labelname}" ${_device} >${LOG} 2>&1; ret=$? ;;
btrfs) mkfs.btrfs -f ${_fsoptions} -L "${_labelname}" ${_btrfsdevices} >${LOG} 2>&1; ret=$? ;;
nilfs2) mkfs.nilfs2 -f ${_fsoptions} -L "${_labelname}" ${_device} >${LOG} 2>&1; ret=$? ;;
vfat) mkfs.vfat -F32 ${_fsoptions} -n "${_labelname}" ${_device} >${LOG} 2>&1; ret=$? ;;
# don't handle anything else here, we will error later
esac
if [[ ${ret} != 0 ]]; then
DIALOG --msgbox "Error creating filesystem ${_fstype} on ${_device}" 0 0
return 1
fi
sleep 2
fi
if [[ "${_fstype}" = "btrfs" && -n "${_btrfssubvolume}" && "${_dosubvolume}" = "yes" ]]; then
create_btrfs_subvolume
fi
btrfs_scan
sleep 2
# create our mount directory
mkdir -p "${_dest}""${_mountpoint}"
# add ssd optimization before mounting
ssd_optimization
_mountoptions=""
# prepare btrfs mount options
[[ -n "${_btrfssubvolume}" ]] && _mountoptions="${_mountoptions} subvol=${_btrfssubvolume}"
[[ -n "${_btrfscompress}" ]] && _mountoptions="${_mountoptions} ${_btrfscompress}"
_mountoptions="${_mountoptions} ${ssd_mount_options}"
# eleminate spaces at beginning and end, replace other spaces with ,
_mountoptions="$(echo "${_mountoptions}" | sed -e 's#^ *##g' -e 's# *$##g' | sed -e 's# #,#g')"
# mount the bad boy
mount -t "${_fstype}" -o "${_mountoptions}" "${_device}" "${_dest}""${_mountpoint}" >${LOG} 2>&1
#shellcheck disable=SC2181
if [[ $? != 0 ]]; then
DIALOG --msgbox "Error mounting ${_dest}${_mountpoint}" 0 0
return 1
fi
# btrfs needs balancing on fresh created raid, else weird things could happen
[[ "${_fstype}" = "btrfs" && "${_domk}" = "yes" ]] && btrfs balance start --full-balance "${_dest}""${_mountpoint}" >${LOG} 2>&1
# change permission of base directories to correct permission
# to avoid btrfs issues
if [[ "${_mountpoint}" = "/tmp" ]]; then
chmod 1777 "${_dest}""${_mountpoint}"
elif [[ "${_mountpoint}" = "/root" ]]; then
chmod 750 "${_dest}""${_mountpoint}"
else
chmod 755 "${_dest}""${_mountpoint}"
fi
fi
# add to .device-names for config files
#shellcheck disable=SC2155
local _fsuuid="$(getfsuuid "${_device}")"
#shellcheck disable=SC2155
local _fslabel="$(getfslabel "${_device}")"
if [[ "${GUID_DETECTED}" == "1" ]]; then
#shellcheck disable=SC2155
local _partuuid="$(getpartuuid "${_device}")"
#shellcheck disable=SC2155
local _partlabel="$(getpartlabel "${_device}")"
echo "# DEVICE DETAILS: ${_device} PARTUUID=${_partuuid} PARTLABEL=${_partlabel} UUID=${_fsuuid} LABEL=${_fslabel}" >> /tmp/.device-names
else
echo "# DEVICE DETAILS: ${_device} UUID=${_fsuuid} LABEL=${_fslabel}" >> /tmp/.device-names
fi
# add to temp fstab
if [[ "${NAME_SCHEME_PARAMETER}" == "FSUUID" ]]; then
if [[ -n "${_fsuuid}" ]]; then
_device="UUID=${_fsuuid}"
fi
elif [[ "${NAME_SCHEME_PARAMETER}" == "FSLABEL" ]]; then
if [[ -n "${_fslabel}" ]]; then
_device="LABEL=${_fslabel}"
fi
else
if [[ "${GUID_DETECTED}" == "1" ]]; then
if [[ "${NAME_SCHEME_PARAMETER}" == "PARTUUID" ]]; then
if [[ -n "${_partuuid}" ]]; then
_device="PARTUUID=${_partuuid}"
fi
elif [[ "${NAME_SCHEME_PARAMETER}" == "PARTLABEL" ]]; then
if [[ -n "${_partlabel}" ]]; then
_device="PARTLABEL=${_partlabel}"
fi
fi
fi
fi
# / root is not needed in fstab, it's mounted automatically
# systemd supports detection on GPT disks:
# /boot as ESP: c12a7328-f81f-11d2-ba4b-00a0c93ec93b
# swap: 0657fd6d-a4ab-43c4-84e5-0933c84b4f4f
# /home: 933ac7e1-2eb4-4f13-b844-0e14e2aef915
# Complex devices, like mdadm, encrypt or lvm are not supported
# _GUID_VALUE:
# get real device name from lsblk first to get GUID_VALUE from blkid
_GUID_VALUE="$(${_BLKID} -p -i -s PART_ENTRY_TYPE -o value "$(${_LSBLK} NAME,UUID,LABEL,PARTLABEL,PARTUUID | grep "$(echo "${_device}" | cut -d"=" -f2)" | cut -d" " -f 1)")"
if ! [[ "${_GUID_VALUE}" == "933ac7e1-2eb4-4f13-b844-0e14e2aef915" && "${_mountpoint}" == "/home" || "${_GUID_VALUE}" == "0657fd6d-a4ab-43c4-84e5-0933c84b4f4f" && "${_mountpoint}" == "swap" || "${_GUID_VALUE}" == "c12a7328-f81f-11d2-ba4b-00a0c93ec93b" && "${_mountpoint}" == "/boot" && "${_DETECTED_UEFI_BOOT}" == "1" || "${_mountpoint}" == "/" ]]; then
if [[ "${_mountoptions}" == "" ]]; then
echo -n "${_device} ${_mountpoint} ${_fstype} defaults 0 " >>/tmp/.fstab
else
echo -n "${_device} ${_mountpoint} ${_fstype} defaults,${_mountoptions} 0 " >>/tmp/.fstab
fi
if [[ "${_fstype}" = "swap" || "${_fstype}" = "btrfs" ]]; then
echo "0" >>/tmp/.fstab
else
echo "1" >>/tmp/.fstab
fi
fi
unset _mountoptions
unset _btrfssubvolume
unset _btrfscompress
}

View file

@ -0,0 +1,150 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# list all net devices with mac adress
net_interfaces() {
find /sys/class/net/* -type l -printf '%f ' -exec cat {}/address \;
}
# check for already active profile
check_nework() {
for i in /etc/netctl/*; do
[[ -f "${i}" ]] && netctl is-active "$(basename "${i}")" && S_NET=1
done
[[ "${S_NET}" == "1" ]] || donetwork
}
# donetwork()
# Hand-hold through setting up networking
#
# args: none
# returns: 1 on failure
donetwork() {
NETPARAMETERS=""
while [[ "${NETPARAMETERS}" = "" ]]; do
# select network interface
INTERFACE=
ifaces=$(net_interfaces)
while [[ "${INTERFACE}" = "" ]]; do
#shellcheck disable=SC2086
DIALOG --ok-label "Select" --menu "Select a network interface" 14 55 7 ${ifaces} 2>${ANSWER}
case $? in
1) return 1 ;;
0) INTERFACE=$(cat ${ANSWER}) ;;
esac
done
# wireless switch
CONNECTION=""
WLAN_HIDDEN=""
WLAN_ESSID=""
WLAN_SECURITY=""
WLAN_KEY=""
DIALOG --defaultno --yesno "Is your network device wireless?" 5 40
#shellcheck disable=SC2181
if [[ $? -eq 0 ]]; then
CONNECTION="wireless"
DIALOG --inputbox "Enter your ESSID" 7 40 "MyNetwork" 2>${ANSWER} || return 1
WLAN_ESSID=$(cat ${ANSWER})
DIALOG --defaultno --yesno "Is your wireless network hidden?" 5 40
#shellcheck disable=SC2181
[[ $? -eq 0 ]] && WLAN_HIDDEN="yes"
DIALOG --yesno "Is your wireless network encrypted?" 5 40
#shellcheck disable=SC2181
if [[ $? -eq 0 ]]; then
while [[ "${WLAN_SECURITY}" = "" ]]; do
DIALOG --ok-label "Select" --menu "Select encryption type" 9 40 7 \
"wep" "WEP encryption" \
"wpa" "WPA encryption" 2>${ANSWER}
case $? in
1) return 1 ;;
0) WLAN_SECURITY=$(cat ${ANSWER}) ;;
esac
done
DIALOG --inputbox "Enter your KEY" 5 40 "WirelessKey" 2>${ANSWER} || return 1
WLAN_KEY=$(cat ${ANSWER})
else
WLAN_SECURITY="none"
fi
else
CONNECTION="ethernet"
fi
# dhcp switch
IP=""
DHCLIENT=""
DIALOG --yesno "Do you want to use DHCP?" 5 40
#shellcheck disable=SC2181
if [[ $? -eq 0 ]]; then
IP="dhcp"
DIALOG --defaultno --yesno "Do you want to use dhclient instead of dhcpcd?" 5 55
#shellcheck disable=SC2181
[[ $? -eq 0 ]] && DHCLIENT="yes"
else
IP="static"
DIALOG --inputbox "Enter your IP address and netmask" 7 40 "192.168.1.23/24" 2>${ANSWER} || return 1
IPADDR=$(cat ${ANSWER})
DIALOG --inputbox "Enter your gateway" 7 40 "192.168.1.1" 2>${ANSWER} || return 1
GW=$(cat ${ANSWER})
DIALOG --inputbox "Enter your DNS server IP" 7 40 "192.168.1.1" 2>${ANSWER} || return 1
DNS=$(cat ${ANSWER})
fi
DIALOG --yesno "Are these settings correct?\n\nInterface: ${INTERFACE}\nConnection: ${CONNECTION}\nESSID: ${WLAN_ESSID}\nHidden: ${WLAN_HIDDEN}\nEncryption: ${WLAN_SECURITY}\nKey: ${WLAN_KEY}\ndhcp or static: ${IP}\nUse dhclient: ${DHCLIENT}\nIP address: ${IPADDR}\nGateway: ${GW}\nDNS server: ${DNS}" 0 0
case $? in
1) ;;
0) NETPARAMETERS="1" ;;
esac
done
# profile name
NETWORK_PROFILE=""
DIALOG --inputbox "Enter your network profile name" 7 40 "${INTERFACE}-${CONNECTION}" 2>${ANSWER} || return 1
NETWORK_PROFILE=/etc/netctl/$(cat ${ANSWER})
# write profile
echo "Connection=${CONNECTION}" >"${NETWORK_PROFILE}"
echo "Description='$NETWORK_PROFILE generated by archboot setup'" >>"${NETWORK_PROFILE}"
echo "Interface=${INTERFACE}" >>"${NETWORK_PROFILE}"
if [[ "${CONNECTION}" = "wireless" ]]; then
#shellcheck disable=SC2129
echo "Security=${WLAN_SECURITY}" >>"${NETWORK_PROFILE}"
echo "ESSID='${WLAN_ESSID}'" >>"${NETWORK_PROFILE}"
echo "Key='${WLAN_KEY}'" >>"${NETWORK_PROFILE}"
[[ "${WLAN_HIDDEN}" = "yes" ]] && echo "Hidden=yes" >>"${NETWORK_PROFILE}"
fi
echo "IP=${IP}" >>"${NETWORK_PROFILE}"
if [[ "${IP}" = "dhcp" ]]; then
[[ "${DHCLIENT}" = "yes" ]] && echo "DHCPClient=dhclient" >>"${NETWORK_PROFILE}"
else
#shellcheck disable=SC2129
echo "Address='${IPADDR}'" >>"${NETWORK_PROFILE}"
echo "Gateway='${GW}'" >>"${NETWORK_PROFILE}"
echo "DNS=('${DNS}')" >>"${NETWORK_PROFILE}"
fi
# bring down interface first
systemctl stop dhcpcd@"${INTERFACE}".service
ip link set dev "${INTERFACE}" down
# run netctl
netctl restart "$(basename "${NETWORK_PROFILE}")" >${LOG}
#shellcheck disable=SC2181
if [[ $? -gt 0 ]]; then
DIALOG --msgbox "Error occured while running netctl. (see 'journalctl -xn' for output)" 0 0
return 1
fi
# http/ftp proxy settings
DIALOG --inputbox "Enter your HTTP proxy server, for example:\nhttp://name:port\nhttp://ip:port\nhttp://username:password@ip:port\n\n Leave the field empty if no proxy is needed to install." 13 65 "" 2>${ANSWER} || return 1
PROXY_HTTP=$(cat ${ANSWER})
DIALOG --inputbox "Enter your FTP proxy server, for example:\nhttp://name:port\nhttp://ip:port\nhttp://username:password@ip:port\n\n Leave the field empty if no proxy is needed to install." 13 65 "" 2>${ANSWER} || return 1
PROXY_FTP=$(cat ${ANSWER})
if [[ "${PROXY_HTTP}" = "" ]]; then
unset http_proxy
else
export http_proxy=${PROXY_HTTP}
fi
if [[ "${PROXY_FTP}" = "" ]]; then
unset ftp_proxy
else
export ftp_proxy=${PROXY_FTP}
fi
# add sleep here dhcp can need some time to get link
DIALOG --infobox "Please wait 5 seconds for network link to come up ..." 0 0
sleep 5
NEXTITEM="2"
S_NET=1
}

View file

@ -0,0 +1,185 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
getsource() {
S_SRC=0
PACMAN_CONF=""
if [[ -e "${LOCAL_DB}" ]]; then
NEXTITEM="4"
local_pacman_conf
DIALOG --msgbox "Setup is running in <Local mode>.\nOnly Local package database is used for package installation.\n\nIf you want to switch to <Online mode>, you have to delete /var/cache/pacman/pkg/archboot.db and rerun this step." 10 70
S_SRC=1
else
select_mirror || return 1
S_SRC=1
fi
}
# select_mirror()
# Prompt user for preferred mirror and set ${SYNC_URL}
#
# args: none
# returns: nothing
select_mirror() {
NEXTITEM="4"
## Download updated mirrorlist, if possible (only on x86_64)
if [[ "${RUNNING_ARCH}" == "x86_64" ]]; then
dialog --infobox "Downloading latest mirrorlist ..." 0 0
${DLPROG} -q "https://www.archlinux.org/mirrorlist/?country=all&protocol=http&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on" -O /tmp/pacman_mirrorlist.txt -o ${LOG} 2>/dev/null
if grep -q '#Server = http:' /tmp/pacman_mirrorlist.txt; then
mv "${MIRRORLIST}" "${MIRRORLIST}.bak"
cp /tmp/pacman_mirrorlist.txt "${MIRRORLIST}"
fi
fi
# FIXME: this regex doesn't honor commenting
MIRRORS=$(grep -E -o '((http)|(https))://[^/]*' "${MIRRORLIST}" | sed 's|$| _|g')
#shellcheck disable=SC2086
DIALOG --menu "Select a mirror" 14 55 7 \
${MIRRORS} \
"Custom" "_" 2>${ANSWER} || return 1
#shellcheck disable=SC2155
local _server=$(cat ${ANSWER})
if [[ "${_server}" = "Custom" ]]; then
DIALOG --inputbox "Enter the full URL to repositories." 8 65 \
"" 2>${ANSWER} || return 1
SYNC_URL=$(cat ${ANSWER})
else
# Form the full URL for our mirror by grepping for the server name in
# our mirrorlist and pulling the full URL out. Substitute 'core' in
# for the repository name, and ensure that if it was listed twice we
# only return one line for the mirror.
SYNC_URL=$(grep -E -o "${_server}.*" "${MIRRORLIST}" | head -n1)
fi
echo "Using mirror: ${SYNC_URL}" >${LOG}
#shellcheck disable=SC2027,SC2086
echo "Server = "${SYNC_URL}"" >> /etc/pacman.d/mirrorlist
if [[ "${DOTESTING}" == "yes" ]]; then
#shellcheck disable=SC2129
echo "[testing]" >> /etc/pacman.conf
echo "Include = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
echo "[community-testing]" >> /etc/pacman.conf
echo "Include = /etc/pacman.d/mirrorlist" >> /etc/pacman.conf
fi
}
# dotesting()
# enable testing repository on network install
dotesting() {
DOTESTING=""
DIALOG --defaultno --yesno "Do you want to enable [testing] repository?\n\nOnly enable this if you need latest available packages for testing purposes!" 8 60 && DOTESTING="yes"
}
# check for updating complete environment with packages
update_environment() {
if [[ -d "/var/cache/pacman/pkg" ]] && [[ -n "$(ls -A "/var/cache/pacman/pkg")" ]]; then
echo "Packages are already in pacman cache... > ${LOG}"
else
detect_uefi_boot
UPDATE_ENVIRONMENT=""
if [[ -e "/usr/bin/update-installer.sh" && "${_DETECTED_UEFI_SECURE_BOOT}" == "0" && "${RUNNING_ARCH}" == "x86_64" ]]; then
DIALOG --defaultno --yesno "Do you want to update the archboot environment to latest packages with caching packages for installation?\n\nATTENTION:\nRequires at least 2.9 GB RAM and will reboot the system using kexec!" 0 0 && UPDATE_ENVIRONMENT="1"
if [[ "${UPDATE_ENVIRONMENT}" == "1" ]]; then
DIALOG --infobox "Now setting up new archboot environment and dowloading latest packages.\n\nRunning at the moment: update-installer.sh -latest-install\nCheck ${LOG} for progress...\n\nGet a cup of coffee ...\nThis needs approx. 5 minutes on a fast internet connection (100Mbit)." 0 0
/usr/bin/update-installer.sh -latest-install > "${LOG}" 2>&1
fi
fi
fi
}
# configures pacman and syncs db on destination system
# params: none
# returns: 1 on error
prepare_pacman() {
# Set up the necessary directories for pacman use
[[ ! -d "${DESTDIR}/var/cache/pacman/pkg" ]] && mkdir -p "${DESTDIR}/var/cache/pacman/pkg"
[[ ! -d "${DESTDIR}/var/lib/pacman" ]] && mkdir -p "${DESTDIR}/var/lib/pacman"
DIALOG --infobox "Refreshing package database..." 6 45
${PACMAN} -Sy >${LOG} 2>&1 || (DIALOG --msgbox "Pacman preparation failed! Check ${LOG} for errors." 6 60; return 1)
return 0
}
# Set PACKAGES parameter before running to install wanted packages
run_pacman(){
# create chroot environment on target system
# code straight from mkarchroot
chroot_mount
# execute pacman in a subshell so we can follow its progress
# pacman output goes /tmp/pacman.log
# /tmp/setup-pacman-running acts as a lockfile
( \
echo "Installing Packages..." >/tmp/pacman.log ; \
echo >>/tmp/pacman.log ; \
touch /tmp/setup-pacman-running ; \
#shellcheck disable=SC2086,SC2069
${PACMAN} -S ${PACKAGES} 2>&1 >> /tmp/pacman.log ; \
echo $? > /tmp/.pacman-retcode ; \
if [[ $(cat /tmp/.pacman-retcode) -ne 0 ]]; then
echo -e "\nPackage Installation FAILED." >>/tmp/pacman.log
else
echo -e "\nPackage Installation Complete." >>/tmp/pacman.log
fi
rm /tmp/setup-pacman-running
) &
# display pacman output while it's running
sleep 2
dialog --backtitle "${TITLE}" --title " Installing... Please Wait " \
--no-kill --tailboxbg "/tmp/pacman.log" 18 70 2>${ANSWER}
while [[ -f /tmp/setup-pacman-running ]]; do
/usr/bin/true
done
#shellcheck disable=SC2046
kill $(cat ${ANSWER})
# pacman finished, display scrollable output
local _result=''
if [[ $(cat /tmp/.pacman-retcode) -ne 0 ]]; then
_result="Installation Failed (see errors below)"
else
_result="Installation Complete"
fi
rm /tmp/.pacman-retcode
DIALOG --title "${_result}" --exit-label "Continue" \
--textbox "/tmp/pacman.log" 18 70 || return 1
# ensure the disk is synced
sync
chroot_umount
}
# install_packages()
# performs package installation to the target system
#
install_packages() {
destdir_mounts || return 1
if [[ "${S_MKFS}" != "1" && "${S_MKFSAUTO}" != "1" ]]; then
getdest
fi
if [[ "${S_SRC}" = "0" ]]; then
select_source || return 1
fi
prepare_pacman
PACKAGES=""
# add packages from archboot defaults
PACKAGES=$(grep '^_PACKAGES' /etc/archboot/defaults | sed -e 's#_PACKAGES=##g' -e 's#"##g')
# fallback if _PACKAGES is empty
[[ -z "${PACKAGES}" ]] && PACKAGES="base linux linux-firmware"
DIALOG --yesno "Next step will install ${PACKAGES}, netctl and filesystem tools for a minimal system.\n\nDo you wish to continue?" 10 50 || return 1
auto_packages
DIALOG --infobox "Package installation will begin in 3 seconds. You can watch the output in the progress window. Please be patient." 0 0
sleep 3
run_pacman
NEXTITEM="6"
chroot_mount
# automagic time!
# any automatic configuration should go here
DIALOG --infobox "Writing base configuration..." 6 40
auto_fstab
auto_ssd
auto_mdadm
auto_luks
auto_pacman
auto_testing
# tear down the chroot environment
chroot_umount
}

View file

@ -0,0 +1,190 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
detect_DISC() {
if [[ "${DISC}" == "" ]] || ! echo "${DISC}" | grep -q '/dev/'; then
DISC="$(${_LSBLK} PKNAME "$(findmnt -vno SOURCE "${DESTDIR}/boot")")"
fi
if [[ "${DISC}" == "" ]]; then
DISC="$(${_LSBLK} PKNAME "$(findmnt -vno SOURCE "${DESTDIR}/")")"
fi
}
check_gpt() {
GUID_DETECTED=""
[[ "$(${_BLKID} -p -i -o value -s PTTYPE "${DISC}")" == "gpt" ]] && GUID_DETECTED="1"
if [[ "${GUID_DETECTED}" == "" ]]; then
DIALOG --yesno "Setup detected no GUID (gpt) partition table on ${DISC}.\n\nDo you want to convert the existing MBR table in ${DISC} to a GUID (gpt) partition table?" 0 0 || return 1
sgdisk --mbrtogpt "${DISC}" > ${LOG} && GUID_DETECTED="1"
# reread partitiontable for kernel
partprobe "${DISC}" > ${LOG}
if [[ "${GUID_DETECTED}" == "" ]]; then
DIALOG --defaultno --yesno "Conversion failed on ${DISC}.\nSetup detected no GUID (gpt) partition table on ${DISC}.\n\nDo you want to create a new GUID (gpt) table now on ${DISC}?\n\n${DISC} will be COMPLETELY ERASED! Are you absolutely sure?" 0 0 || return 1
# clean partition table to avoid issues!
sgdisk --zap "${DISC}" &>/dev/null
# clear all magic strings/signatures - mdadm, lvm, partition tables etc.
dd if=/dev/zero of="${DISC}" bs=512 count=2048 &>/dev/null
wipefs -a "${DISC}" &>/dev/null
# create fresh GPT
sgdisk --clear "${DISC}" &>/dev/null
GUID_DETECTED="1"
fi
fi
if [[ "${GUID_DETECTED}" == "1" ]]; then
### This check is not enabled in any function yet!
if [[ "${CHECK_UEFISYS_PART}" == "1" ]]; then
check_efisys_part
fi
if [[ "${CHECK_BIOS_BOOT_GRUB}" == "1" ]]; then
if ! sgdisk -p "${DISC}" | grep -q 'EF02'; then
DIALOG --msgbox "Setup detected no BIOS BOOT PARTITION in ${DISC}. Please create a >=1 MB BIOS Boot partition for grub BIOS GPT support." 0 0
RUN_CFDISK="1"
fi
fi
fi
if [[ "${RUN_CFDISK}" == "1" ]]; then
DIALOG --msgbox "Now you'll be put into cfdisk where you can partition your storage drive.\nYou should make a swap partition and as many data partitions as you will need." 18 70
clear && cfdisk "${DISC}"
# reread partitiontable for kernel
partprobe "${DEVICE}"
fi
}
## check and mount EFISYS partition at ${UEFISYS_MOUNTPOINT}
check_efisys_part() {
detect_DISC
if [[ "$(${_BLKID} -p -i -o value -s PTTYPE "${DISC}")" != "gpt" ]]; then
GUID_DETECTED=""
DIALOG --defaultno --yesno "Setup detected no GUID (gpt) partition table on ${DISC}.\nUEFI boot requires ${DISC} to be partitioned as GPT.\n\nDo you want to convert the existing MBR table in ${DISC} to a GUID (gpt) partition table?" 0 0 || return 1
DIALOG --msgbox "Setup will now try to non-destructively convert ${DISC} to GPT using sgdisk." 0 0
sgdisk --mbrtogpt "${DISC}" > ${LOG} && GUID_DETECTED="1"
partprobe "${DISC}" > ${LOG}
if [[ "${GUID_DETECTED}" == "" ]]; then
DIALOG --msgbox "Conversion failed on ${DISC}.\nSetup detected no GUID (gpt) partition table on ${DISC}.\n\n You need to fix your partition table first, before setup can proceed." 0 0
return 1
fi
fi
if ! sgdisk -p "${DISC}" | grep -q 'EF00'; then
# Windows 10 recommends a minimum of 260MB Efi Systen Partition
DIALOG --msgbox "Setup detected no EFI System partition in ${DISC}. You will now be put into cfdisk. Please create a >= 260 MB partition with cfdisk type EFI System .\nWhen prompted (later) to format as FAT32, say YES.\nIf you already have a >=260 MB FAT32 EFI System partition, check whether that partition has EFI System cfdisk type code." 0 0
clear && cfdisk "${DISC}"
RUN_CFDISK=""
fi
if sgdisk -p "${DISC}" | grep -q 'EF00'; then
# check on unique PARTTYPE c12a7328-f81f-11d2-ba4b-00a0c93ec93b for EFI System Partition type UUID
UEFISYS_PART="$(${_LSBLK} NAME,PARTTYPE "${DISC}" | grep 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b' | cut -d " " -f1)"
if [[ "$(${_LSBLK} FSTYPE "${UEFISYS_PART}")" != "vfat" ]]; then
## Check whether EFISYS is FAT, otherwise inform the user and offer to format the partition as FAT32.
DIALOG --defaultno --yesno "Detected EFI System partition ${UEFISYS_PART} does not appear to be FAT formatted. UEFI Specification requires EFI System partition to be FAT32 formatted. Do you want to format ${UEFISYS_PART} as FAT32?\nNote: Setup will proceed even if you select NO. Some systems like Apple Macs may work with Non-FAT EFI System partition. However the installed system is not in conformance with UEFI Spec., and MAY NOT boot properly." 0 0 && _FORMAT_UEFISYS_FAT32="1"
fi
if [[ "$(${_LSBLK} FSTYPE "${UEFISYS_PART}")" == "vfat" ]] && [[ "$(${_BLKID} -p -i -o value -s VERSION "${UEFISYS_PART}")" != "FAT32" ]]; then
## Check whether EFISYS is FAT32 (specifically), otherwise warn the user about compatibility issues with UEFI Spec.
DIALOG --defaultno --yesno "Detected EFI System partition ${UEFISYS_PART} does not appear to be FAT32 formatted. Do you want to format ${UEFISYS_PART} as FAT32?\nNote: Setup will proceed even if you select NO. Most systems will boot fine even with FAT16 or FAT12 EFI System partition, however some firmwares may refuse to boot with a non-FAT32 EFI System partition. It is recommended to use FAT32 for maximum compatibility with UEFI Spec." 0 0 && _FORMAT_UEFISYS_FAT32="1"
fi
#autodetect efisys mountpoint, on fail ask for mountpoint
UEFISYS_MOUNTPOINT="/$(basename "$(mount | grep "${UEFISYS_PART}" | cut -d " " -f 3)")"
if [[ "${UEFISYS_MOUNTPOINT}" == "/" ]]; then
DIALOG --inputbox "Enter the mountpoint of your EFI System partition (Default is /boot): " 0 0 "/boot" 2>${ANSWER} || return 1
UEFISYS_MOUNTPOINT="$(cat ${ANSWER})"
fi
umount "${DESTDIR}/${UEFISYS_MOUNTPOINT}" &> /dev/null
umount "${UEFISYS_PART}" &> /dev/null
if [[ "${_FORMAT_UEFISYS_FAT32}" == "1" ]]; then
mkfs.vfat -F32 -n "EFISYS" "${UEFISYS_PART}"
fi
mkdir -p "${DESTDIR}/${UEFISYS_MOUNTPOINT}"
if [[ "$(${_LSBLK} FSTYPE "${UEFISYS_PART}")" == "vfat" ]]; then
mount -o rw,flush -t vfat "${UEFISYS_PART}" "${DESTDIR}/${UEFISYS_MOUNTPOINT}"
else
DIALOG --msgbox "${UEFISYS_PART} is not formatted using FAT filesystem. Setup will go ahead but there might be issues using non-FAT FS for EFI System partition." 0 0
mount -o rw "${UEFISYS_PART}" "${DESTDIR}/${UEFISYS_MOUNTPOINT}"
fi
mkdir -p "${DESTDIR}/${UEFISYS_MOUNTPOINT}/EFI" || true
else
DIALOG --msgbox "Setup did not find any EFI System partition in ${DISC}. Please create >= 260 MB FAT32 partition with cfdisk type EFI System code and try again." 0 0
return 1
fi
}
partition() {
# disable swap and all mounted partitions, umount / last!
_umountall
# activate dmraid
activate_dmraid
# check on encrypted devices, else weird things can happen!
_stopluks
# check on raid devices, else weird things can happen during partitioning!
_stopmd
# check on lvm devices, else weird things can happen during partitioning!
_stoplvm
# update dmraid
! [[ "$(dmraid_devices)" = "" ]] && _dmraid_update
# switch for mbr usage
set_guid
# Select disk to partition
DISCS=$(finddisks _)
DISCS="${DISCS} OTHER _ DONE +"
DIALOG --cr-wrap --msgbox "Available Disks:\n\n$(_getavaildisks)\n" 0 0
DISC=""
while true; do
# Prompt the user with a list of known disks
#shellcheck disable=SC2086
DIALOG --menu "Select the disk you want to partition\n(select DONE when finished)" 14 55 7 ${DISCS} 2>${ANSWER} || return 1
DISC=$(cat ${ANSWER})
if [[ "${DISC}" == "OTHER" ]]; then
DIALOG --inputbox "Enter the full path to the device you wish to partition" 8 65 "/dev/sda" 2>${ANSWER} || DISC=""
DISC=$(cat ${ANSWER})
fi
# Leave our loop if the user is done partitioning
[[ "${DISC}" == "DONE" ]] && break
MSDOS_DETECTED=""
if ! [[ "${DISC}" == "" ]]; then
if [[ "${GUIDPARAMETER}" == "yes" ]]; then
CHECK_BIOS_BOOT_GRUB=""
CHECK_UEFISYS_PART=""
RUN_CFDISK="1"
check_gpt
else
[[ "$(${_BLKID} -p -i -o value -s PTTYPE "${DISC}")" == "dos" ]] && MSDOS_DETECTED="1"
if [[ "${MSDOS_DETECTED}" == "" ]]; then
DIALOG --defaultno --yesno "Setup detected no MS-DOS partition table on ${DISC}.\nDo you want to create a MS-DOS partition table now on ${DISC}?\n\n${DISC} will be COMPLETELY ERASED! Are you absolutely sure?" 0 0 || return 1
# clean partitiontable to avoid issues!
dd if=/dev/zero of="${DEVICE}" bs=512 count=2048 >/dev/null 2>&1
wipefs -a "${DEVICE}" /dev/null 2>&1
parted -a optimal -s "${DISC}" mktable msdos >${LOG}
fi
# Partition disc
DIALOG --msgbox "Now you'll be put into cfdisk where you can partition your storage drive. You should make a swap partition and as many data partitions as you will need." 18 70
clear
cfdisk "${DISC}"
# reread partitiontable for kernel
partprobe "${DISC}"
fi
fi
done
# update dmraid
_dmraid_update
NEXTITEM="4"
}

View file

@ -0,0 +1,156 @@
#!/bin/bash
# created by Tobias Powalowski <tpowa@archlinux.org>
# menu for raid, lvm and encrypt
create_special() {
NEXTITEM=""
SPECIALDONE=0
while [[ "${SPECIALDONE}" = "0" ]]; do
if [[ -n "${NEXTITEM}" ]]; then
DEFAULT="--default-item ${NEXTITEM}"
else
DEFAULT=""
fi
CANCEL=""
#shellcheck disable=SC2086
dialog ${DEFAULT} --backtitle "${TITLE}" --menu "Manage Software Raid, LVM2 and Luks encryption" 14 60 5 \
"1" "Manage Software Raid" \
"2" "Manage LVM2" \
"3" "Manage Luks encryption" \
"4" "Return to Previous Menu" 2>${ANSWER} || CANCEL="1"
NEXTITEM="$(cat ${ANSWER})"
case $(cat ${ANSWER}) in
"1")
_createmd ;;
"2")
_createlvm ;;
"3")
_createluks ;;
*)
SPECIALDONE=1 ;;
esac
done
if [[ "${CANCEL}" = "1" ]]; then
NEXTITEM="3"
else
NEXTITEM="4"
fi
}
# menu for md creation
_createmd() {
NEXTITEM=""
MDDONE=0
while [[ "${MDDONE}" = "0" ]]; do
if [[ -n "${NEXTITEM}" ]]; then
DEFAULT="--default-item ${NEXTITEM}"
else
DEFAULT=""
fi
CANCEL=""
#shellcheck disable=SC2086
dialog ${DEFAULT} --backtitle "${TITLE}" --menu "Manage Software Raid" 12 60 5 \
"1" "Raid Help" \
"2" "Reset Software Raid completely" \
"3" "Create Software Raid" \
"4" "Create Partitionable Software Raid" \
"5" "Return to Previous Menu" 2>${ANSWER} || CANCEL="1"
NEXTITEM="$(cat ${ANSWER})"
case $(cat ${ANSWER}) in
"1")
_helpraid ;;
"2")
_stopmd ;;
"3")
RAID_PARTITION=""
_raid ;;
"4")
RAID_PARTITION="1"
_raid ;;
*)
MDDONE=1 ;;
esac
done
if [[ "${CANCEL}" = "1" ]]; then
NEXTITEM="1"
else
NEXTITEM="4"
fi
}
# menu for lvm creation
_createlvm() {
NEXTITEM=""
LVMDONE=0
while [[ "${LVMDONE}" = "0" ]]; do
if [[ -n "${NEXTITEM}" ]]; then
DEFAULT="--default-item ${NEXTITEM}"
else
DEFAULT=""
fi
CANCEL=""
#shellcheck disable=SC2086
dialog ${DEFAULT} --backtitle "${TITLE}" --menu "Manage physical volume, volume group or logical volume" 13 60 7 \
"1" "LVM Help" \
"2" "Reset Logical Volume completely" \
"3" "Create Physical Volume" \
"4" "Create Volume Group" \
"5" "Create Logical Volume" \
"6" "Return to Previous Menu" 2>${ANSWER} || CANCEL="1"
NEXTITEM="$(cat ${ANSWER})"
case $(cat ${ANSWER}) in
"1")
_helplvm ;;
"2")
_stoplvm ;;
"3")
_createpv ;;
"4")
_createvg ;;
"5")
_createlv ;;
*)
LVMDONE=1 ;;
esac
done
if [[ "${CANCEL}" = "1" ]]; then
NEXTITEM="2"
else
NEXTITEM="4"
fi
}
# menu for luks creation
_createluks() {
NEXTITEM=""
LUKSDONE=0
while [[ "${LUKSDONE}" = "0" ]]; do
if [[ -n "${NEXTITEM}" ]]; then
DEFAULT="--default-item ${NEXTITEM}"
else
DEFAULT=""
fi
CANCEL=""
#shellcheck disable=SC2086
dialog ${DEFAULT} --backtitle "${TITLE}" --menu "Manage Luks Encryption" 12 60 5 \
"1" "Luks Help" \
"2" "Reset Luks Encryption completely" \
"3" "Create Luks" \
"4" "Return to Previous Menu" 2>${ANSWER} || CANCEL="1"
NEXTITEM="$(cat ${ANSWER})"
case $(cat ${ANSWER}) in
"1")
_helpluks ;;
"2")
_stopluks ;;
"3")
_luks ;;
*)
LUKSDONE=1 ;;
esac
done
if [[ "${CANCEL}" = "1" ]]; then
NEXTITEM="3"
else
NEXTITEM="4"
fi
}