This repository has been archived on 2024-09-01. You can view files and clone it, but cannot push or open issues or pull requests.
al-installer/src/lib/utils.sh

217 lines
6.4 KiB
Bash

#!/usr/bin/bash
# vim:ft=sh:fdm=marker:fmr={,}
# archlabs installer library script file
# this file is not meant to be run directly
# sourcing this file in a non bash shell is not advised
# shellcheck disable=2154
# set -n
chrun() {
arch-chroot $MNT /bin/bash -c "$1"
}
json() {
curl -s "http://api.ipstack.com/$2" | python3 -c "import sys, json; print(json.load(sys.stdin)['$1'])"
}
src() {
. "$1" || { printf "\nFailed to source file %s\n" "$1"; die 1; }
}
ssd() {
local dev=$1
dev=${dev#/dev/}
[[ $dev =~ nvme ]] && dev=${dev%p[0-9]*} || dev=${dev%[0-9]*}
[[ $(cat /sys/block/$dev/queue/rotational) -eq 0 ]] || return 1
}
die() {
tput cnorm
if [[ -d $MNT ]] && cd; then
fuser -km $MNT
unmount_install_partitions
if ! [[ $1 =~ [0-9] ]]; then
fuser -km /run/archiso/bootmnt
umount -l /run/archiso/bootmnt
fi
fi
[[ $1 =~ [0-9] ]] && exit $1 || $1
}
sigint() {
printf "\n** CTRL-C caught"
die 1
}
msgbox() {
tput civis
dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0
}
oneshot() {
[[ -e /tmp/.ai_$1 || ! $(type $1) ]] && return 0
$1 || return 1
touch "/tmp/.ai_$1"
return 0
}
getinput() {
local answer
if ! answer="$(dialog --cr-wrap --max-input 63 --stdout --no-cancel \
--backtitle "$BT" --title " $1 " --inputbox "$2" 0 0 "$3")" || [[ $answer == '' ]]; then
return 1
fi
printf "%s" "$answer"
}
infobox() {
local sec="$3"
tput civis
dialog --cr-wrap --backtitle "$BT" --title " $1 " --infobox "$2\n" 0 0
sleep ${sec:-2}
}
printq() {
local str="$*"
if [[ ${#str} -gt $(( ${COLUMNS:-$(tput cols)} / 2 )) ]]; then
q=$(awk '{print int(NF / 4)}' <<< "$str")
str="$(awk '{
pkgs1=pkgs2=pkgs3=pkgs4=""
for (i=1;i<'"$q"';i++) {
if (i == 1) {
pkgs1=$i
} else {
pkgs1=pkgs1" "$i
}
}
for (i='"$q"';i<'"$((q * 2))"';i++) {
pkgs2=pkgs2" "$i
}
for (i='"$((q * 2))"';i<'"$((q * 3))"';i++) {
pkgs3=pkgs3" "$i
}
for (i='"$((q * 3))"';i<NF;i++) {
pkgs4=pkgs4" "$i
}
printf "%s\n %s\n %s\n %s", pkgs1, pkgs2, pkgs3, pkgs4
}' <<< "$str")"
fi
printf "%s\n" "$str"
}
devices() {
IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
if [[ $IGNORE_DEV ]]; then
SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')"
else
SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ {print "/dev/" $1 " " $2}')"
fi
DEV_COUNT="$(wc -l <<< "$SYS_DEVS")"
declare -grx SYS_DEVS IGNORE_DEV DEV_COUNT
}
sysid() {
declare -g IS_64BIT=false
local efidir="/sys/firmware/efi"
if grep -q 'GenuineIntel' /proc/cpuinfo; then
declare -gx UCODE="intel-ucode.img"
elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
declare -gx UCODE="amd-ucode.img"
fi
if grep -qi 'apple' /sys/class/dmi/id/sys_vendor; then
modprobe -r -q efivars
else
modprobe -q efivarfs
fi
if [[ -d $efidir ]]; then
SYS="UEFI"
[[ $(cat $efidir/fw_platform_size) == 64 ]] && export IS_64BIT=true
grep -q $efidir/efivars <<< "$(mount)" || mount -t efivarfs efivarfs $efidir/efivars
else
SYS="BIOS"
fi
declare -g BT="$DIST Installer - $SYS (x86_64) - Version $VER"
return 0
}
checks() {
[[ $(whoami) == "root" ]] || { infobox "$_ErrTitle" "$_NotRoot\n$_Exit" && die 1; }
grep -qw 'lm' /proc/cpuinfo || { infobox "$_ErrTitle" "$_Not64Bit\n$_Exit" && die 1; }
if ! curl -s --head 'https://www.archlinux.org/mirrorlist/all/' | head -n 1 | grep -q '200'; then
if [[ $(systemctl is-active NetworkManager) == "active" ]] && hash nmtui >/dev/null 2>&1; then
tput civis; nmtui-connect
if curl -s --head 'https://www.archlinux.org/mirrorlist/all/' | head -n 1 | grep -q '200'; then
export HAS_NETWORK=true
else
infobox "$_ErrTitle" "$_NoNetwork" 3
fi
fi
fi
return 0
}
echeck() {
# return if the last process exited normally
local last_exit_code=$?
(( last_exit_code == 0 )) && return 0
local msg="\nThe command exited abnormally: $1"
# get error message from logfile and strip any non-printable characters,
# escape sequences, and other messy text
local err
err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")"
[[ $err != "" ]] && msgbox "$_ErrTitle" "$msg\n\nWith the following error message:\n\n$err"
msg="$([[ $err == "" ]] && printf "%s" "$msg")\n$_ErrChoice"
if [[ -e /tmp/debug-log && $TERM == 'linux' ]]; then
msg="$([[ $err == "" ]] && printf "%s" "$msg")\n$_ErrChoiceConsole"
yesno "$_ErrTitle" "$msg" "Exit & Open Log" "Ignore & Continue" && { more /tmp/debug-log; die 0; }
else
yesno "$_ErrTitle" "$msg" "Exit & Shutdown" "Ignore & Continue" && die 'shutdown -h now'
fi
return 0
}
icheck() {
[[ $(lsblk -o MOUNTPOINT) =~ $MNT ]] || { msgbox "$_ErrTitle" "$_ErrNoMount"; export SELECTED=4; return 1; }
[[ $CONFIG_DONE == true ]] || { msgbox "$_ErrTitle" "$_ErrNoConfig"; export SELECTED=5; return 1; }
return 0
}
yesno() {
# usage: yesno <title> <text> [<yes_label> <no_label> [<no>]]
# three options: one --default-no and custom labels, one just custom labels, and one basic.
tput civis
if [[ $# -eq 5 && $5 == "no" ]]; then
dialog --cr-wrap --backtitle "$BT" --defaultno --title " $1 " \
--yes-label "$3" --no-label "$4" --yesno "$2\n" 0 0
elif [[ $# -eq 4 ]]; then
dialog --cr-wrap --backtitle "$BT" --title " $1 " --yes-label "$3" \
--no-label "$4" --yesno "$2\n" 0 0
else
dialog --cr-wrap --backtitle "$BT" --title " $1 " --yesno "$2\n" 0 0
fi
}
debug() {
set -x
exec 3>| /tmp/debug-log
BASH_XTRACEFD=3
if [[ $DISPLAY && $TERM != 'linux' ]]; then
if hash 'termite' >/dev/null 2>&1; then
termite -e "tail -f /tmp/debug-log" &
else
xterm -e "tail -f /tmp/debug-log" &
fi
fi
export DEBUG=true
}