#!/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} \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 echo "INFO : Wait 1 minute for system reboot" sleep 60 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 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 (nous vous conseillons aussi de changer le hostname). 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