diff --git a/etc/conf.d/tiny-cloud b/etc/conf.d/tiny-cloud index 0739192..760ac57 100644 --- a/etc/conf.d/tiny-cloud +++ b/etc/conf.d/tiny-cloud @@ -1,7 +1,8 @@ # Tiny Cloud configuration # REQUIRED: The instance's cloud provider (valid: aws, azure, gcp, oci) -CLOUD= +# valid: aws, azure, gcp, oci +#CLOUD= # User account where instance SSH keys are installed #CLOUD_USER=alpine @@ -20,3 +21,10 @@ CLOUD= # Location of log directory #TINY_CLOUD_LOGS=/var/log + +# Hotplug Method (valid: mdev) +#HOTPLUG_TYPE=mdev + +# Cloud-related Hotplug Modules +# valid: vnic_eth_hotplug, nvme_ebs_links (aws) +#HOTPLUG_MODULES= diff --git a/etc/init.d/tiny-cloud-early b/etc/init.d/tiny-cloud-early index 59249f2..e2e6e78 100755 --- a/etc/init.d/tiny-cloud-early +++ b/etc/init.d/tiny-cloud-early @@ -16,5 +16,9 @@ start() { expand_root eend $? - # TODO: _setup mdev things, if applicable + if has_cloud_hotplugs; then + ebegin "Installing Cloud Hotplugs" + install_hotplugs + eend $? + fi } \ No newline at end of file diff --git a/lib/mdev/nvme-ebs-links b/lib/mdev/nvme-ebs-links new file mode 100755 index 0000000..5b30edf --- /dev/null +++ b/lib/mdev/nvme-ebs-links @@ -0,0 +1,48 @@ +#!/bin/sh +# vim:set ts=2 et: + +# nvme tool not installed? +[ -x /usr/sbin/nvme ] || exit + +PROC="$(basename "$0")[$$]" + +log() { + FACILITY="kern.$1" + shift + logger -p "$FACILITY" -t "$PROC" "$@" +} + +raw_ebs_alias() { + /usr/sbin/nvme id-ctrl "/dev/$BASE" -b 2>/dev/null | dd bs=32 skip=96 count=1 2>/dev/null +} + +case $ACTION in + add|"") + BASE=$(echo "$MDEV" | sed -re 's/^(nvme[0-9]+n[0-9]+).*/\1/') + PART=$(echo "$MDEV" | sed -re 's/nvme[0-9]+n[0-9]+p?//g') + MAXTRY=30 + TRY=0 + until [ -n "$EBS" ]; do + EBS=$(raw_ebs_alias | sed -nre '/^(\/dev\/)?(s|xv)d[a-z]{1,2} /p' | tr -d ' ') + [ -n "$EBS" ] && break + TRY=$((TRY + 1)) + if [ $TRY -eq $MAXTRY ]; then + log err "Failed to get EBS volume alias for $MDEV after $MAXTRY attempts ($(raw_ebs_alias))" + exit 1 + fi + sleep 0.1 + done + # remove any leading '/dev/', 'sd', or 'xvd', and append partition + EBS=${EBS#/dev/} + EBS=${EBS#sd} + EBS=${EBS#xvd}$PART + ln -sf "$MDEV" "sd$EBS" && log notice "Added sd$EBS symlink for $MDEV" + ln -sf "$MDEV" "xvd$EBS" && log notice "Added xvd$EBS symlink for $MDEV" + ;; + remove) + for TARGET in sd* xvd* + do + [ "$(readlink "$TARGET" 2>/dev/null)" = "$MDEV" ] && rm -f "$TARGET" && log notice "Removed $TARGET symlink for $MDEV" + done + ;; +esac diff --git a/lib/tiny-cloud/aws/mdev b/lib/tiny-cloud/aws/mdev new file mode 100644 index 0000000..40d108e --- /dev/null +++ b/lib/tiny-cloud/aws/mdev @@ -0,0 +1,11 @@ +# AWS mdev Hotplug Modules +# vim:set ft=sh ts=4 noet: + +# makes symlinks for NVMe devices that correlate to AWS EBS sd/xvd devices +mod__nvme_ebs_links() { + # nvme-cli not installed? + [ -x /usr/sbin/nvme ] || return 1 + + install_before '^nvme\.\*' \ + 'nvme[0-9]+n.* root:disk 0660 */lib/mdev/nvme-ebs-links' +} \ No newline at end of file diff --git a/lib/tiny-cloud/init-early b/lib/tiny-cloud/init-early index fe99869..5fedfb8 100644 --- a/lib/tiny-cloud/init-early +++ b/lib/tiny-cloud/init-early @@ -17,10 +17,29 @@ expand_root() { ) if [ "$mountpoint" != "$volume" ]; then - partition=$(echo "$mountpoint" | sed -Ee "s/.*(\d+)$/\1/") + # it's a partition, resize it + local partition=$(echo "$mountpoint" | sed -Ee "s/.*(\d+)$/\1/") echo ", +" | sfdisk -q --no-reread -N "$partition" "$volume" partx -u "$volume" fi + # resize filesystem mount -orw,remount / resize2fs "$mountpoint" -} \ No newline at end of file +} + +has_cloud_hotplugs() { [ -n "$HOTPLUG_MODULES" ]; } + +install_hotplugs() { + for module in $HOTPLUG_MODULES; do + local result='-' + + echo -n " $module" + if type "mod__$module" | grep -q "is a function"; then + "mod__$module" && result='+' || result='!' + fi + echo -n "($result)" + done +} + +HOTPLUG_TYPE=${HOTPLUG_TYPE:-mdev} +source "$TINY_CLOUD_LIBS/$HOTPLUG_TYPE" \ No newline at end of file diff --git a/lib/tiny-cloud/mdev b/lib/tiny-cloud/mdev new file mode 100644 index 0000000..bcb3aff --- /dev/null +++ b/lib/tiny-cloud/mdev @@ -0,0 +1,32 @@ +# Tiny Cloud - mdev hotplug functions +# vim:set ft=sh ts=4 noet: + +# generic helper function to install mdev rules +install_before() { + local before="$1" + shift + local line="$*" + + # already installed + fgrep -q "$line" /etc/mdev.conf && return 0 + + if grep -q "$before" /etc/mdev.conf; then + # install before existing rule + line="-$line" + else + # no rule exists, put it before the catch-all fallback + before='^# fallback' + fi + sed -i -Ee "s|($before.*)|$line\n\1|" /etc/mdev.conf +} + +# hotpluggable VNICs (multi-cloud) +mod__vnic_eth_hotplug() { + # TODO: missing dependencies? return 1 + install_before '^eth' \ + 'eth[0-9]* root:root 0644 */lib/mdev/vnic-eth-hotplug' +} + +# load cloud-specific functions + +[ -f "$TINY_CLOUD_LIBS/$CLOUD/mdev" ] && source "$TINY_CLOUD_LIBS/$CLOUD/mdev" \ No newline at end of file