Skip to content

Instantly share code, notes, and snippets.

@Hayao0819
Last active December 17, 2021 12:24
Show Gist options
  • Save Hayao0819/9521f3712e9ae25536430504031a507e to your computer and use it in GitHub Desktop.
Save Hayao0819/9521f3712e9ae25536430504031a507e to your computer and use it in GitHub Desktop.
Alter Linux Installer for Tablet
#!/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
@Hayao0819
Copy link
Author

Hayao0819 commented Dec 17, 2021

curl -sL "https://0e0.pw/KNJ4" > install.sh
bash ./install.sh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment