TemplateBuilder
Building templates with a script. How to use bash, whiptail, pve qm commands and wget. At the same time VM's can be applied for large Kubernetes clusters (K8s, K3s, K3s HA, K0s). LArge lettering done with figlet.
The things utilized in building the GUI and the logic. Proxmox qemu-img resize <size>
and qm set
, --firstboot <file>
, --add <file>
. Bash functions and commands. Downloading stuff with wget
.
Features implemented is sudo detection and setting, logging, initialization of variables and screens, spinner wit many patterns to indicate background working. Graphical user interface with Yes/No, radiobox, msgbox, checklist screens. Large text with figlet
.
Cluster Install
In version 4.2 Kubernetes K8s cluster install was added. K0s and K3s will be added.
- 5.1adds K0s cluster install
- 5.2 adds K3s cluster install
- 5.3 adds K3s HA-cluster install
Figlet
Install figlet
on a PC and do find your font. Then to print CasaUrsus do figlet -f standard CasaUrsus
.
function header() { # print CasaUrsus. figlet -f standard CasaUrsus
clear
cat <<"EOF"
____ _ _
/ ___|__ _ ___ __ _| | | |_ __ ___ _ _ ___
| | / _` / __|/ _` | | | | '__/ __| | | / __|
| |__| (_| \__ \ (_| | |_| | | \__ \ |_| \__ \
\____\__,_|___/\__,_|\___/|_| |___/\__,_|___/
EOF
}
Whiptail
This is like working on MS Dos. You have seen these blue screens with shaded grey boxes all over the place.
It's really a walk down memory lane to use whiptail. I did plenty programming in Dos (starting from version 0.1). XP needed alot of Dos programming and setting to be productive. The best (IMHO) manual/guid I had was around 1.000 pages of commands, explanations and examples.
Later in this blog post you will see examples.
Design
The size of the script is not small but I kept it easy to read and didn't optimize. To keep it readable I use function calls (functions are like sub-rutines) for digestive things lice creating a VM and an other for creating a Template, variables and comments. All output to standard output or the log is in color. Passing parameters to functions makes code more flexible.
Separation of options selection and implementation for extra flexibility.
Spinner
function spinner() { # display a animated spinner
# The different Spinner Arrays to choose from
local array1=("â" "â" "â" "â")
local array2=("â" "â" "â" "â")
local array3=("â" "â" "â" "â")
local array4=("â" "â" "â" "â")
local array5=("â" "â" "â" "â")
local array6=('-' '\' '|' '/') # L to R
local array7=('-' '/' '|' '\') # R to L
local array9=("â " "â " "â š" "â ¸" "â ŧ" "â ´" "â Ļ" "â §" "â " "â ")
local array10=("â" "â" "â" "â" "â" "â" "â" "â")
local array11=("â" "â" "â" "â" "â
" "â" "â" "â")
local delays=0.1 # Delay between each characte
tput civis # Hide cursor and spinn
#echo -e "${yelb} "
while :; do
for character in "${array9[@]}"; do # Use this Array
printf "%s" "$character"
sleep "$delays"
printf "\b" # Move cursor back
done
done
}
Using init-variables
In this example, in the function setLAN
the variables vmbr
and vlan
are initialized by $initVMBR
and by $initVLAN
using whiptail
.
Set root or stop if not root
Read environment from Proxmox
For things like the pools for VM disks and ISO's I read the storage locations into a radiolist depending on a passed variable.
function getPool() { # Show basic pool info and Select a Pool
local ST=$1
local LABEL
local TYPE
case $ST in
VM)
LABEL='VM/CT storage'
TYPE=$zfs_st
;;
ISO)
LABEL='IMG/ISO storage'
TYPE=$img_st
;;
*) exit ;;
esac
local -a LIST
while read -r line; do
local TAG=$(echo $line | awk '{print $1}')
local TYPE=$(echo $line | awk '{printf "%-10s", $2}')
local FREE=$(echo $line | numfmt --field 4-6 --from-unit=K --to=iec --format %.2f | awk '{printf( "%9sB", $6)}')
local ITEM=" Type: $TYPE Free: $FREE "
local OFFSET=2
if [[ $((${#ITEM} + $OFFSET)) -gt ${LONGA:-} ]]; then
local LONGA=$((${#ITEM} + $OFFSET))
fi
LIST+=("$TAG" "$ITEM" "OFF")
done < <(echo "$TYPE" | awk 'NR>1')
# Select storage location
if [ $((${#LIST[@]} / 3)) -eq 0 ]; then
echo "${nocm}${red}Unable to detect valid storage location for ISO storage.${end}" >> $logFILE
elif [ $((${#LIST[@]} / 3)) -eq 1 ]; then
printf ${LIST[0]}
else
local POOL
while [ -z "${POOL:+x}" ]; do
POOL=$(whiptail --backtitle "$backTEXT" --title "Select Storage Pool" --radiolist \
"\nStorage pool to use for the ${LABEL,,}?\nSelect [ Space ] and Accept [ Enter ]\n" \
18 $(($LONGA + 23)) 6 \
"${LIST[@]}" 3>&1 1>&2 2>&3) || echo "getPool RadioList aborted." >> $logFILE
done
printf $POOL
fi
}
References
TemplateBuilder [1] Whiptail [2] Pve qm [3] figlet [4] wget [5]