#!/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 %}