diff --git a/opennebula-images/centos7-build-luks-opennebula-image.sh b/opennebula-images/centos7-build-luks-opennebula-image.sh new file mode 100755 index 0000000..d5696fc --- /dev/null +++ b/opennebula-images/centos7-build-luks-opennebula-image.sh @@ -0,0 +1,182 @@ +#!/bin/sh + +# This script generates CentOS images for OpenNebula. Expected to run on CentOS 7. + +# Depends on the following packages: +# qemu-img util-linux coreutils dnf curl e2fsprogs cryptsetup parted + +# Run locally (without network) with: +# qemu-system-x86_64 -enable-kvm -m 1G -drive file=$IMAGE,format=raw + +set -e +set -x + +RELEASE=7 +ARCH=x86_64 +IMAGE_PATH=centos-luks-$RELEASE-$(date --iso-8601).img +IMAGE_SIZE=10G +LOOPBACK_DEVICE=/dev/loop2 +LUKS_PASSPHRASE=secret +LUKS_DEVICE_NAME=cryptroot2 +LUKS_DEVICE="/dev/mapper/$LUKS_DEVICE_NAME" + +ONE_CONTEXT_RPM_URL="https://github.com/OpenNebula/addon-context-linux/releases/download/v5.10.0/one-context-5.10.0-1.el$RELEASE.noarch.rpm" +ONE_CONTEXT_RPM_PATH=/root/one-context.rpm + +cleanup() { + # The order here is important. + umount /mnt/dev/pts 2>/dev/null || true + umount /mnt/dev/shm 2>/dev/null || true + umount /mnt/dev 2>/dev/null || true + umount /mnt/proc 2>/dev/null || true + umount /mnt/run 2>/dev/null || true + umount /mnt/sys 2>/dev/null || true + umount /mnt/boot 2>/dev/null || true + umount /mnt 2>/dev/null || true + losetup -d "$LOOPBACK_DEVICE" +} + +run_root() { + chroot /mnt /usr/bin/env \ + PATH=/sbin:/usr/sbin:/bin:/usr/bin \ + sh -c "$*" +} + +if [ "$(whoami)" != 'root' ]; then + echo "This script must be run as root." >&2 + exit 1 +fi + +if [ ! -f '/etc/centos-release' ]; then + echo "WARNING: this script has been designed to run on a CentOS system." >&2 + echo "WARNING: Not running CentOS. Giving you 5 seconds to abort." >&2 + sleep 5 +fi + +# Create base RAW image (no LOOPBACK support in RHEL/CentOS). +qemu-img create -f raw "$IMAGE_PATH" "$IMAGE_SIZE" +losetup "$LOOPBACK_DEVICE" "$IMAGE_PATH" + +# Don't forget to cleanup, even if the script crash. +trap cleanup EXIT + +# Create partition table, format partitions. +parted --script "$LOOPBACK_DEVICE" \ + mklabel msdos \ + mkpart primary ext4 1M 500M \ + mkpart primary ext4 500M 100% + +partprobe "$LOOPBACK_DEVICE" + +mkfs.ext4 "${LOOPBACK_DEVICE}p1" +echo -n "$LUKS_PASSPHRASE" | cryptsetup luksFormat -v -d - "${LOOPBACK_DEVICE}p2" +echo -n "$LUKS_PASSPHRASE" | cryptsetup open -v -d - "${LOOPBACK_DEVICE}p2" "$LUKS_DEVICE_NAME" +mkfs.ext4 "$LUKS_DEVICE" + +# Mount partitions, install base OS. +mount "${LUKS_DEVICE}" /mnt +mkdir /mnt/boot +mount "${LOOPBACK_DEVICE}p1" /mnt/boot + +# AppStream landed in CentOS 8. +if [ $RELEASE -ge 8 ]; then + enabled_repos="--enablerepo=BaseOS --enablerepo=AppStream --enablerepo=extras" + release_specific_packages="systemd-udev" +else + enabled_repos="--enablerepo=base --enablerepo=extras" + release_specific_packages="dnf" +fi + +dnf -y \ + --releasever=$RELEASE \ + --installroot=/mnt \ + --disablerepo='*' \ + $enabled_repos \ + --setopt=install_weak_deps=False install \ + --setopt=reposdir=rpm-repositories \ + bash basesystem systemd dnf centos-release cryptsetup $release_specific_packages + +mount --bind /dev /mnt/dev +mount --bind /dev/pts /mnt/dev/pts +mount --bind /dev/shm /mnt/dev/shm +mount --bind /proc /mnt/proc +mount --bind /run /mnt/run +mount --bind /sys /mnt/sys + +# Guest networking is to be handled by the one-context package. +# See https://github.com/OpenNebula/addon-context-linux for details. +# Note: as of writing, one-context does not support NetworkManager or +# systemd-networkd. + +# Required to resolve package mirror in chroot. +cp /etc/resolv.conf /mnt/etc/resolv.conf + +# Initialize /etc/hosts. +cat > /mnt/etc/hosts << EOF +127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 +::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 + +EOF + +# See https://github.com/OpenNebula/addon-context-linux/issues/121 for details. +# network-scripts.x86_64 : Legacy scripts for manipulating of network devices +if [ $RELEASE -ge 8 ]; then + run_root dnf -y install network-scripts +fi + +# Install (magic?) one-context RPM and hope things works as expected. +curl -L "$ONE_CONTEXT_RPM_URL" > "/mnt$ONE_CONTEXT_RPM_PATH" +run_root dnf -y install "$ONE_CONTEXT_RPM_PATH" +run_root rm "$ONE_CONTEXT_RPM_PATH" + +# Install resize2fs, which is required to resize the root file-system. +run_root dnf -y install e2fsprogs + +# Initalize base services. +run_root systemd-machine-id-setup +run_root ln -sf /usr/share/zoneinfo/UTC /etc/localtime + +# Install and configure NTP client. +run_root dnf install -y chrony +run_root systemctl enable chronyd.service + +# Install kernel and bootloader. +# Note: linux-firmware is not required our environment and takes almost 200M +# uncompressed but is a direct dependency of kernel-core... +run_root dnf -y install kernel grub2 + +# Add support for virtio block devices at boot time, configure bootloader. +cat > /mnt/etc/dracut.conf.d/virtio-blk.conf <> /mnt/etc/crypttab + +run_root dracut -v --force --kver $kernel_version +run_root grub2-install --target=i386-pc "${LOOPBACK_DEVICE}" +run_root grub2-mkconfig -o /boot/grub2/grub.cfg + +# Install en configure SSH daemon. +run_root dnf -y install openssh-server +run_root systemctl enable sshd + +# Generate fstab file. +boot_uuid=$(blkid -o value "${LOOPBACK_DEVICE}p1" | head -n 1) +root_uuid=$(blkid -o value "$LUKS_DEVICE" | head -n 1) +cat >>/mnt/etc/fstab <