provisioning/templates/storage.j2
2025-10-07 11:12:02 +01:00

237 lines
9.9 KiB
Django/Jinja
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
#
# storage creation: {{now}}
{%- if debug and debug == "yes" %} set -x {% endif %}
if [ -z "$(type -P jq)" ] ; then
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
sudo DEBIAN_FRONTEND=noninteractive apt-get update >/dev/null
sudo DEBIAN_FRONTEND=noninteractive apt-get upgrade -y >/dev/null
sudo DEBIAN_FRONTEND=noninteractive apt-get install jq -y >/dev/null
fi
[ -z "$(type -P jq)" ] && echo "jq not found" && exit 1
_get_part_name() {
local device_name=$1
local part_pos=$2
if [ "/dev/$device_name${part_pos}" != "/dev/$device_name" ] && [ -e "/dev/$device_name${part_pos}" ] ; then
echo "${device_name}${part_pos}"
elif [ -e "/dev/${device_name}p${part_pos}" ] ; then
echo "${device_name}p${part_pos}"
else
echo ""
fi
}
_get_dev_children() {
sudo lsblk -fA --j | jq -rc '.blockdevices[].children[] | select((.name == "'${1}${2}'") or (.name == "'${1}p${2}'"))' | sed 's/null//g'
}
_on_item() {
local device_name=$1
local part_name=$2
local part_pos=$3
local part_size=$4
local part_type=$5
local local already_created=""
local item_pos=-1
local mkfs_ops=""
local device_data
local dev_part_nanme
local dev_part_path
local child_data
local device_blk_type
local list_mounts
local new_dev_children
[ -r "$etc_disks_parts" ] && has_part="$(grep "^$part_name" "$etc_disks_parts")"
[ -n "$has_part" ] && echo "$part_name already_created" && return
device_data=$(lsblk -fA --j | jq -rc '.blockdevices[] | select(.name == "'$device_name'")')
dev_part_name=$(_get_part_name $device_name $part_pos)
if [ -n "$dev_part_name" ] ; then
dev_part_path="/dev/$dev_part_name"
child_data=$(echo "$device_data" | jq -cr '.children[] | select(.name == "'$dev_part_name'")')
fi
if [ -z "$child_data" ] ; then
list_mounts=$(df | grep ^/dev/$device_name | grep -v " /$" | cut -f1 -d" ")
[ -n "$list_mounts" ] && sudo umount $list_mounts
{#case $(sudo fdisk -V | cut -f4 -d" ") in #}
{# case "$SERVER_PROVIDER" in
upcloud) fdisk_nl="" ;;
aws) fdisk_nl="\n" ;;
*) fdisk_nl="\n"
esac
#}
local str_part_size
[ "$total_storage_parts" != $part_pos ] && str_part_size="+${part_size}G"
echo -e "n\n\n\n${str_part_size}\nw\n" | sudo fdisk /dev/"$device_name" &>/dev/null
#NOTE: sometimes it requires an extra newline. using command exit code ´?' did not work, lsblk it is more secure
[ -z $(_get_dev_children $device_name $part_pos) ] && echo -e "n\n\n\n\n${str_part_size}\nw\n" | sudo fdisk /dev/"$device_name" &>/dev/null
if [ -z $(_get_dev_children $device_name $part_pos) ] ; then
echo "Error create $part_pos in $device_name"
return 1
fi
sudo systemctl daemon-reload
[ -n "$list_mounts" ] && sudo mount $list_mounts
dev_part_name=$(_get_part_name $device_name $part_pos)
[ -n "$dev_part_name" ] && dev_part_path="/dev/$dev_part_name"
fi
[ -z "$dev_part_path" ] && return 1
device_blk_type=$(sudo blkid $dev_part_path | tr ' ' '\n' | grep ^TYPE | cut -f2 -d"=" | sed 's/"//g')
[ -n "$child_data" ] && [ "$device_blk_type" == "$part_type" ] && return
{#[ -n "$child_data" ] && [ "$(echo "$child_data" | jq -rc '.fstype')" == "$part_type" ] && return #}
[ "$part_type" == "raw" ] && return
if [ ! -r "/usr/sbin/fsck.${part_type}" ] ; then
case "$part_type" in
xfs)
sudo DEBIAN_FRONTEND=noninteractive apt-get install xfsprogs -y >/dev/null
;;
esac
fi
case "$part_type" in
xfs)
mkfs_ops="-f"
;;
esac
if [ -z "$dev_part_name" ] ; then
echo "/dev/${device_name} ${part_pos} not found"
return 1
fi
if [ ! -r "/usr/sbin/mkfs.${part_type}" ] ; then
echo "mkfs.${part_type} not found to format $dev_part_path "
exit 1
else
if ! sudo mkfs.${part_type} $mkfs_ops $dev_part_path >/dev/null ; then
echo "Error mkfs.${part_type} format $dev_part_path "
exit 1
fi
fi
}
_on_fs_item() {
local device_name=$1
local part_name=$2
local part_pos=$3
local part_size=$4
local part_type=$5
local part_mount_path=$6
local part_fstab=$7
local device_data
local dev_path_name
local dev_path_path
device_data=$(lsblk -fA --j | jq -rc '.blockdevices[] | select(.name == "'$device_name'")')
dev_part_name=$(_get_part_name $device_name $part_pos)
if [ -z "$dev_part_name" ] ; then
echo "/dev/${device_name} ${part_pos} not found"
return 1
fi
dev_part_path="/dev/$dev_part_name"
part_uuid=$(sudo blkid $dev_part_path | tr ' ' '\n' | grep ^UUID | cut -f2 -d"=" | sed 's/"//g')
{# part_uuid=$(echo "$device_data" | jq -rc '.children[] | select(.name == "'$dev_part_name'") |.uuid' | sed 's/null//g' ) #}
[ -r "$etc_disks_parts" ] && has_part="$(grep "^$part_name" "$etc_disks_parts")"
if [ -n "$has_part" ] ; then
sed -i /^$part_name/d $etc_disks_parts
fi
blkid_data=$(sudo blkid $dev_part_path | cut -f2 -d":" | sed 's/^ //g')
echo "$part_name:${dev_part_path}:$part_size:$part_type:$part_uuid:2024_04_30_21_21_48:$blkid_data" | sudo tee -a "$etc_disks_parts" >/dev/null
[ "$part_type" == "raw" ] && return
[ "$part_type" != "xfs" ] && [ -n "$(type -P tune2fs)" ] && tune2fs -L "$part_name" "$dev_part_path" >/dev/null
if [ -n "$part_mount_path" ] ; then
[ ! -d "$part_mount_path" ] && sudo mkdir -p "$part_mount_path"
has_mount=$(mount | grep "$dev_part_path")
[ -z "$has_mount" ] && sudo mount "$dev_part_path" "$part_mount_path"
if [ -n "$part_fstab" ] ; then
local fstab_uuid
if [ -n "$part_uuid" ] ; then
fstab_uuid=$part_uuid
else
fstab_uuid=$dev_part_path
fi
[ -n "$(sudo grep "$part_mount_path" "$etc_fstab")" ] && grep -v " $part_mount_path " "$etc_fstab" > /tmp/fstab.$$ | sudo mv /tmp/fstab.$$ "$etc_fstab"
case "$part_type" in
xfs)
echo "UUID=$fstab_uuid $part_mount_path $part_type rw,relatime,attr2,inode64,noquota 0 1" | sudo tee -a "$etc_fstab" >/dev/null
;;
*) echo "UUID=$fstab_uuid $part_mount_path $part_type errors=remount-ro 0 1" | sudo tee -a "$etc_fstab" >/dev/null
esac
sudo systemctl daemon-reload
fi
fi
}
etc_disks_parts="/etc/.disks_parts"
etc_fstab="/etc/fstab"
server_pos={{server_pos}}
SERVER_PROVIDER={{server.provider}}
DEVICES_LIST=$(lsblk -d --j | jq -rc '.blockdevices[].name' | sort | tr "\n" " ")
{%- for storage in server.storages %}
# Storage {{loop.index}} {{storage.name}}
storage_pos={{loop.index0}}
device_name=$(echo "$DEVICES_LIST" | cut -f{{loop.index}} -d" ")
if [ -n "$device_name" ] ; then
device_children_len=$(lsblk -fA --j | jq -rc '.blockdevices[] | select(.name == "'$device_name'") | .children | length' 2>/dev/null)
storage_parts={{storage.parts | length }}
total_storage_parts=$(($device_children_len + $storage_parts))
if [ "$(lsblk -fA --j | jq -rc '.blockdevices[].children[] | select(.mountpoints[] == "/") | .name | contains("'$device_name'")' 2>/dev/null)" == "true" ] ; then
device_children_len=$(($device_children_len - 1))
total_storage_parts=$(($total_storage_parts - 1))
fi
{%- if storage.parts %}
{%- for part in storage.parts %}
{%- if part.name == "root" or part.mount_path == "/" -%}{% continue %}{%- endif %}
# Storage {{storage.name}} part {{loop.index}} {{part.name}}
{#
storage_name="{{part.name}}"
storage_size={{part.size}}
storage_total={{part.total}}
storage_type="{{part.type}}"
{% if part.mount %}storage_mount="true"{% endif %}
{% if part.fstab %}storage_fstab="true"{% endif %}
#}
device_pos={{loop.index}}
[ -n "{{part.mount_path}}" ] && has_part=$(lsblk -fA --j | jq -rc '.blockdevices[].children[] | select(.mountpoints[] == "{{part.mount_path}}")' 2>/dev/null)
[ -z "$has_part" ] && [ -r "$etc_disks_parts" ] && has_part="$(grep "^{{part.name}}" "$etc_disks_parts")"
if [ -z "$has_part" ] ; then
device_pos=$(($device_children_len + $device_pos))
if _on_item "$device_name" "{{part.name}}" "$device_pos" "{{part.size}}" "{{part.type}}" ; then
_on_fs_item "$device_name" "{{part.name}}" "$device_pos" "{{part.size}}" "{{part.type}}" {% if part.mount_path %}"{{part.mount_path}}"{% else %}""{% endif %} {% if part.fstab %}"{{part.fstab}}"{% else %}""{% endif %}
else
echo "Error create $device_name {{part.name}} $device_pos {{part.size}} {{part.type}}"
fi
else
device_children_len=$(($device_children_len - 1))
total_storage_parts=$(($total_storage_parts - 1))
fi
{%- endfor %}
{%- else %}
{%- if storage.name == "root" or storage.mount_path == "/" -%}{% continue %}{%- endif -%}
{#
storage_name="{{storage.name}}"
storage_size={{storage.size}}
storage_total={{storage.total}}
storage_type="{{storage.type}}"
{% if storage.mount %}storage_mount="true"{% endif %}
{% if storage.fstab %}storage_fstab="true"{% endif %}
#}
device_pos={{loop.index}}
[ -n "{{part.mount_path}}" ] && has_part=$(lsblk -fA --j | jq -rc '.blockdevices[].children[] | select(.mountpoints[] == "{{part.mount_path}}")' 2>/dev/null)
[ -z "$has_part" ] && [ -r "$etc_disks_parts" ] && has_part="$(grep "^{{part.name}}" "$etc_disks_parts")"
if [ -z "$has_part" ] ; then
device_pos=$(($device_children_len + $device_pos))
if _on_item "$device_name" "{{storage.name}}" "$device_pos" "{{storage.size}}" "{{storage.type}}" ; then
_on_fs_item "$device_name" "{{storage.name}}" "$device_pos" "{{storage.size}}" "{{storage.type}}" {% if storage.mount_path %}"{{storage.mount_path}}"{% else %}""{% endif %} {% if storage.fstab %}"{{storage.fstab}}"{% else %}""{% endif %}
else
echo "Error create $device_name {{storage.name}} $device_pos {{storagesize}} {{storage.type}}"
fi
else
device_children_len=$(($device_children_len - 1))
total_storage_parts=$(($total_storage_parts - 1))
fi
{%- endif %}
fi
{%- endfor %}