-
Notifications
You must be signed in to change notification settings - Fork 6
/
build.sh
executable file
·259 lines (222 loc) · 10.1 KB
/
build.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
#!/bin/bash
set -e
mkosi_output='mkosi.output'
mkosi_rootfs="$mkosi_output/image"
mkosi_cache='mkosi.cache'
mnt_usb="$(pwd)/mnt_usb"
mkosi_supported_version=22
EFI_UUID='3051-D434'
BOOT_UUID='a1492762-3fe2-4908-a8b9-118439becd26'
ROOT_UUID='d747cb2a-aff1-4e47-8a33-c4d9b7475df9'
if [ "$(whoami)" != 'root' ]; then
echo "You must be root to run this script"
echo "Try \`sudo su -\` before running this script"
exit
elif [[ -n $SUDO_USER ]] && [[ $SUDO_USER != 'root' ]]; then
echo "You must run this script as root and not with sudo"
echo "Try \`sudo su -\` before running this script"
exit
fi
[ ! -d $mnt_usb ] && mkdir $mnt_usb
[ ! -d $mkosi_output ] && mkdir $mkosi_output
[ ! -d $mkosi_cache ] && mkdir $mkosi_cache
# specify the usb device with the -d argument
while getopts :d:w arg
do
case "${arg}" in
d) usb_device=${OPTARG};;
w) wipe=true;;
esac
done
shift "$((OPTIND-1))"
[[ -n $usb_device ]] && [[ ! -b $usb_device ]] && echo $usb_device is not a block device && exit
check_mkosi() {
mkosi_cmd=$(command -v mkosi || true)
[[ -z $mkosi_cmd ]] && echo 'mkosi is not installed...exiting' && exit
mkosi_version=$(mkosi --version | awk '{print $2}' | sed 's/\..*$//')
if [[ $mkosi_version -ne $mkosi_supported_version ]]; then
echo "mkosi path: $mkosi_cmd"
echo "mkosi version: $mkosi_version"
echo -e "\nthis project was built with mkosi version $mkosi_supported_version"
echo "please install that version to continue"
exit
fi
}
mount_usb() {
# mounts an existing usb drive to mnt_usb/ so you can inspect the contents or chroot into it...etc
systemctl daemon-reload
sleep 1
# first try to mount the usb partitions via their uuid
if [ $(blkid | grep -Ei "$EFI_UUID|$BOOT_UUID|$ROOT_UUID" | wc -l) -eq 3 ]; then
[[ -z "$(findmnt -n $mnt_usb)" ]] && mount -U $ROOT_UUID $mnt_usb
[[ -z "$(findmnt -n $mnt_usb/boot)" ]] && mount -U $BOOT_UUID $mnt_usb/boot
[[ -z "$(findmnt -n $mnt_usb/boot/efi)" ]] && mount -U $EFI_UUID $mnt_usb/boot/efi
# we need this since we're using set -e
return 0
else
# otherwise mount via the device id
if [[ -z $usb_device ]]; then
echo -e "\nthe usb device can't be mounted via the uuid values"
echo -e "\ntherefore you must specify the usb device ie\n./build.sh -d /dev/sda mount\n"
exit
fi
[[ -z "$(findmnt -n $mnt_usb)" ]] && mount "$usb_device"3 $mnt_usb
[[ -z "$(findmnt -n $mnt_usb/boot)" ]] && mount "$usb_device"2 $mnt_usb/boot
[[ -z "$(findmnt -n $mnt_usb/boot/efi)" ]] && mount "$usb_device"1 $mnt_usb/boot/efi
fi
}
umount_usb() {
# if $usb_device is specified then ensure all partitions from the drive are unmounted
# this is needed for new usb devices and for systems that auto-mount usb devices
if [[ -n $usb_device ]]; then
for partition in ${usb_device}?*; do
[[ -n "$(findmnt -n $partition)" ]] && umount $partition
done
return 0
fi
# umounts usb drive from mnt_usb/
echo '### Checking to see if usb drive is mounted to mnt_usb'
if [ ! "$(findmnt -n $mnt_usb)" ]; then
return 0
fi
echo '### Unmounting usb partitions'
[[ "$(findmnt -n $mnt_usb/boot/efi)" ]] && umount $mnt_usb/boot/efi
[[ "$(findmnt -n $mnt_usb/boot)" ]] && umount $mnt_usb/boot
[[ "$(findmnt -n $mnt_usb)" ]] && umount $mnt_usb
}
wipe_usb() {
# wipe the contents of the usb drive to avoid having to repartition it
# first check if the partitions exist
umount_usb
if [ $(blkid | grep -Ei "$EFI_UUID|$BOOT_UUID|$ROOT_UUID" | wc -l) -eq 3 ]; then
[[ -z "$(findmnt -n $mnt_usb)" ]] && mount -U $ROOT_UUID $mnt_usb
if [ -e $mnt_usb/boot ]; then
[[ -z "$(findmnt -n $mnt_usb/boot)" ]] && mount -U $BOOT_UUID $mnt_usb/boot
fi
if [ -e $mnt_usb/boot/efi ]; then
[[ -z "$(findmnt -n $mnt_usb/boot/efi)" ]] && mount -U $EFI_UUID $mnt_usb/boot/efi
fi
fi
if [ ! "$(findmnt -n $mnt_usb)" ]; then
echo -e '### The usb drive did not mount\nparitioning disk\n'
wipe=false
return
fi
echo '### Wiping usb partitions'
[[ "$(findmnt -n $mnt_usb/boot/efi)" ]] && rm -rf $mnt_usb/boot/efi/* && umount $mnt_usb/boot/efi
[[ "$(findmnt -n $mnt_usb/boot)" ]] && rm -rf $mnt_usb/boot/* && umount $mnt_usb/boot
[[ "$(findmnt -n $mnt_usb)" ]] && rm -rf $mnt_usb/* && umount $mnt_usb
}
# ./build.sh mount
# ./build.sh umount
# ./build chroot
# to mount, unmount, or chroot into the usb drive (that was previously created by this script) to/from mnt_usb
if [[ $1 == 'mount' ]]; then
echo "### Mounting to $mnt_usb"
mount_usb
exit
elif [[ $1 == 'umount' ]] || [[ $1 == 'unmount' ]]; then
echo "### Umounting from $mnt_usb"
umount_usb
exit
elif [[ $1 == 'chroot' ]]; then
mount_usb
echo "### Chrooting into $mnt_usb"
arch-chroot $mnt_usb
exit
elif [[ -n $1 ]]; then
echo "$1 isn't a recogized option"
fi
[[ -z $usb_device ]] && echo "usage ./build -d [usb_device] || ./build {mount,umount,chroot}" && exit
[[ ! -e $usb_device ]] && echo -e "\n$usb_device doesn't exist\n" && exit
prepare_usb_device() {
umount_usb
is_mounted=$(lsblk -no MOUNTPOINT $usb_device | sed '/^$/d')
[[ -n "$is_mounted" ]] && echo -e "\n### The usb drive is currently mounted here\n\n$(lsblk $usb_device)\n\n### Please unmount the drive and then re-run the script\n" && exit
echo '### Preparing USB device'
# create 5GB root partition
#echo -e 'o\ny\nn\n\n\n+600M\nef00\nn\n\n\n+1G\n8300\nn\n\n\n+5G\n8300\nw\ny\n' | gdisk "$usb_device"
# root partition will take up all remaining space\
echo -e 'o\ny\nn\n\n\n+600M\nef00\nn\n\n\n+1G\n8300\nn\n\n\n\n8300\nw\ny\n' | gdisk $usb_device
mkfs.vfat -F 32 -n 'EFI-USB-FED' -i $(echo $EFI_UUID | tr -d '-') "$usb_device"1 || mkfs.vfat -F 32 -n 'EFI-USB-FED' -i $(echo $EFI_UUID | tr -d '-') "$usb_device"p1
mkfs.ext4 -U $BOOT_UUID -L 'fedora-usb-boot' -F "$usb_device"2 || mkfs.ext4 -U $BOOT_UUID -L 'fedora-usb-boot' -F "$usb_device"p2
mkfs.ext4 -U $ROOT_UUID -L 'fedora-usb-root' -F "$usb_device"3 || mkfs.ext4 -U $ROOT_UUID -L 'fedora-usb-root' -F "$usb_device"p3
# reserved for future use: kernel 6.7
#mkfs.f2fs -U $ROOT_UUID -l 'fedora-usb-root' -f "$usb_device"3 || mkfs.f2fs -U $ROOT_UUID -l 'fedora-usb-root' -f "$usb_device"p3
systemctl daemon-reload
if [ $(blkid | grep -Ei "$EFI_UUID|$BOOT_UUID|$ROOT_UUID" | wc -l) -ne 3 ]; then
echo -e "\nthe partitions and/or filesystem were not created correctly on $usb_device\nexiting\n"
exit
fi
}
mkosi_create_rootfs() {
umount_usb
mkosi clean
mkosi
}
install_usb() {
umount_usb
echo '### Cleaning up'
rm -fr $mkosi_rootfs/var/cache/dnf/*
echo '### Mounting usb partitions and copying files'
mount -U $ROOT_UUID $mnt_usb
rsync -aHAX --exclude '/tmp/*' --exclude '/boot/*' --exclude '/efi' $mkosi_rootfs/ $mnt_usb
mount -U $BOOT_UUID $mnt_usb/boot
echo "rsync -aHAX --exclude '/efi/*' $mkosi_rootfs/boot/ $mnt_usb/boot"
rsync -aHAX --exclude '/efi/*' $mkosi_rootfs/boot/ $mnt_usb/boot
mount -U $EFI_UUID $mnt_usb/boot/efi
echo "rsync -aH $mkosi_rootfs/boot/efi/ $mnt_usb/boot/efi"
rsync -aH $mkosi_rootfs/boot/efi/ $mnt_usb/boot/efi
echo '### Setting uuids for partitions in /etc/fstab'
sed -i "s/EFI_UUID_PLACEHOLDER/$EFI_UUID/" $mnt_usb/etc/fstab
sed -i "s/BOOT_UUID_PLACEHOLDER/$BOOT_UUID/" $mnt_usb/etc/fstab
sed -i "s/ROOT_UUID_PLACEHOLDER/$ROOT_UUID/" $mnt_usb/etc/fstab
sed -i "s/BOOT_UUID_PLACEHOLDER/$BOOT_UUID/" $mnt_usb/boot/efi/EFI/fedora/grub.cfg
echo '### Running systemd-machine-id-setup'
# generate a machine-id
[[ -f $mnt_usb/etc/machine-id ]] && rm -f $mnt_usb/etc/machine-id
chroot $mnt_usb systemd-machine-id-setup
chroot $mnt_usb echo "KERNEL_INSTALL_MACHINE_ID=$(cat /etc/machine-id)" > /etc/machine-info
echo "### Creating BLS (/boot/loader/entries/) entry"
arch-chroot $mnt_usb grub2-editenv create
rm -f $mnt_usb/etc/kernel/cmdline
arch-chroot $mnt_usb /image.creation/create.bls.entry
echo -e '\n### Generating GRUB config'
# /etc/grub.d/30_uefi-firmware creates a uefi grub boot entry that doesn't work on this platform
chroot $mnt_usb chmod -x /etc/grub.d/30_uefi-firmware
arch-chroot $mnt_usb grub2-mkconfig -o /boot/grub2/grub.cfg
echo "### Enabling system services"
arch-chroot $mnt_usb systemctl enable NetworkManager sshd systemd-resolved
echo "### Disabling systemd-firstboot"
chroot $mnt_usb rm -f /usr/lib/systemd/system/sysinit.target.wants/systemd-firstboot.service
echo "### SElinux labeling filesystem"
arch-chroot $mnt_usb setfiles -F -p -c /etc/selinux/targeted/policy/policy.* -e /proc -e /sys -e /dev /etc/selinux/targeted/contexts/files/file_contexts /
arch-chroot $mnt_usb setfiles -F -p -c /etc/selinux/targeted/policy/policy.* -e /proc -e /sys -e /dev /etc/selinux/targeted/contexts/files/file_contexts /boot
###### post-install cleanup ######
echo -e '\n### Cleanup'
rm -f $mnt_usb/etc/kernel/{entry-token,install.conf}
rm -rf $mnt_usb/image.creation
rm -f $mnt_usb/etc/dracut.conf.d/initial-boot.conf
rm -f $mnt_usb/etc/yum.repos.d/mkosi*.repo
# not sure how/why a $mnt_usb/root/asahi-fedora-usb directory is being created
# remove it like this to account for it being named something different
find $mnt_usb/root/ -maxdepth 1 -mindepth 1 -type d | grep -Ev '/\..*$' | xargs rm -rf
echo '### Unmounting usb partitions'
umount $mnt_usb/boot/efi
umount $mnt_usb/boot
umount $mnt_usb
echo '### Done'
}
check_mkosi
# if -w argument is specified
# ie
# ./build.sh -wd /dev/sda
# and the disk partitions already exist (from a previous install)
# then remove the files from disk vs repartitioning it
[[ $wipe = true ]] && wipe_usb || prepare_usb_device
if [[ $(command -v getenforce) ]] && [[ "$(getenforce)" = "Enforcing" ]]; then
setenforce 0
trap 'setenforce 1; exit;' EXIT SIGHUP SIGINT SIGTERM SIGQUIT SIGABRT
fi
mkosi_create_rootfs
install_usb