237 lines
9.9 KiB
Plaintext
Raw Permalink Normal View History

2025-10-07 11:12:02 +01:00
#!/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 %}