· 8 years ago · Jul 13, 2018, 08:44 AM
1#!/bin/bash
2#
3# This is an Arch Linux installation script for UEFI virtual machines.
4
5# Btrfs note: CoW can negatively affect performance with large files that have
6# small random writes. Disable CoW for databases and virtual machine images.
7#
8# To disable CoW for single files/directories do:
9# $ chattr +C /dir/file
10
11# Drives
12# sda is 256 GB HDD
13
14# Filesystem tree.
15# [s] = subvolume
16# [d] = directory
17#
18# /dev/sda1 [esp] (HDD) 1024M for EFI System Partition
19#
20# /dev/sda2 [arch] (HDD)
21# |
22# +-- [s] rootvol /
23# +-- [s] boot /boot
24# +-- [s] opt /opt
25# +-- [s] srv /srv
26# +-- [s] home /home
27# +-- [s] data /data
28# +-- [s] var /var
29# +-- [s] pacmanpkg /var/cache/pacman/pkg
30# +-- [s] abs /var/abs
31# +-- [s] var-cache /var/cache
32# +-- [s] var-log /var/log
33# +-- [s] var-spool /var/spool
34# +-- [s] var-tmp /var/tmp
35# +-- [d] snapshots
36# |
37# +-- [s] rootvol /.snapshots
38# +-- [s] home /home/.snapshots
39# +-- [s] var /var/.snapshots
40
41confirm_to_run_command() {
42 local response
43 read -r -p "Run command: \`$1\` ? [Y/N] " response
44
45 if [[ ! "${response}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
46 exit 0
47 fi
48
49 echo -e '\n'
50
51 eval "$1"
52}
53
54clear
55
56echo -e 'Installing Arch Linux on virtual machine...\n'
57
58# Verify the boot mode.
59# To check to boot mode we can also test if the following path exists, like so:
60#
61# ls /sys/firmware/efi/efivars
62#
63# If it exists the system is booted in UEFI mode otherwise it may be booted in
64# BIOS or CSM mode.
65confirm_to_run_command 'efivar -l'
66
67if [ -f /sys/firmware/efi/efivars ]; then
68 echo -e 'System is booted in UEFI mode.\n'
69else
70 echo -e 'System is booted in BIOS mode.\n'
71fi
72
73# Connect to the internet.
74# Since the VM is on a wired connection so it might just work right away.
75# Configuration is needed for wireless connections.
76confirm_to_run_command 'ping -c 3 archlinux.org'
77
78# Update the system clock.
79confirm_to_run_command 'timedatectl set-ntp true'
80confirm_to_run_command 'timedatectl set-timezone Asia/Karachi'
81confirm_to_run_command 'timedatectl status'
82
83# View disks and partitions.
84confirm_to_run_command 'lsblk'
85
86# Erase the partition table. Zero out the first 10000 blocks of the disk.
87confirm_to_run_command 'sgdisk --zap-all /dev/sda'
88confirm_to_run_command 'dd if=/dev/zero of=/dev/sda bs=1M count=10000 status=progress'
89
90# View disks and partitions again to ensure udev has given them the names
91# (i.e. /dev/sdX where X is a, b, c, etc.) you'd want them to have.
92confirm_to_run_command 'lsblk'
93
94# Check UEFI mode (if UEFI variable prints you're in UEFI mode).
95confirm_to_run_command 'efivar -l'
96
97# Use cgdisk to create GPT partitions.
98# UEFI and BIOS are going to have different partition layouts.
99#
100# 1024 MB FAT32 "esp" partition; cgdisk code ef00.
101# The rest for btrfs "arch" partition; cgdisk code 8300.
102confirm_to_run_command 'cgdisk /dev/sda'
103
104# Check if the disk partitions are set as desired.
105confirm_to_run_command 'lsblk'
106
107# Format partitions with desired filesystems.
108confirm_to_run_command 'mkfs.fat -F32 -n esp /dev/sda1'
109confirm_to_run_command 'mkfs.btrfs -L arch /dev/sda2'
110
111# Mount main btrfs partition.
112confirm_to_run_command 'mkdir -p /mnt/btrfs-root'
113confirm_to_run_command 'mount /dev/sda2 /mnt/btrfs-root'
114
115# Create btrfs subvolumes for system.
116confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/rootvol'
117confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/boot'
118confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/opt'
119confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/srv'
120confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/home'
121confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/data'
122confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/var'
123confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/pacmanpkg'
124confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/abs'
125# abs is Arch Build System. It's created inside var/abs but subvol is called
126# abs; not var-abs.
127confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/var-cache'
128confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/var-log'
129confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/var-spool'
130confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/var-tmp'
131
132# Create btrfs subvolumes for snapshots.
133confirm_to_run_command 'mkdir -p /mnt/btrfs-root/snapshots'
134confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/snapshots/rootvol'
135confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/snapshots/home'
136confirm_to_run_command 'btrfs subvolume create /mnt/btrfs-root/snapshots/var'
137
138# List all subvolumes for /mnt/btrfs-root.
139confirm_to_run_command 'btrfs subvolume list -a /mnt/btrfs-root'
140
141# Unmount.
142confirm_to_run_command 'umount -R /mnt/btrfs-root'
143
144# Mount root subvolume.
145confirm_to_run_command 'mount -o subvol=rootvol /dev/sda2 /mnt/btrfs-root'
146
147# Create directories in the root subvolume and mount other subvolumes.
148# Don't change the order of the commands since to create directories inside
149# another subvolume it should be mounted first.
150confirm_to_run_command 'mkdir -p /mnt/btrfs-root/{boot,home,data,var,opt,srv,.snapshots}'
151
152confirm_to_run_command 'mount -o subvol=boot /dev/sda2 /mnt/btrfs-root/boot'
153confirm_to_run_command 'mount -o subvol=home /dev/sda2 /mnt/btrfs-root/home'
154confirm_to_run_command 'mount -o subvol=data /dev/sda2 /mnt/btrfs-root/data'
155confirm_to_run_command 'mount -o subvol=var /dev/sda2 /mnt/btrfs-root/var'
156confirm_to_run_command 'mount -o subvol=opt /dev/sda2 /mnt/btrfs-root/opt'
157confirm_to_run_command 'mount -o subvol=srv /dev/sda2 /mnt/btrfs-root/srv'
158confirm_to_run_command 'mount -o subvol=snapshots/rootvol /dev/sda2 /mnt/btrfs-root/.snapshots'
159
160confirm_to_run_command 'mkdir -p /mnt/btrfs-root/var/{abs,cache,log,spool,tmp,.snapshots}'
161confirm_to_run_command 'mkdir -p /mnt/btrfs-root/home/.snapshots'
162confirm_to_run_command 'mount -o subvol=abs /dev/sda2 /mnt/btrfs-root/var/abs'
163confirm_to_run_command 'mount -o subvol=var-cache /dev/sda2 /mnt/btrfs-root/var/cache'
164confirm_to_run_command 'mount -o subvol=var-log /dev/sda2 /mnt/btrfs-root/var/log'
165confirm_to_run_command 'mount -o subvol=var-spool /dev/sda2 /mnt/btrfs-root/var/spool'
166confirm_to_run_command 'mount -o subvol=var-tmp /dev/sda2 /mnt/btrfs-root/var/tmp'
167confirm_to_run_command 'mount -o subvol=snapshots/home /dev/sda2 /mnt/btrfs-root/home/.snapshots'
168confirm_to_run_command 'mount -o subvol=snapshots/var /dev/sda2 /mnt/btrfs-root/var/.snapshots'
169
170confirm_to_run_command 'mkdir -p /mnt/btrfs-root/var/cache/pacman/pkg'
171confirm_to_run_command 'mount -o subvol=pacmanpkg /dev/sda2 /mnt/btrfs-root/var/cache/pacman/pkg'
172
173# List all subvolumes for /mnt/btrfs-root.
174confirm_to_run_command 'btrfs subvolume list -a /mnt/btrfs-root'
175
176# Mount EFI System Partition.
177confirm_to_run_command 'mkdir -p /mnt/btrfs-root/boot/efi'
178confirm_to_run_command 'mount /dev/sda1 /mnt/btrfs-root/boot/efi'
179
180# Select a mirror.
181confirm_to_run_command 'nano /etc/pacman.d/mirrorlist'
182
183# Check internet connection.
184# It should already be connected since this VM has a wired connection.
185confirm_to_run_command 'ping -c 3 www.google.com'
186
187echo -e 'End of script.\n'