Last active
December 17, 2021 12:24
-
-
Save Hayao0819/9521f3712e9ae25536430504031a507e to your computer and use it in GitHub Desktop.
Alter Linux Installer for Tablet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -eu | |
nocolor=false | |
debug=false | |
install_config=() | |
installer_mountpoint="/var/alterinstall" | |
###################################################################################### | |
# _msg_common [-n] <label color> <label> <str1> <str2> ... | |
_msg_common(){ | |
#[[ "${msgdebug}" = true ]] && set -xv | |
#[[ "${msgdebug}" = false ]] && set +xv | |
local _msg_opts=("-e") _count _message | |
! [[ "${1}" = "while" ]] && _color="${1}" && shift 1 | |
[[ "${1}" = "-n" ]] && _msg_opts+=("-n") && shift 1 | |
_message="$(_colored_text -c "${_color}" "${@}")" | |
for _count in $(seq "1" "$(echo -ne "${_message}\n" | wc -l)"); do | |
echo "${_msg_opts[@]}" " $(echo -e "${_message}" | head -n "${_count}" | tail -n 1 )" | |
done | |
#[[ "${bash_debug}" = true ]] && set -xv | |
#[[ "${bash_debug}" = false ]] && set +xv | |
return 0 | |
} | |
# Show an INFO message | |
# $1: message string | |
_msg_info() { _msg_common green "${@}"; } | |
# Show a Warning message | |
# $1: message string | |
_msg_warn() { _msg_common yellow "${@}"; } | |
# Show a debug message | |
# $1: message string | |
_msg_debug() { [[ "${debug}" = true ]] && _msg_common magenta "<Debug>" "${@}"; return 0;} | |
# Show an ERROR message then exit with status | |
# $1: message string | |
_msg_error() { _msg_common red "${@}"; } | |
# Show a message without label | |
_msg(){ _msg_common white "${@}"; } | |
# 使い方 | |
# text [-b/-c color/-n/-f/-l/] | |
_colored_text() { | |
local OPTIND OPTARG arg _textcolor _decotypes="" _notranslate=false | |
while getopts "c:bnfl" arg; do | |
case "${arg}" in | |
c) | |
case "${OPTARG}" in | |
"black" ) _textcolor="30" ;; | |
"red" ) _textcolor="31" ;; | |
"green" ) _textcolor="32" ;; | |
"yellow" ) _textcolor="33" ;; | |
"blue" ) _textcolor="34" ;; | |
"magenta" ) _textcolor="35" ;; | |
"cyan" ) _textcolor="36" ;; | |
"white" ) _textcolor="37" ;; | |
* ) return 1 ;; | |
esac | |
;; | |
b) _decotypes="${_decotypes};1" ;; | |
f) _decotypes="${_decotypes};5" ;; | |
l) _decotypes="${_decotypes};4" ;; | |
n) _notranslate=true ;; | |
*) : ;; | |
esac | |
done | |
shift "$((OPTIND - 1))" | |
if [[ "${nocolor}" = true ]]; then | |
echo -ne "${@}" | |
else | |
echo -ne "\e[$([[ -v _textcolor ]] && echo -n ";${_textcolor}"; [[ -v _decotypes ]] && echo -n "${_decotypes}")m${*}\e[m" | |
fi | |
} | |
# 質問を行う関数 | |
# Returns only the selected result to standard output | |
# ask_question -n -d <デフォルト値> -p <質問文> <選択肢1> <選択肢2> ... | |
# -n: Return with number | |
ask_question(){ | |
local arg OPTARG OPTIND _default="" _choice_list _count _choice _question _mark _number=false | |
while getopts "ad:p:n" arg; do | |
case "${arg}" in | |
d) _default="${OPTARG}" ;; | |
p) _question="${OPTARG}" ;; | |
n) _number=true ;; | |
*) exit 1 ;; | |
esac | |
done | |
shift "$((OPTIND - 1))" ; _choice_list=("${@}") _digit="${##}" | |
(( ${#_choice_list[@]} < 0 )) && echo "An exception error has occurred." >&2 && exit 1 | |
(( ${#_choice_list[@]} <= 1 )) && { | |
[[ "${_number}" = true ]] && echo "1" || echo "${_choice_list[*]}" | |
} && return 0 | |
[[ -n "${_question-""}" ]] && echo " ${_question}" >&2 | |
for (( _count=1; _count<=${#_choice_list[@]}; _count++)); do | |
_choice="${_choice_list[$(( _count - 1 ))]}" _mark=" " | |
{ [[ ! "${_default}" = "" ]] && [[ "${_choice}" = "${_default}" ]]; } && _mark="*" | |
printf " ${_mark} %${_digit}d: ${_choice}\n" "${_count}" >&2 | |
done | |
echo -n " (1 ~ ${#_choice_list[@]}) > " >&2 && read -r _input | |
{ [[ -z "${_input-""}" ]] && [[ -n "${_default-""}" ]]; } && { | |
[[ "${_number}" = true ]] && echo 0 || echo "${_default}" | |
} && return 0 | |
{ printf "%s" "${_input}" | grep -qE "^[0-9]+$";} && { (( 1 <= _input)) && (( _input <= ${#_choice_list[@]} )); } && { | |
[[ "${_number}" = true ]] && echo "$(( _input ))" || echo "${_choice_list[$(( _input - 1 ))]}" | |
} && return 0 | |
for (( i=0; i <= ${#_choice_list[@]} - 1 ;i++ )); do | |
[[ "${_choice_list["${i}"],,}" = "${_input,,}" ]] && { | |
[[ "${_number}" = true ]] && echo "$(( i + 1))" || echo "${_choice_list["${i}"]}" | |
} && return 0 | |
done | |
return 1 | |
} | |
_add_config(){ | |
_msg_debug "${1}=${2}" | |
install_config+=("${1}=${2}") | |
} | |
_get_config(){ | |
printf "%s\n" "${install_config[@]}" | awk -F "=" "{if (\$1 == \"${1}\"){print \$2; exit}}" | |
} | |
###################################################################################### | |
sudo(){ | |
/bin/sudo -E "${@}" | |
} | |
_check_environment(){ | |
# Check permission | |
(( UID == 0 )) && { | |
_msg_error "Do not run this script as root" | |
_msg_error "This script gets root permission with sudo" | |
} | |
# Confirm | |
case "$(ask_question -d "No" -p "This script is dedicated to some tablet PC. Do you want to continue?" "Yes" "No")" in | |
"Yes") | |
return 0 | |
;; | |
*) | |
exit 0 | |
;; | |
esac | |
} | |
_patch_calamares(){ | |
local _mod | |
_msg_info "== Patch for calamares ==" | |
for _mod in "grubcfg" "bootloader"; do | |
_msg_info "Disable calamares ${_mod} module" | |
sudo sed -i "s| - ${_mod}|# - ${_mod}|g" "/etc/calamares/settings.conf" | |
done | |
sudo sed -i "s|quit-at-end: false|quit-at-end: true|g" "/etc/calamares/settings.conf" | |
} | |
_start_calamares(){ | |
sudo -E calamares -d | |
} | |
_select_disk(){ | |
_msg "== Configure disk to install ==" | |
local _disk_list _choices _disk _answer _selected | |
readarray -t _disk_list < <(lsblk -l -n -o TYPE,NAME | awk '{if ($1=="disk"){print "/dev/"$2}}') | |
for _disk in "${_disk_list[@]}"; do | |
_choices+=("${_disk} : $(lsblk "${_disk}" -l -n -o MODEL | grep -Evx "^$") $(lsblk "${_disk}" -l -n -o TYPE,NAME | awk '{if ($1=="part"){print "/dev/"$2}}' | wc -l) Partition") | |
done | |
_answer="$(ask_question -n -p "Please select the disk installed Alter Linux" "${_choices[@]}")" | |
_selected="${_disk_list[$(( _answer - 1 ))]}" | |
_add_config "disk" "${_selected}" | |
} | |
_select_part(){ | |
local _part_list=() _choices=() | |
_msg "== Configure partition to install ==" | |
# Get partition list | |
readarray -t _part_list < <( | |
lsblk "$(_get_config disk)" -l -n -o TYPE,NAME | awk '{if ($1=="part"){print "/dev/"$2}}' | |
) | |
# Check partition | |
(( ${#_part_list[@]} < 2)) && { | |
_msg_error "The selected disk has less than two partitions." | |
_msg_error "Requires two partitions, main and EFI" | |
exit 1 | |
} || (( ${#_part_list[@]} == 2 )) && { | |
_msg_info "Two partitions were found on the selected disk." | |
_msg_info "Since the purpose of one partition has already been decided, initialize the other partition for EFI." | |
} | |
# Create choices for ask_question | |
for _part in "${_part_list[@]}"; do | |
_choices+=("${_part} : $(lsblk -l -n -o SIZE "${_part}" | sed "s/ *//g")") | |
done | |
_choices+=("Edit disk partition") | |
# Ask | |
_answer="$(ask_question -n -p "Please select the partition to install" "${_choices[@]}")" | |
# Parse input | |
if (( "${_answer}" == "${#_choices[@]}" )); then | |
_run _edit_disk | |
return 0 | |
fi | |
_selected="${_part_list[$(( _answer - 1 ))]}" | |
_add_config "part_main" "${_selected}" | |
} | |
_select_efi_part(){ | |
local _part_list=() _choices=() | |
_msg "== Configure EFI partition to install ==" | |
# Get partition list | |
readarray -t _part_list < <( | |
lsblk "$(_get_config disk)" -l -n -o TYPE,NAME | \ | |
awk '{if ($1=="part"){print "/dev/"$2}}' | \ | |
grep -vx "$(_get_config "part_main")" | |
) | |
# Create choices for ask_question | |
for _part in "${_part_list[@]}"; do | |
_choices+=("${_part} : $(lsblk -l -n -o SIZE "${_part}" | sed "s/ *//g")") | |
done | |
# Ask | |
_answer="$(ask_question -n -p "Please select the partition to use as EFI partition" "${_choices[@]}")" | |
_selected="${_part_list[$(( _answer - 1 ))]}" | |
_add_config "part_efi" "${_selected}" | |
} | |
_install_mount(){ | |
_efi="$(_get_config "part_efi")" | |
_root="$(_get_config "part_main")" | |
_msg_info "Mount ${_root} at ${installer_mountpoint}/main" | |
mkdir -p "${installer_mountpoint}/main" | |
mount "${_root}" "${installer_mountpoint}/main" | |
_msg_info "Mount ${_efi} at ${installer_mountpoint}/main/boot" | |
mkdir -p "${installer_mountpoint}/main/boot" | |
mount "${_efi}" "${installer_mountpoint}/main/boot" | |
} | |
_run_chroot(){ | |
arch-chroot "${installer_mountpoint}/main" "${@}" | |
} | |
_install_efi(){ | |
_msg_info "Create kernel file and initramfs" | |
_run_chroot mkinitcpio -P | |
_msg_info "Reinstall kernel" | |
_run_chroot pacman -Syy | |
_run_chroot pacman -S linux-zen | |
_msg_info "Install Grub to EFI" | |
_run_chroot grub-install --target=i385-efi --efi-directory=/boot --bootloader-id=arch_grub --recheck --debug | |
_msg_info "Create Grub config" | |
_run_chroot grub-mkconfig -o "/boot/grub/grub.cfg" | |
_msg_info "Copy Grub as boot file for EFI" | |
_run_chroot cp /boot/EFI/arch_grub/grubx64.efi /boot/EFI/boot/bootx64.efi | |
} | |
_check_environment | |
_patch_calamares | |
_start_calamares | |
_select_disk | |
_select_part | |
_select_efi_part | |
_install_mount | |
_install_efi |
Author
Hayao0819
commented
Dec 17, 2021
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment