alpine-overlay/kubezero/zdt-base/cb_volumes.sh

131 lines
3.3 KiB
Bash

#!/bin/sh
# We built on top of tiny-cloud
. /etc/tiny-cloud.conf
# archive orig /var, mount new var on top and restore orig var
copy_and_mount() {
local dev=$1
tar cf /tmp/var.tar /var 2>/dev/null
mount -t xfs -o noatime "$dev" /var
tar xf /tmp/var.tar -C / && rm -f /tmp/var.tar
}
setup_var() {
for d in $(find /dev/xvd[a-z] /dev/sd[a-z]); do
# resolve to a valid block device
dev="$(realpath "$d")"
[ -b "$dev" ] || continue
# already mounted
mount | grep -q "$d" && continue
case "$CLOUD" in
aws)
# on AWS look for sdx/xvdx
if [ "$d" = "/dev/sdx" -o "$d" = "/dev/xvdx" ]; then
# check volume for existing filesystem
type=$(file -Lbs $d)
if [[ "$type" =~ "XFS filesystem" ]]; then
xfs_repair $d >/dev/null 2>&1
mount -t xfs -o noatime "$d" /var
else
mkfs.xfs -qf $d >/dev/null
copy_and_mount "$d"
fi
grep -q "$d" /etc/fstab || echo "$d /var xfs defaults,noatime,nofail 0 2" >> /etc/fstab
fi
;;
*)
ewarn "Unsupported cloud: $CLOUD"
return 1
;;
esac
done
}
attach_ebs() {
local volId="$1"
local device="$2"
local tries=30
while true; do
_json="$(aws ec2 describe-volumes --volume-ids $volId --region $REGION --output json)"
rc=$?; [ $rc -ne 0 ] && return $rc
vol_status=$(echo "$_json" | jq -r .Volumes[].State)
attachId=$(echo "$_json" | jq -r .Volumes[].Attachments[].InstanceId)
[ "$attachId" = "$INSTANCE_ID" ] && break
if [ "$vol_status" = "available" ]; then
aws ec2 attach-volume --volume-id "$volId" --instance-id "$INSTANCE_ID" --region "$REGION" --device "$device" > /dev/null
rc=$?; [ $rc -ne 0 ] && return $rc
break
fi
# if attached but not to us -> detach
if [ "$vol_status" = "in-use" ]; then
aws ec2 detach-volume --volume-id "$volId" --region "$REGION" --force
rc=$?; [ $rc -ne 0 ] && return $rc
fi
((tries=tries-1))
[ $tries -eq 0 ] && return 1
sleep 5
done
}
_parse_volume() {
# Todo: proper checks once all is yaml
# For now just replace ':'
echo $1 | sed -e 's/:/ /g'
}
# mount optional remote volumes
mount_volumes() {
local volumes="$1"
for vol in $volumes; do
# Todo: check volume type and call matching func
read volType volId volDevice volPath < <(_parse_volume $vol)
[ "$volType" != "ebs" ] && { echo "Unknown volume type $volType"; break; }
attach_ebs $volId $volDevice
rc=$?
[ $rc -ne 0 ] && { ewarn "error trying to attach $volId"; break; }
# wait for the block device to become available
while true; do
mdev -s
test -b $volDevice && break
sleep 1
done
# check volume for existing filesystem
type=$(file -Lbs $volDevice)
if [[ "$type" =~ "XFS filesystem" ]]; then
xfs_repair $volDevice >/dev/null 2>&1
else
mkfs.xfs -qf $volDevice >/dev/null
fi
# mount
mkdir -p $volPath
mount -t xfs -o noatime $volDevice $volPath
ebegin "mounting $volDevice at $volPath"
done
}
unmount_volumes() {
local volumes="$1"
for vol in $volumes; do
read volType volId volDevice volPath < <(_parse_volume $vol)
umount $volPath && aws ec2 detach-volume --volume-id "$volId" --instance-id $INSTANCE_ID --region $REGION > /dev/null
done
}