#!/bin/bash # set -e echo (){ /bin/echo "#########################################" /bin/echo "$@" /bin/echo "#########################################" } #LICENSE#{{{ # Copyright (c) 2012 Tom Wambold # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. #}}} #ABOUT#{{{ # This script will set up an Arch installation with a 100 MB /boot partition # and an encrypted LVM partition with swap and / inside. It also installs # and configures systemd as the init system (removing sysvinit). # # You should read through this script before running it in case you want to # make any modifications, in particular, the variables just below, and the # following functions: # # partition_drive - Customize to change partition sizes (/boot vs LVM) # setup_lvm - Customize for partitions inside LVM # install_packages - Customize packages installed in base system # (desktop environment, etc.) # install_aur_packages - More packages after packer (AUR helper) is # installed # set_netcfg - Preload netcfg profiles #}}} # CONFIGURE THESE VARIABLES{{{ # Drive to install to. DRIVE='/dev/sda' # Hostname of the installed machine. HOSTNAME='arch' # Encrypt everything (except /boot). Leave blank to disable. ENCRYPT_DRIVE='' # Passphrase used to encrypt the drive (leave blank to be prompted). DRIVE_PASSPHRASE='' # Root password (leave blank to be prompted). ROOT_PASSWORD='' # Main user to create (by default, added to wheel group, and others). USER_NAME='lelgenio' # Link to users dotfiles repo(git) # Assumed to have stow-able modules on its root(cd .dotfiles;stow*/) DOTFILES_URL="https://gitlab.com/$USER_NAME/dotfiles" USER_SHELL='fish' # The main user's password (leave blank to be prompted). USER_PASSWORD='' # System timezone. TIMEZONE='America/Sao_Paulo' # Country code for pacman repos COUNTRY='brazil' # Have /tmp on a tmpfs or not. Leave blank to disable. # Only leave this blank on systems with very little RAM. TMP_ON_TMPFS='TRUE' KEYMAP='br-abnt2' # KEYMAP='dvorak' LANG=pt_BR.UTF-8 # Choose your video driver # For Intel VIDEO_DRIVER="i915" # For nVidia #VIDEO_DRIVER="nouveau" # For ATI #VIDEO_DRIVER="radeon" # For generic stuff #VIDEO_DRIVER="vesa" REMOVE_PKGS=false FULL_INSTALL=false #}}} # PACKAGES{{{ set_pkgs() { # sudo to allow to run as a user later sudo pacman -Sy pkgs_base+=' base linux-zen linux-firmware intel-ucode lvm2 ' pkgs_base+=' fish bluez cronie git man-db' # netctl pkgs_base+=' netctl dhcpd ifplugged wpa_supplicant dialog' pkgs_base+=" $(pacman -Sgq base-devel)" if $IS_BIOS;then pkgs_base+=' grub' fi pkgs+=" $pkgs_base" # DE pkgs+=' ly sway waybar ruby-fusuma light mako udiskie stow yay' pkgs+=' bemenu wofi-hg j4-dmenu-desktop' # passwords and auth pkgs+=' pass gnupg pam-gnupg' # pkgs+=' i3 termite scrot pamixer' pkgs+=' nemo cinnamon-translations thunar redshift-wlr-gamma-control-git ' pkgs+=' pkgfile alacritty neovim moreutils htop-vim-git' # Audio pkgs+=' pulseaudio pavolume-git' # Fonts pkgs+=' ttf-hack inter-font otf-fira-code ttf-material-wifi-icons-git' if $FULL_INSTALL; then # Screenshot pkgs+=' grim slurp wl-clipboard wf-recorder-git' pkgs+=' httpie jq' # Theme pkgs+=' materia-custom-accent papirus-icon-theme' pkgs+=' papirus-folders-git capitaine-cursors ' # Terminal pkgs+=' tmux ranger atool p7zip tree' pkgs+=' neofetch powerline-fonts' pkgs+=' exa bat lolcat cmatrix' # extra font for ranger pkgs+=' otf-nerd-fonts-fira-code' # Network pkgs+=' wget curl bluez-utils rsync rclone nmap gnu-netcat tor mtr speedtest-cli' pkgs+=' openssh sshfs fail2ban' # Browser pkgs+=' qutebrowser youtube-dl' # Email pkgs+=' neomutt isync' # Files pkgs+=' syncthing nextcloud-client ' pkgs+=' deluge deezloader-remix-git smloadr' # Media pkgs+=' imv mpv mpd mpc ncmpcpp mpv-mpris mpdris2 playerctl' pkgs+=' blender gimp kdenlive picard image_optim' # Office pkgs+=' libreoffice-fresh libreoffice-fresh-pt-br hunspell-pt-br papirus-libreoffice-theme' # Programing pkgs+=' code neovim python-pynvim neovim-symlinks ipython how2' pkgs+=' gdb clang' # Virt pkgs+=' qemu' # Gtk pkgs+=' gtk3-nocsd-git' # Qt pkgs+=' qt5-base qt5-wayland qt5ct kvantum-qt5' # Chat pkgs+=' discord telegram-desktop telegram-cli-git' # Gaming pkgs+=' steam lutris gamemode lutris-wine-meta wine wine-mono winetricks' if [ "$VIDEO_DRIVER" == "i915" ];then pkgs+=' xf86-video-intel ' pkgs+=' lib32-mesa vulkan-intel lib32-vulkan-intel vulkan-icd-loader lib32-vulkan-icd-loader' elif [ "$VIDEO_DRIVER" == "radeon" ];then pkgs+=' xf86-video-ati' pkgs+=' lib32-mesa vulkan-radeon lib32-vulkan-radeon vulkan-icd-loader lib32-vulkan-icd-loader' elif [ "$VIDEO_DRIVER" == "nouveau" ];then pkgs+=' xf86-video-nouveau' pkgs+=' nvidia nvidia-utils lib32-nvidia-utils nvidia-settings vulkan-icd-loader lib32-vulkan-icd-loader' elif [ "$VIDEO_DRIVER" == "vesa" ];then packages+=' xf86-video-vesa' fi fi } #}}} # Initial Setup{{{ # Base install{{{ setup() { local boot_dev="$DRIVE"1 local lvm_dev="$DRIVE"2 echo 'Cleaning disk' disk_clean echo 'Creating partitions' partition_drive "$DRIVE" if "$ENCRYPT_DRIVE";then local lvm_part="/dev/mapper/lvm" if [ -z "$DRIVE_PASSPHRASE" ];then echo 'Enter a passphrase to encrypt the disk:' read -s DRIVE_PASSPHRASE fi echo 'Encrypting partition' encrypt_drive "$lvm_dev" "$DRIVE_PASSPHRASE" lvm else local lvm_part="$lvm_dev" fi echo 'Setting up LVM' setup_lvm "$lvm_part" vg00 echo 'Formatting filesystems' format_filesystems "$boot_dev" echo 'Mounting filesystems' mount_filesystems "$boot_dev" echo 'Setting repos' set_repos echo 'Installing base system' install_base echo 'Setting fstab' set_fstab echo 'Chrooting into installed system to continue setup...' cp "$0" "/mnt/setup.sh" chmod +x "/mnt/setup.sh" arch-chroot /mnt "./setup.sh" if [ -f "/mnt/setup.sh" ];then echo 'ERROR: Something failed inside the chroot, not unmounting filesystems so you can investigate.' echo 'Make sure you unmount everything before you try to run this script again.' else echo 'Unmounting filesystems' unmount_filesystems echo 'Done! Reboot system.' fi } #}}} # Remove old LVMs{{{ disk_clean(){ echo 'cleaning disk' umount -R /mnt || true swapoff -a pvs "$DRIVE"2 || return 0 for vg in $(pvs -o vg_name --nohead "$DRIVE"2) do vgremove "$vg" --yes done pvremove "$DRIVE"2 } #}}} # Partition Drive{{{ partition_drive() { local dev="$1"; shift # 100 MB /boot partition, everything else under LVM if $IS_BIOS;then parted \ --align optimal \ --script "$dev" \ mklabel msdos \ mkpart primary fat32 1M 100M \ mkpart primary ext4 100M 100% \ set 1 boot on \ set 2 lvm on else parted \ --align optimal \ --script "$dev" \ mklabel gpt \ mkpart boot 1 100M \ mkpart lvm 100M 100% \ set 1 boot on \ set 2 lvm on fi } #}}} # Encrypt_drive {{{ encrypt_drive() { local dev="$1"; shift local passphrase="$1"; shift local name="$1"; shift /bin/echo -en "$passphrase" | cryptsetup luksFormat "$dev" /bin/echo -en "$passphrase" | cryptsetup luksOpen "$dev" lvm } #}}} # setup_lvm{{{ setup_lvm() { local partition="$1"; shift local volgroup="$1"; shift local d_size=$(lsblk --noheadings --nodeps --bytes --raw --output SIZE $DRIVE) pvcreate "$partition" vgcreate "$volgroup" "$partition" # if the disk has more than if [ "$d_size" -gt $(( 50*10**9 )) ]; then # Create a 4GB swap partition lvcreate --yes -L4G "$volgroup" -n swap # Create a 50GB root partition lvcreate --yes -L '50G' "$volgroup" -n root else # Create a swap partition of 10% the disk lvcreate --yes -l '+10%FREE' "$volgroup" -n swap # Create root partition on 50% of free space lvcreate --yes -l '+50%FREE' "$volgroup" -n root fi # Use the rest of the space for home lvcreate --yes -l '+100%FREE' "$volgroup" -n home # Enable the new volumes vgchange -ay } #}}} # format_filesystems #{{{ format_filesystems() { local boot_dev="$1"; shift mkfs.fat "$boot_dev" mkfs.ext4 -L root /dev/vg00/root mkfs.ext4 -L home /dev/vg00/home mkswap /dev/vg00/swap } #}}} # mount_filesystems #{{{ mount_filesystems() { local boot_dev="$1"; shift mount /dev/vg00/root /mnt mkdir /mnt/home mount /dev/vg00/home /mnt/home mkdir /mnt/boot mount "$boot_dev" /mnt/boot swapon /dev/vg00/swap } #}}} # set_repos() {{{{ set_repos() { # /etc/pacman.conf{{{ cat > /etc/pacman.conf < /mnt/etc/fstab } #}}} # Unmount filesystems #{{{ unmount_filesystems() { umount -R /mnt swapoff /dev/vg00/swap vgchange -an if [ -n "$ENCRYPT_DRIVE" ];then cryptsetup luksClose lvm fi } #}}} # is_bios{{{ if ls /sys/firmware/efi/efivars/ &> /dev/null then IS_BIOS=false else IS_BIOS=true fi #}}} #}}} # Configuration{{{ # configure() {#{{{ configure() { local boot_dev="$DRIVE"1 local lvm_dev="$DRIVE"2 echo 'Setting hostname' set_hostname "$HOSTNAME" echo 'Setting timezone' set_timezone "$TIMEZONE" echo 'Setting locale' set_locale echo 'Setting console keymap' set_inputs echo 'Configuring initial ramdisk' set_initcpio echo 'Setting initial daemons' set_daemons "$TMP_ON_TMPFS" echo 'Configuring Bluetooth' set_bluetooth echo 'Configuring bootloader' set_bootctl "$boot_dev" "$lvm_dev" echo 'Configuring sudo' set_sudoers echo 'Configuring PAM' set_pam echo 'Configuring logind' set_logind if [ -z "$ROOT_PASSWORD" ];then echo 'Enter the root password:' read -s ROOT_PASSWORD fi echo 'Setting root password' set_root_password "$ROOT_PASSWORD" if [ -z "$USER_PASSWORD" ];then echo "Enter the password for user $USER_NAME" read -s USER_PASSWORD fi echo 'Creating initial user' create_user "$USER_NAME" "$USER_PASSWORD" echo 'setting up user' cp $0 "/home/$USER_NAME/setup.sh" chown $USER_NAME "/home/$USER_NAME/setup.sh" su $USER_NAME -c "/home/$USER_NAME/setup.sh" shred "/home/$USER_NAME/setup.sh" rm "/home/$USER_NAME/setup.sh" echo 'Updating pkgfile database' update_pkgfile } #}}} # set_hostname() {#{{{ set_hostname() { local hostname="$1"; shift /bin/echo "$hostname" > /etc/hostname cat > /etc/hosts < /etc/locale.conf < /etc/locale.gen < /etc/X11/xorg.conf.d/30-touchpad.conf < /etc/mkinitcpio.conf < /etc/netctl/ethernet-dhcp < /etc/netctl/interfaces/en-any < /etc/ly/config.ini << EOF animate = true blank_box = true hide_borders = true lang = br EOF #}}} } #}}} # set_bluetooth{{{ set_bluetooth() { mkdir -p /etc/bluetooth/ cat > /etc/bluetooth/main.conf <> /etc/default/grub < /boot/loader/entries/arch.conf < /etc/sudoers < /etc/pam.d/system-local-login < /etc/systemd/logind.conf < /dev/null # Mark some packages as explicit yay -D --asexplicit $pkgs > /dev/null # Query orphan dependencies TO_REMOVE=$(yay -Qtdq) if [ -n "$TO_REMOVE" ];then # Remove queried packages yay -Rns --noconfirm $TO_REMOVE fi } #}}} # Stow dotfiles{{{ stow_dots() { if [ ! -d ~/.dotfiles ];then git clone $DOTFILES_URL ~/.dotfiles fi cd ~/.dotfiles stow */ cd - } #}}} #}}} set_pkgs if [ ! "$USER" == "root" ];then user_setup elif is_chroot;then configure else setup fi # vim:foldmethod=marker