#!/usr/bin/bash # needed configuration values # BOOTSTRAP_HOSTNAME= # BOOTSTRAP_ROOTFS= # BOOTSTRAP_IFNAME= # BOOTSTRAP_IFADDR= # BOOTSTRAP_IFGW= # BOOTSTRAP_DNS= # BOOTSTRAP_ALPINE_VERSION= # Must be root notroot() { echo "You must be root to run this script" exit 1 } [ `id -u` -eq 0 ] || notroot # Set the variable in the environment or give a file defining them as an argument if [ $# -ge 1 ]; then source $1 fi echo "Starting to bootstrap an Alpine Linux OS with the following configuration:" echo BOOTSTRAP_HOSTNAME=$BOOTSTRAP_HOSTNAME echo BOOTSTRAP_ROOTFS=$BOOTSTRAP_ROOTFS echo BOOTSTRAP_IFNAME=$BOOTSTRAP_IFNAME echo BOOTSTRAP_IFADDR=$BOOTSTRAP_IFADDR echo BOOTSTRAP_IFGW=$BOOTSTRAP_IFGW echo BOOTSTRAP_DNS=$BOOTSTRAP_DNS echo BOOTSTRAP_ALPINE_VERSION=$BOOTSTRAP_ALPINE_VERSION echo "confirm (y/n)" read confirm [ "$confirm" != "y" ] && exit 0 APK_BINARY= TARGET_MNT=`mktemp -d` error_mount() { echo "Cannot mount $BOOTSTRAP_ROOTFS to $TARGET_MNT" exit 1 } mount_rootfs() { mount -t ext4 $BOOTSTRAP_ROOTFS $TARGET_MNT || error_mount } error_download_apk() { echo "Cannot download apk binary file" exit 1 } download_apk() { APK_BINARY=`mktemp` curl https://gitlab.alpinelinux.org/api/v4/projects/5/packages/generic/v2.14.6/x86_64/apk.static > $APK_BINARY || error_download_apk chmod +x $APK_BINARY } error_bootstrap() { echo "Cannot bootstrap alpine" exit 1 } bootstrap() { REPO=https://dl-cdn.alpinelinux.org/alpine/v$BOOTSTRAP_ALPINE_VERSION/main/ $APK_BINARY --arch x86_64 \ -X $REPO \ -U --allow-untrusted --initdb \ --root $TARGET_MNT \ add alpine-base agetty || error_bootstrap } genfstab() { echo "UUID=`blkid -s UUID -o value $BOOTSTRAP_ROOTFS` / ext4 defaults,errors=remount-ro,discard,noatime 0 1" } # geninittab() { # } geninterfaces() { cat << EOF auto lo iface lo inet loopback auto $BOOTSTRAP_IFNAME iface $BOOTSTRAP_IFNAME inet static address $BOOTSTRAP_IFADDR gateway $BOOTSTRAP_IFGW EOF } genresolvconf() { cat << EOF nameserver $BOOTSTRAP_DNS search `echo $BOOTSTRAP_HOSTNAME|cut -d. -f2-` EOF } genapkrepo() { cat << EOF https://dl-cdn.alpinelinux.org/alpine/v$BOOTSTRAP_ALPINE_VERSION/main https://dl-cdn.alpinelinux.org/alpine/v$BOOTSTRAP_ALPINE_VERSION/community EOF } chrooting() { for dir in /proc /sys /dev; do mount -o bind $dir $TARGET_MNT$dir done } unchroot() { for dir in /proc /sys /dev; do umount $TARGET_MNT$dir done } exit_clean() { unchroot umount $TARGET_MNT rmdir $TARGET_MNT rm $APK_BINARY } echo "Installing" mount_rootfs [ ! -x "$APK_BINARY" ] && download_apk bootstrap echo $BOOTSTRAP_HOSTNAME > $TARGET_MNT/etc/hostname genfstab > $TARGET_MNT/etc/ftsab # geninittab > $TARGET_MNT/etc/inittab geninterfaces > $TARGET_MNT/etc/network/interfacces genresolvconf > $TARGET_MNT/etc/resolv.conf genapkrepo > $TARGET_MNT/etc/apk/repositories chrooting CHROOT_CMD="chroot $TARGET_MNT" ( PATH=/sbin:/bin:/usr/sbin:/usr/bin # Install packages $CHROOT_CMD apk update $CHROOT_CMD apk add linux-virt linux-firmware-none acpi mkinitfs vim screen qemu-guest-agent openssh-server # Enable services for svc in seedrng swap networking modules hostname hwclock bootmisc; do $CHROOT_CMD rc-update add $svc boot; done; for svc in acpid crond qemu-guest-agent sshd; do $CHROOT_CMD rc-update add $svc default; done; for svc in devfs dmesg mdev hwdrivers; do $CHROOT_CMD rc-update add $svc sysinit; done; for svc in killprocs mount-ro savecache; do $CHROOT_CMD rc-update add $svc shutdown; done; ) exit_clean