-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgentoo-deploy.sh
339 lines (275 loc) · 10.5 KB
/
gentoo-deploy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
#!/bin/bash
########################################
#
# Gentoo Deploy Script
# Usage: ./gentoo-deploy.sh install
#
# Creates a simple MBR install of Gentoo
#
########################################
SCRIPT=$(realpath "$0")
PACKAGE_LIST=$(realpath packages.txt)
GENFSTAB=$(realpath glacion-genfstab/genfstab)
ROOT_DIR="/mnt/gentoo"
BOOT_DIR="${ROOT_DIR}/boot"
HOME_DIR="${ROOT_DIR}/home"
TFTP="192.168.0.3"
MIRROR="https://bouncer.gentoo.org/fetch/root/all/"
ARCH="amd64"
LOCATION="$MIRROR/releases/$ARCH/autobuilds/current-stage3-$ARCH/"
FOLDER="20210321"
STAGE3="stage3-$ARCH-$FOLDER.tar.xz"
FSTAB="/etc/fstab"
MAKECONF="/etc/portage/make.conf"
PACKAGELICENSE="/etc/portage/package.license"
PACKAGEKEYWORDS="/etc/portage/package.keywords"
MAKECFLAGS='-march=native -O3 -pipe'
MAKEOPTS="-j$(($(nproc) + 1))"
MAKEUSE='-bindist -systemd -consolekit -webkit -vulkan -vaapi -vdpau -opencl -bluetooth -kde \
-llvm -mdadm elogind udev threads alsa pulseaudio mpeg mp3 flac aac lame midi ogg vorbis \
x264 xvid win32codecs real png jpeg jpeg2k raw gif svg tiff xml opengl bash \
bash-completion i3 dbus vim vim-syntax git dbus qt5 cairo gtk unicode fontconfig \
truetype wifi laptop acpi lm_sensors dvd dvdr cdr cdrom policykit X dhcpcd \
logrotate'
MAKEPYTHON='python3_8'
MAKEINPUTDEVICES='evdev synaptics mouse keyboard'
MAKEVIDEOCARDS='intel i965'
MAKELINGUAS='en_US en'
unmount_disk() {
# Get all mounted partitions other than swap
mounts=$(lsblk -i -o kname,fstype,mountpoint --noheadings $1 |
awk 'NF==3 && ($2 != "swap") {print $1,$2,$3}' |
sort -r -k 3
)
# Get swap partitions
swap_mounts=$(lsblk -i -o kname,fstype --noheadings $1 |
awk '$2 == "swap" {print $1}'
)
# Unmount partitions
IFS=$'\n'
for mounted_part in $mounts; do
umount -l /dev/$(awk '{print $1}' <<< "$mounted_part")
done
# Disable any swap partitions
for swap_mount in $swap_mounts; do
swapoff /dev/$(awk '{print $1}' <<< "$swap_mount")
done
}
install() {
#######################################################
# Prepare the disks for the MBR Gentoo Install
# partition target disk
# create filesystems in each partition
# Show all disks for the user
lsblk
local disk
# Prompt user for input and save the input
read -rp "Which disk should be erased? (i.e. /dev/sdj): " disk
echo "WARNING! BLOCK DEVICE: $disk WILL BE ERASED IN 60 SECONDS..."
echo "PLEASE MAKE SURE THIS IS THE CORRECT DISK"
# Print countdown and wait 60 seconds before erasing disk
for seconds in {60..1}; do
printf "PRESS CTRL+C TO CANCEL (%2d seconds)\r" ${seconds}
sleep 1
done
unmount_disk "$disk"
# Create new partitions and setup for an MBR install
parted --script "$disk" --align optimal \
mklabel msdos \
mkpart primary ext2 0% 1GiB \
set 1 boot on \
mkpart primary linux-swap 1GiB 9GiB \
mkpart primary ext4 9GiB 30GiB \
mkpart primary ext4 30GiB 100% >&2
if [ $? -ne 0 ]; then
echo "Error! Something went wrong while writing partion" >&2
echo "Disk is in an unknown state. You are on your own" >&2
exit 1
fi
# Make local names for disk partitions
local boot_dev=${disk}1
local swap_dev=${disk}2
local root_dev=${disk}3
local home_dev=${disk}4
# Create the filesystems
mkfs.ext4 -F "$boot_dev"
mkswap -f "$swap_dev"
mkfs.ext4 -F "$root_dev"
mkfs.ext4 -F "$home_dev"
#######################################################
# Mount the partitions in the proper order
# root must be mounted first
# then either /boot or /home
if [[ $(mount "$root_dev" "$ROOT_DIR" >&2) && $(findmnt -M "$ROOT_DIR" >&2) ]]; then
echo "Error! Cannot mount $root_dev to $ROOT_DIR..." >&2
exit 1
fi
mkdir "$BOOT_DIR"
mkdir "$HOME_DIR"
if [[ $(mount "$boot_dev" "$BOOT_DIR" >&2) && $(findmnt -M "$BOOT_DIR" >&2) ]]; then
echo "Error! Cannot mount $boot_dev to $BOOT_DIR..." >&2
exit 1
fi
if [[ $(mount "$home_dev" "$HOME_DIR" >&2) && $(findmnt -M "$HOME_DIR" >&2) ]]; then
echo "Error! Cannot mount $home_dev to $HOME_DIR..." >&2
exit 1
fi
if [ $(swapon "$swap_dev" >&2) ]; then
echo "Error! Failed to activate SWAP partition." >&2
exit 1
fi
#######################################################
# Fetch stage3 tarball from local or remote sources
# either from TFTP or remote mirror
# then extract archive to $ROOT_DIR
cd "$ROOT_DIR" || exit
# If STAGE3 does not exist, get from tftp server
if [ ! -f "$STAGE3" ]; then
echo "Warning! $STAGE3 not in directory, downloading from local tftp..."
curl --connect-timeout 30 --speed-time 15 --speed-limit 500 -o "$STAGE3" tftp://"$TFTP"/gentoo-deploy/"$FOLDER"/"$STAGE3" >&2
fi
# If STAGE3 does not exist, get from the internet
if [ ! -f "$STAGE3" ]; then
echo "Warning! $STAGE3 not in directory, downloading from mirror..."
wget -l1 -np "${LOCATION}" -P ./ -A index.html -O index.tmp >&2
STAGE3=$(grep -m1 -Eo ">stage3-${ARCH}-[0-9]*.*\.tar\.xz" index.tmp | cut -c 2-)
wget -N "${LOCATION}/${STAGE3}"
fi
# Extract STAGE3 to $ROOT_DIR directory
if [ $(tar xpvf "$STAGE3" --xattrs-include='*.*' --numeric-owner >&2) ]; then
echo "File does not exist, maybe it failed to download?"
exit 1
fi
#######################################################
# Modify make.conf and add make vars and use flags
# update cflags
# and update global use flags
# Define CFLAGS and CXXFLAGS
if [ -n "$MAKECFLAGS" ]; then
sed -i "s/COMMON_FLAGS=.*/COMMON_FLAGS=\"$MAKECFLAGS\"/" ".$MAKECONF"
fi
# Append MAKEOPTS and other make vars to make.conf
echo "MAKEOPTS=\"$MAKEOPTS\"" >> ".$MAKECONF"
echo "USE=\"$MAKEUSE\"" >> ".$MAKECONF"
echo "PYTHON_TARGETS=\"$MAKEPYTHON\"" >> ".$MAKECONF"
echo "INPUT_DEVICES=\"$MAKEINPUTDEVICES\"" >> ".$MAKECONF"
echo "VIDEO_CARDS=\"$MAKEVIDEOCARDS\"" >> ".$MAKECONF"
echo "LINGUAS=\"$MAKELINGUAS\"" >> ".$MAKECONF"
# Select Mirrors
mirrorselect -s10 -o >> ".$MAKECONF"
# Copy DNS info before chrooting
cp -L /etc/resolv.conf ./etc/
# Copy itself into the chroot directory before chrooting
cp -L -u "$SCRIPT" ./root/gentoo-deploy.sh
cp -L -u "$GENFSTAB" ./root/genfstab
chmod +x ./root/genfstab
# Copy package list to chroot directory before chrooting
cp -L "$PACKAGE_LIST" ./root/packages.txt
# Mount important partitions before chrooting
mount -t proc proc ./proc
mount --rbind /sys ./sys
mount --rbind /dev ./dev
echo "Chrooting..." >&2
source /etc/profile
chroot ./ /bin/bash -c "/root/gentoo-deploy.sh chroot ${disk}"
}
chroot_install() {
# Show visual (chroot) on shell prompt
export PS1="(chroot) ${PS1}"
#######################################################
# Setup the Portage Build system
# define a system profile
# emerge all packages required by global use flags
# Update the Gentoo ebuild repository to the latest
mkdir -p "$PACKAGEKEYWORDS"
emerge-webrsync
emerge --sync
emerge --oneshot portage
# Detect all CPU features and set use flags in make.conf
emerge --oneshot --ask=n --autounmask-continue app-portage/cpuid2cpuflags
echo "CPU_FLAGS_X86=\"$(cpuid2cpuflags | cut -c 15-)\"" >> "$MAKECONF"
# Choose the portage profile
eselect profile list
local profile_num=1
read -rp "Which profile?: " profile_num
eselect profile set "$profile_num"
# Set the hostname for the machine
local hostname
read -rp "Enter desired hostname for this machine: " hostname
echo "hostname=\"${hostname}\"" > /etc/conf.d/hostname
# Change root password
echo "Set the password for the root account"
while passwd
[ $? -ne 0 ]
do :; done
# Update the @world set
emerge --ask=n --autounmask-continue --with-bdeps=y --verbose --update --deep --newuse @world
# Set timezone
echo "America/Chicago" > /etc/timezone
# Set locales
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
# Automatically update package config
env-update && source /etc/profile
# Create fstab
/root/genfstab -U / >> "$FSTAB"
#######################################################
# Setup the Gentoo Kernel and install packages
# unmask and install required firmware blobs
# emerge and configure the gentoo kernel
# emerge optional packages from packages.txt
# Install firmware for special hardware
echo "sys-kernel/linux-firmware linux-fw-redistributable no-source-code" >> "$PACKAGELICENSE"
emerge --ask=n --autounmask-continue sys-kernel/linux-firmware
# Install Kernel Sources
emerge --ask=n --autounmask-continue sys-kernel/gentoo-sources
emerge --ask=n --autounmask-continue sys-kernel/genkernel
genkernel all
# Install a few helpful packages and services
local packages
packages=$(sed -e 's/#.*$//' -e '/^$/d' /root/packages.txt | tr '\n' ' ')
emerge --ask=n --autounmask-continue --keep-going "$packages"
# Enable some services to the default runlevel
rc-update add NetworkManager default
rc-update add sysklogd default
# disk variable is passed as $1 before chroot
local disk="$1"
# Install the bootloader
emerge --ask=n --autounmask-continue sys-boot/grub:2
grub-install "$disk"
grub-mkconfig -o /boot/grub/grub.cfg
}
main() {
# Script must be ran as root user
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root"
exit 1
fi
# Open stderr and forward errors to a log file
exec 3>&2
exec 2> >(tee "$SCRIPT.log" >&2)
# Check for commandline parameter
if [ "$1" = "install" ]; then
install || exit
elif [ "$1" = "chroot" ]; then
chroot_install "$2" || exit
else
echo "Could not understand $1"
echo "To start installation, please run $SCRIPT install"
exit 1
fi
echo "Deployment Complete."
# Print countdown and wait 15 seconds before rebooting
for seconds in {15..1}; do
printf "Machine will reboot in %2d seconds...\r" ${seconds}
sleep 1
done
# Cleanup and remove installation files
rm "${ROOT}/index.tmp"
rm "${ROOT}/stage3-*.tar*"
rm "${ROOT}/root/packages.txt"
rm "${ROOT}/root/genfstab"
rm "${ROOT}/root/gentoo-deploy.sh"
shutdown -r now
}
main "$@"