mirror of
https://git.myvelabs.com/lab/archlinux.git
synced 2025-12-17 19:46:25 +00:00
First commit
This commit is contained in:
commit
36ad41a2fc
18 changed files with 10005 additions and 0 deletions
39
README.md
Normal file
39
README.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
# MyveArch
|
||||||
|
|
||||||
|
This repo is a compilation of installation scripts written in bash that install [Arch Linux](https://archlinux.org/) on any x86_64 EFI system. From a home server ([homelab.sh](homelab.sh)) to a laptop or desktop computer ([arch.sh](arch.sh)), these scripts are highly customizable and can be tailored to very specific needs.
|
||||||
|
|
||||||
|
## :: Pre-installation
|
||||||
|
Acquire an installation ISO and burn it into a USB drive:
|
||||||
|
```
|
||||||
|
dd bs=4M if=${/path/to/archlinux-version-x86_64.iso} of=${/dev/disk/by-id/usb-My_flash_drive} conv=fsync oflag=direct status=progress
|
||||||
|
```
|
||||||
|
|
||||||
|
## :: Usage
|
||||||
|
Download the script of choice and execute it in the terminal:
|
||||||
|
|
||||||
|
```
|
||||||
|
wget https://myvelabs.com/lab/archlinux/raw/branch/master/arch.sh
|
||||||
|
bash arch.sh
|
||||||
|
```
|
||||||
|
OR
|
||||||
|
```
|
||||||
|
curl --fail -s -L -O https://myvelabs.com/lab/archlinux/raw/branch/master/homelab.sh
|
||||||
|
bash homelab.sh
|
||||||
|
```
|
||||||
|
OR
|
||||||
|
```
|
||||||
|
git clone https://myvelabs.com/lab/archlinux.git
|
||||||
|
cd archlinux/
|
||||||
|
bash arch.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## :: Installation
|
||||||
|
The following flags are available:
|
||||||
|
```
|
||||||
|
-s, --ssh-key Authorized SSH public key (one entry per flag, enclosed in quotes)
|
||||||
|
-c, --cache Pacman cache server address
|
||||||
|
-k, --kernel Linux kernel (eg, linux, linux-lts, linux-hardened, linux-zen)
|
||||||
|
-f, --filesystem Choice of filesystem (eg, ext4, btrfs, zfs)
|
||||||
|
-o, --option Arch installation setup, if known
|
||||||
|
```
|
||||||
|
Fill out the prompts and you'll have a full-fledged Arch Linux system up and running in no time.
|
||||||
728
functions/chroot
Executable file
728
functions/chroot
Executable file
|
|
@ -0,0 +1,728 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
revision=0.1a
|
||||||
|
set -a
|
||||||
|
set -E
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
tee -a /etc/environment >/dev/null <<- environment
|
||||||
|
EDITOR=vim
|
||||||
|
SUDO_EDITOR=vim
|
||||||
|
environment
|
||||||
|
|
||||||
|
# Global bashrc
|
||||||
|
tee -a /etc/skel/.bashrc >/dev/null <<- 'bashglobal'
|
||||||
|
|
||||||
|
# Source bash functions
|
||||||
|
if [ -d ~/.local/functions ]
|
||||||
|
then
|
||||||
|
for file in $(find ~/.local/functions -type f)
|
||||||
|
do
|
||||||
|
. ${file}
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add local functions folder to path
|
||||||
|
export PATH=${PATH}:${HOME}/.local/bin:/zfs/bin:/opt/local/bin
|
||||||
|
export SUDO_PROMPT=$'\a'"$(tput rev)[sudo] password for %p:$(tput sgr0)"' '
|
||||||
|
|
||||||
|
# Colored prompts
|
||||||
|
alias diff='diff --color=auto'
|
||||||
|
alias ip='ip -color=auto'
|
||||||
|
export LESS='-R --use-color -Dd+r$Du+b$'
|
||||||
|
|
||||||
|
# Adjust terminal upon window resize
|
||||||
|
shopt -s checkwinsize
|
||||||
|
|
||||||
|
# Auto cd into directory
|
||||||
|
shopt -s autocd
|
||||||
|
|
||||||
|
# Enable tab complete for sudo
|
||||||
|
complete -c -f sudo
|
||||||
|
|
||||||
|
# Ignore duplicate and whitespace history entries
|
||||||
|
export HISTCONTROL=ignoreboth
|
||||||
|
|
||||||
|
#
|
||||||
|
# ~/.bash_aliases
|
||||||
|
#
|
||||||
|
|
||||||
|
# ZFS/btrfs
|
||||||
|
alias zfs='sudo zfs'
|
||||||
|
alias zpool='sudo zpool'
|
||||||
|
alias btrfs='sudo btrfs'
|
||||||
|
|
||||||
|
# Shutdown reboot
|
||||||
|
alias poweroff='sudo poweroff'
|
||||||
|
alias reboot='sudo reboot'
|
||||||
|
|
||||||
|
# Text editors
|
||||||
|
alias v='vim'
|
||||||
|
alias sv='sudo vim'
|
||||||
|
|
||||||
|
# Clear bash history
|
||||||
|
alias clearhistory='rm ${HISTFILE}; history -c -w'
|
||||||
|
|
||||||
|
# Miscellanous pacman
|
||||||
|
alias orphans='sudo pacman -Rcns $(pacman -Qtdq)'
|
||||||
|
alias unlockpacman='sudo rm /var/lib/pacman/db.lck && sudo pacman -Syyu'
|
||||||
|
|
||||||
|
# Rsync
|
||||||
|
alias rsync='rsync -v -h --progress --info=progress2 --partial --append-verify'
|
||||||
|
# --log-file=
|
||||||
|
# --remove-source-files
|
||||||
|
|
||||||
|
#
|
||||||
|
# ~/.bash_functions
|
||||||
|
#
|
||||||
|
|
||||||
|
# Pacman tools
|
||||||
|
function installer
|
||||||
|
{
|
||||||
|
/opt/local/bin/cacheserver
|
||||||
|
sudo pacman -S ${@}
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall
|
||||||
|
{
|
||||||
|
sudo pacman -Rcns ${@}
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function mirrors
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
sudo reflector --country CA,US --age 24 --latest 20 --protocol https --fastest 25 --sort rate --save /etc/pacman.d/mirrorlist
|
||||||
|
echo
|
||||||
|
cat /etc/pacman.d/mirrorlist
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function syur
|
||||||
|
{
|
||||||
|
/opt/local/bin/syu &&
|
||||||
|
reboot
|
||||||
|
}
|
||||||
|
|
||||||
|
function syup
|
||||||
|
{
|
||||||
|
/opt/local/bin/syu &&
|
||||||
|
poweroff
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update bash
|
||||||
|
function update-bash
|
||||||
|
{
|
||||||
|
vim ~/.bashrc &&
|
||||||
|
source ~/.bashrc
|
||||||
|
}
|
||||||
|
bashglobal
|
||||||
|
|
||||||
|
# Root bashrc
|
||||||
|
rsync -a /etc/skel/.bashrc ~/
|
||||||
|
mkdir -p ~/.local/functions/
|
||||||
|
cat > ~/.local/functions/bashrc <<- 'bashrc'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Root shell color
|
||||||
|
PS1="$(tput setaf 1)[\u@\h \W \$?]\$$(tput sgr0) "
|
||||||
|
|
||||||
|
# Colored prompts
|
||||||
|
alias ll='ls --color=auto -l -a -h'
|
||||||
|
alias egrep='egrep --color=auto'
|
||||||
|
alias fgrep='fgrep --color=auto'
|
||||||
|
|
||||||
|
# Disable history
|
||||||
|
unset HISTFILE
|
||||||
|
rm -f ${HISTFILE}
|
||||||
|
history -c -w
|
||||||
|
bashrc
|
||||||
|
|
||||||
|
# Locale
|
||||||
|
sed '/#en_US.UTF-8 UTF-8/ s/#//' -i /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
echo 'LANG=en_US.UTF-8' >>/etc/locale.conf
|
||||||
|
say as heading 'Locale configured'
|
||||||
|
|
||||||
|
# Time zone
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
ln -s -f $(find /usr/share/zoneinfo/ | shuf -n 1) /etc/localtime
|
||||||
|
else
|
||||||
|
ln -s -f /usr/share/zoneinfo/UTC /etc/localtime
|
||||||
|
fi
|
||||||
|
hwclock --systohc --utc
|
||||||
|
say as heading 'Time zone configured'
|
||||||
|
|
||||||
|
# Hostname
|
||||||
|
echo ${hostname} >/etc/hostname
|
||||||
|
cat >>/etc/hosts <<HOSTS
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 ${hostname}
|
||||||
|
HOSTS
|
||||||
|
say as heading 'Hostname configured'
|
||||||
|
|
||||||
|
# User and superuser
|
||||||
|
useradd -m -g users -G wheel -s /usr/bin/bash ${username} || die 'User account creation has failed'
|
||||||
|
printf '%s\n' "${userpass}" "${userpass}" | passwd ${username} >/dev/null 2>&1
|
||||||
|
unset userpass userpass2
|
||||||
|
|
||||||
|
# Disable root account
|
||||||
|
passwd -l root >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Sudoers
|
||||||
|
install -m 0440 /dev/stdin /etc/sudoers.d/01-DEFAULTS <<- DEFAULTS
|
||||||
|
Defaults passwd_timeout=0
|
||||||
|
Defaults timestamp_type=global
|
||||||
|
Defaults insults
|
||||||
|
DEFAULTS
|
||||||
|
|
||||||
|
install -m 0440 /dev/stdin /etc/sudoers.d/02-COMMANDS <<- COMMANDS
|
||||||
|
Cmnd_Alias POWER = /usr/bin/poweroff, /usr/bin/reboot
|
||||||
|
Cmnd_Alias ZFS = /usr/bin/zfs, /usr/bin/zpool
|
||||||
|
Cmnd_Alias BTRFS = /usr/bin/btrfs, /usr/bin/timeshift, /usr/bin/timeshift-gtk, /usr/bin/timeshift-launcher
|
||||||
|
Cmnd_Alias QEMU = /usr/bin/virsh, /usr/bin/qemu-system-x86_64, /usr/bin/virt-install
|
||||||
|
Cmnd_Alias FAIL2BAN = /usr/bin/fail2ban-client
|
||||||
|
Cmnd_Alias ARCHISO = /opt/local/bin/mkairgap, /opt/local/bin/mkiso
|
||||||
|
Cmnd_Alias PACMAN = /usr/bin/pacman -Sy
|
||||||
|
Cmnd_Alias IPTABLES = /usr/bin/iptables, /usr/bin/iptables-save
|
||||||
|
Cmnd_Alias MISC = /usr/bin/rsync
|
||||||
|
COMMANDS
|
||||||
|
|
||||||
|
install -m 0440 /dev/stdin /etc/sudoers.d/03-WHEEL <<- WHEEL
|
||||||
|
%wheel ALL=(ALL:ALL) ALL
|
||||||
|
%wheel ALL=(ALL:ALL) NOPASSWD: POWER, ZFS, BTRFS, QEMU, FAIL2BAN, ARCHISO, PACMAN, IPTABLES, MISC
|
||||||
|
WHEEL
|
||||||
|
|
||||||
|
install -m 0440 /dev/stdin /etc/sudoers.d/.zz-NOPASSWD <<- NOPASSWD
|
||||||
|
Defaults:${username} !authenticate
|
||||||
|
NOPASSWD
|
||||||
|
|
||||||
|
case ${filesystem} in
|
||||||
|
zfs)
|
||||||
|
# ZFS setup
|
||||||
|
zpool set cachefile=/etc/zfs/zpool.cache zroot
|
||||||
|
zgenhostid $(hostid)
|
||||||
|
|
||||||
|
# ZFS files
|
||||||
|
touch /zfs/snapshot-syu
|
||||||
|
chown ${username}:users /zfs/snapshot-syu
|
||||||
|
|
||||||
|
# Trim zroot monthly
|
||||||
|
cat >/etc/systemd/system/zfs-trim@.timer <<- 'TRIM'
|
||||||
|
[Unit]
|
||||||
|
Description=Monthly zpool trim on %i
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=monthly
|
||||||
|
AccuracySec=1h
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
TRIM
|
||||||
|
cat >/etc/systemd/system/zfs-trim@.service <<- 'TRIM'
|
||||||
|
[Unit]
|
||||||
|
Description=zpool trim on %i
|
||||||
|
Documentation=man:zpool-trim(8)
|
||||||
|
Requires=zfs.target
|
||||||
|
After=zfs.target
|
||||||
|
ConditionACPower=true
|
||||||
|
ConditionPathIsDirectory=/sys/module/zfs
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Nice=19
|
||||||
|
IOSchedulingClass=idle
|
||||||
|
KillSignal=SIGINT
|
||||||
|
ExecStart=/bin/sh -c '\
|
||||||
|
if /usr/bin/zpool status %i | grep "trimming"; then\
|
||||||
|
exec /usr/bin/zpool wait -t trim %i;\
|
||||||
|
else exec /usr/bin/zpool trim -w %i; fi'
|
||||||
|
ExecStop=-/bin/sh -c '/usr/bin/zpool trim -s %i 2>/dev/null || true'
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
TRIM
|
||||||
|
# Scrub zroot monthly
|
||||||
|
cat >/etc/systemd/system/zfs-scrub@.timer <<- 'SCRUB'
|
||||||
|
[Unit]
|
||||||
|
Description=Monthly zpool scrub on %i
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=monthly
|
||||||
|
AccuracySec=1h
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SCRUB
|
||||||
|
cat >/etc/systemd/system/zfs-scrub@.service <<- 'SCRUB'
|
||||||
|
[Unit]
|
||||||
|
Description=zpool scrub on %i
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Nice=19
|
||||||
|
IOSchedulingClass=idle
|
||||||
|
KillSignal=SIGINT
|
||||||
|
ExecStart=/usr/bin/zpool scrub %i
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
SCRUB
|
||||||
|
|
||||||
|
# Pre and Post update backup hooks
|
||||||
|
cat >/etc/pacman.d/hooks/00-syu_pre.hook <<- pre
|
||||||
|
[Trigger]
|
||||||
|
Type = Path
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Creating pre zroot snapshot...
|
||||||
|
When = PreTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'zfs snapshot zroot/ROOT@pre-\$(cat /zfs/snapshot-syu)'
|
||||||
|
AbortOnFail
|
||||||
|
pre
|
||||||
|
cat >/etc/pacman.d/hooks/55-bootbackup_pre.hook <<- pre
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Path
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = rsync
|
||||||
|
Description = Backing up pre /boot...
|
||||||
|
When = PreTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'mount /boot; rsync -a --mkpath --delete /boot/ "/.boot/\$(cat /zfs/snapshot-syu)_pre"/'
|
||||||
|
AbortOnFail
|
||||||
|
pre
|
||||||
|
cat >/etc/pacman.d/hooks/95-bootbackup_post.hook <<- post
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Path
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = rsync
|
||||||
|
Description = Backing up post /boot...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete /boot/ "/.boot/\$(cat /zfs/snapshot-syu)_post"/'
|
||||||
|
post
|
||||||
|
cat >/etc/pacman.d/hooks/zz-syu_post.hook <<- post
|
||||||
|
[Trigger]
|
||||||
|
Type = Path
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Creating post zroot snapshot...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'zfs snapshot zroot/ROOT@post-\$(cat /zfs/snapshot-syu)'
|
||||||
|
post
|
||||||
|
|
||||||
|
# Custom pacman wrapper
|
||||||
|
install /dev/stdin /opt/local/bin/syu <<- syu
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
mirrorlist=
|
||||||
|
|
||||||
|
# Enable or disable pacman cache server
|
||||||
|
/opt/local/bin/cacheserver
|
||||||
|
|
||||||
|
# Fetch latest mirrors
|
||||||
|
sudo curl --fail --silent \${mirrorlist} -o /etc/pacman.d/mirrorlist
|
||||||
|
|
||||||
|
# Record current time
|
||||||
|
echo \$(date "+%Y-%m-%d-%H:%M:%S") >/zfs/snapshot-syu
|
||||||
|
|
||||||
|
# Check for new packages and continue if found
|
||||||
|
newpkg+=(\$(checkupdates --nocolor | awk '{print \$1}'))
|
||||||
|
if [ "\${newpkg}" ]
|
||||||
|
then
|
||||||
|
# Sync pacman dbs
|
||||||
|
sudo pacman --ask 4 -Sy >/dev/null
|
||||||
|
|
||||||
|
# Check zfs-linux kernel dependency
|
||||||
|
zfslinux=\$(pacman -Si zfs-${linux_kernel} | grep "Depends On" | sed "s|.*${linux_kernel}=||")
|
||||||
|
linux=\$(pacman -Si ${linux_kernel} | grep "Version" | awk '{print \$3}')
|
||||||
|
if [ \${zfslinux} != \${linux} ]
|
||||||
|
then
|
||||||
|
archzfs="--ignore zfs-utils,zfs-${linux_kernel},${linux_kernel}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update archlinux-keyring first
|
||||||
|
if [[ \${newpkg[@]} =~ "archlinux-keyring" ]]
|
||||||
|
then
|
||||||
|
sudo pacman --ask 4 -S archlinux-keyring
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Perform update if dependencies are satisfied
|
||||||
|
if sudo pacman --ask 4 -Syu \${archzfs} --needed
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
sudo pacdiff
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
syu
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
case ${filesystem} in
|
||||||
|
btrfs)
|
||||||
|
# Pre and post update backup hooks
|
||||||
|
cat >/etc/pacman.d/hooks/00-syu_pre.hook <<- pre
|
||||||
|
[Trigger]
|
||||||
|
Type = Path
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = timeshift
|
||||||
|
Description = Creating pre root snapshot...
|
||||||
|
When = PreTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'timeshift --create --comments "pre_\$(date "+%Y-%m-%d-%H:%M:%S")" >/dev/null'
|
||||||
|
AbortOnFail
|
||||||
|
pre
|
||||||
|
cat >/etc/pacman.d/hooks/55-bootbackup_pre.hook <<- pre
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Path
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = rsync
|
||||||
|
Description = Backing up pre /boot...
|
||||||
|
When = PreTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete --exclude 'header.img' /boot/ "/.boot/\$(date "+%Y-%m-%d-%H:%M:%S")_pre"/'
|
||||||
|
AbortOnFail
|
||||||
|
pre
|
||||||
|
cat >/etc/pacman.d/hooks/95-bootbackup_post.hook <<- post
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Path
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = rsync
|
||||||
|
Description = Backing up post /boot...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'rsync -a --mkpath --delete --exclude 'header.img' /boot/ "/.boot/\$(date "+%Y-%m-%d-%H:%M:%S")_post"/'
|
||||||
|
post
|
||||||
|
cat >/etc/pacman.d/hooks/zz-syu_post.hook <<- post
|
||||||
|
[Trigger]
|
||||||
|
Type = Path
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Target = usr/lib/modules/*/vmlinuz
|
||||||
|
Target = usr/lib/initcpio/*
|
||||||
|
Target = usr/lib/firmware/*
|
||||||
|
Target = usr/src/*/dkms.conf
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Depends = timeshift
|
||||||
|
Description = Creating post root snapshot...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/bash -c 'timeshift --create --comments "post_\$(date "+%Y-%m-%d-%H:%M:%S")" >/dev/null'
|
||||||
|
post
|
||||||
|
|
||||||
|
install /dev/stdin /usr/local/bin/timeshift-gui <<- 'timeshift'
|
||||||
|
#!/bin/sh
|
||||||
|
pkexec env WAYLAND_DISPLAY="$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY" XDG_RUNTIME_DIR=/run/user/0 timeshift-launcher
|
||||||
|
timeshift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Custom pacman wrapper
|
||||||
|
install /dev/stdin /opt/local/bin/syu <<- syu
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
mirrorlist=
|
||||||
|
|
||||||
|
# Enable or disable pacman cache server
|
||||||
|
/opt/local/bin/cacheserver
|
||||||
|
|
||||||
|
# Fetch latest mirrors
|
||||||
|
sudo curl --fail --silent \${mirrorlist} -o /etc/pacman.d/mirrorlist
|
||||||
|
|
||||||
|
# Check for new packages and continue if found
|
||||||
|
newpkg+=(\$(checkupdates --nocolor | awk '{print \$1}'))
|
||||||
|
if [ "\${newpkg}" ]
|
||||||
|
then
|
||||||
|
# Update archlinux-keyring first
|
||||||
|
if [[ \${newpkg[@]} =~ "archlinux-keyring" ]]
|
||||||
|
then
|
||||||
|
sudo pacman --ask 4 -S archlinux-keyring
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Perform update if dependencies are satisfied
|
||||||
|
if sudo pacman --ask 4 -Syu --needed
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
sudo pacdiff
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
syu
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo
|
||||||
|
|
||||||
|
# /opt/local/bin/cacheserver
|
||||||
|
install /dev/stdin /opt/local/bin/cacheserver <<- 'cacheserver'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Enable cacheserver if active
|
||||||
|
cacheserver=
|
||||||
|
port=
|
||||||
|
scheme=
|
||||||
|
|
||||||
|
if [ -z ${cacheserver} ]
|
||||||
|
then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if nc -z -4 -w 3 ${cacheserver} ${port:-80} >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
if grep -q "CacheServer" /etc/pacman.conf
|
||||||
|
then
|
||||||
|
sudo sed "/CacheServer/ s/^\(#\)*//g" -i /etc/pacman.conf
|
||||||
|
else
|
||||||
|
sudo sed "/^\[core\]$\|^\[extra\]$\|^\[myvezfs\]$/a CacheServer = ${scheme:-http}://${cacheserver}:${port:-80}" -i /etc/pacman.conf
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
sudo sed "/CacheServer/ s/^/#/g" -i /etc/pacman.conf
|
||||||
|
fi
|
||||||
|
cacheserver
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
sed -e "/^cacheserver=/c cacheserver=192.168.122.1" \
|
||||||
|
-e "/^port=/c port=9090" \
|
||||||
|
-i /opt/local/bin/cacheserver
|
||||||
|
/opt/local/bin/cacheserver
|
||||||
|
fi
|
||||||
|
|
||||||
|
# mkinitcpio
|
||||||
|
say as heading 'Regenerating cpio image'
|
||||||
|
mkinitcpio -P
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Install GRUB
|
||||||
|
if [[ ${arch} = [3567] ]]
|
||||||
|
then
|
||||||
|
say as heading 'Installing GRUB'
|
||||||
|
grub-install --target=x86_64-efi --bootloader-id="Arch Linux (${hostname})" --efi-directory=/boot/efi --recheck || die 'Grub installation failed'
|
||||||
|
grub-mkconfig -o /boot/grub/grub.cfg
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sysctl custom settings
|
||||||
|
cat >/etc/sysctl.d/99-sysctl.conf <<- SYSCTL
|
||||||
|
net.core.netdev_max_backlog = 16384
|
||||||
|
net.core.somaxconn = 8192
|
||||||
|
net.core.rmem_default = 1048576
|
||||||
|
net.core.rmem_max = 16777216
|
||||||
|
net.core.wmem_default = 1048576
|
||||||
|
net.core.wmem_max = 16777216
|
||||||
|
net.core.optmem_max = 65536
|
||||||
|
net.ipv4.tcp_rmem = 4096 1048576 2097152
|
||||||
|
net.ipv4.tcp_wmem = 4096 65536 16777216
|
||||||
|
net.ipv4.udp_rmem_min = 8192
|
||||||
|
net.ipv4.udp_wmem_min = 8192
|
||||||
|
net.ipv4.tcp_fastopen = 3
|
||||||
|
net.ipv4.tcp_timestamps = 0
|
||||||
|
net.core.default_qdisc = cake
|
||||||
|
net.ipv4.tcp_congestion_control = bbr
|
||||||
|
vm.swappiness=10
|
||||||
|
vm.vfs_cache_pressure=50
|
||||||
|
SYSCTL
|
||||||
|
|
||||||
|
# iptables
|
||||||
|
cat >/etc/iptables/userinput.rules <<- IPTABLES
|
||||||
|
## User input
|
||||||
|
|
||||||
|
# SSH port
|
||||||
|
-A INPUT -p tcp -m tcp --dport ${port:-22} -j ACCEPT -m comment --comment "SSH Port"
|
||||||
|
|
||||||
|
## Simple Firewall
|
||||||
|
IPTABLES
|
||||||
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules
|
||||||
|
|
||||||
|
# zram
|
||||||
|
echo 'zram' >/etc/modules-load.d/zram.conf
|
||||||
|
echo 'options zram num_devices=1' >/etc/modprobe.d/zram.conf
|
||||||
|
echo 'KERNEL=="zram0", ATTR{comp_algorithm}="lz4", ATTR{disksize}="512M" RUN="/usr/bin/mkswap /dev/zram0", TAG+="systemd"' >/etc/udev/rules.d/99-zram.rules
|
||||||
|
echo '/dev/zram0 none swap defaults 0 0' >>/etc/fstab
|
||||||
|
|
||||||
|
# Configure ssh and ssh_config.d/10-global.conf
|
||||||
|
ssh-keygen -q \
|
||||||
|
-t ed25519 \
|
||||||
|
-P "" \
|
||||||
|
-C "${USER}@${hostname}" \
|
||||||
|
-f ~/.ssh/id_ed25519
|
||||||
|
mkdir ~/.ssh/sockets/
|
||||||
|
cat >/etc/ssh/sshd_config.d/10-sshd.conf <<- sshd
|
||||||
|
PermitRootLogin no
|
||||||
|
PasswordAuthentication no
|
||||||
|
AuthenticationMethods publickey
|
||||||
|
sshd
|
||||||
|
cat >/etc/ssh/ssh_config.d/10-global.conf <<- 'sshconfig'
|
||||||
|
# Preferred ciphers
|
||||||
|
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
|
||||||
|
|
||||||
|
# Only use ipv4
|
||||||
|
AddressFamily inet
|
||||||
|
|
||||||
|
# Multiplex
|
||||||
|
ControlMaster auto
|
||||||
|
ControlPath ~/.ssh/sockets/%r@%h-%p
|
||||||
|
ControlPersist 10m
|
||||||
|
|
||||||
|
# Ease up on local area network devices
|
||||||
|
Host 192.168.*
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
UserKnownHostsFile=/dev/null
|
||||||
|
LogLevel Error
|
||||||
|
sshconfig
|
||||||
|
|
||||||
|
# Polkit
|
||||||
|
mkdir -p /etc/polkit-1/rules.d/
|
||||||
|
cat >/etc/polkit-1/rules.d/49-nopasswd_global.rules <<- 'polkit'
|
||||||
|
/* Allow members of the wheel group to execute any actions
|
||||||
|
* without password authentication, similar to "sudo NOPASSWD:"
|
||||||
|
*/
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (subject.isInGroup("wheel")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
polkit
|
||||||
|
|
||||||
|
# Persistent journal logging
|
||||||
|
mkdir -p /etc/systemd/journald.conf.d/
|
||||||
|
cat >/etc/systemd/journald.conf.d/zz-journald.conf <<- eof
|
||||||
|
[Journal]
|
||||||
|
Storage=persistent
|
||||||
|
eof
|
||||||
|
|
||||||
|
# makepkg
|
||||||
|
mkdir -p /etc/makepkg.conf.d/
|
||||||
|
cat >/etc/makepkg.conf.d/zz-makepkg.conf <<- makepkg
|
||||||
|
PKGEXT=".pkg.tar"
|
||||||
|
MAKEFLAGS="--jobs=$(nproc)"
|
||||||
|
COMPRESSZST=(zstd -c -T0 --auto-threads=logical -)
|
||||||
|
makepkg
|
||||||
|
|
||||||
|
# Virtual machine settings
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
mv /etc/sudoers.d/.zz-NOPASSWD /etc/sudoers.d/zz-NOPASSWD
|
||||||
|
fi
|
||||||
|
|
||||||
|
##
|
||||||
|
## Hooks
|
||||||
|
##
|
||||||
|
|
||||||
|
# paccache
|
||||||
|
cat >/etc/pacman.d/hooks/zz-paccache.hook <<- paccache
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Package
|
||||||
|
Target = *
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Cleaning pacman cache...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/paccache --remove
|
||||||
|
paccache
|
||||||
|
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
install /dev/stdin /opt/local/hooks/localegen <<- hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/locale.gen.pacnew ]
|
||||||
|
then
|
||||||
|
sed '/#en_US.UTF-8 UTF-8/ s/#//' -i /etc/locale.gen.pacnew
|
||||||
|
mv /etc/locale.gen.pacnew /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
cat >/etc/pacman.d/hooks/100-localegen.hook <<- localegen
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = glibc
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing locale.gen
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/localegen
|
||||||
|
localegen
|
||||||
|
|
||||||
|
# iptables
|
||||||
|
cat >/etc/pacman.d/hooks/100-iptables.rules.hook <<iptables
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = iptables-nft
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing iptables rules
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/iptables.rules
|
||||||
|
iptables
|
||||||
|
install /dev/stdin /opt/local/hooks/iptables.rules <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/iptables/iptables.rules.pacsave ]
|
||||||
|
then
|
||||||
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules
|
||||||
|
rm /etc/iptables/iptables.rules.pacsave
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
|
||||||
|
su ${username} <<- "user"
|
||||||
|
curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/user -o /tmp/user
|
||||||
|
bash /tmp/user
|
||||||
|
user
|
||||||
670
functions/desktop
Executable file
670
functions/desktop
Executable file
|
|
@ -0,0 +1,670 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
revision='0.1f (feb 24/25)'
|
||||||
|
set -a
|
||||||
|
set -E
|
||||||
|
|
||||||
|
# Exit function
|
||||||
|
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||||
|
function die
|
||||||
|
{
|
||||||
|
if [ ${@} ]
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
echo -e "\e[1;31mError encountered for the following reason:\e[0m
|
||||||
|
|
||||||
|
\e[33m${@}\e[0m
|
||||||
|
|
||||||
|
\e[1;31mScript aborted...\e[0m"
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
echo -e '\e[1;31mError encountered, script aborted...\e[0m'
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
sudo timedatectl set-ntp true
|
||||||
|
else
|
||||||
|
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||||
|
fi
|
||||||
|
|
||||||
|
totalde=21
|
||||||
|
cat <<- menu
|
||||||
|
$(tput setaf 5 bold)
|
||||||
|
Select a desktop$(tput sgr0)
|
||||||
|
$(tput smul setaf 7 dim)# none$(tput sgr0)
|
||||||
|
0) none
|
||||||
|
$(tput smul setaf 7 dim)# wayland$(tput sgr0)
|
||||||
|
1) sway
|
||||||
|
2) hyprland
|
||||||
|
3) qtile-wayland
|
||||||
|
4) river
|
||||||
|
5) plasma-wayland
|
||||||
|
6) gnome-wayland
|
||||||
|
7) cosmic
|
||||||
|
$(tput smul setaf 7 dim)# x11$(tput sgr0)
|
||||||
|
8) qtile-x11
|
||||||
|
9) bspwm
|
||||||
|
10) awesome
|
||||||
|
11) i3
|
||||||
|
12) i3-plasma
|
||||||
|
13) plasma-x11
|
||||||
|
14) gnome-x11
|
||||||
|
15) xfce4
|
||||||
|
16) budgie
|
||||||
|
17) cinnamon
|
||||||
|
18) deepin
|
||||||
|
19) mate
|
||||||
|
20) pantheon
|
||||||
|
21) cutefish
|
||||||
|
22) lxde
|
||||||
|
23) lxqt
|
||||||
|
menu
|
||||||
|
if [ ${1} ]
|
||||||
|
then
|
||||||
|
desktop=${1}
|
||||||
|
else
|
||||||
|
desktop=-1
|
||||||
|
fi
|
||||||
|
until [[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]]
|
||||||
|
do
|
||||||
|
read -p '> ' desktop
|
||||||
|
[[ ${desktop} -ge 0 && ${desktop} -le ${totalde} ]] ||\
|
||||||
|
echo -e "\n\n\e[1;31mInvalid selection, type an option from 0 to ${totalde}\e[0m"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Configure btrfs
|
||||||
|
if findmnt / | grep -w -q btrfs
|
||||||
|
then
|
||||||
|
desktop_packages+=(btrfs-progs)
|
||||||
|
if pacman -Q | grep -q "^grub"
|
||||||
|
then
|
||||||
|
desktop_packages+=(grub-btrfs inotify-tools)
|
||||||
|
systemd_services+=(grub-btrfsd.service)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# echo -e '\n\e[1;35mConfiguring snapper\e[0m'
|
||||||
|
# sudo pacman --sync --ask 4 snapper snap-pac
|
||||||
|
# echo
|
||||||
|
# sudo umount /.snapshots /home/.snapshots
|
||||||
|
# sudo rm -r /.snapshots /home/.snapshots
|
||||||
|
# sudo snapper -c root create-config /
|
||||||
|
# sudo snapper -c home create-config /home
|
||||||
|
# sudo sed -i 's/TIMELINE_LIMIT_HOURLY="10"/TIMELINE_LIMIT_HOURLY="4"/' /etc/snapper/configs/root
|
||||||
|
# sudo sed -i 's/TIMELINE_LIMIT_DAILY="10"/TIMELINE_LIMIT_DAILY="7"/' /etc/snapper/configs/root
|
||||||
|
# sudo sed -i 's/TIMELINE_LIMIT_MONTHLY="10"/TIMELINE_LIMIT_MONTHLY="1"/' /etc/snapper/configs/root
|
||||||
|
# sudo sed -i 's/TIMELINE_LIMIT_YEARLY="10"/TIMELINE_LIMIT_YEARLY="0"/' /etc/snapper/configs/root
|
||||||
|
# sudo sed -i 's/TIMELINE_CREATE="yes"/TIMELINE_CREATE="no"/' /etc/snapper/configs/home
|
||||||
|
# sudo btrfs subvolume delete /.snapshots
|
||||||
|
# sudo btrfs subvolume delete /home/.snapshots
|
||||||
|
# sudo mkdir -p --mode=750 /.snapshots /home/.snapshots
|
||||||
|
# sudo mount -a
|
||||||
|
# sudo systemctl --quiet enable --now snapper-cleanup.timer snapper-timeline.timer
|
||||||
|
|
||||||
|
# # Create snapshots for fresh installation
|
||||||
|
# sudo snapper -c root create --description "fresh install"
|
||||||
|
# sudo snapper -c home create --description "fresh install"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Assign DE variables
|
||||||
|
case ${desktop} in
|
||||||
|
0)
|
||||||
|
# TTY only
|
||||||
|
desktop_choice=none
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
systemd_user_services+=(wireplumber.service pipewire-pulse.service pipewire.service)
|
||||||
|
desktop_packages+=(ttf-dejavu pipewire pipewire-audio pipewire-pulse pipewire-jack wireplumber)
|
||||||
|
case ${desktop} in
|
||||||
|
[1-7])
|
||||||
|
# Wayland
|
||||||
|
desktop_packages+=(wayland)
|
||||||
|
case ${desktop} in
|
||||||
|
1)
|
||||||
|
desktop_choice=sway
|
||||||
|
desktop_packages+=(sway seatd swaylock swayidle swaybg bemenu bemenu-wayland i3status foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent)
|
||||||
|
systemd_services+=(seatd.service)
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
desktop_choice=hyprland
|
||||||
|
desktop_packages+=(hyprland uwsm swaylock swayidle bemenu bemenu-wayland waybar foot kate dolphin konsole kompare kcalc breeze-icons kde-cli-tools ttf-font-awesome brightnessctl gnome-keyring fakeroot qt5-wayland polkit-kde-agent)
|
||||||
|
systemd_user_services+=(foot-server.service)
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
desktop_choice=qtile-wayland
|
||||||
|
desktop_packages+=(qtile python-pywlroots xorg-xwayland foot)
|
||||||
|
systemd_user_services+=(foot-server.service)
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
desktop_choice=river
|
||||||
|
desktop_packages+=(river foot)
|
||||||
|
systemd_user_services+=(foot-server.service)
|
||||||
|
;;
|
||||||
|
5)
|
||||||
|
desktop_choice=plasma-wayland
|
||||||
|
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole foot kate dolphin kompare kcalc)
|
||||||
|
systemd_services+=(sddm.service)
|
||||||
|
systemd_user_services+=(foot-server.service)
|
||||||
|
;;
|
||||||
|
6)
|
||||||
|
desktop_choice=gnome-wayland
|
||||||
|
desktop_packages+=(gnome foot)
|
||||||
|
systemd_services+=(gdm.service)
|
||||||
|
systemd_user_services+=(foot-server.service)
|
||||||
|
;;
|
||||||
|
7)
|
||||||
|
desktop_choice=cosmic
|
||||||
|
desktop_packages+=(cosmic)
|
||||||
|
systemd_services+=(cosmic-greeter.service)
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
desktop_packages+=(vulkan-virtio)
|
||||||
|
elif lspci | grep VGA | grep -q NVIDIA
|
||||||
|
then
|
||||||
|
desktop_packages+=(nvidia-utils)
|
||||||
|
elif lscpu | grep 'Model name:' | grep -q AMD
|
||||||
|
then
|
||||||
|
desktop_packages+=(amdvlk)
|
||||||
|
elif lscpu | grep 'Model name:' | grep -q Intel
|
||||||
|
then
|
||||||
|
desktop_packages+=(vulkan-intel)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
# Environment
|
||||||
|
sudo tee -a /etc/environment >/dev/null <<- environment
|
||||||
|
QT_QPA_PLATFORM=wayland
|
||||||
|
environment
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Xorg
|
||||||
|
desktop_packages+=(xorg)
|
||||||
|
case ${desktop} in
|
||||||
|
8)
|
||||||
|
desktop_choice=qtile-x11
|
||||||
|
desktop_packages+=(qtile xorg-xinit konsole)
|
||||||
|
;;
|
||||||
|
9)
|
||||||
|
desktop_choice=bspwm
|
||||||
|
desktop_packages+=(bspwm sxhkd xorg-xinit polybar konsole)
|
||||||
|
;;
|
||||||
|
10)
|
||||||
|
desktop_choice=awesome
|
||||||
|
desktop_packages+=(awesome xorg-xinit konsole)
|
||||||
|
;;
|
||||||
|
11)
|
||||||
|
desktop_choice=i3
|
||||||
|
desktop_packages+=(i3-wm i3status i3lock dmenu lightdm lightdm-gtk-greeter pavucontrol konsole kate dolphin kompare breeze-icons)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
12)
|
||||||
|
desktop_choice=i3-plasma
|
||||||
|
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc i3-wm i3status dmenu wmctrl feh)
|
||||||
|
systemd_services+=(sddm.service)
|
||||||
|
;;
|
||||||
|
13)
|
||||||
|
desktop_choice=plasma-x11
|
||||||
|
desktop_packages+=($(pacman -Sgq plasma | grep -v 'discover\|oxygen\|plasma-nm') konsole kate dolphin kompare kcalc)
|
||||||
|
systemd_services+=(sddm.service)
|
||||||
|
;;
|
||||||
|
14)
|
||||||
|
desktop_choice=gnome-x11
|
||||||
|
desktop_packages+=(gnome)
|
||||||
|
systemd_services+=(gdm.service)
|
||||||
|
;;
|
||||||
|
15)
|
||||||
|
desktop_choice=xfce4
|
||||||
|
desktop_packages+=(xfce4 lightdm lightdm-gtk-greeter)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
16)
|
||||||
|
desktop_choice=budgie
|
||||||
|
desktop_packages+=(budgie lightdm lightdm-gtk-greeter tilix)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
17)
|
||||||
|
desktop_choice=cinnamon
|
||||||
|
desktop_packages+=(cinnamon lightdm lightdm-gtk-greeter gnome-console)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
18)
|
||||||
|
desktop_choice=deepin
|
||||||
|
desktop_packages+=(deepin deepin-kwin $(pacman -Sgq deepin-extra | grep -v deepin-reader) lightdm lightdm-gtk-greeter gnome-keyring)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
if uname -r | grep -q 'lts\|hardened\|zen'
|
||||||
|
then
|
||||||
|
desktop_packages+=(deepin-anything-dkms)
|
||||||
|
else
|
||||||
|
desktop_packages+=(deepin-anything-arch)
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
19)
|
||||||
|
desktop_choice=mate
|
||||||
|
desktop_packages+=(mate mate-extra lightdm lightdm-gtk-greeter)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
20)
|
||||||
|
desktop_choice=pantheon
|
||||||
|
desktop_packages+=(pantheon lightdm-pantheon-greeter lightdm)
|
||||||
|
systemd_services+=(lightdm.service)
|
||||||
|
;;
|
||||||
|
21)
|
||||||
|
desktop_choice=cutefish
|
||||||
|
desktop_packages+=(cutefish sddm)
|
||||||
|
systemd_services+=(sddm.service)
|
||||||
|
;;
|
||||||
|
22)
|
||||||
|
desktop_choice=lxde
|
||||||
|
desktop_packages+=(lxde lxdm)
|
||||||
|
systemd_services+=(lxdm.service)
|
||||||
|
;;
|
||||||
|
23)
|
||||||
|
desktop_choice=lxqt
|
||||||
|
desktop_packages+=(lxqt sddm breeze-icons)
|
||||||
|
systemd_services+=(sddm.service)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo
|
||||||
|
echo -e "\t\e[1mYou have chosen \e[32m${desktop_choice}\e[0m\e[1m desktop\e[0m"
|
||||||
|
echo
|
||||||
|
echo -e '\e[1;35mInstalling base packages\e[0m'
|
||||||
|
sudo pacman --sync --ask 4 ${desktop_packages[@]} || die 'Failed to install required packages'
|
||||||
|
echo
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case ${desktop_choice} in
|
||||||
|
plasma-wayland)
|
||||||
|
mkdir -p ~/.config/{autostart-scripts,foot}/
|
||||||
|
# install /dev/stdin ~/.config/autostart-scripts/foot.sh <<- foot
|
||||||
|
# #!/bin/sh
|
||||||
|
# foot --server
|
||||||
|
# foot
|
||||||
|
cat >>~/.config/kglobalshortcutsrc <<- shortcuts
|
||||||
|
|
||||||
|
[services][footclient.desktop]
|
||||||
|
_launch=Alt+Return
|
||||||
|
|
||||||
|
[services][org.kde.konsole.desktop]
|
||||||
|
_launch=none
|
||||||
|
shortcuts
|
||||||
|
;;
|
||||||
|
gnome-wayland)
|
||||||
|
mkdir -p ~/.config/{autostart,foot}/
|
||||||
|
# cat > ~/.config/autostart/foot-server.desktop <<- foot
|
||||||
|
# [Desktop Entry]
|
||||||
|
# Type=Application
|
||||||
|
# Name=Foot server
|
||||||
|
# Exec=foot --server
|
||||||
|
# foot
|
||||||
|
gsettings set $(gsettings list-schemas | grep terminal) exec footclient
|
||||||
|
;;
|
||||||
|
cosmic)
|
||||||
|
mkdir -p ~/.config/foot/
|
||||||
|
;;
|
||||||
|
i3|i3-plasma)
|
||||||
|
# i3-config
|
||||||
|
mkdir -p ~/.config/i3/
|
||||||
|
curl --fail -s -L https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
||||||
|
case ${desktop_choice} in
|
||||||
|
i3-plasma)
|
||||||
|
kwriteconfig6 --file startkderc --group General --key systemdBoot false
|
||||||
|
sudo install /dev/stdin /opt/local/bin/plasma-i3.sh <<- EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
export KDEWM=/usr/bin/i3
|
||||||
|
/usr/bin/startplasma-x11
|
||||||
|
EOF
|
||||||
|
sudo tee /usr/share/xsessions/plasma-i3.desktop >/dev/null <<- EOF
|
||||||
|
[Desktop Entry]
|
||||||
|
Type=XSession
|
||||||
|
Exec=/opt/local/bin/plasma-i3.sh
|
||||||
|
DesktopNames=KDE
|
||||||
|
Name=Plasma (i3)
|
||||||
|
Comment=KDE Plasma with i3 as the WM
|
||||||
|
EOF
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
cat >> ~/.config/i3/config <<- 'i3'
|
||||||
|
|
||||||
|
exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080
|
||||||
|
exec xrandr --dpi 192
|
||||||
|
|
||||||
|
exec spice-vdagent
|
||||||
|
exec VBoxClient-all
|
||||||
|
i3
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
qtile-x11)
|
||||||
|
echo 'exec qtile start' >~/.xinitrc
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||||
|
then
|
||||||
|
exec startx
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
;;
|
||||||
|
qtile-wayland)
|
||||||
|
mkdir -p ~/.config/foot/
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
# Start sway on login from tty
|
||||||
|
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||||
|
then
|
||||||
|
exec qtile start -b wayland
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
;;
|
||||||
|
river)
|
||||||
|
mkdir -p ~/.config/foot/
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
# Start sway on login from tty
|
||||||
|
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||||
|
then
|
||||||
|
exec river
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
;;
|
||||||
|
bspwm)
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||||
|
then
|
||||||
|
exec startx /usr/bin/bspwm
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
mkdir -p ~/.config/{bspwm,sxhkd,polybar}/
|
||||||
|
install -Dm755 /usr/share/doc/bspwm/examples/bspwmrc ~/.config/bspwm/bspwmrc
|
||||||
|
install -Dm644 /usr/share/doc/bspwm/examples/sxhkdrc ~/.config/sxhkd/sxhkdrc
|
||||||
|
cp /etc/polybar/config.ini ~/.config/polybar/
|
||||||
|
;;
|
||||||
|
awesome)
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||||
|
then
|
||||||
|
exec startx /usr/bin/awesome
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
mkdir -p ~/.config/awesome/
|
||||||
|
sed -e '/^terminal =/c terminal = "konsole"' \
|
||||||
|
-e '/^modkey =/c modkey = "Mod1"' /etc/xdg/awesome/rc.lua > ~/.config/awesome/
|
||||||
|
;;
|
||||||
|
sway)
|
||||||
|
# Sway
|
||||||
|
sudo gpasswd -a ${USER} seat >/dev/null
|
||||||
|
|
||||||
|
# Dolphin default apps
|
||||||
|
mkdir -p ~/.config/menus/
|
||||||
|
curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
||||||
|
kbuildsycoca6 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Dolphin default terminal
|
||||||
|
cat >> ~/.config/kdeglobals <<- foot
|
||||||
|
[General]
|
||||||
|
TerminalApplication=footclient
|
||||||
|
foot
|
||||||
|
|
||||||
|
# Create conf directories
|
||||||
|
mkdir -p ~/.config/{sway/config.d,foot}/
|
||||||
|
|
||||||
|
# Identify conf locations
|
||||||
|
cat > ~/.config/sway/config <<- 'config'
|
||||||
|
include /etc/sway/config.d/*
|
||||||
|
include ~/.config/sway/config.d/*
|
||||||
|
config
|
||||||
|
|
||||||
|
# Default sway config
|
||||||
|
sed -e 's/mod Mod4/mod Mod1/' \
|
||||||
|
-e 's/term foot/&client/' \
|
||||||
|
-e '/set $menu/c set $menu bemenu-run -p "" --no-overlap --tb "#285577" --hb "#285577" --tf "#eeeeee" --hf "#eeeeee" --nf "#bbbbbb"' \
|
||||||
|
/etc/sway/config > ~/.config/sway/config.d/00-config
|
||||||
|
sed -n "/^# Status Bar:$/q;p" -i ~/.config/sway/config.d/00-config
|
||||||
|
|
||||||
|
# Sway config
|
||||||
|
cat > ~/.config/sway/config.d/zz-sway <<- 'config'
|
||||||
|
# Disable xwayland
|
||||||
|
xwayland disable
|
||||||
|
|
||||||
|
# Start foot terminal server
|
||||||
|
exec foot --server
|
||||||
|
|
||||||
|
# Use i3status
|
||||||
|
bar {
|
||||||
|
status_command i3status
|
||||||
|
}
|
||||||
|
|
||||||
|
# Floating windows
|
||||||
|
for_window [window_role="About"] floating enable
|
||||||
|
for_window [window_role="Organizer"] floating enable
|
||||||
|
for_window [window_role="Preferences"] floating enable
|
||||||
|
for_window [window_role="bubble"] floating enable
|
||||||
|
for_window [window_role="page-info"] floating enable
|
||||||
|
for_window [window_role="pop-up"] floating enable
|
||||||
|
for_window [window_role="task_dialog"] floating enable
|
||||||
|
for_window [window_role="toolbox"] floating enable
|
||||||
|
for_window [window_role="webconsole"] floating enable
|
||||||
|
for_window [window_type="dialog"] floating enable
|
||||||
|
for_window [window_type="menu"] floating enable
|
||||||
|
|
||||||
|
# Floating for KCalc
|
||||||
|
for_window [title="KCalc"] floating enable
|
||||||
|
|
||||||
|
# Bind keys for brightness
|
||||||
|
bindsym XF86MonBrightnessDown exec brightnessctl set 5%-
|
||||||
|
bindsym XF86MonBrightnessUp exec brightnessctl set 5%+
|
||||||
|
|
||||||
|
# Mouse and keyboard defaults
|
||||||
|
input type:keyboard xkb_numlock enabled
|
||||||
|
input type:touchpad {
|
||||||
|
tap enabled
|
||||||
|
natural_scroll enabled
|
||||||
|
}
|
||||||
|
config
|
||||||
|
|
||||||
|
# Display config
|
||||||
|
cat > ~/.config/sway/config.d/zz-display <<- 'display'
|
||||||
|
# # Declare output
|
||||||
|
# set $laptop eDP-1 (swaymsg -t get_outputs)
|
||||||
|
|
||||||
|
# Swayidle
|
||||||
|
exec swayidle -w \
|
||||||
|
timeout 300 'swaylock -e -f -c 000000' \
|
||||||
|
timeout 315 'swaymsg "output * power off"' \
|
||||||
|
resume 'swaymsg "output * power on"' \
|
||||||
|
timeout 600 'systemctl suspend' \
|
||||||
|
before-sleep 'swaylock -e -f -c 000000'
|
||||||
|
|
||||||
|
# Laptop lid switches
|
||||||
|
bindswitch --reload --locked lid:on output * disable
|
||||||
|
bindswitch --reload --locked lid:off output * enable
|
||||||
|
|
||||||
|
# Swaylock
|
||||||
|
bindsym Mod4+l exec swaylock -e -f -c 000000
|
||||||
|
|
||||||
|
# Solid black background
|
||||||
|
output * bg #000000 solid_color
|
||||||
|
|
||||||
|
# Prevent swayidle when a window is in fullscreen
|
||||||
|
for_window [class=".*"] inhibit_idle fullscreen
|
||||||
|
for_window [app_id=".*"] inhibit_idle fullscreen
|
||||||
|
display
|
||||||
|
|
||||||
|
# Polkit
|
||||||
|
cat > ~/.config/sway/config.d/zz-polkit <<- 'polkit'
|
||||||
|
exec "/usr/lib/polkit-kde-authentication-agent-1"
|
||||||
|
polkit
|
||||||
|
|
||||||
|
# Monitor
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
cat > ~/.config/sway/config.d/zz-virtualmonitor <<- 'monitor'
|
||||||
|
# Virtual monitor
|
||||||
|
output Virtual-1 {
|
||||||
|
pos 0,0
|
||||||
|
mode 1920x1080@60Hz
|
||||||
|
scale 1.25
|
||||||
|
}
|
||||||
|
monitor
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TTY sway autostart
|
||||||
|
cat >> ~/.bash_profile <<- 'sway'
|
||||||
|
|
||||||
|
# Start sway on login from tty
|
||||||
|
if [ -z "${WAYLAND_DISPLAY}" ] && [ "${XDG_VTNR}" = 1 ]
|
||||||
|
then
|
||||||
|
exec sway
|
||||||
|
fi
|
||||||
|
sway
|
||||||
|
;;
|
||||||
|
hyprland)
|
||||||
|
# Hyprland
|
||||||
|
mkdir -p ~/.config/{menus,hypr/scripts,foot,waybar}/
|
||||||
|
|
||||||
|
# Dolphin default apps
|
||||||
|
curl --fail -s -L https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
||||||
|
kbuildsycoca6 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Dolphin default terminal
|
||||||
|
cat >> ~/.config/kdeglobals <<- foot
|
||||||
|
[General]
|
||||||
|
TerminalApplication=footclient
|
||||||
|
foot
|
||||||
|
|
||||||
|
# Swayidle
|
||||||
|
install /dev/stdin ~/.config/hypr/scripts/sleep.sh <<- 'swayidle'
|
||||||
|
swayidle -w timeout 300 'swaylock -f -c 000000' \
|
||||||
|
timeout 600 'systemctl suspend' \
|
||||||
|
before-sleep 'swaylock -f -c 000000' &
|
||||||
|
swayidle
|
||||||
|
|
||||||
|
# Config
|
||||||
|
curl --silent --fail https://raw.githubusercontent.com/hyprwm/Hyprland/refs/heads/main/example/hyprland.conf |\
|
||||||
|
sed -e '/Autostart/i exec-once = /usr/lib/polkit-kde-authentication-agent-1' \
|
||||||
|
-e '/Autostart/i exec-once = waybar -c ~/.config/waybar/waybar.conf' \
|
||||||
|
-e '/Autostart/i exec-once = ~/.config/hypr/scripts/sleep.sh' \
|
||||||
|
-e '/^$terminal =/c $terminal = footclient' \
|
||||||
|
-e '/gaps_in =/c gaps_in = 0' \
|
||||||
|
-e '/gaps_out =/c gaps_out = 0' \
|
||||||
|
-e '/^$menu =/c $menu = bemenu-run -p "" --no-overlap --tb "##285577" --hb "##285577" --tf "##eeeeee" --hf "##eeeeee" --nf "##bbbbbb"' \
|
||||||
|
-e 's/bind = $mainMod, R, exec, $menu/bind = $mainMod, D, exec, $menu/' \
|
||||||
|
-e 's/bind = $mainMod, Q, exec, $terminal/bind = $mainMod, RETURN, exec, $terminal/' \
|
||||||
|
-e 's/bind = $mainMod, C, killactive/bind = $mainMod SHIFT, Q, killactive/' \
|
||||||
|
-e '/$mainMod =/c $mainMod = ALT' \
|
||||||
|
-e '/RETURN/a bind = SUPER, L, exec, swaylock -e -f -c 000000' \
|
||||||
|
> ~/.config/hypr/hyprland.conf
|
||||||
|
# -e '/Autostart/i exec-once = uwsm app -- foot --server' \
|
||||||
|
|
||||||
|
# QEMU monitor
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX\|virtio\|QEMU'
|
||||||
|
then
|
||||||
|
sed -i "/^monitor/c monitor = $(hyprctl monitors all | grep "^Monitor" | awk '{print $2}'), 1920x1080@60, 0x0, 1.5" ~/.config/hypr/hyprland.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Waybar
|
||||||
|
sed -e 's|sway/workspaces|sway/workspaces|g' \
|
||||||
|
-e 's|sway/mode|hyprland/submap|g' \
|
||||||
|
-e '/position/ s|//||' \
|
||||||
|
/etc/xdg/waybar/config.jsonc > ~/.config/waybar/waybar.conf
|
||||||
|
|
||||||
|
# TTY sway autostart
|
||||||
|
cat >> ~/.bash_profile <<- 'hyprland'
|
||||||
|
|
||||||
|
# Start sway on login from tty
|
||||||
|
if uwsm check may-start
|
||||||
|
then
|
||||||
|
exec uwsm start hyprland.desktop
|
||||||
|
fi
|
||||||
|
hyprland
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Foot terminal config (/etc/xdg/foot/foot.ini)
|
||||||
|
if [ -d ~/.config/foot/ ]
|
||||||
|
then
|
||||||
|
cat > ~/.config/foot/foot.ini <<- 'foot'
|
||||||
|
[main]
|
||||||
|
include=/usr/share/foot/themes/kitty
|
||||||
|
font=Source Code Pro:size=12
|
||||||
|
workers=32
|
||||||
|
|
||||||
|
[scrollback]
|
||||||
|
# lines=1000
|
||||||
|
foot
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add user to shared folder group if in virtualbox guest
|
||||||
|
if ls -l /dev/disk/* | grep -q VBOX
|
||||||
|
then
|
||||||
|
sudo gpasswd -a ${USER} vboxsf >/dev/null
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# iwd status function
|
||||||
|
if pacman -Q | grep -w -q iwd
|
||||||
|
then
|
||||||
|
cat > ~/.local/functions/iwd-status <<- iwd
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# iwd connection status
|
||||||
|
function iwd-status
|
||||||
|
{
|
||||||
|
iwctl station "$(iwctl station list | grep connected | awk '{print $(NF-1)}')" show
|
||||||
|
}
|
||||||
|
|
||||||
|
alias iwctl='iwctl station $(iwctl station list | grep connected | awk '{print $(NF-1)}')'
|
||||||
|
iwd
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${desktop_choice}" == "none" ]]
|
||||||
|
then
|
||||||
|
sudo rm -f ${0}
|
||||||
|
echo -e '\e[1;34mSetup complete, press any key to continue\e[5m...\e[0m\n'
|
||||||
|
read -n 1 -s -p ''
|
||||||
|
elif ls /usr/share/*sessions | grep -q desktop
|
||||||
|
then
|
||||||
|
install /dev/stdin ~/.local/bin/startup <<- 'EOF'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
vim ~/.local/bin/startupscript
|
||||||
|
~/.local/bin/startupscript
|
||||||
|
rm -f ${0}
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e '\n\e[31mNo internet connectivity detected'
|
||||||
|
echo -e 'Connect to a network and try again'
|
||||||
|
echo -e 'Aborting installer...\e[0m\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
EOF
|
||||||
|
|
||||||
|
install /dev/stdin ~/.local/bin/startupscript <<- EOF
|
||||||
|
$(curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/startup)
|
||||||
|
EOF
|
||||||
|
sudo rm -f ${0}
|
||||||
|
echo -e '\e[1;34mDesktop installed, press any key to load '${desktop_choice}'\e[5m...\e[0m'
|
||||||
|
read -n 1 -s -p ''
|
||||||
|
echo
|
||||||
|
else
|
||||||
|
die 'Something does not feel right'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Systemd services
|
||||||
|
for service in ${systemd_user_services[@]}
|
||||||
|
do
|
||||||
|
systemctl --quiet --user enable --now ${service}
|
||||||
|
done
|
||||||
|
sudo systemctl --quiet enable --now ${systemd_services[@]}
|
||||||
297
functions/startup
Executable file
297
functions/startup
Executable file
|
|
@ -0,0 +1,297 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# AUR package list
|
||||||
|
aur_list=(
|
||||||
|
# nomachine
|
||||||
|
# realvnc-vnc-viewer
|
||||||
|
# jdownloader2
|
||||||
|
# ledger-live-bin
|
||||||
|
# czkawka-gui-bin
|
||||||
|
)
|
||||||
|
|
||||||
|
# Optional packages list
|
||||||
|
optional=(
|
||||||
|
firefox firefox-decentraleyes firefox-ublock-origin
|
||||||
|
ark okular shotwell mpv ffmpegthumbs
|
||||||
|
veracrypt keepassxc
|
||||||
|
# nextcloud-client
|
||||||
|
# ntfs-3g exfatprogs
|
||||||
|
# libreoffice-fresh
|
||||||
|
# remmina libvncserver
|
||||||
|
# torbrowser-launcher
|
||||||
|
# thunderbird
|
||||||
|
# filezilla
|
||||||
|
# chromium
|
||||||
|
# vlc
|
||||||
|
# gnome-disk-utility
|
||||||
|
# xdg-user-dirs
|
||||||
|
# noto-fonts-cjk
|
||||||
|
# noto-fonts-emoji
|
||||||
|
)
|
||||||
|
|
||||||
|
function INSTALL
|
||||||
|
{
|
||||||
|
sudo pacman --sync ${@} --ask 4
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# VirtualBox
|
||||||
|
until [[ ${install_virtualbox} = [yYnN] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to install Virtualbox? (y/n): \e[0m' install_virtualbox
|
||||||
|
[[ ${install_virtualbox} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
# QEMU
|
||||||
|
until [[ ${install_qemu} = [yYnN] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to install QEMU? (y/n): \e[0m' install_qemu
|
||||||
|
[[ ${install_qemu} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Package groups installation
|
||||||
|
INSTALL ${optional[@]}
|
||||||
|
|
||||||
|
# Remmina
|
||||||
|
if [[ ${optional[@]} =~ "remmina" ]] && [ -d ~/.config/sway/config.d/ ]
|
||||||
|
then
|
||||||
|
# Remmina passthrough
|
||||||
|
cat > ~/.config/sway/config.d/zz-remmina <<- 'remmina'
|
||||||
|
# VNC passthrough
|
||||||
|
mode remmina {
|
||||||
|
bindsym Mod4+Shift+p mode default
|
||||||
|
}
|
||||||
|
bindsym Mod4+Shift+p mode remmina
|
||||||
|
remmina
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Tor
|
||||||
|
if [[ ${optional[@]} =~ "torbrowser-launcher" ]]
|
||||||
|
then
|
||||||
|
torbrowser-launcher
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Bluetooth
|
||||||
|
if pacman -Q | grep -q bluez-utils
|
||||||
|
then
|
||||||
|
INSTALL bluedevil
|
||||||
|
sudo systemctl --quiet enable --now bluetooth.service
|
||||||
|
fi
|
||||||
|
|
||||||
|
# AUR packages
|
||||||
|
if [ ${#aur_list[@]} -gt 0 ]
|
||||||
|
then
|
||||||
|
if ! pacman -Q | grep -q -w git
|
||||||
|
then
|
||||||
|
INSTALL git
|
||||||
|
fi
|
||||||
|
echo -e '#!/usr/bin/env bash' > ~/.local/functions/aur-packages
|
||||||
|
for aur_package in ${aur_list[@]}
|
||||||
|
do
|
||||||
|
cd
|
||||||
|
git clone https://aur.archlinux.org/${aur_package}.git
|
||||||
|
if echo ${aur_package} | grep -q nomachine
|
||||||
|
then
|
||||||
|
sed -i 's/_autoservice=n/_autoservice=y/' nomachine/PKGBUILD
|
||||||
|
sed -i 's/_autofirewall=n/_autofirewall=y/' nomachine/PKGBUILD
|
||||||
|
fi
|
||||||
|
cd ${aur_package}/
|
||||||
|
makepkg -csi
|
||||||
|
echo
|
||||||
|
cd ..
|
||||||
|
rm -r ${aur_package}/ -f
|
||||||
|
cat >> ~/.local/functions/aur-packages <<- aur
|
||||||
|
function aur-${aur_package}
|
||||||
|
{
|
||||||
|
cd ~/
|
||||||
|
git clone https://aur.archlinux.org/${aur_package}.git
|
||||||
|
cd ${aur_package}/
|
||||||
|
makepkg -csi
|
||||||
|
echo
|
||||||
|
cd ~/
|
||||||
|
rm -r ${aur_package}/ -f
|
||||||
|
}
|
||||||
|
|
||||||
|
aur
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Optional AUR extras
|
||||||
|
# freefilesync
|
||||||
|
# pdfsam
|
||||||
|
# fslint pygtk
|
||||||
|
|
||||||
|
# Printers
|
||||||
|
# yay -S --ask 4 print-manager cups system-config-printer skanlite && echo && sudo systemctl --quiet enable --now org.cups.cupsd && sudo gpasswd -a ${USER} sys >/dev/null
|
||||||
|
# Webcam
|
||||||
|
# sudo gpasswd -a ${USER} video >/dev/null
|
||||||
|
|
||||||
|
# i3
|
||||||
|
if [ -f ~/.config/i3/config ]
|
||||||
|
then
|
||||||
|
cat >> ~/.config/i3/config <<- 'config'
|
||||||
|
|
||||||
|
# gaps inner 8
|
||||||
|
# gaps outer 4
|
||||||
|
# for_window [class="^.*"] border pixel 2
|
||||||
|
config
|
||||||
|
|
||||||
|
cat > ~/.local/functions/i3-config <<- 'config'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# i3 config
|
||||||
|
function i3-config
|
||||||
|
{
|
||||||
|
vim ~/.config/i3/config
|
||||||
|
}
|
||||||
|
config
|
||||||
|
|
||||||
|
if [ -f /usr/share/xsessions/plasma-i3.desktop ]
|
||||||
|
then
|
||||||
|
tee -a ~/.config/i3/config >/dev/null <<- 'integration'
|
||||||
|
|
||||||
|
# >>> Plasma Integration <<<
|
||||||
|
# Try to kill the wallpaper set by Plasma (it takes up the entire workspace and hides everything)
|
||||||
|
exec --no-startup-id wmctrl -c Plasma
|
||||||
|
for_window [title="Desktop — Plasma"] kill; floating enable; border none
|
||||||
|
no_focus [class=”plasmashell”]
|
||||||
|
|
||||||
|
# Avoid tiling popups, dropdown windows from plasma
|
||||||
|
for_window [class="plasmashell"] floating enable
|
||||||
|
for_window [class="Plasma"] floating enable
|
||||||
|
for_window [class="krunner"] floating enable
|
||||||
|
for_window [class="Kmix"] floating enable
|
||||||
|
for_window [class="Klipper"] floating enable
|
||||||
|
for_window [class="Plasmoidviewer"] floating enable
|
||||||
|
|
||||||
|
# >>> Window Rules <<<
|
||||||
|
# >>> Avoid tiling for non-Plasma stuff <<<
|
||||||
|
for_window [window_role="pop-up"] floating enable
|
||||||
|
for_window [window_role="bubble"] floating enable
|
||||||
|
for_window [window_role="task_dialog"] floating enable
|
||||||
|
for_window [window_role="Preferences"] floating enable
|
||||||
|
for_window [window_role="About"] floating enable
|
||||||
|
for_window [window_type="dialog"] floating enable
|
||||||
|
for_window [window_type="menu"] floating enable
|
||||||
|
integration
|
||||||
|
|
||||||
|
install /dev/stdin ~/.local/bin/rotate-wallpapers <<- feh
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
sleep 1
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
feh --bg-max --randomize /home/${USER}/Pictures
|
||||||
|
sleep 15
|
||||||
|
done
|
||||||
|
feh
|
||||||
|
else
|
||||||
|
if ls -l /dev/disk/* | grep -q 'VBOX'
|
||||||
|
then
|
||||||
|
echo 'exec VBoxClient-all' >> ~/.config/i3/config
|
||||||
|
elif ls -l /dev/disk/* | grep -q 'virtio\|QEMU'
|
||||||
|
then
|
||||||
|
echo 'exec spice-vdagent' >> ~/.config/i3/config
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sway nextcloud
|
||||||
|
if [[ ${optional[@]} =~ "nextcloud-client" ]] && [ -f ~/.config/sway/config.d/zz-sway ]
|
||||||
|
then
|
||||||
|
cat > ~/.config/sway/config.d/zz-nextcloud <<- 'nextcloud'
|
||||||
|
# Nextcloud
|
||||||
|
exec nextcloud
|
||||||
|
for_window [title="Nextcloud Settings"] floating enable
|
||||||
|
nextcloud
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Virtualbox
|
||||||
|
if [[ ${install_virtualbox} = [yY] ]]
|
||||||
|
then
|
||||||
|
echo 'Installing Virtualbox'
|
||||||
|
|
||||||
|
if uname -r | grep -q 'lts\|hardened\|zen'
|
||||||
|
then
|
||||||
|
host_modules='virtualbox-host-dkms'
|
||||||
|
else
|
||||||
|
host_modules='virtualbox-host-modules-arch'
|
||||||
|
fi
|
||||||
|
|
||||||
|
INSTALL virtualbox ${host_modules} virtualbox-guest-iso
|
||||||
|
echo
|
||||||
|
|
||||||
|
sudo gpasswd -a ${USER} vboxusers >/dev/null
|
||||||
|
echo
|
||||||
|
|
||||||
|
if findmnt '/' | grep -q -w 'btrfs'
|
||||||
|
then
|
||||||
|
mkdir ~/VirtualBox\ VMs/
|
||||||
|
chattr +C ~/VirtualBox\ VMs/
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# QEMU
|
||||||
|
if [[ ${install_qemu} = [yY] ]]
|
||||||
|
then
|
||||||
|
echo 'Installing QEMU'
|
||||||
|
INSTALL qemu-desktop virt-manager edk2-ovmf \
|
||||||
|
dnsmasq dmidecode vde2 bridge-utils
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Make host system a pacman cache server
|
||||||
|
sudo tee /etc/systemd/system/local-cacheserver.service >/dev/null <<- 'CACHESERVER'
|
||||||
|
[Unit]
|
||||||
|
Description=Python HTTP server for Pacman Cache Server
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/bin/python3 -m http.server --directory /var/cache/pacman/pkg/ 9090
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
CACHESERVER
|
||||||
|
|
||||||
|
# Host iptables rules as a pacman cache server
|
||||||
|
sudo iptables -I INPUT -s 192.168.0.0/16 -p tcp -m tcp --dport 9090 -j ACCEPT -m comment --comment "Pacman cache server"
|
||||||
|
sudo sed -i '/## Simple Firewall/i\
|
||||||
|
# Pacman cache server\
|
||||||
|
-A INPUT -s 192.168.0.0/16 -p tcp -m tcp --dport 9090 -j ACCEPT -m comment --comment "Pacman cache server"\n' \
|
||||||
|
/etc/iptables/userinput.rules
|
||||||
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules | sudo tee /etc/iptables/iptables.rules >/dev/null
|
||||||
|
|
||||||
|
# QEMU pacman cache service
|
||||||
|
sudo tee /etc/systemd/system/local-update-virtpkg-cache.service >/dev/null <<- 'service'
|
||||||
|
[Unit]
|
||||||
|
Description=Refresh package cache twice daily
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/bash -c "/usr/bin/pacman -Syw -d --ask 4 $(curl --fail -s -L https://git.myvelabs.com/lab/archlinux/raw/branch/master/pkg/qemu)"
|
||||||
|
service
|
||||||
|
|
||||||
|
# QEMU pacman cache timer
|
||||||
|
sudo tee /etc/systemd/system/local-update-virtpkg-cache.timer >/dev/null <<- 'timer'
|
||||||
|
[Unit]
|
||||||
|
Description=Refresh pacman package cache
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-* 00/12:00:00
|
||||||
|
RandomizedDelaySec=12h
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
timer
|
||||||
|
|
||||||
|
# Enable services
|
||||||
|
sudo systemctl --quiet enable --now libvirtd.service
|
||||||
|
sudo systemctl --quiet enable local-cacheserver.service local-update-virtpkg-cache.timer
|
||||||
|
sudo virsh -q net-start default
|
||||||
|
sudo virsh -q net-autostart default
|
||||||
|
sudo gpasswd -a ${USER} libvirt >/dev/null
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
rm -f ${0}
|
||||||
|
echo -e '\e[1;32mSupplementary installer completed, reboot one last time\e[0m\n'
|
||||||
110
functions/user
Executable file
110
functions/user
Executable file
|
|
@ -0,0 +1,110 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
revision=0.1a
|
||||||
|
set -a
|
||||||
|
set -E
|
||||||
|
|
||||||
|
# Create local paths
|
||||||
|
mkdir -p ~/.local/{bin,functions}
|
||||||
|
|
||||||
|
# Generate ssh identity
|
||||||
|
ssh-keygen -q \
|
||||||
|
-t ed25519 \
|
||||||
|
-P "" \
|
||||||
|
-C "${username}@${hostname}" \
|
||||||
|
-f ~/.ssh/id_ed25519
|
||||||
|
mkdir ~/.ssh/sockets/
|
||||||
|
|
||||||
|
# Custom bashrc
|
||||||
|
cat > ~/.local/functions/bashrc <<- 'BASHRC'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Shell color
|
||||||
|
PS1="$(tput setaf 6)[\u@\h \W \$?]\$ $(tput sgr0)"
|
||||||
|
|
||||||
|
# Colored prompts
|
||||||
|
alias ll='ls --color=auto -l -a -h'
|
||||||
|
alias egrep='egrep --color=auto'
|
||||||
|
alias fgrep='fgrep --color=auto'
|
||||||
|
BASHRC
|
||||||
|
|
||||||
|
# Btrfs functions
|
||||||
|
if findmnt / | grep -w -q btrfs
|
||||||
|
then
|
||||||
|
cat > ~/.local/functions/btrfs <<- 'btrfs'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Btrfs check
|
||||||
|
function btrfs-check
|
||||||
|
{
|
||||||
|
sudo dmesg | grep -i btrfs
|
||||||
|
}
|
||||||
|
# # Snapper
|
||||||
|
# function snapshot-home
|
||||||
|
# {
|
||||||
|
# if [ "${*}" ]
|
||||||
|
# then
|
||||||
|
# sudo snapper -c home create --description "${*}"
|
||||||
|
# else
|
||||||
|
# sudo snapper -c home create --description "$(date)"
|
||||||
|
# fi
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# function snapshot-root
|
||||||
|
# {
|
||||||
|
# if [ "${*}" ]
|
||||||
|
# then
|
||||||
|
# sudo snapper -c root create --description "${*}"
|
||||||
|
# else
|
||||||
|
# sudo snapper -c root create --description "$(date)"
|
||||||
|
# fi
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# function snapshot-list
|
||||||
|
# {
|
||||||
|
# sudo -v
|
||||||
|
# echo -e '\n\e[1;33mRoot snapshots:\e[0m'
|
||||||
|
# sudo snapper -c root ls
|
||||||
|
# echo -e '\n\e[1;33mHome snapshots:\e[0m'
|
||||||
|
# sudo snapper -c home ls
|
||||||
|
# echo
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# function snapshot-delete
|
||||||
|
# {
|
||||||
|
# if ! grep -w -q 'root\|home' <<< "${1}" || [ -z "${2}" ]
|
||||||
|
# then
|
||||||
|
# echo -e '\n\t\e[1;31mInvalid option, use syntax: ${root,home} $snapshot\e[0m\n'
|
||||||
|
# return 1
|
||||||
|
# elif grep -w -q '1' <<< "${2}"
|
||||||
|
# then
|
||||||
|
# echo -e '\n\t\e[1;31mUnable to delete "fresh install" snapshot\e[0m\n'
|
||||||
|
# return 1
|
||||||
|
# fi
|
||||||
|
#
|
||||||
|
# if [[ "${1}" = "root" ]]
|
||||||
|
# then
|
||||||
|
# if ls /.snapshots | grep -q $(sed -e 's/-/\\\|/g' <<< "${2}")
|
||||||
|
# then
|
||||||
|
# sudo snapper -c root delete "${2}"
|
||||||
|
# elif ! [ -d /.snapshots/"${2}" ]
|
||||||
|
# then
|
||||||
|
# echo -e '\n\t\e[1;31mSnapshot doesn't exist, try again\e[0m\n'
|
||||||
|
# fi
|
||||||
|
# elif [[ "${1}" = "home" ]]
|
||||||
|
# then
|
||||||
|
# if ls /home/.snapshots | grep -q $(sed -e 's/-/\\\|/g' <<< "${2}")
|
||||||
|
# then
|
||||||
|
# sudo snapper -c home delete "${2}"
|
||||||
|
# elif ! [ -d /home/.snapshots/"${2}" ]
|
||||||
|
# then
|
||||||
|
# echo -e '\n\t\e[1;31mSnapshot doesn't exist, try again\e[0m\n'
|
||||||
|
# fi
|
||||||
|
# fi
|
||||||
|
# }
|
||||||
|
btrfs
|
||||||
|
fi
|
||||||
|
|
||||||
|
if pacman -Q | grep -q yubikey
|
||||||
|
then
|
||||||
|
install /dev/stdin ~/yksetup.sh <<- 'yubikey'
|
||||||
|
$(curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/functions/yubikey)
|
||||||
|
yubikey
|
||||||
|
fi
|
||||||
86
functions/yubikey
Executable file
86
functions/yubikey
Executable file
|
|
@ -0,0 +1,86 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
echo
|
||||||
|
|
||||||
|
[ -d ~/.config/Yubico ] || mkdir -p ~/.config/Yubico
|
||||||
|
|
||||||
|
sudo pacman -S --ask 4 pam-u2f yubico-pam
|
||||||
|
|
||||||
|
read -n 1 -s -p $'\n\e[1;33mInsert your yubikey and press the enter key to continue \e[0m'
|
||||||
|
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||||
|
|
||||||
|
pamu2fcfg > ~/.config/Yubico/u2f_keys
|
||||||
|
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
|
||||||
|
until [[ "$YUBIKEY" = [nN] ]]
|
||||||
|
do
|
||||||
|
if [[ "$YUBIKEY" != [yYnN] ]]
|
||||||
|
then
|
||||||
|
echo -e '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||||
|
read -n 1 -p $'\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
elif [[ "$YUBIKEY" = [yY] ]]
|
||||||
|
then
|
||||||
|
read -n 1 -s -p $'\n\n\e[1;33mInsert the next yubikey and press the enter key to continue \e[0m'
|
||||||
|
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||||
|
|
||||||
|
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||||
|
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e '\n\n\e[1;33mUpdating pam configs'
|
||||||
|
echo -e 'Open another terminal or tty and login as sudo in case an issue comes up'
|
||||||
|
read -n 1 -s -p $'Press the enter key once logged in as sudo in another terminal or tty \e[0m\n'
|
||||||
|
|
||||||
|
# System wide user authentication
|
||||||
|
sudo sed -i '/^auth .* required .* pam_faillock.so .* authsucc/a\
|
||||||
|
auth required pam_u2f.so' /etc/pam.d/system-auth
|
||||||
|
|
||||||
|
# Polkit authentication
|
||||||
|
sudo sed -i '/^#%PAM.*/a\
|
||||||
|
auth sufficient pam_u2f.so' /etc/pam.d/polkit-1
|
||||||
|
|
||||||
|
# Sudo authentication
|
||||||
|
sudo sed -i '/^#%PAM.*/a\
|
||||||
|
auth sufficient pam_u2f.so' /etc/pam.d/sudo
|
||||||
|
|
||||||
|
# KDE lockscreen authentication
|
||||||
|
sudo sed -i '/^#%PAM.*/a\
|
||||||
|
auth required pam_u2f.so' /etc/pam.d/kde
|
||||||
|
|
||||||
|
cat > ~/.local/functions/add-yubikey <<- 'ADDYUBIKEY'
|
||||||
|
# Add a new yubikey
|
||||||
|
function add-yubikey
|
||||||
|
{
|
||||||
|
read -n 1 -s -p $'\n\e[1;33mInsert your yubikey and press the enter key to continue \e[0m'
|
||||||
|
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||||
|
|
||||||
|
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||||
|
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
until [[ "$YUBIKEY" = [nN] ]]
|
||||||
|
do
|
||||||
|
if [[ "$YUBIKEY" != [yYnN] ]]
|
||||||
|
then
|
||||||
|
echo -e '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||||
|
read -n 1 -p $'\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
elif [[ "$YUBIKEY" = [yY] ]]
|
||||||
|
then
|
||||||
|
read -n 1 -s -p $'\n\n\e[1;33mInsert the next yubikey and press the enter key to continue \e[0m'
|
||||||
|
echo -e '\n\e[1mTouch the yubikey when it starts blinking\e[0m'
|
||||||
|
|
||||||
|
pamu2fcfg -n >> ~/.config/Yubico/u2f_keys
|
||||||
|
|
||||||
|
read -n 1 -p $'\n\e[1mWould you like to add another yubikey? (y/n): \e[0m' YUBIKEY
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo -e '\n\n\e[1;34mYubikeys updated'
|
||||||
|
echo -e 'Exiting...\e[0m\n'
|
||||||
|
}
|
||||||
|
ADDYUBIKEY
|
||||||
|
|
||||||
|
echo -e '\n\e[1;34mYubikey setup completed'
|
||||||
|
echo -e 'To update your saved yubikeys, run "add-yubikey" in the terminal'
|
||||||
|
echo -e 'Exiting...\e[0m\n'
|
||||||
|
rm -f ${0}
|
||||||
2315
homelab.sh
Executable file
2315
homelab.sh
Executable file
File diff suppressed because it is too large
Load diff
67
installer.sh
Executable file
67
installer.sh
Executable file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
download_url=git.myvelabs.com/lab/archlinux/raw/branch/master
|
||||||
|
|
||||||
|
# Detect network connectivity
|
||||||
|
if ! nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || ! nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
echo -e '\n\t\e[31mNo internet connection detected\e[0m\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Function to list available script options
|
||||||
|
function listScripts
|
||||||
|
{
|
||||||
|
echo -e '\n\e[1;36mSelect a script to run\e[0m
|
||||||
|
1) Arch Linux
|
||||||
|
2) Arch Linux VM
|
||||||
|
3) Arch Linux Passthrough
|
||||||
|
4) Arch Linux Server
|
||||||
|
5) Recovery'
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -n 1 -p '> ' script_selection
|
||||||
|
case ${script_selection} in
|
||||||
|
1) script=arch
|
||||||
|
break;;
|
||||||
|
2) script=virtual-machine
|
||||||
|
break;;
|
||||||
|
3) script=passthrough
|
||||||
|
break;;
|
||||||
|
4) script=homelab
|
||||||
|
break;;
|
||||||
|
5) script=recover
|
||||||
|
break;;
|
||||||
|
*) echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 5\e[0m'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect script choice
|
||||||
|
case ${1} in
|
||||||
|
arch)
|
||||||
|
script=arch ;;
|
||||||
|
vm|virtual-machine)
|
||||||
|
script=virtual-machine ;;
|
||||||
|
passthrough)
|
||||||
|
script=passthrough ;;
|
||||||
|
server|homelab)
|
||||||
|
script=homelab ;;
|
||||||
|
recover)
|
||||||
|
script=recover ;;
|
||||||
|
*)
|
||||||
|
listScripts ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Run script if successful, abort installer otherwise
|
||||||
|
if curl --fail -s -L https://${download_url}/${script}.sh -o ./arch
|
||||||
|
then
|
||||||
|
/usr/bin/bash ./arch "${@:2}"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e '\e[31mInvalid script or server may be offline, make another selection or try again later\e[0m\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
1582
notes/archvps.sh
Executable file
1582
notes/archvps.sh
Executable file
File diff suppressed because it is too large
Load diff
12
notes/sshkeys.pub
Normal file
12
notes/sshkeys.pub
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHGQ2rLYB6U2i3dyb1+Fn8fKSsfsTno87Vf++yFQkD2k user@zenbook
|
||||||
|
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFPJnaY1RtJ+JdfAEJfUcO99yrSGuH0UQit0itzrpgeI user@dotfiles
|
||||||
|
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA5Zwmxt3kTIZT9fsQW+NCcTRYFz97Qp+hXbj7AcJXi6 root@mini
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIES0RiFcV2yoLwNrK6iB3xU3OlQ85vAWgxjoNaG3iuMp root@phone
|
||||||
|
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUz2KdC9MWYLwYgGfjdxPGd0XZbdRLUJog4IbWp9EZl user@myvelabs
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGlaVV3oZo/IAGXF3F9qdaiSRTQLzc2aJ50h3MNdLUmI root@myvelabs
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIAnDy15V5hT9+TX/gZeEpStamJOJNpruKdx3PXpcIX6 user@docker
|
||||||
|
|
||||||
|
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDmgC/c0Rjyk6sL+PXhuxOfaBVw/sPTrWfX5GBGwqq/g user@desktop
|
||||||
48
notes/ubuntu-nginx
Normal file
48
notes/ubuntu-nginx
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Ubuntu - nginx-mainline
|
||||||
|
# https://nginx.org/en/linux_packages.html
|
||||||
|
|
||||||
|
# Install the prerequisites:
|
||||||
|
|
||||||
|
sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y
|
||||||
|
|
||||||
|
# Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key:
|
||||||
|
|
||||||
|
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
|
||||||
|
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
|
||||||
|
|
||||||
|
# Verify that the downloaded file contains the proper key:
|
||||||
|
|
||||||
|
gpg --dry-run --quiet --no-keyring --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg \
|
||||||
|
| grep -q 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 || exit 1
|
||||||
|
|
||||||
|
# The output should contain the full fingerprint 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 as follows:
|
||||||
|
#
|
||||||
|
# pub rsa2048 2011-08-19 [SC] [expires: 2027-05-24]
|
||||||
|
# 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
|
||||||
|
# uid nginx signing key <signing-key@nginx.com>
|
||||||
|
|
||||||
|
# Note that the output can contain other keys used to sign the packages.
|
||||||
|
|
||||||
|
# # To set up the apt repository for stable nginx packages, run the following command:
|
||||||
|
#
|
||||||
|
# echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||||
|
# http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
|
||||||
|
# | sudo tee /etc/apt/sources.list.d/nginx.list
|
||||||
|
|
||||||
|
# If you would like to use mainline nginx packages, run the following command instead:
|
||||||
|
|
||||||
|
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \
|
||||||
|
http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \
|
||||||
|
| sudo tee /etc/apt/sources.list.d/nginx.list
|
||||||
|
|
||||||
|
# Set up repository pinning to prefer our packages over distribution-provided ones:
|
||||||
|
|
||||||
|
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
|
||||||
|
| sudo tee /etc/apt/preferences.d/99nginx
|
||||||
|
|
||||||
|
# To install nginx, run the following commands:
|
||||||
|
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install nginx -y
|
||||||
73
notes/wireguard
Normal file
73
notes/wireguard
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
############
|
||||||
|
# Key generation
|
||||||
|
############
|
||||||
|
for peer in {0..9}
|
||||||
|
do
|
||||||
|
wg genkey | (umask 0077 && tee peer${peer}.key) | wg pubkey > peer${peer}.pub
|
||||||
|
done
|
||||||
|
|
||||||
|
############
|
||||||
|
# Server configuration
|
||||||
|
############
|
||||||
|
/etc/wireguard/wg0.conf
|
||||||
|
############
|
||||||
|
[Interface]
|
||||||
|
Address = 10.200.200.1/24
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = SERVER_PRIVATE_KEY
|
||||||
|
|
||||||
|
# substitute eth0 in the following lines to match the Internet-facing interface
|
||||||
|
# the FORWARD rules will always be needed since traffic needs to be forwarded between the WireGuard
|
||||||
|
# interface and the other interfaces on the server.
|
||||||
|
# if the server is behind a router and receives traffic via NAT, specify static routing back to the
|
||||||
|
# 10.200.200.0/24 subnet, the NAT iptables rules are not needed but the FORWARD rules are needed.
|
||||||
|
# if the server is behind a router and receives traffic via NAT but one cannot specify static routing back to
|
||||||
|
# 10.200.200.0/24 subnet, both the NAT and FORWARD iptables rules are needed.
|
||||||
|
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||||
|
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# foo
|
||||||
|
PublicKey = PEER_FOO_PUBLIC_KEY
|
||||||
|
PresharedKey = PRE-SHARED_KEY
|
||||||
|
AllowedIPs = 10.200.200.2/32
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
# bar
|
||||||
|
PublicKey = PEER_BAR_PUBLIC_KEY
|
||||||
|
PresharedKey = PRE-SHARED_KEY
|
||||||
|
AllowedIPs = 10.200.200.3/32
|
||||||
|
|
||||||
|
###
|
||||||
|
# The interface may be brought up using wg-quick up wg0 respectively by starting and potentially enabling the interface via wg-quick@interface.service, e.g. wg-quick@wg0.service. To close the interface use wg-quick down wg0 respectively stop wg-quick@interface.service.
|
||||||
|
###
|
||||||
|
|
||||||
|
############
|
||||||
|
# Client configuration
|
||||||
|
############
|
||||||
|
foo.conf
|
||||||
|
[Interface]
|
||||||
|
Address = 10.200.200.2/32
|
||||||
|
PrivateKey = PEER_FOO_PRIVATE_KEY
|
||||||
|
DNS = 10.200.200.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SERVER_PUBLICKEY
|
||||||
|
PresharedKey = PRE-SHARED_KEY
|
||||||
|
Endpoint = my.ddns.example.com:51820
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
bar.conf
|
||||||
|
[Interface]
|
||||||
|
Address = 10.200.200.3/32
|
||||||
|
PrivateKey = PEER_BAR_PRIVATE_KEY
|
||||||
|
DNS = 10.200.200.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = SERVER_PUBLICKEY
|
||||||
|
PresharedKey = PRE-SHARED KEY
|
||||||
|
Endpoint = my.ddns.example.com:51820
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
|
||||||
|
###
|
||||||
|
# Note: Users of NetworkManager, may need to enable the NetworkManager-wait-online.service and users of systemd-networkd may need to enable the systemd-networkd-wait-online.service to wait until devices are network-ready before attempting a WireGuard connection.
|
||||||
|
###
|
||||||
782
passthrough.sh
Executable file
782
passthrough.sh
Executable file
|
|
@ -0,0 +1,782 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -a
|
||||||
|
set -E
|
||||||
|
|
||||||
|
# SSH public keys
|
||||||
|
sshkeys=''
|
||||||
|
|
||||||
|
## Tput codes
|
||||||
|
reset=$(tput sgr0)
|
||||||
|
|
||||||
|
bold=$(tput bold)
|
||||||
|
italic=$(tput sitm)
|
||||||
|
blink=$(tput blink)
|
||||||
|
|
||||||
|
black=${reset}$(tput setaf 0)
|
||||||
|
red=${reset}$(tput setaf 1)
|
||||||
|
green=${reset}$(tput setaf 2)
|
||||||
|
yellow=${reset}$(tput setaf 3)
|
||||||
|
blue=${reset}$(tput setaf 4)
|
||||||
|
magenta=${reset}$(tput setaf 5)
|
||||||
|
cyan=${reset}$(tput setaf 6)
|
||||||
|
white=${reset}$(tput setaf 7)
|
||||||
|
|
||||||
|
# Color codes
|
||||||
|
function say
|
||||||
|
{
|
||||||
|
for format in ${@:2}
|
||||||
|
do
|
||||||
|
echo -n ${!format}
|
||||||
|
done
|
||||||
|
echo -e "${1}"
|
||||||
|
echo -n ${reset}
|
||||||
|
}
|
||||||
|
function say_n
|
||||||
|
{
|
||||||
|
for format in ${@:2}
|
||||||
|
do
|
||||||
|
echo -n ${!format}
|
||||||
|
done
|
||||||
|
echo -e -n "${1}"
|
||||||
|
echo -n ${reset}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Exit function
|
||||||
|
trap '[ "$?" -ne 77 ] || exit 77' ERR
|
||||||
|
function die
|
||||||
|
{
|
||||||
|
cat <<- abort
|
||||||
|
${red}
|
||||||
|
Error encountered for the following reason:
|
||||||
|
${yellow}
|
||||||
|
"${1}"
|
||||||
|
${red}
|
||||||
|
Script aborted...
|
||||||
|
${reset}
|
||||||
|
abort
|
||||||
|
exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
timedatectl set-ntp true
|
||||||
|
else
|
||||||
|
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||||
|
fi
|
||||||
|
|
||||||
|
function returnUUID
|
||||||
|
{
|
||||||
|
for partuuid in \
|
||||||
|
$(blkid -s UUID -o value ${1}) \
|
||||||
|
$(lsblk -d -n -o uuid ${1}) \
|
||||||
|
$(ls -l -a /dev/disk/by-uuid | grep "$(echo ${1} | sed 's\/dev\\')" | awk '{print $9}')
|
||||||
|
do
|
||||||
|
if [ ${partuuid} ]
|
||||||
|
then
|
||||||
|
echo ${partuuid}
|
||||||
|
break
|
||||||
|
else
|
||||||
|
unset partuuid
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z ${partuuid} ]
|
||||||
|
then
|
||||||
|
die 'Unable to determine partition UUID'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
cat <<title
|
||||||
|
${black}${bold}## rev ${revision}${reset}
|
||||||
|
${blue}${bold}
|
||||||
|
Arch Passthrough
|
||||||
|
${reset}${bold}
|
||||||
|
Press any key when ready...${reset}
|
||||||
|
title
|
||||||
|
read -n 1 -s
|
||||||
|
echo
|
||||||
|
|
||||||
|
if ls -l /dev/disk/* | grep -q 'virtio'
|
||||||
|
then
|
||||||
|
installation_disk='vda'
|
||||||
|
elif ls -l /dev/disk/* | grep -q 'QEMU'
|
||||||
|
then
|
||||||
|
installation_disk='sda'
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Hostname
|
||||||
|
say "Create a name for your computer" blue
|
||||||
|
until [ ${hostname} ]
|
||||||
|
do
|
||||||
|
read -r -p 'Hostname: ' hostname
|
||||||
|
echo
|
||||||
|
[ ${hostname} ] || say "Hostname cannot be empty, try again" red
|
||||||
|
done
|
||||||
|
|
||||||
|
# User password
|
||||||
|
say "Set a password for user" blue
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -s -r -p 'User password: ' userpass
|
||||||
|
echo
|
||||||
|
|
||||||
|
read -s -r -p 'Verify user password: ' userpass2
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ -z ${userpass} ] || [ "${userpass}" = "${userpass2}" ]
|
||||||
|
then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
say "Passwords did not match, try again" red
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
say "user@${hostname}'s password has been saved" green
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Superuser password
|
||||||
|
say "Create a root superuser password" blue
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -s -r -p 'Superuser password: ' rootpass
|
||||||
|
echo
|
||||||
|
|
||||||
|
read -s -r -p $'Verify superuser password: ' rootpass2
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
|
||||||
|
if [ -z ${rootpass} ] || [ "${rootpass}" = "${rootpass2}" ]
|
||||||
|
then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
say "Passwords did not match, try again" red
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
say "Root superuser password has been saved" green
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Assign system drive
|
||||||
|
say "Identify the system drive from the list of available devices below" blue
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||||
|
say '## SSD and HDD device format begins with "sd" or "hd" (sda, sdb, sd[*])
|
||||||
|
## NVME and PCI device format is "nvme[*]n1" (nvme0n1, nvme1n1, nvme[*]n1)' black bold
|
||||||
|
lsblk -o name | grep -q -w ${installation_disk} ||
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -r -p 'Installation device: ' installation_disk
|
||||||
|
|
||||||
|
if [ ${installation_disk} ] && lsblk -o name | grep -q -w ${installation_disk}
|
||||||
|
then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||||
|
if [ -z ${installation_disk} ]
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
say "Field cannot be empty, try again" red
|
||||||
|
else
|
||||||
|
echo
|
||||||
|
say "Invalid selection or drive not available, try again" red
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
say "Installation drive set as ${green}${reset}/dev/${installation_disk}" reset
|
||||||
|
|
||||||
|
# Choose a linux kernel
|
||||||
|
cat <<menu
|
||||||
|
${blue}
|
||||||
|
Select a linux kernel version${reset}
|
||||||
|
1) linux
|
||||||
|
2) linux-lts
|
||||||
|
3) linux-hardened
|
||||||
|
4) linux-zen
|
||||||
|
menu
|
||||||
|
|
||||||
|
until [[ ${kernel_choice} = [1-4] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p '> ' kernel_choice
|
||||||
|
echo
|
||||||
|
if ! [[ ${kernel_choice} = [1-4] ]]
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
say 'Invalid selection, type an option from 1 to 4' red
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
case ${kernel_choice} in
|
||||||
|
1)
|
||||||
|
linux_kernel='linux'
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
linux_kernel='linux-lts'
|
||||||
|
;;
|
||||||
|
3)
|
||||||
|
linux_kernel='linux-hardened'
|
||||||
|
;;
|
||||||
|
4)
|
||||||
|
linux_kernel='linux-zen'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
echo
|
||||||
|
say " You have chosen ${green}${linux_kernel}${reset} as a kernel" reset
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Unmount if mounted
|
||||||
|
if findmnt '/mnt' | grep -q -w '/mnt'
|
||||||
|
then
|
||||||
|
umount -R /mnt
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Shred installation drive
|
||||||
|
say "Partitioning /dev/${installation_disk}" yellow bold
|
||||||
|
wipefs -f -a /dev/${installation_disk}
|
||||||
|
blkdiscard -f /dev/${installation_disk}
|
||||||
|
if [ -d /sys/firmware/efi/efivars ]
|
||||||
|
then
|
||||||
|
parted --script --align=optimal /dev/${installation_disk} \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart primary fat32 1MiB 100MiB \
|
||||||
|
mkpart primary ${partition} 100MiB 100% \
|
||||||
|
set 1 esp on
|
||||||
|
partprobe /dev/${installation_disk}
|
||||||
|
export {efivol,bootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*1$)
|
||||||
|
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*2$)
|
||||||
|
echo
|
||||||
|
|
||||||
|
function bootLoader
|
||||||
|
{
|
||||||
|
# Systemd-boot
|
||||||
|
say "Configuring systemd-boot" yellow bold
|
||||||
|
bootctl --path=/boot install
|
||||||
|
echo -e 'title Arch Linux
|
||||||
|
linux /vmlinuz-'${linux_kernel}'
|
||||||
|
initrd /initramfs-'${linux_kernel}'.img
|
||||||
|
options quiet root=UUID='$(returnUUID ${rootpart})' rw' > /boot/loader/entries/arch.conf
|
||||||
|
echo -e 'default arch
|
||||||
|
timeout 0
|
||||||
|
console-mode max
|
||||||
|
editor no' > /boot/loader/loader.conf
|
||||||
|
systemdbootservice='systemd-boot-update.service'
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bios='syslinux'
|
||||||
|
parted --script --align=optimal /dev/${installation_disk} \
|
||||||
|
mklabel msdos \
|
||||||
|
mkpart primary ${partition} 1MiB 100% \
|
||||||
|
set 1 boot on || die 'Disk partitioning failed'
|
||||||
|
partprobe /dev/${installation_disk}
|
||||||
|
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}".*1$)
|
||||||
|
echo
|
||||||
|
|
||||||
|
function bootLoader
|
||||||
|
{
|
||||||
|
# Syslinux
|
||||||
|
say "Configuring syslinux" yellow bold
|
||||||
|
syslinux-install_update -i -a -m
|
||||||
|
sed -i 's\LINUX ../vmlinuz-linux.*\LINUX ../vmlinuz-'${linux_kernel}'\g' /boot/syslinux/syslinux.cfg
|
||||||
|
sed -i 's/APPEND root.*/APPEND root=UUID='"$(returnUUID ${rootpart})"' rw quiet/g' /boot/syslinux/syslinux.cfg
|
||||||
|
sed -i 's/.*PROMPT.*/PROMPT 0/g' /boot/syslinux/syslinux.cfg
|
||||||
|
sed -i 's/.*TIMEOUT.*/TIMEOUT 0/g' /boot/syslinux/syslinux.cfg
|
||||||
|
sed -i 's/.*UI menu.*/#UI menu/g' /boot/syslinux/syslinux.cfg
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
say "Configuring volumes" yellow bold
|
||||||
|
yes | mkfs.ext4 ${rootvol}
|
||||||
|
mount ${rootvol} /mnt
|
||||||
|
|
||||||
|
if [ -d /sys/firmware/efi/efivars ]
|
||||||
|
then
|
||||||
|
mkdir /mnt/boot
|
||||||
|
yes | mkfs.fat -F 32 ${efivol}
|
||||||
|
mount ${bootvol} /mnt/boot
|
||||||
|
findmnt '/mnt/boot' | grep -q -w "${bootvol}" || die 'Boot partition has not been mounted properly'
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
say "Installing Arch Linux base packages on /dev/${installation_disk}" yellow bold
|
||||||
|
sed -i \
|
||||||
|
-e '/Color/c\Color' \
|
||||||
|
-e '/ParallelDownloads/c\ParallelDownloads = 10' \
|
||||||
|
-e 's#^\[core\]$\|^\[extra\]$#&\
|
||||||
|
CacheServer = http://192.168.122.1:9090#' \
|
||||||
|
/etc/pacman.conf
|
||||||
|
|
||||||
|
# Temporarily disable mkinitcpio
|
||||||
|
ln -s -f /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
|
||||||
|
|
||||||
|
pacstrap -K /mnt ${linux_kernel} qemu-guest-agent base mkinitcpio sudo \
|
||||||
|
${bios} reflector openssh rsync \
|
||||||
|
wireguard-tools systemd-resolvconf \
|
||||||
|
pacman-contrib bash-completion vim
|
||||||
|
|
||||||
|
genfstab -U -p /mnt >> /mnt/etc/fstab
|
||||||
|
grep -q 'UUID' /mnt/etc/fstab || die
|
||||||
|
|
||||||
|
# Make custom directories
|
||||||
|
mkdir -p /mnt/etc/pacman.d/hooks /mnt/usr/bin/local
|
||||||
|
|
||||||
|
# pacman.conf hook
|
||||||
|
install /dev/stdin /mnt/usr/bin/local/hook-pacman.conf <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/pacman.conf.pacnew ]
|
||||||
|
then
|
||||||
|
sed -i \\
|
||||||
|
-e '/Color/c\Color' \\
|
||||||
|
-e '/ParallelDownloads/c\ParallelDownloads = 10' \\
|
||||||
|
-e 's#^\[core\]$\|^\[extra\]\$#&\\
|
||||||
|
CacheServer = http://192.168.122.1:9090#' /etc/pacman.conf.pacnew
|
||||||
|
mv /etc/pacman.conf.pacnew /etc/pacman.conf
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
|
||||||
|
cat >/mnt/etc/pacman.d/hooks/pacman.conf.hook <<pacman
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = pacman
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing pacman.conf
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/local/hook-pacman.conf
|
||||||
|
pacman
|
||||||
|
sed -i \
|
||||||
|
-e '/Color/c\Color' \
|
||||||
|
-e '/ParallelDownloads/c\ParallelDownloads = 10' \
|
||||||
|
-e 's#^\[core\]$\|^\[extra\]$#&\
|
||||||
|
CacheServer = http://192.168.122.1:9090#' \
|
||||||
|
/mnt/etc/pacman.conf
|
||||||
|
|
||||||
|
# Manually configure mkinitcpio
|
||||||
|
sed -e "s|%PKGBASE%|linux|g" \
|
||||||
|
-e "s/^fallback/#&/g" \
|
||||||
|
-e "s/ 'fallback'//" \
|
||||||
|
/mnt/usr/share/mkinitcpio/hook.preset >/mnt/etc/mkinitcpio.d/linux.preset
|
||||||
|
rm /mnt/usr/share/mkinitcpio/hook.preset
|
||||||
|
rsync -a /mnt/usr/lib/modules/*/vmlinuz /mnt/boot/vmlinuz-linux
|
||||||
|
|
||||||
|
# mkinitcpio preset hook
|
||||||
|
cat >/mnt/etc/pacman.d/hooks/linux.preset.hook <<preset
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = mkinitcpio
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Updating mkinitcpio linux preset
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/local/hook-linux.preset
|
||||||
|
preset
|
||||||
|
install /dev/stdin /mnt/usr/bin/local/hook-linux.preset <<'hook'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /usr/share/mkinitcpio/hook.preset ]
|
||||||
|
then
|
||||||
|
sed \
|
||||||
|
-e "s|%PKGBASE%|linux|g" \
|
||||||
|
-e "s/^fallback/#&/g" \
|
||||||
|
-e "s/ 'fallback'//" \
|
||||||
|
/usr/share/mkinitcpio/hook.preset >/etc/mkinitcpio.d/linux.preset
|
||||||
|
rm /usr/share/mkinitcpio/hook.preset
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
|
||||||
|
arch-chroot /mnt mkinitcpio -P
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
ln -s -f /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
|
||||||
|
rsync -a /etc/systemd/network/20-ethernet.network /mnt/etc/systemd/network
|
||||||
|
|
||||||
|
arch-chroot /mnt /bin/bash <<"SYU"
|
||||||
|
# Install bootloader
|
||||||
|
echo
|
||||||
|
bootLoader
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Locale
|
||||||
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
echo 'LANG=en_US.UTF-8' >>/etc/locale.conf
|
||||||
|
say 'Locale configured' yellow bold
|
||||||
|
|
||||||
|
# Time zone
|
||||||
|
ln -s -f /usr/share/zoneinfo/UTC /etc/localtime
|
||||||
|
hwclock --systohc --utc
|
||||||
|
say 'Time zone configured' yellow bold
|
||||||
|
|
||||||
|
# Hostname
|
||||||
|
echo ${hostname} >/etc/hostname
|
||||||
|
cat >>/etc/hosts <<HOSTS
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 ${hostname}
|
||||||
|
HOSTS
|
||||||
|
say 'Hostname configured' yellow bold
|
||||||
|
|
||||||
|
# User and superuser
|
||||||
|
useradd -m -g users -G wheel -s /bin/bash user || die
|
||||||
|
if [ ${userpass} ]
|
||||||
|
then
|
||||||
|
printf '%s\n' ${userpass} ${userpass} | passwd user &>/dev/null
|
||||||
|
echo '%wheel ALL=(ALL:ALL) ALL' > /etc/sudoers.d/wheel
|
||||||
|
else
|
||||||
|
echo -e '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' > /etc/sudoers.d/wheel
|
||||||
|
mkdir -p /etc/systemd/system/getty@tty1.service.d
|
||||||
|
echo '[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=-/usr/bin/agetty --autologin user --noclear %I $TERM' > /etc/systemd/system/getty@tty1.service.d/override.conf
|
||||||
|
fi
|
||||||
|
if [ "$rootpass" ]
|
||||||
|
then
|
||||||
|
printf '%s\n' "$rootpass" "$rootpass" | passwd &>/dev/null
|
||||||
|
fi
|
||||||
|
say "Configured superuser and user" yellow bold
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Sysctl custom settings
|
||||||
|
echo -e 'net.core.netdev_max_backlog = 16384
|
||||||
|
net.core.somaxconn = 8192
|
||||||
|
net.core.rmem_default = 1048576
|
||||||
|
net.core.rmem_max = 16777216
|
||||||
|
net.core.wmem_default = 1048576
|
||||||
|
net.core.wmem_max = 16777216
|
||||||
|
net.core.optmem_max = 65536
|
||||||
|
net.ipv4.tcp_rmem = 4096 1048576 2097152
|
||||||
|
net.ipv4.tcp_wmem = 4096 65536 16777216
|
||||||
|
net.ipv4.udp_rmem_min = 8192
|
||||||
|
net.ipv4.udp_wmem_min = 8192
|
||||||
|
net.ipv4.tcp_fastopen = 3
|
||||||
|
net.ipv4.tcp_timestamps = 0
|
||||||
|
net.core.default_qdisc = cake
|
||||||
|
net.ipv4.tcp_congestion_control = bbr' > /etc/sysctl.d/99-sysctl.conf
|
||||||
|
|
||||||
|
# iptables
|
||||||
|
install /dev/stdin /usr/bin/local/iptables.hook <<IPTABLES
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
iptables -N TCP
|
||||||
|
iptables -N UDP
|
||||||
|
|
||||||
|
iptables -P FORWARD DROP
|
||||||
|
iptables -P OUTPUT ACCEPT
|
||||||
|
iptables -P INPUT DROP
|
||||||
|
|
||||||
|
iptables -A INPUT -s 192.168.122.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
iptables -A INPUT -i lo -j ACCEPT
|
||||||
|
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
|
||||||
|
iptables -A INPUT -p icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
|
||||||
|
iptables -A INPUT -p udp -m conntrack --ctstate NEW -j UDP
|
||||||
|
iptables -A INPUT -p tcp --syn -m conntrack --ctstate NEW -j TCP
|
||||||
|
iptables -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
|
||||||
|
iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
|
||||||
|
iptables -A INPUT -j REJECT --reject-with icmp-proto-unreachable
|
||||||
|
|
||||||
|
iptables-save -f \${1}
|
||||||
|
IPTABLES
|
||||||
|
/usr/bin/local/iptables.hook /etc/iptables/iptables.rules
|
||||||
|
|
||||||
|
# iptables hook
|
||||||
|
install /dev/stdin /usr/bin/local/hook-iptables.rules <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/iptables/iptables.rules.pacnew ]
|
||||||
|
then
|
||||||
|
/usr/bin/local/iptables.hook /etc/iptables/iptables.rules.pacnew
|
||||||
|
mv /etc/iptables/iptables.rules.pacnew /etc/iptables/iptables.rules
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
cat >/etc/pacman.d/hooks/iptables.rules.hook <<iptables
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = iptables*
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing iptables rules
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/local/hook-iptables.rules
|
||||||
|
iptables
|
||||||
|
|
||||||
|
# Paccache hook
|
||||||
|
cat >/etc/pacman.d/hooks/paccache.hook <<'paccache'
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Package
|
||||||
|
Target = *
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Cleaning pacman cache...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/paccache -r
|
||||||
|
paccache
|
||||||
|
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
install /dev/stdin /usr/bin/local/hook-localegen <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/locale.gen.pacnew ]
|
||||||
|
then
|
||||||
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen.pacnew
|
||||||
|
mv /etc/locale.gen.pacnew /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
cat >/etc/pacman.d/hooks/localegen.hook <<localegen
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = glibc
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing locale.gen
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/local/hook-localegen
|
||||||
|
localegen
|
||||||
|
|
||||||
|
# ssh
|
||||||
|
cat >/etc/ssh/sshd_config.d/10-sshd.conf <<sshd
|
||||||
|
PermitRootLogin no
|
||||||
|
PasswordAuthentication no
|
||||||
|
AuthenticationMethods publickey
|
||||||
|
Protocol 2
|
||||||
|
sshd
|
||||||
|
cat >/etc/ssh/ssh_config.d/10-global.conf <<sshconfig
|
||||||
|
# Preferred ciphers
|
||||||
|
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
|
||||||
|
|
||||||
|
# Only use ipv4
|
||||||
|
AddressFamily inet
|
||||||
|
sshconfig
|
||||||
|
|
||||||
|
# Polkit
|
||||||
|
mkdir -p /etc/polkit-1/rules.d
|
||||||
|
cat >/etc/polkit-1/rules.d/49-nopasswd_global.rules <<'polkit'
|
||||||
|
/* Allow members of the wheel group to execute any actions
|
||||||
|
* without password authentication, similar to "sudo NOPASSWD:"
|
||||||
|
*/
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (subject.isInGroup("wheel")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
polkit
|
||||||
|
|
||||||
|
# Custom pacman wrapper
|
||||||
|
install /dev/stdin /usr/local/bin/syu <<syu
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
sudo curl --fail -s -L wdas.sh/mirrorlist -o /etc/pacman.d/mirrorlist
|
||||||
|
|
||||||
|
if checkupdates | grep -q 'archlinux-keyring'
|
||||||
|
then
|
||||||
|
sudo pacman -Sy --noconfirm archlinux-keyring
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if sudo pacman -Syu --noconfirm
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
sudo pacdiff
|
||||||
|
fi
|
||||||
|
syu
|
||||||
|
|
||||||
|
# System services
|
||||||
|
systemctl -q enable systemd-networkd.service systemd-resolved.service sshd.service iptables.service qemu-guest-agent.service ${systemdbootservice}
|
||||||
|
|
||||||
|
su user <<"CHANGEUSER"
|
||||||
|
# SSH
|
||||||
|
ssh-keygen -t ed25519 -q -f ~/.ssh/id_ed25519 -P ""
|
||||||
|
echo "${sshkeys[@]}" > ~/.ssh/authorized_keys
|
||||||
|
|
||||||
|
# bash
|
||||||
|
# cp /etc/skel/.bash* ~/
|
||||||
|
|
||||||
|
cat >> ~/.bashrc <<'BASHRC'
|
||||||
|
|
||||||
|
unset HISTFILE
|
||||||
|
|
||||||
|
alias ll='ls -l -a -h'
|
||||||
|
|
||||||
|
# Grep color
|
||||||
|
alias grep='grep --color=auto'
|
||||||
|
alias egrep='egrep --color=auto'
|
||||||
|
alias fgrep='fgrep --color=auto'
|
||||||
|
|
||||||
|
# Adjust terminal upon window resize
|
||||||
|
shopt -s checkwinsize
|
||||||
|
|
||||||
|
# Auto cd into directory
|
||||||
|
shopt -s autocd
|
||||||
|
|
||||||
|
# Ignore duplicate and whitespace history entries
|
||||||
|
export HISTCONTROL=ignoreboth
|
||||||
|
|
||||||
|
#
|
||||||
|
# ~/.bash_aliases
|
||||||
|
#
|
||||||
|
|
||||||
|
# Reboot and poweroff
|
||||||
|
alias poweroff='sudo poweroff'
|
||||||
|
alias reboot='sudo reboot'
|
||||||
|
|
||||||
|
# Miscellanous pacman
|
||||||
|
alias orphans='pacman -Rcns $(pacman -Qtdq)'
|
||||||
|
alias unlockpacmandb='rm /var/lib/pacman/db.lck && pacman -Syy'
|
||||||
|
|
||||||
|
# Rsync
|
||||||
|
alias rsync='rsync --progress --info=progress2 -v -h'
|
||||||
|
|
||||||
|
#
|
||||||
|
# ~/.bash_functions
|
||||||
|
#
|
||||||
|
|
||||||
|
# Pacman tools
|
||||||
|
function installer
|
||||||
|
{
|
||||||
|
sudo pacman -S "$@"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall
|
||||||
|
{
|
||||||
|
sudo pacman -Rcns "$@"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function syur
|
||||||
|
{
|
||||||
|
/usr/local/bin/syu &&
|
||||||
|
reboot
|
||||||
|
}
|
||||||
|
|
||||||
|
function syup
|
||||||
|
{
|
||||||
|
/usr/local/bin/syu &&
|
||||||
|
poweroff
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update configs
|
||||||
|
function update-bash
|
||||||
|
{
|
||||||
|
vim ~/.bashrc &&
|
||||||
|
source ~/.bashrc
|
||||||
|
}
|
||||||
|
|
||||||
|
BASHRC
|
||||||
|
CHANGEUSER
|
||||||
|
SYU
|
||||||
|
|
||||||
|
# Script for installing desktop environment
|
||||||
|
install /dev/stdin /mnt/usr/local/bin/desktop <<'DESKTOPINSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -a -E
|
||||||
|
|
||||||
|
# Exit function
|
||||||
|
trap '[ "$?" -ne 77 ] || exit 77' ERR
|
||||||
|
die()
|
||||||
|
{
|
||||||
|
echo -e '\e[1;31m\nError encountered, script aborted...\n\e[0m'
|
||||||
|
exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
sudo timedatectl set-ntp true
|
||||||
|
else
|
||||||
|
echo -e '\n\e[31mNo internet connectivity detected'
|
||||||
|
echo -e 'Connect to a network and try again'
|
||||||
|
echo -e 'Aborting installer...\e[0m\n'
|
||||||
|
die
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e '\n\e[1;35mSelect a desktop\e[0m'
|
||||||
|
echo -e '\t1) i3'
|
||||||
|
echo -e '\t2) none'
|
||||||
|
until [[ ${desktop} = [12] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p '> ' desktop
|
||||||
|
[[ ${desktop} = [12] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 2\e[0m'
|
||||||
|
done
|
||||||
|
|
||||||
|
# Assign DE variables
|
||||||
|
case ${desktop} in
|
||||||
|
1)
|
||||||
|
# Install and configure x
|
||||||
|
echo -e '\n\n\t\e[1mYou have chosen \e[32mi3\e[0m\e[1m desktop\e[0m'
|
||||||
|
echo -e '\n\e[1;35mInstalling base packages\e[0m'
|
||||||
|
sudo pacman -S --noconfirm spice-vdagent xf86-video-qxl xorg xorg-xinit phonon-qt5-gstreamer ttf-dejavu ttf-liberation noto-fonts noto-fonts-cjk noto-fonts-emoji firefox i3-gaps i3status i3lock dmenu lightdm lightdm-gtk-greeter pavucontrol konsole kate dolphin kompare breeze-icons
|
||||||
|
echo
|
||||||
|
echo 'exec i3' > ~/.xinitrc
|
||||||
|
echo -e '\nXDG_CURRENT_DESKTOP=gnome' | sudo tee -a /etc/environment >/dev/null
|
||||||
|
|
||||||
|
# i3
|
||||||
|
mkdir -p ~/.config/i3
|
||||||
|
curl -s -L https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
||||||
|
tee -a ~/.config/i3/config >/dev/null <<'I3CONFIG'
|
||||||
|
|
||||||
|
exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080
|
||||||
|
|
||||||
|
gaps inner 8
|
||||||
|
gaps outer 4
|
||||||
|
|
||||||
|
# for_window [class="^.*"] border pixel 2
|
||||||
|
|
||||||
|
exec spice-vdagent
|
||||||
|
I3CONFIG
|
||||||
|
# i3 function
|
||||||
|
echo -e '\n# i3 config
|
||||||
|
function i3-config
|
||||||
|
{
|
||||||
|
vim ~/.config/i3/config
|
||||||
|
}' >> ~/.bash_functions
|
||||||
|
cat >> ~/.bashrc <<'BASHRC'
|
||||||
|
|
||||||
|
# Autostart i3
|
||||||
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||||
|
then
|
||||||
|
exec startx
|
||||||
|
fi
|
||||||
|
BASHRC
|
||||||
|
;;
|
||||||
|
2) echo
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
sudo rm -f ${0}
|
||||||
|
|
||||||
|
case ${desktop} in
|
||||||
|
1)
|
||||||
|
echo -e '\e[1;34mDesktop installed, press any key to load i3\e[5m...\e[0m\n'
|
||||||
|
read -n 1 -s
|
||||||
|
sudo systemctl -q enable --now lightdm.service
|
||||||
|
;;
|
||||||
|
2)
|
||||||
|
echo -e '\e[1;34mSetup complete, press any key to continue\e[5m...\e[0m\n'
|
||||||
|
read -n 1 -s
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
die
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
DESKTOPINSTALL
|
||||||
|
|
||||||
|
# Reboot only if script succeeded
|
||||||
|
if /usr/bin/sh -c 'arch-chroot /mnt uname -a' | grep -q Linux
|
||||||
|
then
|
||||||
|
umount -R /mnt
|
||||||
|
echo -e '\e[1;34mInstaller has completed and system drive has been unmounted'
|
||||||
|
echo -e 'Boot into the new system, connect to a network and install a DE by running \e[35mdesktop\e[34m in the terminal'
|
||||||
|
echo -e 'Rebooting...\n\e[0m'
|
||||||
|
reboot
|
||||||
|
else
|
||||||
|
die
|
||||||
|
fi
|
||||||
139
pkg/homelab
Normal file
139
pkg/homelab
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
amd-ucode
|
||||||
|
apache
|
||||||
|
apcupsd
|
||||||
|
archiso
|
||||||
|
ark
|
||||||
|
base
|
||||||
|
bash-completion
|
||||||
|
bemenu
|
||||||
|
bemenu-wayland
|
||||||
|
bluez
|
||||||
|
bluez-utils
|
||||||
|
breeze-icons
|
||||||
|
bridge-utils
|
||||||
|
brightnessctl
|
||||||
|
btrfs-progs
|
||||||
|
certbot
|
||||||
|
certbot-nginx
|
||||||
|
chromium
|
||||||
|
core/linux
|
||||||
|
dbus-broker-units
|
||||||
|
dmenu
|
||||||
|
dmidecode
|
||||||
|
dnsmasq
|
||||||
|
docker
|
||||||
|
docker-buildx
|
||||||
|
docker-compose
|
||||||
|
dolphin
|
||||||
|
dosfstools
|
||||||
|
edk2-ovmf
|
||||||
|
efibootmgr
|
||||||
|
exfatprogs
|
||||||
|
fail2ban
|
||||||
|
fakeroot
|
||||||
|
feh
|
||||||
|
ffmpegthumbs
|
||||||
|
filezilla
|
||||||
|
firefox
|
||||||
|
firefox-decentraleyes
|
||||||
|
firefox-ublock-origin
|
||||||
|
foot
|
||||||
|
git
|
||||||
|
gnome
|
||||||
|
gnome-keyring
|
||||||
|
grub
|
||||||
|
grub-btrfs
|
||||||
|
i3lock
|
||||||
|
i3status
|
||||||
|
i3-wm
|
||||||
|
inetutils
|
||||||
|
inotify-tools
|
||||||
|
intel-ucode
|
||||||
|
iptables-nft
|
||||||
|
iwd
|
||||||
|
jdk-openjdk
|
||||||
|
jre-openjdk
|
||||||
|
kate
|
||||||
|
kcalc
|
||||||
|
kde-cli-tools
|
||||||
|
keepassxc
|
||||||
|
kfind
|
||||||
|
kompare
|
||||||
|
konsole
|
||||||
|
libreoffice-fresh
|
||||||
|
libvncserver
|
||||||
|
lightdm
|
||||||
|
lightdm-gtk-greeter
|
||||||
|
linux-firmware
|
||||||
|
man-db
|
||||||
|
mkinitcpio
|
||||||
|
mkinitcpio-netconf
|
||||||
|
mkinitcpio-tinyssh
|
||||||
|
mpv
|
||||||
|
networkmanager
|
||||||
|
nextcloud-client
|
||||||
|
nginx-mainline
|
||||||
|
noto-fonts-cjk
|
||||||
|
ntfs-3g
|
||||||
|
nvidia-open
|
||||||
|
nvidia-settings
|
||||||
|
okular
|
||||||
|
openbsd-netcat
|
||||||
|
opendoas
|
||||||
|
openssh
|
||||||
|
pacman-contrib
|
||||||
|
pam-u2f
|
||||||
|
parted
|
||||||
|
pavucontrol
|
||||||
|
pipewire
|
||||||
|
pipewire-audio
|
||||||
|
pipewire-jack
|
||||||
|
pipewire-pulse
|
||||||
|
plasma
|
||||||
|
pv
|
||||||
|
qemu-desktop
|
||||||
|
qemu-guest-agent
|
||||||
|
reflector
|
||||||
|
remmina
|
||||||
|
rsync
|
||||||
|
seatd
|
||||||
|
shotwell
|
||||||
|
smartmontools
|
||||||
|
snap-pac
|
||||||
|
snapper
|
||||||
|
spice-vdagent
|
||||||
|
sshfs
|
||||||
|
sudo
|
||||||
|
sudo-rs
|
||||||
|
sway
|
||||||
|
swaybg
|
||||||
|
swayidle
|
||||||
|
swaylock
|
||||||
|
syslinux
|
||||||
|
systemd-resolvconf
|
||||||
|
thunderbird
|
||||||
|
tinyssh
|
||||||
|
torbrowser-launcher
|
||||||
|
ttf-dejavu
|
||||||
|
vde2
|
||||||
|
veracrypt
|
||||||
|
vim
|
||||||
|
virt-manager
|
||||||
|
virtualbox
|
||||||
|
virtualbox-guest-iso
|
||||||
|
virtualbox-guest-utils
|
||||||
|
virtualbox-host-modules-arch
|
||||||
|
wayland
|
||||||
|
wayvnc
|
||||||
|
wireguard-tools
|
||||||
|
wireplumber
|
||||||
|
wmctrl
|
||||||
|
xf86-video-qxl
|
||||||
|
xfce4
|
||||||
|
xorg
|
||||||
|
xorg-xinit
|
||||||
|
yubico-pam
|
||||||
|
yubikey-full-disk-encryption
|
||||||
|
yubikey-personalization
|
||||||
|
zfs-linux
|
||||||
|
zfs-utils
|
||||||
43
pkg/qemu
Normal file
43
pkg/qemu
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
base
|
||||||
|
bash-completion
|
||||||
|
breeze-icons
|
||||||
|
btrfs-progs
|
||||||
|
chromium
|
||||||
|
dmenu
|
||||||
|
dolphin
|
||||||
|
ffmpegthumbs
|
||||||
|
firefox
|
||||||
|
firefox-decentraleyes
|
||||||
|
firefox-ublock-origin
|
||||||
|
git
|
||||||
|
i3lock
|
||||||
|
i3status
|
||||||
|
i3-wm
|
||||||
|
kate
|
||||||
|
kfind
|
||||||
|
kompare
|
||||||
|
konsole
|
||||||
|
linux
|
||||||
|
mkinitcpio
|
||||||
|
opendoas
|
||||||
|
openssh
|
||||||
|
pacman-contrib
|
||||||
|
pavucontrol
|
||||||
|
pipewire
|
||||||
|
pipewire-jack
|
||||||
|
qemu-guest-agent
|
||||||
|
reflector
|
||||||
|
rsync
|
||||||
|
spice-vdagent
|
||||||
|
sudo
|
||||||
|
sudo-rs
|
||||||
|
syslinux
|
||||||
|
systemd-resolvconf
|
||||||
|
ttf-dejavu
|
||||||
|
vim
|
||||||
|
virtualbox-guest-utils
|
||||||
|
wireguard-tools
|
||||||
|
wireplumber
|
||||||
|
xf86-video-qxl
|
||||||
|
xorg
|
||||||
|
xorg-xinit
|
||||||
347
recover.sh
Executable file
347
recover.sh
Executable file
|
|
@ -0,0 +1,347 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -a -E
|
||||||
|
|
||||||
|
# Exit function
|
||||||
|
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||||
|
function die
|
||||||
|
{
|
||||||
|
echo -e '\n\e[1;31mError encountered, script aborted...\e[0m\n'
|
||||||
|
exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if ! nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || ! nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die 'No internet connectivity detected, plug in an ethernet cable or run \e[32miwd-connect\e[33m if using wifi and try again'
|
||||||
|
fi
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
echo -e '\e[3m## rev '${revision}'\e[0m\n'
|
||||||
|
echo -e '\t\e[1;4;34mArch Linux Recovery\e[0m\n\n'
|
||||||
|
echo -e '\e[1mSelect a system configuration from the options below\e[0m\n'
|
||||||
|
echo -e '\t1) Basic'
|
||||||
|
echo -e '\t2) Full Disk LUKS Encryption with EFISTUB'
|
||||||
|
echo -e '\t3) Full Disk LUKS Encryption with Secured GRUB'
|
||||||
|
echo -e '\t4) Yubikey Full Disk Encryption with EFISTUB'
|
||||||
|
echo -e '\t5) Yubikey Full Disk Encryption with Secured GRUB'
|
||||||
|
|
||||||
|
if ls -l /dev/disk/* | grep -q 'virtio\|QEMU'
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
until [[ ${arch} = [1-5] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p '> ' arch
|
||||||
|
[[ ${arch} = [1-5] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 5\e[0m'
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo -e '\t6) Full Disk Encryption with Detached LUKS Header and Secured GRUB'
|
||||||
|
echo -e '\t7) Yubikey Encrypted Detached LUKS Header with Secured GRUB\n'
|
||||||
|
until [[ ${arch} = [1-7] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p '> ' arch
|
||||||
|
[[ ${arch} = [1-7] ]] || echo -e '\n\n\e[1;31mInvalid selection, type an option from 1 to 7\e[0m'
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prevent continuing unless yubikey is detected, only applies to yubikey setups
|
||||||
|
if [[ ${arch} = [457] ]] && ! dmesg | grep -q -i YubiKey
|
||||||
|
then
|
||||||
|
echo -e '\n\n\e[1mYubikey not detected'
|
||||||
|
echo -e 'Insert one to continue\e[5m...\e[0m'
|
||||||
|
until dmesg | grep -q -i YubiKey
|
||||||
|
do
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Installation drive
|
||||||
|
echo -e '\n\n\e[1;36mIdentify the system drive from the list of available devices below\e[0m'
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||||
|
echo -e '\e[3m## SSD and HDD device format begins with "sd" or "hd" (sda, sdb, sd[*])'
|
||||||
|
echo -e '## NVME and PCI device format is "nvme[*]n1" (nvme0n1, nvme1n1, nvme[*]n1)\e[0m'
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -r -p 'Installation device: ' installation_disk
|
||||||
|
lsblk -o name | grep -q -w ${installation_disk} && [ ${installation_disk} ] && break
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v 'archiso'
|
||||||
|
[ -z ${installation_disk} ] && echo -e '\e[1;31mField cannot be empty, try again\e[0m' ||
|
||||||
|
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||||
|
done
|
||||||
|
echo -e '\n\e[1mInstallation drive set as \e[32m/dev/'${installation_disk}'\e[0m'
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Detached boot drive
|
||||||
|
if [[ ${arch} = [67] ]]
|
||||||
|
then
|
||||||
|
echo -e '\e[1;34mIdentify the removable boot drive from the list of available devices below\e[0m'
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||||
|
echo -e '\e[3m## Removable drives usually begin with "sd" (sda, sdb, sd[*])\e[0m'
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
read -r -p 'Removable boot device: ' external_boot_disk
|
||||||
|
lsblk -o name | grep -v ${installation_disk} | grep -q -w ${external_boot_disk} && [ ${external_boot_disk} ] && break
|
||||||
|
lsblk -d -o name,model,size,mountpoint | grep -v "archiso\|${installation_disk}"
|
||||||
|
if [ -z ${external_boot_disk} ]
|
||||||
|
then
|
||||||
|
echo -e '\e[1;31mField cannot be empty, try again\e[0m'
|
||||||
|
elif [ ${external_boot_disk} = ${installation_disk} ]
|
||||||
|
then
|
||||||
|
echo -e '\e[1;31mBoot drive cannot be the same as the system drive, try again\e[0m'
|
||||||
|
else
|
||||||
|
echo -e '\e[1;31mInvalid selection or drive not available, try again\e[0m'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo -e '\n\e[1mDetached boot drive set as \e[32m/dev/'${external_boot_disk}'\e[0m'
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${arch} = [457] ]]
|
||||||
|
then
|
||||||
|
until [[ ${decrypt_root} = [yYnN] ]]
|
||||||
|
do
|
||||||
|
read -n 1 -p $'\n\e[1mDoes the yubikey automatically decrypt root upon boot (1FA)? (y/n): \e[0m' decrypt_root
|
||||||
|
[[ ${decrypt_root} = [yYnN] ]] || echo -e -n '\n\n\e[1;31mNot a valid answer, type "y" or "n"\e[0m'
|
||||||
|
done
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Functions
|
||||||
|
function decryptRootLuks
|
||||||
|
{
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
unset lukspass
|
||||||
|
|
||||||
|
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||||
|
until [ ${lukspass} ]
|
||||||
|
do
|
||||||
|
read -s -r -p 'Encryption password: ' lukspass
|
||||||
|
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}'\e[0m'
|
||||||
|
if printf '%s' "${lukspass}" | cryptsetup open -v ${rootpart} cryptroot ${luks_header}
|
||||||
|
then
|
||||||
|
unset lukspass
|
||||||
|
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function decryptRootYubikey
|
||||||
|
{
|
||||||
|
echo
|
||||||
|
yes | pacman -Sy &>/dev/null
|
||||||
|
|
||||||
|
for package in yubikey-personalization yubikey-full-disk-encryption
|
||||||
|
do
|
||||||
|
if ! pacman -Q | grep -q -w ${package}
|
||||||
|
then
|
||||||
|
missing_yubikey_req+=(${package})
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${missing_yubikey_req} ]
|
||||||
|
then
|
||||||
|
yes | pacman -Sy ${missing_yubikey_req[@]}
|
||||||
|
unset missing_yubikey_req
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# # Custom challenge slot
|
||||||
|
# sed -i '/YKFDE_CHALLENGE_SLOT/c\YKFDE_CHALLENGE_SLOT="1"' /etc/ykfde.conf
|
||||||
|
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
unset lukspass
|
||||||
|
|
||||||
|
echo -e '\e[1;36mEnter the encryption passphrase for the system drive\e[0m'
|
||||||
|
until [ ${lukspass} ]
|
||||||
|
do
|
||||||
|
read -s -r -p 'Encryption password: ' lukspass
|
||||||
|
[ ${lukspass} ] || echo -e '\n\n\e[1;31mPassphrase field cannot be empty, try again\e[0m'
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${decrypt_root} = [yY] ]]
|
||||||
|
then
|
||||||
|
sed -i '/YKFDE_CHALLENGE=/c\YKFDE_CHALLENGE="'"$(printf '%q' ${lukspass})"'"' /etc/ykfde.conf
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e '\n\n\e[1;36mAttempting to decrypt '${rootpart}' with yubikey HMAC encryption\e[0m'
|
||||||
|
if printf '%s\n' "${lukspass}" | ykfde-open -d ${rootpart} -n cryptroot -- ${luks_header}
|
||||||
|
then
|
||||||
|
unset lukspass
|
||||||
|
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function decryptBootLuks
|
||||||
|
{
|
||||||
|
while true
|
||||||
|
do
|
||||||
|
unset grubpass
|
||||||
|
|
||||||
|
echo -e '\e[1;36mEnter the encryption passphrase for the bootloader\e[0m'
|
||||||
|
until [ ${grubpass} ]
|
||||||
|
do
|
||||||
|
read -s -r -p 'Bootloader password: ' grubpass
|
||||||
|
[ ${grubpass} ] || echo -e '\n\n\e[1;31mPassword field cannot be empty, try again\e[0m'
|
||||||
|
done
|
||||||
|
|
||||||
|
echo -e '\n\n\e[1;36mAttempting to decrypt bootloader...\e[0m'
|
||||||
|
if printf '%s' "${grubpass}" | cryptsetup open ${bootpart} cryptboot
|
||||||
|
then
|
||||||
|
unset grubpass
|
||||||
|
echo -e '\e[1;92mDecryption successful\e[0m'
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo -e '\e[1;31mPassphrase failed, try again\e[0m\n'
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function configureVolumes
|
||||||
|
{
|
||||||
|
echo -e '\n\e[1;36mMounting volumes\e[0m'
|
||||||
|
|
||||||
|
case $(blkid -s TYPE -o value ${rootvol}) in
|
||||||
|
zfs_member)
|
||||||
|
if ! zpool list | grep -q zroot
|
||||||
|
then
|
||||||
|
zpool import -R /mnt zroot -N -d ${rootvol}
|
||||||
|
fi
|
||||||
|
zfs mount zroot/ROOT
|
||||||
|
zfs mount -a
|
||||||
|
;;
|
||||||
|
btrfs)
|
||||||
|
mount ${rootvol} /mnt
|
||||||
|
;;
|
||||||
|
ext4)
|
||||||
|
mount ${rootvol} /mnt
|
||||||
|
mount ${bootvol} /mnt/boot
|
||||||
|
if [[ ${arch} = [3567] ]]
|
||||||
|
then
|
||||||
|
mount ${efivol} /mnt/boot/efi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Grab disk-id of ${drive}
|
||||||
|
installation_disk_id=$(ls -l /dev/disk/by-id/* | grep "${installation_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX' | awk '{print $9}' | head -1)
|
||||||
|
external_boot_disk_id=$(ls -l /dev/disk/by-id/* | grep "${external_boot_disk}$" | grep 'wwn\|nvme-uuid\|nvme-nvme\|nvme-eui\|QEMU\|virtio\|VBOX\|usb' | awk '{print $9}' | head -1)
|
||||||
|
|
||||||
|
# System configurations
|
||||||
|
case ${arch} in
|
||||||
|
1) # Basic
|
||||||
|
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||||
|
export {rootpart,rootvol}=${installation_disk_id}-part2
|
||||||
|
configureVolumes
|
||||||
|
;;
|
||||||
|
|
||||||
|
2|4) # FDE with EFISTUB
|
||||||
|
export {efivol,bootvol}=${installation_disk_id}-part1
|
||||||
|
rootpart=${installation_disk_id}-part2
|
||||||
|
rootvol=/dev/mapper/cryptroot
|
||||||
|
|
||||||
|
case ${arch} in
|
||||||
|
2)
|
||||||
|
if [[ $(blkid -s TYPE -o value ${rootpart}) = "zfs_member" ]]
|
||||||
|
then
|
||||||
|
zpool import -R /mnt zroot -N -d ${rootpart}
|
||||||
|
printf '%s' "${lukspass}" | zfs load-key zroot
|
||||||
|
else
|
||||||
|
decryptRootLuks
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
4) decryptRootYubikey;;
|
||||||
|
esac
|
||||||
|
configureVolumes
|
||||||
|
;;
|
||||||
|
|
||||||
|
3|5) # FDE with Secured GRUB
|
||||||
|
efivol=${installation_disk_id}-part1
|
||||||
|
bootpart=${installation_disk_id}-part2
|
||||||
|
rootpart=${installation_disk_id}-part3
|
||||||
|
rootvol=/dev/mapper/cryptroot
|
||||||
|
bootvol=/dev/mapper/cryptboot
|
||||||
|
|
||||||
|
case ${arch} in
|
||||||
|
3) decryptRootLuks;;
|
||||||
|
5) decryptRootYubikey;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
decryptBootLuks
|
||||||
|
configureVolumes
|
||||||
|
;;
|
||||||
|
|
||||||
|
6|7) # FDE with detached luks header
|
||||||
|
efivol=${external_boot_disk_id}-part1
|
||||||
|
bootpart=${external_boot_disk_id}-part2
|
||||||
|
rootpart=${installation_disk_id}
|
||||||
|
rootvol=/dev/mapper/cryptroot
|
||||||
|
bootvol=/dev/mapper/cryptboot
|
||||||
|
luks_header='--header /mnt/header.img'
|
||||||
|
|
||||||
|
decryptBootLuks
|
||||||
|
mount /dev/mapper/cryptboot /mnt
|
||||||
|
case ${arch} in
|
||||||
|
6) decryptRootLuks;;
|
||||||
|
7) decryptRootYubikey;;
|
||||||
|
esac
|
||||||
|
umount /mnt
|
||||||
|
configureVolumes
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -e '\e[1;92mSystem successfully mounted...\e[0m\n'
|
||||||
|
|
||||||
|
if [[ $(blkid -s TYPE -o value ${rootvol}) = "btrfs" ]]
|
||||||
|
then
|
||||||
|
install /dev/stdin /usr/local/bin/btrfs-mount <<- BTRFSSU
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
btrfsopts=$(awk '$2=="/"' /mnt/etc/fstab | awk '{print $4}' | sed 's/,subvol=.*//')
|
||||||
|
umount -R /mnt
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Mount @root subvolume
|
||||||
|
mount -o ${btrfsopts},subvol=@ ${rootvol} /mnt
|
||||||
|
|
||||||
|
# Mount all subvolumes
|
||||||
|
arch-chroot /mnt mount --all
|
||||||
|
lsblk
|
||||||
|
echo -e '\n\t\e[1;92mBtrfs subvolumes successful mounted!\e[0m\n'
|
||||||
|
BTRFSSU
|
||||||
|
|
||||||
|
echo -e '\e[1mRun \e[92mbtrfs-mount\e[0m\e[1m to mount all the btrfs subvolumes\e[0m\n'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${arch} = [3567] ]]
|
||||||
|
then
|
||||||
|
install /dev/stdin /usr/local/bin/re-grub <<REGRUB
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if findmnt '/mnt/boot/efi' | grep -q "${efivol}" && findmnt '/mnt/boot' | grep -q "${bootvol}"
|
||||||
|
then
|
||||||
|
arch-chroot /mnt /bin/bash <<'GRUB'
|
||||||
|
grub-install --target=x86_64-efi --bootloader-id=GRUB --efi-directory=/boot/efi --recheck
|
||||||
|
grub-mkconfig -o /boot/grub/grub.cfg
|
||||||
|
echo -e '\n\t\e[1;92mGrub successfuly re-installed!\e[0m\n'
|
||||||
|
GRUB
|
||||||
|
else
|
||||||
|
echo -e '\n\t\e[1;31mEFI partition not mounted, try again\e[0m\n'
|
||||||
|
fi
|
||||||
|
REGRUB
|
||||||
|
|
||||||
|
echo -e '\e[1mRun \e[92mre-grub\e[0m\e[1m to regenerate grub\e[0m\n'
|
||||||
|
fi
|
||||||
912
virtual-machine.sh
Executable file
912
virtual-machine.sh
Executable file
|
|
@ -0,0 +1,912 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -a
|
||||||
|
set -E
|
||||||
|
revision=1.0h
|
||||||
|
|
||||||
|
## Tput codes
|
||||||
|
reset=$(tput sgr0)
|
||||||
|
|
||||||
|
bold=$(tput bold)
|
||||||
|
italic=$(tput sitm)
|
||||||
|
blink=$(tput blink)
|
||||||
|
|
||||||
|
black=${reset}$(tput setaf 0)
|
||||||
|
red=${reset}$(tput setaf 1)
|
||||||
|
green=${reset}$(tput setaf 2)
|
||||||
|
yellow=${reset}$(tput setaf 3)
|
||||||
|
blue=${reset}$(tput setaf 4)
|
||||||
|
magenta=${reset}$(tput setaf 5)
|
||||||
|
cyan=${reset}$(tput setaf 6)
|
||||||
|
white=${reset}$(tput setaf 7)
|
||||||
|
|
||||||
|
# Color codes
|
||||||
|
function say
|
||||||
|
{
|
||||||
|
for format in ${@:2}
|
||||||
|
do
|
||||||
|
echo -n ${!format}
|
||||||
|
done
|
||||||
|
echo -e "${1}"
|
||||||
|
echo -n ${reset}
|
||||||
|
}
|
||||||
|
function say_n
|
||||||
|
{
|
||||||
|
for format in ${@:2}
|
||||||
|
do
|
||||||
|
echo -n ${!format}
|
||||||
|
done
|
||||||
|
echo -e -n "${1}"
|
||||||
|
echo -n ${reset}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Exit function
|
||||||
|
trap '[ "${?}" -ne 77 ] || exit 77' ERR
|
||||||
|
function die
|
||||||
|
{
|
||||||
|
cat <<- abort
|
||||||
|
${red}
|
||||||
|
Error encountered for the following reason:
|
||||||
|
${yellow}
|
||||||
|
"${1}"
|
||||||
|
${red}
|
||||||
|
Script aborted...
|
||||||
|
${reset}
|
||||||
|
abort
|
||||||
|
exit 77
|
||||||
|
}
|
||||||
|
|
||||||
|
# Repeat a command until it exits with code 0
|
||||||
|
function repeat
|
||||||
|
{
|
||||||
|
until ${@}
|
||||||
|
do
|
||||||
|
sleep 3
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Read flags
|
||||||
|
rm -f sshkeys
|
||||||
|
while [ ${1} ]
|
||||||
|
do
|
||||||
|
case ${1} in
|
||||||
|
-s | --ssh-key )
|
||||||
|
if [ "${2}" ]
|
||||||
|
then
|
||||||
|
echo "${2}" >>sshkeys
|
||||||
|
if ! ssh-keygen -l -f sshkeys >/dev/null
|
||||||
|
then
|
||||||
|
die 'Invalid SSH public key detected'
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
-? | -h | --help )
|
||||||
|
cat <<- help
|
||||||
|
Parameters:
|
||||||
|
-s, --ssh-key Add SSH public key (enclosed in quotes)
|
||||||
|
-?, -h, --help This help screen
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
* ) die "Unknown flag: ${1}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Ensure pacman.conf settings are properly set
|
||||||
|
if [ ! -f /etc/pacman.conf.bkp ]
|
||||||
|
then
|
||||||
|
cp /etc/pacman.conf /etc/pacman.conf.bkp
|
||||||
|
fi
|
||||||
|
sed -e "/Color/c Color" \
|
||||||
|
-e "/ParallelDownloads/c ParallelDownloads = 10" \
|
||||||
|
-e "/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090" \
|
||||||
|
/etc/pacman.conf.bkp >/etc/pacman.conf
|
||||||
|
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
timedatectl set-ntp true
|
||||||
|
curl --fail --silent https://git.myvelabs.com/lab/archlinux/raw/branch/master/mirrorlist -o /etc/pacman.d/mirrorlist || die "Unable to fetch latest mirrorlist"
|
||||||
|
else
|
||||||
|
die 'No internet connectivity detected, try again'
|
||||||
|
fi
|
||||||
|
|
||||||
|
clear
|
||||||
|
|
||||||
|
cat <<- title
|
||||||
|
$(tput setaf 7 smul dim)## rev ${revision}${reset}
|
||||||
|
${blue}${bold}
|
||||||
|
Arch VM
|
||||||
|
${reset}
|
||||||
|
title
|
||||||
|
|
||||||
|
# Default systemd services
|
||||||
|
systemd_services=(systemd-networkd.service systemd-resolved.service sshd.service iptables.service wireguard-startup.service)
|
||||||
|
|
||||||
|
# Firmware
|
||||||
|
if ls -l /dev/disk/* | grep -q VBOX
|
||||||
|
then
|
||||||
|
linux_firmware+=(virtualbox-guest-utils)
|
||||||
|
systemd_services+=(vboxservice.service)
|
||||||
|
installation_disk=sda
|
||||||
|
else
|
||||||
|
linux_firmware+=(qemu-guest-agent spice-vdagent)
|
||||||
|
systemd_services+=(qemu-guest-agent.service)
|
||||||
|
if ls -l /dev/disk/* | grep -q virtio
|
||||||
|
then
|
||||||
|
installation_disk=vda
|
||||||
|
elif ls -l /dev/disk/* | grep -q QEMU
|
||||||
|
then
|
||||||
|
installation_disk=sda
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if lspci | grep VGA | grep -q QXL
|
||||||
|
then
|
||||||
|
linux_firmware+=(xf86-video-qxl)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generate username and hostname
|
||||||
|
hostname=$(cat /dev/urandom | tr -d -c 'a-zA-Z' | fold -w 6 | head -n 1)
|
||||||
|
|
||||||
|
# Unmount if mounted
|
||||||
|
for mount in /mnt/boot /mnt
|
||||||
|
do
|
||||||
|
until ! mount | grep -q ${mount}
|
||||||
|
do
|
||||||
|
umount ${mount}
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
say "Partitioning /dev/${installation_disk}" yellow bold
|
||||||
|
wipefs -f -a /dev/${installation_disk}
|
||||||
|
echo
|
||||||
|
if [ -d /sys/firmware/efi/efivars/ ]
|
||||||
|
then
|
||||||
|
parted --script --align=optimal /dev/${installation_disk} \
|
||||||
|
mklabel gpt \
|
||||||
|
mkpart boot 1MiB 100MiB \
|
||||||
|
mkpart zroot 100MiB 100% \
|
||||||
|
set 1 esp on
|
||||||
|
partprobe /dev/${installation_disk}
|
||||||
|
else
|
||||||
|
bios=syslinux
|
||||||
|
parted --script --align=optimal /dev/${installation_disk} \
|
||||||
|
mklabel msdos \
|
||||||
|
mkpart primary 1MiB 100MiB \
|
||||||
|
mkpart primary 100MiB 100% \
|
||||||
|
set 1 boot on
|
||||||
|
partprobe /dev/${installation_disk}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Assign partitions
|
||||||
|
export {efivol,bootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}.*1$")
|
||||||
|
export {rootpart,rootvol}=/dev/$(lsblk -l -o name | grep "${installation_disk}.*2$")
|
||||||
|
|
||||||
|
say "Configuring volumes" yellow bold
|
||||||
|
yes | mkfs.ext4 ${rootvol}
|
||||||
|
mount -o noatime ${rootvol} /mnt
|
||||||
|
|
||||||
|
# Boot partition
|
||||||
|
yes | mkfs.fat -F 32 ${efivol}
|
||||||
|
mount --mkdir -o uid=0,gid=0,fmask=0077,dmask=0077 ${bootvol} /mnt/boot
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Temporarily disable mkinitcpio
|
||||||
|
ln -s -f /dev/null /etc/pacman.d/hooks/90-mkinitcpio-install.hook
|
||||||
|
|
||||||
|
# Install Arch on new root
|
||||||
|
say "Installing Arch Linux on /dev/${installation_disk}" yellow bold
|
||||||
|
archpkgs="sudo-rs fakeroot \
|
||||||
|
${linux_firmware[@]} ${bios} \
|
||||||
|
reflector openssh vim \
|
||||||
|
git rsync pacman-contrib bash-completion ffmpegthumbs \
|
||||||
|
xorg xorg-xinit \
|
||||||
|
i3-wm i3status dmenu konsole kate dolphin kompare breeze-icons kde-cli-tools ttf-dejavu \
|
||||||
|
firefox firefox-decentraleyes firefox-ublock-origin \
|
||||||
|
chromium \
|
||||||
|
wireguard-tools systemd-resolvconf \
|
||||||
|
noto-fonts-cjk \
|
||||||
|
iptables-nft pipewire-jack \
|
||||||
|
openbsd-netcat debugedit"
|
||||||
|
|
||||||
|
# Pacstrap
|
||||||
|
repeat pacstrap -K /mnt --ask 4 \
|
||||||
|
linux base mkinitcpio \
|
||||||
|
${archpkgs}
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Generate fs table
|
||||||
|
genfstab -U -p /mnt >>/mnt/etc/fstab
|
||||||
|
|
||||||
|
# Make custom directories
|
||||||
|
mkdir -p /mnt/etc/{pacman.d/hooks,makepkg.conf.d,systemd/journald.conf.d}/ \
|
||||||
|
/mnt/opt/local/{bin,hooks}/
|
||||||
|
|
||||||
|
# makepkg
|
||||||
|
cat >/mnt/etc/makepkg.conf.d/zz-makepkg.conf <<- makepkg
|
||||||
|
PKGEXT=".pkg.tar"
|
||||||
|
MAKEFLAGS="--jobs=$(nproc)"
|
||||||
|
COMPRESSZST=(zstd -c -T0 --auto-threads=logical -)
|
||||||
|
makepkg
|
||||||
|
|
||||||
|
# pacman.conf hook
|
||||||
|
install /dev/stdin /mnt/opt/local/hooks/pacman.conf <<'hook'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/pacman.conf.pacnew ]
|
||||||
|
then
|
||||||
|
sed -e '/ParallelDownloads/c ParallelDownloads = 10' \
|
||||||
|
-e '/Color/c Color' \
|
||||||
|
-e '/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090' \
|
||||||
|
/etc/pacman.conf.pacnew >/etc/pacman.conf
|
||||||
|
rm /etc/pacman.conf.pacnew
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
cat >/mnt/etc/pacman.d/hooks/100-pacman.hook <<- pacman
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = pacman
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing pacman.conf
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/pacman.conf
|
||||||
|
pacman
|
||||||
|
|
||||||
|
# Configure pacman cache server
|
||||||
|
sed -e '/ParallelDownloads/c ParallelDownloads = 10' \
|
||||||
|
-e '/Color/c Color' \
|
||||||
|
-e '/^\[core\]$\|^\[extra\]$/a CacheServer = http://192.168.122.1:9090' \
|
||||||
|
-i /mnt/etc/pacman.conf
|
||||||
|
|
||||||
|
# Mkinitcpio decompress
|
||||||
|
echo 'MODULES_DECOMPRESS="yes"' >/mnt/etc/mkinitcpio.conf.d/zz-modules.conf
|
||||||
|
|
||||||
|
# Manually configure mkinitcpio
|
||||||
|
sed -e "s|%PKGBASE%|linux|g" \
|
||||||
|
-e "s/^fallback/#&/g" \
|
||||||
|
-e "s/ 'fallback'//" \
|
||||||
|
/mnt/usr/share/mkinitcpio/hook.preset >/mnt/etc/mkinitcpio.d/linux.preset
|
||||||
|
rsync -a /mnt/usr/lib/modules/*/vmlinuz /mnt/boot/vmlinuz-linux
|
||||||
|
|
||||||
|
# Networking
|
||||||
|
ln -s -f /run/systemd/resolve/stub-resolv.conf /mnt/etc/resolv.conf
|
||||||
|
rsync -a /etc/systemd/network/20-ethernet.network /mnt/etc/systemd/network/
|
||||||
|
|
||||||
|
if [ -d /sys/firmware/efi/efivars/ ]
|
||||||
|
then
|
||||||
|
# Systemd-boot
|
||||||
|
say "Configuring systemd-boot" yellow bold
|
||||||
|
arch-chroot -S /mnt bootctl --path=/boot/ install
|
||||||
|
cat >/mnt/boot/loader/entries/arch.conf <<- systemd-boot
|
||||||
|
title Arch Linux
|
||||||
|
linux /vmlinuz-linux
|
||||||
|
initrd /initramfs-linux.img
|
||||||
|
options root=${rootpart} rw quiet
|
||||||
|
systemd-boot
|
||||||
|
cat >/mnt/boot/loader/loader.conf <<- entry
|
||||||
|
default arch
|
||||||
|
timeout 0
|
||||||
|
console-mode max
|
||||||
|
editor no
|
||||||
|
entry
|
||||||
|
systemd_services+=(systemd-boot-update.service)
|
||||||
|
else
|
||||||
|
# Syslinux
|
||||||
|
say "Configuring syslinux" yellow bold
|
||||||
|
mkdir /mnt/boot/syslinux/
|
||||||
|
arch-chroot /mnt extlinux --install /boot/syslinux/
|
||||||
|
arch-chroot /mnt syslinux-install_update -i -a -m
|
||||||
|
cat >/mnt/boot/syslinux/syslinux.cfg <<-syslinux
|
||||||
|
DEFAULT arch
|
||||||
|
PROMPT 0
|
||||||
|
TIMEOUT 0
|
||||||
|
|
||||||
|
MENU TITLE Arch Linux
|
||||||
|
MENU COLOR border 30;44 #40ffffff #a0000000 std
|
||||||
|
MENU COLOR title 1;36;44 #9033ccff #a0000000 std
|
||||||
|
MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all
|
||||||
|
MENU COLOR unsel 37;44 #50ffffff #a0000000 std
|
||||||
|
MENU COLOR help 37;40 #c0ffffff #a0000000 std
|
||||||
|
MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std
|
||||||
|
MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std
|
||||||
|
MENU COLOR msg07 37;40 #90ffffff #a0000000 std
|
||||||
|
MENU COLOR tabmsg 31;40 #30ffffff #00000000 std
|
||||||
|
|
||||||
|
LABEL arch
|
||||||
|
MENU LABEL Arch Linux
|
||||||
|
LINUX ../vmlinuz-linux
|
||||||
|
APPEND root=${rootpart} rw quiet
|
||||||
|
INITRD ../initramfs-linux.img
|
||||||
|
LABEL hdt
|
||||||
|
MENU LABEL HDT (Hardware Detection Tool)
|
||||||
|
COM32 hdt.c32
|
||||||
|
LABEL reboot
|
||||||
|
MENU LABEL Reboot
|
||||||
|
COM32 reboot.c32
|
||||||
|
LABEL poweroff
|
||||||
|
MENU LABEL Poweroff
|
||||||
|
COM32 poweroff.c32
|
||||||
|
syslinux
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
|
arch-chroot /mnt /usr/bin/bash <<- "CHROOT"
|
||||||
|
# Root bashrc
|
||||||
|
cat >> /etc/skel/.bashrc <<- 'bashrc'
|
||||||
|
|
||||||
|
# Add local functions folder to path
|
||||||
|
export PATH=${PATH}:/opt/local/bin
|
||||||
|
|
||||||
|
# Source bash functions
|
||||||
|
if [ -d ~/.local/functions ]
|
||||||
|
then
|
||||||
|
for file in $(find ~/.local/functions -type f)
|
||||||
|
do
|
||||||
|
. ${file}
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Disable history
|
||||||
|
unset HISTFILE
|
||||||
|
rm -f ${HISTFILE}
|
||||||
|
history -c -w
|
||||||
|
|
||||||
|
# Rsync
|
||||||
|
alias rsync='rsync --progress --info=progress2 -v -h'
|
||||||
|
bashrc
|
||||||
|
cp /etc/skel/.bashrc ~/
|
||||||
|
|
||||||
|
# Locale
|
||||||
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
echo 'LANG=en_US.UTF-8' >>/etc/locale.conf
|
||||||
|
say 'Locale configured' yellow bold
|
||||||
|
|
||||||
|
# Time zone
|
||||||
|
ln -s -f $(find /usr/share/zoneinfo/ | shuf -n 1) /etc/localtime
|
||||||
|
hwclock --systohc --utc
|
||||||
|
say 'Time zone configured' yellow bold
|
||||||
|
|
||||||
|
# Hostname
|
||||||
|
echo ${hostname} >/etc/hostname
|
||||||
|
cat >>/etc/hosts <<- HOSTS
|
||||||
|
127.0.0.1 localhost
|
||||||
|
127.0.1.1 ${hostname}
|
||||||
|
HOSTS
|
||||||
|
say 'Hostname configured' yellow bold
|
||||||
|
|
||||||
|
# User and superuser
|
||||||
|
useradd -m -g users -G wheel -s /usr/bin/bash user || die 'User account creation has failed'
|
||||||
|
# echo -e '%wheel ALL=(ALL:ALL) NOPASSWD: ALL' >/etc/sudoers.d/zz-NOPASSWD
|
||||||
|
# install -m 0440 /dev/stdin /etc/doas.conf <<- doas
|
||||||
|
# permit nopass :root
|
||||||
|
# permit nopass :wheel
|
||||||
|
# doas
|
||||||
|
# install /dev/stdin /usr/local/bin/sudo <<- 'doas'
|
||||||
|
# #!/usr/bin/env bash
|
||||||
|
# exec doas "${@/--preserve-env*/}"
|
||||||
|
# doas
|
||||||
|
cat >/etc/pam.d/sudo <<- 'sudo'
|
||||||
|
#%PAM-1.0
|
||||||
|
auth include system-auth
|
||||||
|
account include system-auth
|
||||||
|
session include system-auth
|
||||||
|
sudo
|
||||||
|
ln -s -f /etc/pam.d/sudo /etc/pam.d/sudo-i
|
||||||
|
install -m 0440 /dev/stdin /etc/sudoers-rs <<- 'DEFAULTS'
|
||||||
|
Defaults!/usr/bin/visudo env_keep += "SUDO_EDITOR EDITOR VISUAL"
|
||||||
|
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/bin"
|
||||||
|
root ALL=(ALL:ALL) ALL
|
||||||
|
%wheel ALL=(ALL:ALL) NOPASSWD: ALL
|
||||||
|
DEFAULTS
|
||||||
|
ln -s -f /usr/bin/sudo-rs /usr/local/bin/sudo
|
||||||
|
|
||||||
|
# Disable root account
|
||||||
|
passwd -dl root >/dev/null 2>&1
|
||||||
|
|
||||||
|
mkdir -p /etc/systemd/system/getty@tty1.service.d/
|
||||||
|
cat >/etc/systemd/system/getty@tty1.service.d/override.conf <<- 'autologin'
|
||||||
|
[Service]
|
||||||
|
ExecStart=
|
||||||
|
ExecStart=-/usr/bin/agetty --autologin user --noclear %I $TERM
|
||||||
|
autologin
|
||||||
|
say "Configured root user" yellow bold
|
||||||
|
echo
|
||||||
|
|
||||||
|
say "Regenerating cpio image" yellow bold
|
||||||
|
mkinitcpio -P
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Paccache hook
|
||||||
|
cat >/etc/pacman.d/hooks/zz-paccache.hook <<paccache
|
||||||
|
[Trigger]
|
||||||
|
Operation = Upgrade
|
||||||
|
Operation = Install
|
||||||
|
Operation = Remove
|
||||||
|
Type = Package
|
||||||
|
Target = *
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Cleaning pacman cache...
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /usr/bin/paccache --remove
|
||||||
|
paccache
|
||||||
|
|
||||||
|
# Sysctl custom settings
|
||||||
|
cat >/etc/sysctl.d/10-sysctl.conf <<- SYSCTL
|
||||||
|
net.core.netdev_max_backlog = 16384
|
||||||
|
net.core.somaxconn = 8192
|
||||||
|
net.core.rmem_default = 1048576
|
||||||
|
net.core.rmem_max = 16777216
|
||||||
|
net.core.wmem_default = 1048576
|
||||||
|
net.core.wmem_max = 16777216
|
||||||
|
net.core.optmem_max = 65536
|
||||||
|
net.ipv4.tcp_rmem = 4096 1048576 2097152
|
||||||
|
net.ipv4.tcp_wmem = 4096 65536 16777216
|
||||||
|
net.ipv4.udp_rmem_min = 8192
|
||||||
|
net.ipv4.udp_wmem_min = 8192
|
||||||
|
net.ipv4.tcp_fastopen = 3
|
||||||
|
net.ipv4.tcp_timestamps = 0
|
||||||
|
net.core.default_qdisc = cake
|
||||||
|
net.ipv4.tcp_congestion_control = bbr
|
||||||
|
vm.swappiness=10
|
||||||
|
vm.vfs_cache_pressure=50
|
||||||
|
SYSCTL
|
||||||
|
|
||||||
|
# iptables
|
||||||
|
cat >/etc/iptables/userinput.rules <<- IPTABLES
|
||||||
|
|
||||||
|
## User input
|
||||||
|
# Accept all connections from hypervisor subnet
|
||||||
|
-A INPUT -s 192.168.122.0/24 -j ACCEPT
|
||||||
|
|
||||||
|
## Simple Firewall
|
||||||
|
IPTABLES
|
||||||
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules
|
||||||
|
|
||||||
|
# iptables hook
|
||||||
|
install /dev/stdin /opt/local/hooks/iptables <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/iptables/iptables.rules.pacsave ]
|
||||||
|
then
|
||||||
|
sed "/OUTPUT ACCEPT/r /etc/iptables/userinput.rules" /etc/iptables/simple_firewall.rules >/etc/iptables/iptables.rules.pacsave
|
||||||
|
mv /etc/iptables/iptables.rules.pacsave /etc/iptables/iptables.rules
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
cat >/etc/pacman.d/hooks/100-iptables.hook <<iptables
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = iptables-nft
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing iptables rules
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/iptables
|
||||||
|
iptables
|
||||||
|
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
install /dev/stdin /opt/local/hooks/localegen <<hook
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
if [ -f /etc/locale.gen.pacnew ]
|
||||||
|
then
|
||||||
|
sed -i '/#en_US.UTF-8 UTF-8/ s/#//' /etc/locale.gen.pacnew
|
||||||
|
mv /etc/locale.gen.pacnew /etc/locale.gen
|
||||||
|
locale-gen >/dev/null
|
||||||
|
fi
|
||||||
|
hook
|
||||||
|
# locale.gen.pacnew hook
|
||||||
|
cat >/etc/pacman.d/hooks/100-localegen.hook <<localegen
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = glibc
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Fixing locale.gen
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/localegen
|
||||||
|
localegen
|
||||||
|
|
||||||
|
# mkinitcpio conf hook
|
||||||
|
cat >/etc/pacman.d/hooks/85-mkinitcpio.conf.hook <<preset
|
||||||
|
[Trigger]
|
||||||
|
Operation = Install
|
||||||
|
Operation = Upgrade
|
||||||
|
Type = Package
|
||||||
|
Target = mkinitcpio
|
||||||
|
|
||||||
|
[Action]
|
||||||
|
Description = Updating mkinitcpio.conf
|
||||||
|
When = PostTransaction
|
||||||
|
Exec = /opt/local/hooks/mkinitcpio
|
||||||
|
preset
|
||||||
|
install /dev/stdin /opt/local/hooks/mkinitcpio <<'hook'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Linux preset
|
||||||
|
sed -e "s|%PKGBASE%|linux|g" \
|
||||||
|
-e "s/^fallback/#&/g" \
|
||||||
|
-e "s/ 'fallback'//" \
|
||||||
|
/usr/share/mkinitcpio/hook.preset >/etc/mkinitcpio.d/linux.preset
|
||||||
|
hook
|
||||||
|
|
||||||
|
# Wireguard
|
||||||
|
install /dev/stdin /usr/local/bin/wireguard-startup <<- 'wireguard'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
wireguard=$(ls /etc/wireguard | shuf -n 1 | sed 's/.conf//')
|
||||||
|
/usr/bin/wg-quick up ${wireguard}
|
||||||
|
/usr/bin/wg-quick down ${wireguard}
|
||||||
|
/usr/bin/wg-quick up ${wireguard}
|
||||||
|
wireguard
|
||||||
|
cat >/etc/systemd/system/wireguard-startup.service <<- 'wireguard'
|
||||||
|
[Unit]
|
||||||
|
Description=Start wireguard on boot
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/wireguard-startup
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
wireguard
|
||||||
|
|
||||||
|
# SSH
|
||||||
|
cat >/etc/ssh/sshd_config.d/zz-sshd.conf <<sshd
|
||||||
|
PermitRootLogin no
|
||||||
|
PasswordAuthentication no
|
||||||
|
AuthenticationMethods publickey
|
||||||
|
sshd
|
||||||
|
|
||||||
|
cat >/etc/ssh/ssh_config.d/zz-ssh.conf <<sshconfig
|
||||||
|
# Preferred ciphers
|
||||||
|
Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
|
||||||
|
|
||||||
|
# Only use ipv4
|
||||||
|
AddressFamily inet
|
||||||
|
sshconfig
|
||||||
|
|
||||||
|
# Polkit
|
||||||
|
mkdir -p /etc/polkit-1/rules.d/
|
||||||
|
cat >/etc/polkit-1/rules.d/49-nopasswd_global.rules <<'polkit'
|
||||||
|
/* Allow members of the wheel group to execute any actions
|
||||||
|
* without password authentication, similar to "sudo NOPASSWD:"
|
||||||
|
*/
|
||||||
|
polkit.addRule(function(action, subject) {
|
||||||
|
if (subject.isInGroup("wheel")) {
|
||||||
|
return polkit.Result.YES;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
polkit
|
||||||
|
|
||||||
|
# Persistent journal logging
|
||||||
|
cat >/etc/systemd/journald.conf.d/zz-journald.conf <<- eof
|
||||||
|
[Journal]
|
||||||
|
Storage=persistent
|
||||||
|
SystemMaxUse=100M
|
||||||
|
eof
|
||||||
|
|
||||||
|
# Default environment vars
|
||||||
|
tee -a /etc/environment >/dev/null <<- environment
|
||||||
|
EDITOR=vim
|
||||||
|
SUDO_EDITOR=vim
|
||||||
|
environment
|
||||||
|
|
||||||
|
su user <<- "CHANGEUSER"
|
||||||
|
# ssh identity
|
||||||
|
ssh-keygen -q \
|
||||||
|
-t ed25519 \
|
||||||
|
-f ~/.ssh/id_ed25519 \
|
||||||
|
-C "user@${hostname}" \
|
||||||
|
-P ""
|
||||||
|
|
||||||
|
# Config dirs
|
||||||
|
mkdir -p ~/.local/functions/ \
|
||||||
|
~/.config/{i3,menus}/ \
|
||||||
|
~/.local/share/konsole/
|
||||||
|
|
||||||
|
# i3-config
|
||||||
|
curl --fail --silent https://raw.githubusercontent.com/i3/i3/next/etc/config | sed 's/exec i3-config-wizard/# &/' > ~/.config/i3/config
|
||||||
|
cat >> ~/.config/i3/config <<- 'i3'
|
||||||
|
|
||||||
|
exec xrandr --output $(xrandr -q | grep -w 'connected primary' | awk '{print $1}') --mode 1920x1080
|
||||||
|
exec xrandr --dpi 192
|
||||||
|
|
||||||
|
exec spice-vdagent
|
||||||
|
exec VBoxClient-all
|
||||||
|
i3
|
||||||
|
|
||||||
|
# Konsole
|
||||||
|
cat > ~/.config/konsolerc <<- konsole
|
||||||
|
[Desktop Entry]
|
||||||
|
DefaultProfile=profile.profile
|
||||||
|
|
||||||
|
[General]
|
||||||
|
ConfigVersion=1
|
||||||
|
|
||||||
|
[UiSettings]
|
||||||
|
ColorScheme=
|
||||||
|
konsole
|
||||||
|
cat >~/.local/share/konsole/profile.profile <<- 'profile'
|
||||||
|
[Appearance]
|
||||||
|
Font=monospace,16,-1,2,400,0,0,0,0,0,0,0,0,0,0,1
|
||||||
|
|
||||||
|
[General]
|
||||||
|
Name=profile
|
||||||
|
Parent=FALLBACK/
|
||||||
|
|
||||||
|
[Scrolling]
|
||||||
|
HistoryMode=2
|
||||||
|
profile
|
||||||
|
|
||||||
|
# Dolphin
|
||||||
|
curl --fail --silent https://raw.githubusercontent.com/KDE/plasma-workspace/master/menu/desktop/plasma-applications.menu -o ~/.config/menus/applications.menu
|
||||||
|
kbuildsycoca6 >/dev/null 2>&1
|
||||||
|
|
||||||
|
# Autostart i3
|
||||||
|
cat >> ~/.bash_profile <<- 'autostart'
|
||||||
|
|
||||||
|
if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = 1 ]
|
||||||
|
then
|
||||||
|
exec startx /usr/bin/i3
|
||||||
|
fi
|
||||||
|
autostart
|
||||||
|
|
||||||
|
cat > ~/.local/functions/i3 <<- 'i3'
|
||||||
|
# Edit i3 config
|
||||||
|
function i3-config
|
||||||
|
{
|
||||||
|
vim ~/.config/i3/config
|
||||||
|
}
|
||||||
|
i3
|
||||||
|
|
||||||
|
cat > ~/.local/functions/alias <<- 'alias'
|
||||||
|
#
|
||||||
|
# ~/.bash_aliases
|
||||||
|
#
|
||||||
|
|
||||||
|
# ls
|
||||||
|
alias ll='ls -l -a -h'
|
||||||
|
|
||||||
|
# Grep color
|
||||||
|
alias grep='grep --color=auto'
|
||||||
|
alias egrep='egrep --color=auto'
|
||||||
|
alias fgrep='fgrep --color=auto'
|
||||||
|
|
||||||
|
# Ignore duplicate and whitespace history entries
|
||||||
|
export HISTCONTROL=ignoreboth
|
||||||
|
|
||||||
|
# Reboot and poweroff
|
||||||
|
alias poweroff='sudo poweroff'
|
||||||
|
alias reboot='sudo reboot'
|
||||||
|
|
||||||
|
# Miscellanous pacman
|
||||||
|
alias orphans='sudo pacman -Rcns $(pacman -Qtdq)'
|
||||||
|
alias unlockpacmandb='sudo rm /var/lib/pacman/db.lck && sudo pacman -Syy'
|
||||||
|
alias
|
||||||
|
|
||||||
|
cat > ~/.local/functions/functions <<- 'functions'
|
||||||
|
#
|
||||||
|
# ~/.bash_functions
|
||||||
|
#
|
||||||
|
|
||||||
|
# Pacman tools
|
||||||
|
function installer
|
||||||
|
{
|
||||||
|
sudo pacman -S ${@}
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function uninstall
|
||||||
|
{
|
||||||
|
sudo pacman -Rcns "$@"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
function syur
|
||||||
|
{
|
||||||
|
/opt/local/bin/syu &&
|
||||||
|
reboot
|
||||||
|
}
|
||||||
|
|
||||||
|
function syup
|
||||||
|
{
|
||||||
|
/opt/local/bin/syu &&
|
||||||
|
poweroff
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update configs
|
||||||
|
function update-bash
|
||||||
|
{
|
||||||
|
vim ~/.bashrc &&
|
||||||
|
source ~/.bashrc
|
||||||
|
}
|
||||||
|
functions
|
||||||
|
|
||||||
|
cat > ~/.local/functions/wireguard <<- 'wg'
|
||||||
|
# Wireguard
|
||||||
|
function wglist
|
||||||
|
{
|
||||||
|
if [ ${1} ]
|
||||||
|
then
|
||||||
|
sudo ls /etc/wireguard | grep ${1}
|
||||||
|
else
|
||||||
|
sudo ls /etc/wireguard
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function wgupdate
|
||||||
|
{
|
||||||
|
if ls | grep -q ".*\.conf"
|
||||||
|
then
|
||||||
|
sudo find /etc/wireguard -type f -delete
|
||||||
|
sudo cp -v * /etc/wireguard
|
||||||
|
echo -e '\n\t\e[1;32mWireguard profiles updated\e[0m\n'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function wd
|
||||||
|
{
|
||||||
|
for wireguard in $(sudo wg show | grep interface | awk '{print $2}')
|
||||||
|
do
|
||||||
|
sudo wg-quick down ${wireguard}
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function wu
|
||||||
|
{
|
||||||
|
wd
|
||||||
|
if [ ${1} ]
|
||||||
|
then
|
||||||
|
sudo wg-quick up $(sudo ls /etc/wireguard | grep ${1} | shuf -n 1 | sed -e 's/.conf//')
|
||||||
|
else
|
||||||
|
sudo wg-quick up $(sudo ls /etc/wireguard | shuf -n 1 | sed -e 's/.conf//')
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
wg
|
||||||
|
CHANGEUSER
|
||||||
|
CHROOT
|
||||||
|
|
||||||
|
# System services
|
||||||
|
arch-chroot /mnt systemctl enable ${systemd_services[@]} || die "Unable to start systemd services"
|
||||||
|
|
||||||
|
# SSH Authentication
|
||||||
|
if [ -f sshkeys ]
|
||||||
|
then
|
||||||
|
cat sshkeys >/mnt/home/user/.ssh/authorized_keys
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Custom pacman wrapper
|
||||||
|
install /dev/stdin /mnt/opt/local/bin/syu <<- 'syu'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Fetch latest mirrors
|
||||||
|
sudo reflector --age 24 --latest 10 --protocol https --save /etc/pacman.d/mirrorlist
|
||||||
|
|
||||||
|
# Check for new packages and continue if found
|
||||||
|
newpkg=($(checkupdates --nocolor | awk '{print $1}'))
|
||||||
|
if [ "${newpkg}" ]
|
||||||
|
then
|
||||||
|
# Sync pacman dbs
|
||||||
|
sudo pacman --ask 4 -Sy >/dev/null
|
||||||
|
|
||||||
|
# Update archlinux-keyring first
|
||||||
|
if [[ ${newpkg[@]} =~ "archlinux-keyring" ]]
|
||||||
|
then
|
||||||
|
sudo pacman --ask 4 -S archlinux-keyring
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Perform update if dependencies are satisfied
|
||||||
|
if sudo pacman --ask 4 -Syu --needed
|
||||||
|
then
|
||||||
|
echo
|
||||||
|
sudo pacdiff
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
syu
|
||||||
|
|
||||||
|
# Script for installing desktop environment
|
||||||
|
install /dev/stdin /mnt/opt/local/bin/startup <<'DESKTOPINSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Internet connection check
|
||||||
|
if nc -z -w 1 archlinux.org 443 >/dev/null 2>&1 || nc -z -w 1 google.com 443 >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
sudo timedatectl set-ntp true
|
||||||
|
sudo vim /opt/local/bin/startupscript
|
||||||
|
/opt/local/bin/startupscript
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo -e '\n\e[31mNo internet connectivity detected'
|
||||||
|
echo -e 'Connect to a network and try again'
|
||||||
|
echo -e 'Aborting installer...\e[0m\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
DESKTOPINSTALL
|
||||||
|
install /dev/stdin /mnt/opt/local/bin/startupscript <<'DESKTOPINSTALL'
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# AUR package list
|
||||||
|
aur_list=(
|
||||||
|
# jdownloader2
|
||||||
|
# instaloader
|
||||||
|
# czkawka-gui-bin
|
||||||
|
# ledger-udev ledger-live-bin
|
||||||
|
)
|
||||||
|
|
||||||
|
function enable-audio
|
||||||
|
{
|
||||||
|
sudo pacman -S --ask 4 pipewire pipewire-audio pipewire-pulse wireplumber
|
||||||
|
echo
|
||||||
|
systemctl --user --quiet enable --now wireplumber.service pipewire-pulse.service pipewire.service
|
||||||
|
}
|
||||||
|
|
||||||
|
function wireguard-setup
|
||||||
|
{
|
||||||
|
if ! sudo wg show | grep -q interface
|
||||||
|
then
|
||||||
|
echo -e '\n\e[31mNo wireguard profile installed\e[0m\n'
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function tor-installer
|
||||||
|
{
|
||||||
|
sudo pacman -S --ask 4 torbrowser-launcher
|
||||||
|
echo
|
||||||
|
torbrowser-launcher
|
||||||
|
}
|
||||||
|
|
||||||
|
wireguard-setup
|
||||||
|
tor-installer
|
||||||
|
# enable-audio # uncomment to enable audio
|
||||||
|
|
||||||
|
# AUR packages
|
||||||
|
if [ ${aur_list} ]
|
||||||
|
then
|
||||||
|
for package in ${aur_list[@]}
|
||||||
|
do
|
||||||
|
cd ~/
|
||||||
|
git clone https://aur.archlinux.org/${package}.git
|
||||||
|
cd ${package}/
|
||||||
|
makepkg -csi
|
||||||
|
echo
|
||||||
|
cd ~
|
||||||
|
rm -rf ${package}/
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add user to shared folder group if in virtualbox guest
|
||||||
|
if ls -l /dev/disk/* | grep -q VBOX
|
||||||
|
then
|
||||||
|
sudo gpasswd -a user vboxsf >/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e '\n\e[1;32mSupplementary installer completed, reboot one last time\e[0m'
|
||||||
|
sudo rm -f /opt/local/bin/startup*
|
||||||
|
sudo systemctl reboot
|
||||||
|
DESKTOPINSTALL
|
||||||
|
|
||||||
|
# Reboot only if script succeeded
|
||||||
|
if arch-chroot /mnt uname -a | grep -q Linux
|
||||||
|
then
|
||||||
|
for mount in /mnt/boot /mnt
|
||||||
|
do
|
||||||
|
until ! mount | grep -q ${mount}
|
||||||
|
do
|
||||||
|
umount ${mount}
|
||||||
|
done
|
||||||
|
done
|
||||||
|
echo -e '\e[1;34mInstaller has completed and system drive has been unmounted
|
||||||
|
Boot into the new system, connect to a network and install a DE by running \e[35mdesktop\e[34m in the terminal
|
||||||
|
Rebooting...\n\e[0m'
|
||||||
|
reboot
|
||||||
|
else
|
||||||
|
die 'Something does not feel right'
|
||||||
|
fi
|
||||||
Loading…
Add table
Add a link
Reference in a new issue