Created
April 18, 2021 11:05
-
-
Save riskiwah/7ddd0f52ed8abf02111e5d543cd9a230 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#!/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