vm-start/vm-start.sh
2024-03-03 18:26:33 +00:00

421 lines
11 KiB
Bash
Executable file

#!/usr/bin/bash
#
#RESULT_POSSIBLE=("init","list","start","start_backup","create","backup","restore","suppr")
# Constante d'éxecutions.
Version="0.7.0"
USAGE="vm-start [PARAMETTER] [ NAME COMMAND [OPTION] ]
Script to manage virtual machine easily.
NAME is the name of the virtual machine to use.
PARAMETTER available
-h, --help Print this help and exit
-v, --version Print the version of this program and quit
-l, --list Print the list of all availables machines and quit
COMMAND available
init Create the conf file in conf/NAME_var.sh
init_cdrom init a RO image/cdrom. The network will have to be set later in the conf file. NO EUFI
start Start the virtual machine using the variabes in conf/NAME_var.sh
start-backup Start the virtual machine using the backup volume if it exists.
create Create the virtual machine using the conf in conf/NAME_var.sh
backup Create a backup file for the vm
restore Restore the virtual machine using to backup file
suppr Suppr all data related to the virtual machine other than the conf file.
suppr-all Suppr all data related to the vm even the conf file
OPTION available
--nproc=<nb proc> Def the number of proc of the vm
--memory=<mem> Def the qty of memory allocated to the vm
--size=<size> Def the size that will be allocated by create. Have no effect on other commands.
--uefi Select if there will be an UEFI by default.
can be either set or unset. By default is unset.
--options=<option> additinal options to give to qemu. By default is
-display gtk -vga qxl
--create_disk=<loc_disk> Def a create disk to boot on. Is necessary for using create, or need the variable INSTALLATION_DISK_LOCATION to be set.
--net=nat:id Add a nat connection to the vm. By default there is already one.
--net=br:<br-id> Connect the vm to the bridge <br-id>. Please use the script set-tap.sh as root to create the bridge. in the conf file, a mac field have to be set. for two vm to connect togethers, their mac addresses on the same network have to be differents.
--net=none The vm will have no network interface
"
MAIN_LOCATION="$HOME/virtual_machine"
# if MAIN_LOCATION doesn't exists, create the folder.
if [ -f "$MAIN_LOCATION" ]
then
mkdir "$MAIN_LOCATION" || exit 0 #Exit in case the folder can't be created.
echo "$MAIN_LOCATION created to contain all virtual machines."
fi
OPTION="-display gtk,gl=on,show-cursor=on,show-menubar=off \
-device virtio-gpu-gl \
-usbdevice tablet \
-daemonize"
# other options choices
#
#-display gtk,show-menubar=off,gl=on,show-cursor=on,zoom-to-fit=on \
#-display sdl
#-vga qxl
#-usbdevice tablet \
list() {
echo "this is the list of all vm actually configured."
for vm in $(ls conf); do
echo "${vm%-vm_var.sh}"
done
exit 0
}
HELP() {
echo "$USAGE"
exit 0
}
INIT() {
echo "INIT for vm $1"
NAME="$1"
read -p "How many proccessor will you use ? " -r NPROC
read -p "How much memory will you need ? " -r MEMORY
# from now on, ssh port forward to choose while exec the script.
#read -p "Do you want to forward ssh port (y/n) " -r entry
#if echo "$entry" | grep -q "^[yY]$"
#then
# FORWARD=",hostfwd=tcp::10022-:22" # forward VM 22 port to Host 10022
#fi
mkdir -p conf
cat << EOF > "conf/$NAME-vm_var.sh"
NAME="${NAME}"
VMHOSTNAME="\${NAME}-vm"
VMDRIVE="\${VMHOSTNAME}.cow"
NPROC="${NPROC}"
MEMORY="${MEMORY}"
FORWARD="${FORWARD}"
LOCATION="\${NAME}-sandbox"
mac="00:00:00:00:00:00"
EOF
chmod +x "conf/$NAME-vm_var.sh"
}
INIT_cdrom() {
echo "Init for a cdrom."
echo "Init was already called."
# necessite au moins l'addresse de l'image en tant que $1
VMROM="$(basename $1)"
if [ ! -f "${MAIN_LOCATION}/${LOCATION}/${VMROM}" ]
then
echo "create directory ${MAIN_LOCATION}/${LOCATION}/"
mkdir -p "${MAIN_LOCATION}/${LOCATION}/"
cp $1 "${MAIN_LOCATION}/${LOCATION}/${VMROM}"
fi
echo "CDROM_DISK=\"${VMROM}\"" >> "conf/$NAME-vm_var.sh"
echo "Done"
}
start_the_vm() {
if [ "${network}" == "" ]
then
network="-net nic \
-net user${FORWARD},hostname=${VMHOSTNAME}"
fi
if [ "${CDROM_DISK}" != "" ]
then
DRIVE="-drive file=${MAIN_LOCATION}/${LOCATION}/${CDROM_DISK},index=2,id=maindrive,media=cdrom"
else
DRIVE="-drive file=${MAIN_LOCATION}/${LOCATION}/${VMDRIVE},index=2,id=maindrive,media=disk"
fi
qemu-system-x86_64 \
-enable-kvm \
-cpu host \
-smp "$NPROC" \
$network \
-m "$MEMORY" \
$DRIVE \
$OPTION
}
START() {
start_the_vm
}
START_BACKUP() {
VMDRIVE="${VMDRIVE}.backup"
start_the_vm
}
CREATE() {
if [ -z "${SIZE+x}" ]
then
SIZE="40G"
fi
if [ ! -f "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow" ]
then
echo "create directory ${MAIN_LOCATION}/${LOCATION}/"
mkdir -p "${MAIN_LOCATION}/${LOCATION}/"
qemu-img create -f qcow2 "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow" "$SIZE"
fi
if [ "${UEFI}" == "set" ]
then
echo "create UEFIVAR"
if [ ! -f "${MAIN_LOCATION}/${LOCATION}/OVMF_VARS.4m.fd" ]
then
cp /usr/share/edk2/x64/OVMF_VARS.4m.fd "${MAIN_LOCATION}/${LOCATION}"
else
echo "INFO, UEFIVAR already existing"
fi
fi
OPTION="$OPTION \
-boot d \
-drive file=$1,if=none,media=cdrom,id=drive-cd1 \
-device ide-cd,drive=drive-cd1,id=cd1,bootindex=1"
start_the_vm
}
RESTORE() {
read -p "Are you sure you want to restore the rescue? (y/N) " -r entry
if echo "$entry" | grep -q "^[yY]$"
then
cp -i "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow.backup" "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow"
echo "Done"
fi
}
BACKUP() {
read -p "Are you sure you want to backup the volume? If you continue the previous backup will be lost (y/N) " -r entry
if echo "$entry" | grep -q "^[yY]$"
then
cp -i "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow" "${MAIN_LOCATION}/${LOCATION}/${VMHOSTNAME}.cow.backup"
echo "Done"
fi
}
SUPPRESS() {
read -p "Are you sure you want to delete all data relative to the vm $1? (y/N)" -r entry
if echo "$entry" | grep -q "^[yY]$"
then
rm -Ri "${MAIN_LOCATION}/${LOCATION}"
fi
}
suppress_all() {
read -p "Are you sure you want to delete all data relative to the vm $1 even conf file? (y/N)" -r entry
if echo "$entry" | grep -q "^[yY]$"
then
rm -i conf/$1-vm_var.sh
rm -Ri "${MAIN_LOCATION}/${LOCATION}"
fi
}
set_uefi() {
UEFI="set"
OPTION="${OPTION} \
-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \
-drive if=pflash,format=raw,file=${MAIN_LOCATION}/${LOCATION}/OVMF_VARS.4m.fd"
}
set_net() {
case "${1%:*}" in
"nat")
network="${network} \
-netdev user,id=${1#*:} \
-device virtio-net,netdev=${1#*:}"
;;
"br")
if [ "${mac}" == "" ]
then
echo "error, no mac set"
exit 1
fi
if [ "${driver}" == "" ]
then
driver="virtio-net"
fi
network="${network} \
-netdev bridge,id=${1#*:},br=${1#*:} \
-device ${driver},netdev=${1#*:},mac=${mac}"
;;
"none")
echo "no interface will be connected."
network="-nic none"
;;
*)
echo "type ${1%:*} not known, it should be either nat, br or none" >&2
exit 1
;;
esac
}
# change active directory to became the one is stored vm-start. In case it is impossible, quit.
cd "$( dirname "$( readlink -f "$0" )" )" || exit
# gère les paramètres
for i in "$@"; do
case "$i" in
"-h" | "--help")
HELP
;;
"-v" | "--version")
echo "vm-start ${Version}"
exit 0
;;
"-l" | "--list")
list
;;
esac
done
# verifie au moins assez d'options pour utiliser le programme.
if [ $# -lt 2 ]
then
echo "Error, not enough args" >&2
HELP
fi
# vérifie que le dossier pour stocker les vms existe & change le dossier actif pour qu'il soit cellui du lanceur.
mkdir -p "$MAIN_LOCATION"
# Vérifie qu'il y ait bien un fichier de config pour la vm que l'on tente de démarer dans la cas contraire en génére un.
# possibilitée de générer à nouveau le fichier de config avec vm-start nom-vm init
if [ ! -f "conf/$1-vm_var.sh" ]
then
echo "no config file found. creating one in conf/${1}-vm_var.sh"
INIT "$1"
if [ "$2" == "init" ]
then
# Exit, it is the end of the program.
exit 0
fi
fi
#Vérifie si l'option UEFI est set dans le fichier de config. Si oui l'ajoutte aux options.
. "conf/$1-vm_var.sh"
for i in ${net}; do
set_net "${i}"
done
for (( i=3; i<=$#; i++)); do
case "${!i%=*}" in
"--nproc")
NPROC="${!i#*=}"
;;
"--memory")
MEMORY="${!i#*=}"
;;
"--size")
SIZE="${!i#*=}"
;;
"--uefi")
set_uefi
;;
"--create_disk")
INSTALLATION_DISK_LOCATION="${!i#*=}"
;;
"--net")
param="${!i#*=}"
set_net "${param}"
;;
esac
done
if [ "${UEFI}" == "yes" ]
then
set_uefi
fi
case "$2" in
"start")
echo "starting VM $1"
START
;;
"start-backup")
echo "starting VM rescue"
START_BACKUP
;;
"backup")
echo "backup VM"
BACKUP
;;
"restore")
echo "restore backup"
RESTORE
;;
"create")
echo "creating VM"
if [ ! "${INSTALLATION_DISK_LOCATION}" == "" ]
then
echo "using image disk ${INSTALLATION_DISK_LOCATION}"
CREATE "${INSTALLATION_DISK_LOCATION}"
else
echo "Error, no image defined." >&2
echo "use --create_disk=<loc_disk>" >&2
fi
;;
"suppr")
echo "suppressing all data of the vm $1"
SUPPRESS "$1"
;;
"suppr-all")
echo "suppressing all data and conf file of the vm $1"
suppress_all "$1"
;;
"init")
echo "Init volume $1"
#INIT "$1"
echo "Error, Normally, already called before."
;;
"init_cdrom")
echo "Init cdrom $1"
if [ ! "${INSTALLATION_DISK_LOCATION}" == "" ]
then
echo "using image disk ${INSTALLATION_DISK_LOCATION}"
INIT_cdrom "${INSTALLATION_DISK_LOCATION}"
else
echo "Error, no image defined." >&2
echo "use --create_disk=<loc_disk>" >&2
fi
;;
*)
echo "commande $2 inconnue" >&2
HELP
esac