Skip to content

Instantly share code, notes, and snippets.

@riskiwah
Created April 18, 2021 11:05
Show Gist options
  • Save riskiwah/7ddd0f52ed8abf02111e5d543cd9a230 to your computer and use it in GitHub Desktop.
Save riskiwah/7ddd0f52ed8abf02111e5d543cd9a230 to your computer and use it in GitHub Desktop.
#!/bin/sh
set -e
function help () {
cat <<EOF >&2
Run script via curl:
sh -c "\$(curl -s https://gitlab.com/romanilin/alis/-/raw/main/install.sh)"
or equivalently:
sh -c "\$(curl -sL https://v.gd/alisa)"
or run version from development branch:
sh -c "\$(curl -s https://gitlab.com/romanilin/alis/-/raw/dev/install.sh)"
Supported options:
-l, --lts install linux-lts package instead of linux
-p, --post run post-installation: grub, swapiness, pacman configuring, GNOME installation, etc.
-v, --vbox install VirtualBox guest utilities
-x, --xorg configure GNOME to use only Xorg and disable Wayland
-d, --drive <drive> install Arch Linux to <drive>, /dev/sda by default
-u, --update just update rc-files and other configurations
EOF
exit
}
MIRRORS_COUNTRIES=(
'indonesia'
'singapore'
)
MIRRORS_COUNTRIES=`printf ',%s' "${MIRRORS_COUNTRIES[@]}" | cut -c 2-`
FONTS_PACKAGES=(
'noto-fonts'
'noto-fonts-emoji'
'noto-fonts-cjk'
)
GNOME_PACKAGES=(
'gdm'
'gnome-terminal'
'jack2'
'gnome-control-center'
'nautilus'
'chrome-gnome-shell'
'gnome-tweaks'
'eog'
)
ADDITIONAL_PACKAGES=(
'man'
'xdg-user-dirs'
'inetutils'
'python-pip'
'pkgfile'
'firefox'
'wl-clipboard'
'xclip'
)
GNOME_EXTENSIONS=(
'19/user-themes'
'1010/archlinux-updates-indicator'
)
function setup_color_scheme () {
export BLACK='#121212'
export RED='#ff714f'
export GREEN='#00d965'
export YELLOW='#e0e000'
export BLUE='#7e9df9'
export MAGENTA='#ff5de1'
export CYAN='#90cbdb'
export WHITE='#ffffff'
export BLACK_BRIGHT='#7c7c7c'
export RED_BRIGHT=$RED
export GREEN_BRIGHT=$GREEN
export YELLOW_BRIGHT=$YELLOW
export BLUE_BRIGHT=$BLUE
export MAGENTA_BRIGHT=$MAGENTA
export CYAN_BRIGHT=$CYAN
export WHITE_BRIGHT=$WHITE
export FOREGROUND=$WHITE
export BACKGROUND=$BLACK
export BACKGROUND_HIGHLIGHT='#3298ff66'
export BACKGROUND_HIGHLIGHT_OPAQUE='#1f4871' # $BACKGROUND_HIGHLIGHT on #121212 background
export PALETTE="['$BLACK', '$RED', '$GREEN', '$YELLOW', '$BLUE', '$MAGENTA', '$CYAN', '$WHITE', '$BLACK_BRIGHT', '$RED_BRIGHT', '$GREEN_BRIGHT', '$YELLOW_BRIGHT', '$BLUE_BRIGHT', '$MAGENTA_BRIGHT', '$CYAN_BRIGHT', '$WHITE_BRIGHT']"
COLORS_LIST='$BLACK,$RED,$GREEN,$YELLOW,$BLUE,$MAGENTA,$CYAN,$WHITE,$BLACK_BRIGHT,$RED_BRIGHT,$GREEN_BRIGHT,$YELLOW_BRIGHT,$BLUE_BRIGHT,$MAGENTA_BRIGHT,$CYAN_BRIGHT,$WHITE_BRIGHT,$FOREGROUND,$BACKGROUND,$BACKGROUND_HIGHLIGHT,$BACKGROUND_HIGHLIGHT_OPAQUE,$PALETTE'
}
function invalid_option () {
cat <<-EOF >&2
ALIS: invalid option -- '$1'
Try run with '--help' option for more information.
EOF
exit 1
}
for option in "$@"; do
shift
case "$option" in
'--help') set -- "$@" '-h' ;;
'--update') set -- "$@" '-u' ;;
'--lts') set -- "$@" '-l' ;;
'--post') set -- "$@" '-p' ;;
'--vbox') set -- "$@" '-v' ;;
'--xorg') set -- "$@" '-x' ;;
'--drive') set -- "$@" '-d' ;;
*) [[ "$option" == --* ]] && invalid_option "$option"
set -- "$@" "$option"
esac
done
LTS=false
MODE='base'
VBOX=false
XORG=false
DRIVE='/dev/sda'
UPDATE_CONFIGURATION=false
OPTIND=1
while getopts ':d:hlpuvx' option; do
case "$option" in
h) help ;;
u) UPDATE_CONFIGURATION=true ;;
d) DRIVE="$OPTARG" ;;
l) LTS=true ;;
p) MODE='post' ;;
v) VBOX=true ;;
x) XORG=true ;;
?) invalid_option "$option"
esac
done
shift $((OPTIND-1))
[ "${1:-}" = '--' ] && shift
[ "$EUID" == 0 ] || SUDO=sudo
[ "$MODE" == 'post' ] || CHROOT='arch-chroot /mnt'
function setup_terminal_colors () {
# only use colors if connected to a terminal
if [ -t 1 ]; then
ES_BLACK=`tput setaf 0`
ES_RED=`tput setaf 1`
ES_GREEN=`tput setaf 2`
ES_YELLOW=`tput setaf 3`
ES_BLUE=`tput setaf 4`
ES_MAGENTA=`tput setaf 5`
ES_CYAN=`tput setaf 6`
ES_WHITE=`tput setaf 7`
ES_BOLD=`tput bold`
ES_RESET=`tput sgr0`
fi
}
function log () {
# log function
# -i <depth> Add indent in message beggining
# -s Print "Started ..." message
# -f Print "Finished ..." message
# -n Prevent line break
# -e End message with provided string, '.' by default
# -w Wrap message with provided escape sequence
local DEPTH=0
local FORMAT="$ES_BOLD"
local PADDING=''
local NEWLINE='\n'
local END='.'
local STATUS=''
local OPTIND=1
while getopts 'i:e:fnsw:' option; do
case "$option" in
i) DEPTH="$OPTARG" ;;
e) END="$OPTARG" ;;
w) FORMAT="${FORMAT}${OPTARG}" ;;
f) STATUS='Finished ' ;;
s) STATUS='Started ' ;;
n) NEWLINE='' ;;
esac
done
shift $((OPTIND-1))
[ "${1:-}" = '--' ] && shift
if [ $DEPTH -gt 0 ]; then
PADDING=$(printf "=%.0s" `seq $(($DEPTH * 2))`)
PADDING="${ES_CYAN}${PADDING}>${ES_RESET} "
fi
printf "${ES_BOLD}${ES_CYAN}[ALIS]${ES_RESET} ${PADDING}${STATUS}${FORMAT}$@${ES_RESET}${END}${NEWLINE}" >&2
}
function ask () {
# -i <depth> Add indent in message beggining
# -n Set 'no' as default answer
local indent=''
local question_ending="? [${ES_BOLD}Y${ES_RESET}|n] "
local result=1
local default_result=0
local OPTIND=1
while getopts 'i:n' option; do
case "$option" in
i) indent="-i $OPTARG" ;;
n) question_ending="? [y|${ES_BOLD}N${ES_RESET}] "
default_result=1 ;;
esac
done
while true; do
log $indent -n -e "$question_ending" "$@"
read -e answer
case $answer in
'')
echo
result=$default_result
break ;;
[Yy]*)
result=0
break ;;
[Nn]*)
break ;;
*)
log $indent 'Try again'
esac
done
return $result
}
function check_system_errors () {
log -e ':' 'System errors information'
log -i 1 -e ':' 'systemctl --failed'
PAGER= $SUDO systemctl --failed
log -i 1 -e ':' 'journalctl -p 3 -xb'
PAGER= $SUDO journalctl -p 3 -xb
if ask -i 1 'Clear these logs'; then
$SUDO systemctl reset-failed
$SUDO journalctl --vacuum-time=1s
fi
}
function revert_sudoers () {
# revert original /etc/sudoers after preventing sudo timeout
[ -f '/etc/sudoers.bak' ] && sudo mv /etc/sudoers.bak /etc/sudoers
}
function install_packages () {
command="$SUDO pacman"
$command -S --noconfirm --needed "$@"
}
function install_vbox_guest_utils () {
$CHROOT sh -c "pacman -Q linux 2>/dev/null || $SUDO pacman -S --noconfirm --needed virtualbox-guest-dkms"
$CHROOT $SUDO pacman -S --noconfirm --needed virtualbox-guest-utils
$CHROOT $SUDO systemctl enable vboxservice
if [ "$MODE" == 'post' ]; then $SUDO systemctl start vboxservice; fi
}
function update_configuration () {
echo "Update_config"
}
function install_base () {
log -s -w "$ES_CYAN" 'Arch Linux base installation'
log -s 'getting user data'
log -n -i 1 -e ': ' '(1/7) Hostname [host]'
read HOSTNAME
HOSTNAME=${HOSTNAME:-host}
while true; do
log -n -i 1 -e ': ' '(2/7) Root password [root]'
read -s ROOT_PASSWORD
echo
log -n -i 1 -e ': ' '(3/7) Retype root password [root]'
read -s ROOT_PASSWORD_CHECK
echo
if [ "$ROOT_PASSWORD" == "$ROOT_PASSWORD_CHECK" ]; then break; fi
log -i 1 -w "$ES_RED" 'Passwords do not match, try again'
done
ROOT_PASSWORD=${ROOT_PASSWORD:-root}
log -n -i 1 -e ': ' '(4/7) User full name [User]'
read USER_FULLNAME
USER_FULLNAME=${USER_FULLNAME:-User}
log -n -i 1 -e ': ' '(5/7) Username [user]'
read USER_USERNAME
USER_USERNAME=${USER_USERNAME:-user}
while true; do
log -n -i 1 -e ': ' '(6/7) User password [user]'
read -s USER_PASSWORD
echo
log -n -i 1 -e ': ' '(7/7) Retype user password [user]'
read -s USER_PASSWORD_CHECK
echo
if [ "$USER_PASSWORD" == "$USER_PASSWORD_CHECK" ]; then break; fi
log -i 1 -w "$ES_RED" 'Passwords do not match, try again'
done
USER_PASSWORD=${USER_PASSWORD:-user}
log -f 'getting user data'
log -s 'system clock synchronizing'
timedatectl set-ntp true
log -f 'system clock synchronizing'
log -s 'partitioning'
SECTOR_SIZE=512
SWAP_SECTORS=$((`free -b | awk '/Mem/ {print $2}'` / $SECTOR_SIZE))
if [ -d /sys/firmware/efi/efivars ]; then
cat <<-EOF | sfdisk --force $DRIVE
label: gpt
sector-size: $SECTOR_SIZE
${DRIVE}1: type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, size=532480
${DRIVE}2: type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, size=$SWAP_SECTORS
${DRIVE}3: type=0FC63DAF-8483-4772-8E79-3D69D8477DE4
EOF
log -f 'partitioning'
log -s 'partitions formatting'
mkfs.fat -F 32 "$DRIVE"1
mkswap "$DRIVE"2
mkfs.ext4 "$DRIVE"3
log -f 'partitions formatting'
log -s 'file systems mounting'
mount "$DRIVE"3 /mnt
swapon "$DRIVE"2
log -f 'file systems mounting'
else
cat <<-EOF | sfdisk --force $DRIVE
label: dos
sector-size: $SECTOR_SIZE
${DRIVE}1: type=82, size=$SWAP_SECTORS
${DRIVE}2: type=83, bootable
EOF
log -f 'partitioning'
log -s 'partitions formatting'
mkswap "$DRIVE"1
mkfs.ext4 "$DRIVE"2
log -f 'partitions formatting'
log -s 'file systems mounting'
mount "$DRIVE"2 /mnt
swapon "$DRIVE"1
log -f 'file systems mounting'
fi
log -s 'mirrors list updating'
reflector --fastest 5 --sort rate -c "$MIRRORS_COUNTRIES" --protocol https --save /etc/pacman.d/mirrorlist
log -f 'mirrors list updating'
log -s 'essential packages installation'
pacman -Syy
pacstrap /mnt base linux-firmware
if [ "$LTS" == true ]; then
pacstrap /mnt linux-lts linux-lts-headers
else
pacstrap /mnt linux
fi
log -f 'essential packages installation'
log -s 'system configuring'
genfstab -U /mnt >>/mnt/etc/fstab
$CHROOT ln --force --symbolic /usr/share/zoneinfo/Europe/Moscow /etc/localtime
$CHROOT hwclock --systohc
sed -i 's/^#\(\(en_US\|ru_RU\)\.UTF-8 UTF-8\)/\1/' /mnt/etc/locale.gen
$CHROOT locale-gen
echo LANG=en_US.UTF-8 >/mnt/etc/locale.conf
cp /etc/pacman.d/mirrorlist /mnt/etc/pacman.d/mirrorlist
log -f 'system configuring'
log -s 'network configuring'
echo "$HOSTNAME" >/mnt/etc/hostname
echo '127.0.0.1 localhost' >/mnt/etc/hosts
echo '::1 localhost' >>/mnt/etc/hosts
echo "127.0.1.1 $HOSTNAME.localdomain $HOSTNAME" >>/mnt/etc/hosts
$CHROOT pacman -S --noconfirm --needed networkmanager
$CHROOT systemctl enable NetworkManager
log -f 'network configuring'
log -s 'users configuring'
ROOT_PASSWORD=$(openssl passwd -crypt ${ROOT_PASSWORD})
$CHROOT usermod --password ${ROOT_PASSWORD} root
USER_PASSWORD=$(openssl passwd -crypt ${USER_PASSWORD})
$CHROOT useradd --create-home --comment "$USER_FULLNAME" --password "$USER_PASSWORD" --gid users --groups wheel "$USER_USERNAME"
$CHROOT pacman -S --noconfirm --needed sudo
sed -i 's/^# \(%wheel ALL=(ALL) ALL\)/\1/' /mnt/etc/sudoers
log -f 'users configuring'
if [ "$VBOX" == true ]; then
log -s 'VirtualBox guest utilities installation'
install_vbox_guest_utils
log -f 'VirtualBox guest utilities installation'
fi
log -s 'boot loader installation and configuring'
$CHROOT pacman -S --noconfirm --needed grub
if [ -d /sys/firmware/efi/efivars ]; then
$CHROOT pacman -S --noconfirm --needed efibootmgr
mkdir /mnt/boot/efi
mount "$DRIVE"1 /mnt/boot/efi
$CHROOT grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
else
$CHROOT grub-install --target=i386-pc "$DRIVE"
fi
$CHROOT grub-mkconfig -o /boot/grub/grub.cfg
log -f 'boot loader installation and configuring'
log -s 'partitions unmounting'
umount -R /mnt
log -f 'partitions unmounting'
log -f -w "$ES_CYAN" 'Arch Linux base installation'
}
function install_post () {
log -s -w "$ES_CYAN" 'Arch Linux post-installation'
log -s 'sudo timeout preventing'
command -v sudo >/dev/null 2>&1 || {
log -w "$ES_RED" "sudo isn't installed"
exit 1
}
trap revert_sudoers EXIT SIGHUP SIGINT SIGTERM
sudo cp /etc/sudoers /etc/sudoers.bak
sudo sh -c "echo '$(whoami) ALL=(ALL) NOPASSWD: ALL' | (EDITOR='tee -a' visudo)" >/dev/null
log -f 'sudo timeout preventing'
log -s 'swappiness configuring'
sudo sh -c 'echo "vm.swappiness=10" >/etc/sysctl.conf'
log -f 'swappiness configuring'
log -s 'grub configuring'
sudo sed -i 's/^\(GRUB_TIMEOUT\).*/\1=0/' /etc/default/grub
sudo grub-mkconfig -o /boot/grub/grub.cfg
log -f 'grub configuring'
log -s 'pacman configuring'
sudo pacman -Syyu --noconfirm --needed
install_packages reflector
sudo sh -c "cat <<-EOF >/etc/xdg/reflector/reflector.conf
--save /etc/pacman.d/mirrorlist
--protocol https
--country $MIRRORS_COUNTRIES
--sort rate
--fastest 5
EOF"
sudo systemctl enable --now reflector.timer
log -f 'pacman configuring'
log -s 'fonts installation'
install_packages "${FONTS_PACKAGES[@]}"
log -f 'fonts installation'
log -s 'GNOME installation'
install_packages "${GNOME_PACKAGES[@]}"
sudo systemctl enable gdm
log -f 'GNOME installation'
log -s 'OpenSSH installation'
install_packages openssh
sudo sh -c 'echo "DisableForwarding yes # disable all forwarding features (overrides all other forwarding-related options)" >>/etc/ssh/sshd_config'
sudo sed -i 's/^#\(IgnoreRhosts\).*/\1 yes/' /etc/ssh/sshd_config
# sudo sed -i 's/^#\(PasswordAuthentication\).*/\1 no/' /etc/ssh/sshd_config
sudo sed -i 's/^#\(PermitRootLogin\).*/\1 no/' /etc/ssh/sshd_config
sudo systemctl enable sshd
log -f 'OpenSSH installation'
log -s 'additional packages installation'
install_packages "${ADDITIONAL_PACKAGES[@]}"
sudo systemctl enable --now pkgfile-update.timer
log -f 'additional packages installation'
if [ "$VBOX" == true ]; then
log -s 'VirtualBox guest utilities installation'
install_vbox_guest_utils
log -f 'VirtualBox guest utilities installation'
fi
log -s 'GDM configuring'
tempdir=$(mktemp -d)
cd "$tempdir"
echo '<?xml version="1.0" encoding="UTF-8"?>' >"$tempdir"/gnome-shell-theme.gresource.xml
echo '<gresources><gresource>' >>"$tempdir"/gnome-shell-theme.gresource.xml
for file in $(gresource list /usr/share/gnome-shell/gnome-shell-theme.gresource); do
mkdir -p `dirname "${tempdir}${file}"`
gresource extract /usr/share/gnome-shell/gnome-shell-theme.gresource "$file" >"${tempdir}${file}"
echo "<file>${file#\/}</file>" >>"$tempdir"/gnome-shell-theme.gresource.xml
done
echo '</gresource></gresources>' >>"$tempdir"/gnome-shell-theme.gresource.xml
sed -i -zE 's/(#lockDialogGroup \{)[^}]+/\1 background-color: #000000; /g' "$tempdir"/org/gnome/shell/theme/gnome-shell.css
glib-compile-resources "$tempdir"/gnome-shell-theme.gresource.xml
sudo cp -f "$tempdir"/gnome-shell-theme.gresource /usr/share/gnome-shell/
cd - >/dev/null
rm -rf "$tempdir"
log -f 'GDM configuring'
log -s 'GNOME configuring'
[ "$XORG" == true ] && sudo sed -i 's/^#\(WaylandEnable=false\)/\1/' /etc/gdm/custom.conf
if [ "$VBOX" == true ]; then
log -s 'VirtualBox guest utilities installation'
install_vbox_guest_utils
log -f 'VirtualBox guest utilities installation'
fi
log -s 'pacman clearing up'
orphans=`pacman -Qtdq | tee`
[[ -n "$orphans" ]] && sudo pacman -Rcns --noconfirm "$orphans"
sudo pacman -Scc --noconfirm
log -f 'pacman clearing up'
log -f -w "$ES_CYAN" 'Arch Linux post-installation'
}
setup_terminal_colors
setup_color_scheme
if [ "$UPDATE_CONFIGURATION" == true ]; then
update_configuration
else
if [ "$MODE" == 'post' ]; then
install_post
else
install_base
fi
check_system_errors
if ask 'Reboot now'; then
revert_sudoers
reboot
fi
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment