563 lines
20 KiB
Bash
Executable file
563 lines
20 KiB
Bash
Executable file
#!/bin/bash
|
||
|
||
# Script to deploy a VM based on debian template
|
||
# You need to provide a VM conf file with all params defined (see vm-template.conf)
|
||
|
||
echo -e "\n---------- SCRIPT ${0} ----------\n"
|
||
echo "INFO : the script ${0} started..."
|
||
|
||
# Get ID for new VM
|
||
VM_ID=$(pvesh get /cluster/nextid)
|
||
echo "INFO : the VM_ID for the new VM will be ${VM_ID}"
|
||
|
||
usage() {
|
||
printf "Usage of ${0} : ${0} <vm-conf-file>\n"
|
||
printf "\tvm-conf-file has to contain variables VM_HOSTNAME, USER_MAIL, USER_SSH_PUB_KEY, VM_DISK, VM_CPU, VM_RAM and VM_TEMPLATE_ID\n"
|
||
printf "\t-h, --help\tPrint this help\n"
|
||
}
|
||
|
||
echo -e "\n---------- CHECK REQUIREMENTS ----------\n"
|
||
|
||
# Check if file is provided or help asked
|
||
echo "INFO : Check if VM conf file provided..."
|
||
if [ $1 ]; then
|
||
if [ $1 = '-h' ] || [ $1 = '--help' ]; then
|
||
usage
|
||
exit 0
|
||
elif [ $# -lt 1 ]; then
|
||
echo 'ERROR : VM conf file not specified'
|
||
usage
|
||
exit 1
|
||
else
|
||
# Check the presence of VM conf file
|
||
if [ -f "$1" ]; then
|
||
VM_CONF_FILE=$1
|
||
. ${VM_CONF_FILE}
|
||
|
||
if [ $? -ne 0 ]
|
||
then
|
||
echo 'ERROR : problem during read VM conf file, please check the VM conf file'
|
||
exit 1
|
||
fi
|
||
else
|
||
echo 'ERROR : VM conf file not found, check path'
|
||
exit 1
|
||
fi
|
||
fi
|
||
else
|
||
echo 'ERROR : No parameter specified'
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
# INFO : Check if creds file is found
|
||
echo "INFO : Check if creds file is found (IPAM credentials)..."
|
||
CREDS_FILE='./creds'
|
||
if [ -f $CREDS_FILE ]; then
|
||
. $CREDS_FILE
|
||
CURL='curl -s -k -sS'
|
||
else
|
||
echo 'ERROR : The file creds doesn’t exist'
|
||
exit 1
|
||
fi
|
||
|
||
# Check if general script params file is found
|
||
echo "INFO : Check if general script params file is found..."
|
||
CONF_FILE='./deploy_vm.conf'
|
||
if [ -f $CONF_FILE ]; then
|
||
. $CONF_FILE
|
||
else
|
||
echo "ERROR : The file ${CONF_FILE} doesn’t exist"
|
||
exit 1
|
||
fi
|
||
|
||
# Check if all required params are provided and not empty
|
||
echo "INFO : Check if all required params are provided and not empty in VM conf file..."
|
||
if [ -z "${VM_HOSTNAME}" ] || [ -z "${USER_MAIL}" ] || [ -z "${USER_SSH_PUB_KEY}" ] || [ -z "${VM_DISK}" ] || [ -z "${VM_CPU}" ] || [ -z "${VM_RAM}" ] || [ -z "${VM_TEMPLATE_ID}" ]
|
||
then
|
||
echo 'ERROR : all required params not defined in VM conf file, required params : VM_HOSTNAME, USER_MAIL, USER_SSH_PUB_KEY, VM_DISK, VM_CPU, VM_RAM and VM_TEMPLATE_ID.'
|
||
exit 1
|
||
fi
|
||
|
||
# Delete space from hostname and truncate to 32 chars
|
||
VM_HOSTNAME_TRUNCATE=$(echo ${VM_HOSTNAME} | cut -c 1-32)
|
||
|
||
echo "INFO : Check VM_HOSTNAME param format (after truncate if necessary)..."
|
||
# Check VM_HOSTNAME_TRUNCATE
|
||
echo ${VM_HOSTNAME_TRUNCATE} | grep "^[-a-zA-Z0-9]*$" > /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : the VM hostname can only contain "a-z", "A-Z", "0-9" or "-" chars (no space or other special chars)'
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Check USER_MAIL param format..."
|
||
# Check USER_MAIL
|
||
if [[ ! "${USER_MAIL}" =~ ^(.*)+@(.*)$ ]]; then
|
||
echo 'ERROR: Email address is invalid'
|
||
exit 1
|
||
fi
|
||
|
||
# Regex to check if value is a number
|
||
RE='^[0-9]+$'
|
||
|
||
# Var to contain size to extend disk
|
||
VM_DISK_EXTEND=0
|
||
|
||
echo "INFO : Check VM_DISK param format and size limits..."
|
||
# Check VM_DISK
|
||
if [ ${VM_DISK} -lt ${VM_DISK_MIN} ] || [ ${VM_DISK} -gt ${VM_DISK_MAX} ] || [[ ! ${VM_DISK} =~ ${RE} ]]; then
|
||
echo "ERROR : the disk size has to be between ${VM_DISK_MIN} and ${VM_DISK_MAX}"
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Get the size to extend disk if necessary..."
|
||
# Set the size to extend disk if necessary
|
||
if [ ${VM_DISK} -gt ${VM_DISK_MIN} ]; then
|
||
VM_DISK_EXTEND=$(( ${VM_DISK}-${VM_DISK_MIN} ))
|
||
fi
|
||
|
||
echo "INFO : Check VM_CPU param format and number limits..."
|
||
# Check VM_CPU
|
||
if [ ${VM_CPU} -lt ${VM_CPU_MIN} ] || [ ${VM_CPU} -gt ${VM_CPU_MAX} ] || [[ ! ${VM_CPU} =~ ${RE} ]]; then
|
||
echo "ERROR : the vCPU core number has to be between ${VM_CPU_MIN} and ${VM_CPU_MAX}"
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Check VM_RAM param format and size limits..."
|
||
# Check VM_RAM
|
||
if [ ${VM_RAM} -lt ${VM_RAM_MIN} ] || [ ${VM_RAM} -gt ${VM_RAM_MAX} ] || [[ ! ${VM_RAM} =~ ${RE} ]]; then
|
||
echo "ERROR : the RAM size has to be between ${VM_RAM_MIN} and ${VM_RAM_MAX}"
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Check VM_TEMPLATE_ID param format..."
|
||
# Check VM_TEMPLATE_ID
|
||
if [[ ! ${VM_TEMPLATE_ID} =~ ${RE} ]]; then
|
||
echo "ERROR : VM template ID provided is not a number"
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Check if VM_TEMPLATE_ID param match with a VM template on this HV..."
|
||
# Check if VM_TEMPLATE_ID is a VM template on this HV
|
||
qm config ${VM_TEMPLATE_ID} | grep "^template: 1$" > /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo "ERROR : VM template ID does not match with a template VM on this HV"
|
||
exit 1
|
||
fi
|
||
|
||
# Connection to IPAM API
|
||
echo 'INFO : Connecting to the IPAM API...'
|
||
RES_AUTHENT=$(${CURL} -X POST --user ${USER_IPAM}:${PASSWORD_IPAM} ${URL}/user/)
|
||
CODE_RETOUR_RES_AUTHENT=$(echo ${RES_AUTHENT} | jq '.code')
|
||
if [ ${CODE_RETOUR_RES_AUTHENT} != 200 ]; then
|
||
echo "ERROR : Wrong HTTP code from the API : ${CODE_RETOUR_RES_AUTHENT} ${RES_AUTHENT}"
|
||
echo "ERROR : Unable to join/connect IPAM (to register VM IPs)"
|
||
exit 1
|
||
fi
|
||
|
||
# Get IPAM API Token
|
||
echo 'INFO : Getting IPAM API token...'
|
||
TOKEN=$(echo ${RES_AUTHENT} | jq -r '.data.token')
|
||
if [ ! -n "${TOKEN}" ]; then
|
||
echo 'ERROR : Empty IPAM API token'
|
||
exit 1
|
||
fi
|
||
|
||
# Check if VM_ID is already used by an IPAM IPv4
|
||
echo "INFO : Check if VM_ID is already used by an IPAM IPv4..."
|
||
for ID_RANGE_V4 in ${ID_RANGES_V4}; do
|
||
# Get IPV4 informations and check HTTP code
|
||
INFOS_V4=$(${CURL} --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X GET "${URL}/subnets/${ID_RANGE_V4}/addresses")
|
||
CODE_RETOUR_INFOS_V4=$(echo ${INFOS_V4} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_INFOS_V4} != 200 ]; then
|
||
echo "ERROR : Wrong code returned for IPv4 range ${ID_RANGE_V4}: ${CODE_RETOUR_INFOS_V4}"
|
||
exit 1
|
||
fi
|
||
|
||
VM_IPV4=$(echo ${INFOS_V4} | jq -r ".data[] | select(.custom_vm_id==\"${VM_ID}\") | .ip")
|
||
|
||
if [ ! -z "${VM_IPV4}" ]
|
||
then
|
||
|
||
echo "ERROR : the next VM ID is already used by an IPv4 in IPAM (${VM_IPV4}), please check an delete all IPAM's entries associated to the new vm_id ${VM_ID} before run this script."
|
||
exit 1
|
||
fi
|
||
|
||
done
|
||
|
||
# Check if VM_ID is already used by an IPAM IPv6 range
|
||
echo "INFO : Check if VM_ID is already used by an IPAM IPv6 range..."
|
||
for ID_RANGE_V6 in ${ID_RANGES_V6}; do
|
||
# Get IPV6 ranges informations and check HTTP code
|
||
INFOS_RANGES_V6=$(${CURL} --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X GET ${URL}/subnets/${ID_RANGE_V6}/slaves/)
|
||
CODE_RETOUR_INFOS_RANGES_V6=$(echo ${INFOS_RANGES_V6} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_INFOS_RANGES_V6} != 200 ]; then
|
||
echo "ERROR : Wrong code returned for IPv4 range ${ID_RANGE_V6}: ${CODE_RETOUR_INFOS_RANGES_V6}"
|
||
exit 1
|
||
fi
|
||
|
||
VM_IPV6=$( echo ${INFOS_RANGES_V6} | jq -r ".data[] | select(.custom_vm_id==\"${VM_ID}\") | .subnet")
|
||
|
||
if [ ! -z "${VM_IPV6}" ]
|
||
then
|
||
|
||
echo "ERROR : the next VM ID is already used by an IPv6 range in IPAM (${VM_IPV6}/48), please check an delete all IPAM's entries associated to the new vm_id ${VM_ID} before run this script."
|
||
exit 1
|
||
fi
|
||
|
||
done
|
||
|
||
echo -e "\n---------- CHECK REQUIREMENTS OK ----------"
|
||
|
||
echo -e "\n---------- CREATE IPAM ENTRIES ----------\n"
|
||
|
||
# Add IPv4 in IPAM for the new VM
|
||
echo "INFO : Add IPv4 in IPAM... (UPDATE IPAM)"
|
||
ADD_V4=$(${CURL} --data "description"="VM ${VM_HOSTNAME_TRUNCATE}" --data "custom_vm_id"="${VM_ID}" --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X POST "${URL}/addresses/first_free/${ID_RANGE_V4_TO_CREATE_VM}")
|
||
CODE_RETOUR_ADD_V4=$(echo ${ADD_V4} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_ADD_V4} != 201 ]; then
|
||
echo "ERROR : Wrong code returned for IPv4 ADD on range ${ID_RANGE_V4_TO_CREATE_VM} : ${CODE_RETOUR_ADD_V4} ${ADD_V4}"
|
||
exit 1
|
||
fi
|
||
|
||
VM_IPV4_NEW=$(echo ${ADD_V4} | jq -r '.data')
|
||
|
||
echo "INFO : VM IPv4 is ${VM_IPV4_NEW}"
|
||
|
||
# Get the subnet ID of the VM
|
||
echo "INFO : Get the subnet mask and gateway for the VM..."
|
||
IPAM_NEW_IPV4_DETAILS=$(${CURL} --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X GET "${URL}/addresses/search/${VM_IPV4_NEW}/")
|
||
CODE_RETOUR_IPAM_NEW_IPV4_DETAILS=$(echo ${IPAM_NEW_IPV4_DETAILS} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_IPAM_NEW_IPV4_DETAILS} != 200 ]; then
|
||
echo "ERROR : Wrong code returned while getting subnet for ${VM_IPV4_NEW} : ${CODE_RETOUR_IPAM_NEW_IPV4_DETAILS}"
|
||
exit 1
|
||
fi
|
||
|
||
VM_IPV4_NEW_SUBNET_ID=$(echo ${IPAM_NEW_IPV4_DETAILS} | jq -r ".data[] | .subnetId")
|
||
|
||
echo "INFO : IPAM Subnet ID of the VM is ${VM_IPV4_NEW_SUBNET_ID}"
|
||
|
||
# Get the gateway and the mask of the VM
|
||
echo "INFO : Get the gateway and the mask of the VM..."
|
||
IPAM_NEW_IPV4_SUBNET=$(${CURL} --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X GET "${URL}/subnets/${VM_IPV4_NEW_SUBNET_ID}/")
|
||
CODE_RETOUR_IPAM_NEW_IPV4_SUBNET=$(echo ${IPAM_NEW_IPV4_SUBNET} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_IPAM_NEW_IPV4_SUBNET} != 200 ]; then
|
||
echo "ERROR : Wrong code returned for IPv4 subnet ${VM_IPV4_NEW_SUBNET_ID} : ${CODE_RETOUR_IPAM_NEW_IPV4_SUBNET}"
|
||
exit 1
|
||
fi
|
||
|
||
VM_IPV4_NEW_SUBNET_GW=$(echo ${IPAM_NEW_IPV4_SUBNET} | jq -r ".data.gateway.ip_addr")
|
||
VM_IPV4_NEW_SUBNET_MASK=$(echo ${IPAM_NEW_IPV4_SUBNET} | jq -r ".data.mask")
|
||
|
||
echo "INFO : IPv4 Gateway for the VM is ${VM_IPV4_NEW_SUBNET_GW}"
|
||
echo "INFO : IPv4 Mask of the VM is ${VM_IPV4_NEW_SUBNET_MASK}"
|
||
|
||
# Add IPv6 range in IPAM for the new VM
|
||
echo "INFO : Add IPv6 range in IPAM... (UPDATE IPAM)"
|
||
ADD_RANGES_V6=$(${CURL} --data "custom_vm_id"="${VM_ID}" --data "isFull"="1" --data "description"="VM ${VM_HOSTNAME_TRUNCATE}" --header "Content-type: application/x-www-form-urlencoded" --header "token: $TOKEN" -X POST ${URL}/subnets/${ID_RANGE_V6_TO_CREATE_VM}/first_subnet/48/)
|
||
CODE_RETOUR_ADD_RANGES_V6=$(echo ${ADD_RANGES_V6} | jq '.code')
|
||
|
||
if [ ${CODE_RETOUR_ADD_RANGES_V6} != 201 ]; then
|
||
echo "ERROR : Wrong code returned for IPv6 range ${ID_RANGE_V6_TO_CREATE_VM}: ${CODE_RETOUR_ADD_RANGES_V6} ${ADD_RANGES_V6}"
|
||
echo "ERROR : Before retry, don't forget to DELETE previously registered IPv4 in IPAM : {VM_IPV4_NEW}."
|
||
exit 1
|
||
fi
|
||
|
||
RANGE_IPV6_NEW=$(echo ${ADD_RANGES_V6} | jq -r '.data')
|
||
|
||
RANGE_IPV6_NEW_WITHOUT_MASK=$(echo ${RANGE_IPV6_NEW} | cut -d'/' -f1)
|
||
RANGE_IPV6_NEW_MASK=$(echo ${RANGE_IPV6_NEW} | cut -d'/' -f2)
|
||
|
||
echo "INFO : IPv6 range for the VM : ${RANGE_IPV6_NEW_WITHOUT_MASK}/${RANGE_IPV6_NEW_MASK}"
|
||
|
||
echo -e "\n---------- CREATE IPAM ENTRIES OK ----------"
|
||
|
||
echo -e "\n---------- CREATE VM ----------\n"
|
||
|
||
# Clone template to new VM
|
||
echo "INFO : create new VM by cloning template (more than 1min to wait)... (CREATE NEW VM ${VM_ID} ${VM_HOSTNAME_TRUNCATE})"
|
||
qm clone ${VM_TEMPLATE_ID} ${VM_ID} -full -name ${VM_HOSTNAME_TRUNCATE} -storage local_data &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during cloning, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Wait some seconds to be sure the cloning is finished (else problems occurs)
|
||
sleep 60
|
||
|
||
# Change CPU number if necessary
|
||
if [ "${VM_CPU}" -ne 1 ]; then
|
||
echo "INFO : Change vCPU core number to ${VM_CPU} core(s)..."
|
||
qm set ${VM_ID} --cores ${VM_CPU} &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during changing vCPU core number, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "INFO : No need to change vCPU core number, value is ${VM_CPU} core(s)"
|
||
fi
|
||
|
||
# Change RAM size if necessary
|
||
if [ "${VM_RAM}" -ne 512 ]; then
|
||
echo "INFO : Extend RAM (resize to ${VM_RAM}MB)..."
|
||
qm set ${VM_ID} --memory ${VM_RAM} &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during resizing RAM, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "INFO : No need to resize RAM, value is ${VM_RAM}MB"
|
||
fi
|
||
|
||
# Change Disk size if necessary
|
||
if [ "${VM_DISK_EXTEND}" -ne 0 ]; then
|
||
echo "INFO : Extend disk (resize to ${VM_DISK}GB)..."
|
||
qm resize ${VM_ID} virtio0 +${VM_DISK_EXTEND}G #&> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during resizing disk, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "INFO : No need to resize disk, value is ${VM_DISK}GB"
|
||
fi
|
||
|
||
# Start VM
|
||
echo "INFO : start the new VM..."
|
||
qm start ${VM_ID}
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during starting the VM, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Wait the VM starting
|
||
sleep 20
|
||
|
||
# Define SSH params
|
||
SSH_OPT="-6 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
||
|
||
# Get the FE80 IPv6 of the new VM
|
||
echo "INFO : Get the FE80 IPv6 of the new VM..."
|
||
VM_MAC=$(grep net0 /etc/pve/qemu-server/${VM_ID}.conf | cut -d '=' -f 2 | cut -d ',' -f 1)
|
||
VM_FE80=$(ipv6calc --action prefixmac2ipv6 --in prefix+mac --out ipv6addr fe80:: $VM_MAC)
|
||
|
||
# Define SSH host
|
||
SSH_HOST="root@${VM_FE80}%${VM_BRIDGE_DEV}"
|
||
|
||
# Create network configuration file for new VM
|
||
echo "INFO : Create network configuration file for new VM..."
|
||
echo "# This file describes the network interfaces available on your system
|
||
# and how to activate them. For more information, see interfaces(5).
|
||
|
||
source /etc/network/interfaces.d/*
|
||
|
||
# The loopback network interface
|
||
auto lo
|
||
iface lo inet loopback
|
||
|
||
# The primary network interface
|
||
auto ens18
|
||
allow-hotplug ens18
|
||
iface ens18 inet static
|
||
address ${VM_IPV4_NEW}/${VM_IPV4_NEW_SUBNET_MASK}
|
||
gateway ${VM_IPV4_NEW_SUBNET_GW}
|
||
dns-nameservers ${DNS_NAMESERVERS_IPV4}
|
||
|
||
iface ens18 inet6 static
|
||
address ${RANGE_IPV6_NEW_WITHOUT_MASK}1/${RANGE_IPV6_NEW_MASK}
|
||
gateway ${IPV6_GATEWAY}
|
||
dns-nameservers ${DNS_NAMESERVERS_IPV6}" > /tmp/interfaces_vm${VM_ID}
|
||
|
||
# Replace network configuration file on new VM
|
||
echo "INFO : Replace network configuration file on new VM... (VM NETWORK CONF UPDATE)"
|
||
scp ${SSH_OPT} /tmp/interfaces_vm${VM_ID} root@[${VM_FE80}%${VM_BRIDGE_DEV}]:/etc/network/interfaces &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during copy of the new network conf file, please finish manually the deploy OR delete VM and IPAM information'
|
||
|
||
# Clean temp file
|
||
echo "INFO : Clean temp file"
|
||
rm /tmp/interfaces_vm${VM_ID}
|
||
|
||
exit 1
|
||
fi
|
||
|
||
# Clean temp file
|
||
echo "INFO : Clean temp file"
|
||
rm /tmp/interfaces_vm${VM_ID}
|
||
|
||
# Restart networking service on VM to apply new network configuration
|
||
echo "INFO : Restart networking service on VM to apply new network configuration... (systemctl restart networking)"
|
||
ssh ${SSH_OPT} ${SSH_HOST} "systemctl restart networking" &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during restart networking service on VM, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Regenerate SSH host keys for the VM and restart SSHD
|
||
echo "INFO : Regenerate SSH host keys for the VM and restart SSHD..."
|
||
ssh ${SSH_OPT} ${SSH_HOST} "/bin/rm -v /etc/ssh/ssh_host_* && dpkg-reconfigure openssh-server && systemctl restart ssh" &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during regenerate SSH host keys for the VM, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Get FingerPrint
|
||
echo "INFO : Get SSH FingerPrint of the new VM..."
|
||
file=$(mktemp)
|
||
sleep 1
|
||
ssh-keyscan ${VM_FE80}%${VM_BRIDGE_DEV} >${file} 2>/dev/null
|
||
sleep 1
|
||
SSH_FP="$(ssh-keygen -l -f ${file})"
|
||
sleep 1
|
||
rm ${file}
|
||
|
||
# Resize disk and LV if disk has been extended
|
||
if [ "${VM_DISK_EXTEND}" -ne 0 ]; then
|
||
|
||
echo "INFO : Create new primary partition to extend VG... (Create new partition)"
|
||
|
||
# Dirty but it's just work
|
||
ssh ${SSH_OPT} ${SSH_HOST} "echo -e \"n\np\n\n\n\nt\n\n8e\nw\n\" | fdisk /dev/vda" &> /dev/null
|
||
|
||
# Don't check errors because return code in error (system has to reboot)
|
||
|
||
echo "INFO : Reboot the system to reload partition table etc... (reboot)"
|
||
|
||
ssh ${SSH_OPT} ${SSH_HOST} "reboot" &> /dev/null
|
||
|
||
# Wait for system reboot
|
||
sleep 20
|
||
echo "INFO : wait 3 minutes to be sure that ssh service is started"
|
||
|
||
echo "INFO : Create new PV... (pvcreate /dev/vda3)"
|
||
|
||
ssh ${SSH_OPT} ${SSH_HOST} "pvcreate /dev/vda3" &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during create PV, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
DEFAULT_VG=$(vgs | awk '/vg/ {print $1}')
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during get the name of the default VG'
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Add new PV to VG ${DEFAULT_VG}... (vgextend ${DEFAULT_VG} /dev/vda3)"
|
||
|
||
ssh ${SSH_OPT} ${SSH_HOST} "vgextend ${DEFAULT_VG} /dev/vda3" &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during add new PV in VG, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : Resize LV on disk... (RESIZE VM LV)"
|
||
|
||
DEFAULT_LV_ROOT=$(find /dev/mapper -name '*root*')
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during get the name of the default root LV'
|
||
exit 1
|
||
fi
|
||
|
||
ssh ${SSH_OPT} ${SSH_HOST} "lvextend -l +100%FREE ${DEFAULT_LV_ROOT}" &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during resizing LV, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
echo "INFO : resize2fs the LV... (RESIZE VM LV FS)"
|
||
|
||
ssh ${SSH_OPT} ${SSH_HOST} "resize2fs ${DEFAULT_LV_ROOT}" &> /dev/null
|
||
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during resize2fs, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
else
|
||
echo "INFO : No need to resize LV on disk"
|
||
fi
|
||
|
||
# Update VM system
|
||
echo "INFO : Update VM OS, this can take some minutes... (apt update -q && apt upgrade -y -q)"
|
||
ssh ${SSH_OPT} ${SSH_HOST} "apt update -q && apt upgrade -y -q" &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during updating the VM, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Delete root .bash_history
|
||
echo "INFO : Delete root user .bash_history... (rm /root/.bash_history)"
|
||
ssh ${SSH_OPT} ${SSH_HOST} "rm /root/.bash_history" &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during deleting root .bash_history, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
# Add user SSH Pub key to root (and erase HV pub key) and reboot
|
||
echo "INFO : Add user SSH Pub key to root (and erase HV pub key) and reboot in 1 minute... (WARN : if you provided incorrect SSH pub key, nobody could log in the VM...)"
|
||
ssh ${SSH_OPT} ${SSH_HOST} "shutdown --reboot +1 'System is going down for reboot in 1 minute'; echo ${USER_SSH_PUB_KEY} > /root/.ssh/authorized_keys" &> /dev/null
|
||
if [ $? -ne 0 ]; then
|
||
echo 'ERROR : problem during replace HV SSH pub keys by user SSH pub key or during reboot programming, please finish manually the deploy OR delete VM and IPAM information'
|
||
exit 1
|
||
fi
|
||
|
||
echo -e "\n---------- CREATE VM OK ----------\n"
|
||
|
||
echo "INFO : Send the final mail..."
|
||
|
||
SUBJECT=$(perl -wse "use utf8; use Encode qw(encode); print encode(\"MIME-Q\",\
|
||
\"Votre machine virtuelle GRIFON vient d’être créée\");")
|
||
|
||
echo "From: Adminsys GRIFON <adminsys@grifon.fr>
|
||
To: ${USER_MAIL}
|
||
Cc: adminsys@grifon.fr
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Subject: ${SUBJECT}
|
||
|
||
Bonjour,
|
||
|
||
Votre machine virtuelle vient d’être créée.
|
||
|
||
La clé publique SSH que vous nous avez fournie a été mise sur le compte root.
|
||
Vous pouvez vous connecter en SSH via
|
||
ssh root@${VM_IPV4_NEW}
|
||
ssh root@${RANGE_IPV6_NEW_WITHOUT_MASK}1
|
||
|
||
Votre range IPv6 est ${RANGE_IPV6_NEW}
|
||
|
||
Nous vous recommandons très vivement de changer les mots de passe root et default-user-grifon (utilisateur par défaut) ainsi que
|
||
d’interdire la connexion par SSH en tant que root.
|
||
|
||
Voir pouvez donc vous connecter, démarrer votre machine virtuelle
|
||
et la configurer comme vous le souhaitez.
|
||
|
||
Le fingerprint SSH de votre VM est :
|
||
${SSH_FP}
|
||
|
||
Si vous souhaitez avoir un reverse DNS, vous pouvez contacter
|
||
adminsys@grifon.fr en précisant si vous souhaitez une délagation ou en donnant
|
||
le FQDN.
|
||
|
||
Cordialement,
|
||
--
|
||
Les adminsys de GRIFON" | /usr/sbin/sendmail -f adminsys@grifon.fr -t
|
||
|
||
echo "INFO : script finished, mail sent to the user and adminsys@grifon.fr"
|
||
|
||
echo -e "\n---------- END OF SCRIPT ${0} ---------\n"
|
||
|
||
exit 0
|
||
|