-
Notifications
You must be signed in to change notification settings - Fork 5
/
centos.sh
250 lines (215 loc) · 10.8 KB
/
centos.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
# SPDX-License-Identifier: GPL-3.0-or-later
. fedora.sh # Inherit Fedora's RPM functions.
options[loadpin]=
options[verity_sig]=
DEFAULT_RELEASE=9
function create_buildroot() {
local -r cver=20241112.0
local -r image="https://cloud.centos.org/centos/${options[release]:=$DEFAULT_RELEASE}-stream/$DEFAULT_ARCH/images/CentOS-Stream-Container-Minimal-${options[release]}-$cver.$DEFAULT_ARCH.tar.xz"
opt bootable && packages_buildroot+=(kernel-core zstd)
opt bootable && [[ ${options[arch]:-$DEFAULT_ARCH} == *[3-6x]86* ]] && packages_buildroot+=(linux-firmware microcode_ctl)
opt bootable && opt squash && packages_buildroot+=(kernel-modules)
opt gpt && packages_buildroot+=(util-linux)
opt gpt && opt uefi && packages_buildroot+=(dosfstools mtools)
opt read_only || packages_buildroot+=(findutils)
opt read_only && ! opt squash && packages_buildroot+=(erofs-utils)
opt secureboot && packages_buildroot+=(pesign)
opt selinux && packages_buildroot+=(kernel-core policycoreutils qemu-kvm-core zstd)
opt squash && packages_buildroot+=(squashfs-tools)
opt uefi && packages_buildroot+=(binutils centos-logos ImageMagick systemd-boot-unsigned)
opt uefi_vars && packages_buildroot+=(dosfstools mtools qemu-kvm-core)
opt verity && packages_buildroot+=(veritysetup)
opt verity_sig && opt bootable && packages_buildroot+=(kernel-devel keyutils)
packages_buildroot+=(crypto-policies-scripts e2fsprogs openssl systemd)
$curl -L "$image" > "$output/image.txz"
verify_distro "$output/image.txz"
$tar -C "$output" --transform='s,^\([^/]*/\)\?,tmp/,' -xJf "$output/image.txz"
$tar -C "$buildroot" -xf "$output/tmp/layer.tar"
$rm -fr "$output/image.txz" "$output/tmp"
# Disable bad packaging options.
$sed -i -e '/^[[]main]/ainstall_weak_deps=False' "$buildroot/etc/dnf/dnf.conf"
[[ -x $buildroot/usr/bin/dnf ]] || $ln -fns dnf-3 "$buildroot/usr/bin/dnf"
configure_initrd_generation
initialize_buildroot "$@"
opt networkd || { opt read_only && ! opt squash ; } || opt uefi && enable_repo_epel # EPEL now has core RPMs.
script "${packages_buildroot[@]}" << 'EOF'
dnf --assumeyes --setopt={keepcache=1,tsflags=nodocs} upgrade
exec dnf --assumeyes --setopt={keepcache=1,tsflags=nodocs} install "$@"
EOF
}
# Override package installation to go back to pre-dnf5.
eval "$(declare -f install_packages |
$sed 's/libdnf5/dnf/g;s/ --use-host-config / /')"
function distro_tweaks() {
exclude_paths+=('usr/lib/.build-id')
rm -fr root/etc/rc.{d,local}
mkdir -p root/usr/lib/systemd/system/local-fs.target.wants
ln -fst root/usr/lib/systemd/system/local-fs.target.wants ../tmp.mount
[[ -d root/etc/crypto-policies ]] &&
base_dir=$PWD/root/etc/crypto-policies \
profile_dir=$PWD/root/usr/share/crypto-policies \
update-crypto-policies --no-reload --set FUTURE
[[ -s root/etc/dnf/dnf.conf ]] &&
sed -i -e '/^[[]main]/ainstall_weak_deps=False' root/etc/dnf/dnf.conf
[[ -s root/etc/locale.conf ]] ||
echo LANG=C.UTF-8 > root/etc/locale.conf
sed -i -e 's/^[^#]*PS1="./&\\$? /;s/mask 002$/mask 022/' root/etc/bashrc
}
# Override the UEFI logo source to use the dark background variant for CentOS.
eval "$(declare -f save_boot_files | $sed \
-e s/magick/convert/ \
-e "s/-trim/& -color-matrix '0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0'/" \
-e 's,fedora\(-logos/fedora_logo\),centos\1_darkbackground,')"
# Override SELinux labeling to work with the CentOS kernel (and no busybox).
function relabel() if opt selinux
then
local -r root=$(mktemp --directory --tmpdir="$PWD" relabel.XXXXXXXXXX)
mkdir -p "$root"/{bin,dev,etc,lib,proc,sys,sysroot}
ln -fns lib "$root/lib64"
ln -fst "$root/etc" ../sysroot/etc/selinux
cat << 'EOF' > "$root/init" ; chmod 0755 "$root/init"
#!/bin/bash -eux
trap -- 'echo o > /proc/sysrq-trigger ; read -rst 60' EXIT
export PATH=/bin
mount -t devtmpfs devtmpfs /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys
for mod in sd_mod libata ata_piix jbd2 mbcache ext4
do insmod "/lib/$mod.ko"
done
mount /dev/sda /sysroot
load_policy -i
policy=$(sed -n 's/^SELINUXTYPE=//p' /etc/selinux/config)
setfiles -vFr /sysroot \
"/sysroot/etc/selinux/$policy/contexts/files/file_contexts" /sysroot
[[ -x /bin/mksquashfs ]] && /bin/mksquashfs /sysroot /sysroot/squash.img \
-noappend -comp zstd -Xcompression-level 22 -wildcards -ef /ef
[[ -x /bin/mkfs.erofs ]] && IFS=$'\n' && /bin/mkfs.erofs \
$(while read ; do echo "$REPLY" ; done < /ef) \
/sysroot/erofs.img /sysroot
echo SUCCESS > /sysroot/LABEL-SUCCESS
umount /sysroot
EOF
if opt squash
then
disk=squash.img
echo "$disk" > "$root/ef"
(IFS=$'\n' ; echo "${exclude_paths[*]}") >> "$root/ef"
cp -t "$root/bin" /usr/sbin/mksquashfs
elif opt read_only
then
disk=erofs.img
local path
for path in "$disk" "${exclude_paths[@]//\*/[^/]*}"
do
path=${path//+/[+]} ; path=${path//./[.]}
echo "--exclude-regex=^${path//\?/[^/]}$"
done > "$root/ef"
cp -t "$root/bin" /usr/bin/mkfs.erofs
fi
cp -t "$root/bin" \
/usr/*bin/{bash,load_policy,mount,sed,setfiles,umount}
cp /usr/bin/kmod "$root/bin/insmod"
find /usr/lib/modules/*/kernel '(' \
-name sd_mod.ko.xz -o \
-name libata.ko.xz -o -name ata_piix.ko.xz -o \
-name ext4.ko.xz -o -name jbd2.ko.xz -o -name mbcache.ko.xz -o \
-false ')' -exec cp -at "$root/lib" '{}' +
unxz "$root"/lib/*.xz
{ ldd "$root"/bin/* || : ; } |
sed -n 's,^[^/]\+\(/[^ ]*\).*,\1,p' | sort -u |
while read -rs ; do cp -t "$root/lib" "$REPLY" ; done
find "$root" -mindepth 1 -printf '%P\n' |
cpio -D "$root" -H newc -R 0:0 -o |
zstd --threads=0 --ultra -22 > relabel.img
umount root
local -r cores=$([[ -e /dev/kvm ]] && nproc)
/usr/libexec/qemu-kvm -nodefaults -no-reboot -serial stdio < /dev/null \
${cores:+-cpu host -smp cores="$cores"} -m 1G \
-kernel /lib/modules/*/vmlinuz -initrd relabel.img \
-append 'console=ttyS0 enforcing=0 lsm=selinux' \
-drive file=/dev/loop-root,format=raw,media=disk
mount /dev/loop-root root
opt read_only && mv -t . "root/$disk"
[[ -s root/LABEL-SUCCESS ]] ; rm -f root/LABEL-SUCCESS
fi
# Override early microcode ramdisk creation for CentOS Intel paths.
eval "$(declare -f build_microcode_ramdisk | $sed \
-e s,lib/firmware/i,usr/share/microcode_ctl/ucode_with_caveats/intel/i,g)"
# Override dm-init with userspace since the CentOS kernel disables it.
eval "$(
declare -f kernel_cmdline | $sed 's/opt ramdisk[ &]*dmsetup=/dmsetup=/'
declare -f configure_initrd_generation | $sed 's/if opt ramdisk/if true/'
)"
# Override UEFI variable generation to deal with CentOS disabling vvfat.
eval "$(declare -f set_uefi_variables | $sed -e '/timeout/i\
mkfs.vfat -CF 32 -n ENROLL "$root.img" $(( 260 << 10 ))\
MTOOLS_SKIP_CHECK=1 mcopy -Qsi "$root.img" "$root"/* ::/
s|file="fat:[^,]*"|file="$root.img"|
s,qemu-system-\S*,/usr/libexec/qemu-kvm,')"
# CentOS container releases are horribly broken. Check sums with no signature.
function verify_distro() [[
$($sha256sum "$1") == $(case $DEFAULT_ARCH in
aarch64) echo ff4189a767e1e30bd4579d89ed5e4007657c9258901365a881935cad22277fde ;;
ppc64le) echo a59f8a6e61bfa5574de4eca14ed93bb5c8ea356cb76c10f14e30c0a07f4359ac ;;
s390x) echo 33a3e024ec9f2b2409e99b44e4c8d4987d09f4ef29de2342f342b366afd0a57e ;;
x86_64) echo c3be98f79edc2b4c4db596df9c1896fda934a44f2aaec6d9d7037c69f73f4812 ;;
esac)\ *
]]
# OPTIONAL (BUILDROOT)
function enable_repo_epel() {
local -r key="RPM-GPG-KEY-EPEL-${options[release]}"
local -r url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-${options[release]}.noarch.rpm"
$sed -i -e '/^[[]crb]$/,/^$/s/^enabled=.*/enabled=1/' "$buildroot/etc/yum.repos.d/centos.repo"
[[ -s $buildroot/etc/pki/rpm-gpg/$key ]] || script "$url"
} << 'EOF'
cat << 'EOG' > /tmp/key ; rpmkeys --import /tmp/key
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGE3mOsBEACsU+XwJWDJVkItBaugXhXIIkb9oe+7aadELuVo0kBmc3HXt/Yp
CJW9hHEiGZ6z2jwgPqyJjZhCvcAWvgzKcvqE+9i0NItV1rzfxrBe2BtUtZmVcuE6
2b+SPfxQ2Hr8llaawRjt8BCFX/ZzM4/1Qk+EzlfTcEcpkMf6wdO7kD6ulBk/tbsW
DHX2lNcxszTf+XP9HXHWJlA2xBfP+Dk4gl4DnO2Y1xR0OSywE/QtvEbN5cY94ieu
n7CBy29AleMhmbnx9pw3NyxcFIAsEZHJoU4ZW9ulAJ/ogttSyAWeacW7eJGW31/Z
39cS+I4KXJgeGRI20RmpqfH0tuT+X5Da59YpjYxkbhSK3HYBVnNPhoJFUc2j5iKy
XLgkapu1xRnEJhw05kr4LCbud0NTvfecqSqa+59kuVc+zWmfTnGTYc0PXZ6Oa3rK
44UOmE6eAT5zd/ToleDO0VesN+EO7CXfRsm7HWGpABF5wNK3vIEF2uRr2VJMvgqS
9eNwhJyOzoca4xFSwCkc6dACGGkV+CqhufdFBhmcAsUotSxe3zmrBjqA0B/nxIvH
DVgOAMnVCe+Lmv8T0mFgqZSJdIUdKjnOLu/GRFhjDKIak4jeMBMTYpVnU+HhMHLq
uDiZkNEvEEGhBQmZuI8J55F/a6UURnxUwT3piyi3Pmr2IFD7ahBxPzOBCQARAQAB
tCdGZWRvcmEgKGVwZWw5KSA8ZXBlbEBmZWRvcmFwcm9qZWN0Lm9yZz6JAk4EEwEI
ADgWIQT/itE0RZcQbs6BO5GKOHK/MihGfAUCYTeY6wIbDwULCQgHAgYVCgkICwIE
FgIDAQIeAQIXgAAKCRCKOHK/MihGfFX/EACBPWv20+ttYu1A5WvtHJPzwbj0U4yF
3zTQpBglQ2UfkRpYdipTlT3Ih6j5h2VmgRPtINCc/ZE28adrWpBoeFIS2YAKOCLC
nZYtHl2nCoLq1U7FSttUGsZ/t8uGCBgnugTfnIYcmlP1jKKA6RJAclK89evDQX5n
R9ZD+Cq3CBMlttvSTCht0qQVlwycedH8iWyYgP/mF0W35BIn7NuuZwWhgR00n/VG
4nbKPOzTWbsP45awcmivdrS74P6mL84WfkghipdmcoyVb1B8ZP4Y/Ke0RXOnLhNe
CfrXXvuW+Pvg2RTfwRDtehGQPAgXbmLmz2ZkV69RGIr54HJv84NDbqZovRTMr7gL
9k3ciCzXCiYQgM8yAyGHV0KEhFSQ1HV7gMnt9UmxbxBE2pGU7vu3CwjYga5DpwU7
w5wu1TmM5KgZtZvuWOTDnqDLf0cKoIbW8FeeCOn24elcj32bnQDuF9DPey1mqcvT
/yEo/Ushyz6CVYxN8DGgcy2M9JOsnmjDx02h6qgWGWDuKgb9jZrvRedpAQCeemEd
fhEs6ihqVxRFl16HxC4EVijybhAL76SsM2nbtIqW1apBQJQpXWtQwwdvgTVpdEtE
r4ArVJYX5LrswnWEQMOelugUG6S3ZjMfcyOa/O0364iY73vyVgaYK+2XtT2usMux
VL469Kj5m13T6w==
=Mjs/
-----END PGP PUBLIC KEY BLOCK-----
EOG
curl -L "$1" > epel.rpm
rpm --checksig --define=_pkgverify_{'flags 0x0','level all'} epel.rpm
rpm --install epel.rpm
exec rm -f epel.rpm
EOF
# OPTIONAL (IMAGE)
function save_rpm_db() {
opt selinux && local policy &&
for policy in root/etc/selinux/*/contexts/files
do echo /usr/lib/rpm-db /var/lib/rpm >> "$policy/file_contexts.subs_dist"
done
mv root/var/lib/rpm root/usr/lib/rpm-db
ln -fns ../../usr/lib/rpm-db root/var/lib/rpm
echo > root/usr/lib/tmpfiles.d/rpm-db.conf \
'L /var/lib/rpm - - - - ../../usr/lib/rpm-db'
}
# WORKAROUNDS
# Older CentOS releases are still available, but most of them are EOL.
[[ ${options[release]:-$DEFAULT_RELEASE} -ge DEFAULT_RELEASE ]] ||
. "legacy/${options[distro]}$(( --DEFAULT_RELEASE )).sh"