🔒 Repository is read-only – file editing is disabled.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
#!/usr/bin/env bash
_error() {
$ECHOCMD "${RED}${1}, exit... ${NORMAL}"
exit 1
}
_warning() {
$ECHOCMD "${RED}Attention ..., ${1}${NORMAL}"
}
_info() {
$ECHOCMD "${YELLOW}${1} ${NORMAL}"
}
_success() {
$ECHOCMD "${GREEN}${1} ${NORMAL}"
}
nbcoresquery() {
_info "How many cores will the VM use ? (by default 2)"
read coresquery
if [[ -z $coresquery ]]
then
cores=2
$ECHOCMD "NUMBER_OF_CORES=$cores" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The number of cores allocated to the VM will be $cores"
else
cores=$coresquery
$ECHOCMD "NUMBER_OF_CORES=$cores" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The number of cores allocated to the VM will be $cores"
fi
}
cpuquery() {
_info "What kind of CPU ? (host by default, kvm32, kvm64, base)"
read cpuquery
[[ -z $cpuquery ]] && cpuquery=host
case $cpuquery in
host)
cpu=host
$ECHOCMD "CPU_TYPE=$cpu" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The host CPU will be used"
;;
kvm32)
cpu=kvm32
$ECHOCMD "CPU_TYPE=$cpu" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The CPU used will be $cpu"
;;
kvm64)
cpu=kvm64
$ECHOCMD "CPU_TYPE=$cpu" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The CPU used will be $cpu"
;;
base)
cpu=base
$ECHOCMD "CPU_TYPE=$cpu" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The CPU used will be $cpu"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
unset cpuquery
cpuquery
;;
esac
}
tabletquery() {
_info "Need the tablet pointer support ? (yes or no (by default))"
read tabletquery
[[ -z $tabletquery ]] && tabletquery=N
case $tabletquery in
Y|y|yes)
tablet="-device usb-tablet"
$ECHOCMD "TABLET_POINTER=YES" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The tablet pointer support is activated"
;;
N|n|no)
tablet=""
$ECHOCMD "TABLET_POINTER=NONE" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The tablet pointer support is not activated"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
unset tabletquery
tabletquery
;;
esac
}
soundhwquery() {
case $displayquery in
vnc|spice)
sndhw=""
$ECHOCMD "SOUND_CARD_TYPE=NONE" >> ${_FULLPATHNAME}/${_NAME}.var
_success "No sound card"
;;
*)
_info "What type of sound card ? (ac97 by default, hda, sb16, none)"
read sndhwquery
[[ -z $sndhwquery ]] && sndhwquery=ac97
case $sndhwquery in
AC97|ac97)
sndhw="ac97"
$ECHOCMD "SOUND_CARD_TYPE=${sndhw}" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The sound card will be $sndhwquery"
;;
HDA|hda)
sndhw="hda"
$ECHOCMD "SOUND_CARD_TYPE=${sndhw}" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The sound card will be $sndhwquery"
;;
SB16|sb16)
sndhw="sb16"
$ECHOCMD "SOUND_CARD_TYPE=${sndhw}" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The sound card will be $sndhwquery"
;;
NONE|none)
sndhw=""
$ECHOCMD "SOUND_CARD_TYPE=NONE" >> ${_FULLPATHNAME}/${_NAME}.var
_success "No sound card"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
unset sndhwquery
soundhwquery
;;
esac
;;
esac
}
vgaquery() {
_info "What type of graphics card ? (virtio by default, std, cirrus, qxl)"
read vgaquery
[[ -z $vgaquery ]] && vgaquery=VIRTIO
case $vgaquery in
virtio|Virtio|VIRTIO)
vga=virtio
$ECHOCMD "VGA_HARDWARE_TYPE=$vga" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "VGA_MEMORY_SIZE=512M" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The graphics card will be $vga"
_info "Do you want OpenGL support, yes or no (by default)"
read glquery
[[ -z $glquery ]] && glquery=N
case $glquery in
Y|y|O|o|yes)
gl="-display sdl,gl=on"
$ECHOCMD "GL_ACCELERATION=YES" >> ${_FULLPATHNAME}/${_NAME}.var
_success "OpenGL acceleration is enabled in the VM"
;;
N|n|no)
gl=""
$ECHOCMD "GL_ACCELERATION=NO" >> ${_FULLPATHNAME}/${_NAME}.var
_success "No openGL acceleration of the VM"
;;
*)
_warning "The answer is not correct"
unset vgaquery
vgaquery
;;
esac
;;
std)
vga=std
$ECHOCMD "VGA_HARDWARE_TYPE=$vga" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The graphics card will be $vga"
;;
cirrus)
vga=cirrus
$ECHOCMD "VGA_HARDWARE_TYPE=$vga" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "VGA_MEMORY_SIZE=8M" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The graphics card will be $vga"
;;
qxl)
vga=qxl
$ECHOCMD "VGA_HARDWARE_TYPE=$vga" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "VGA_MEMORY_SIZE=512M" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The graphics card will be $vga"
display="spice"
$ECHOCMD "VGA_DISPLAY_TYPE=$display" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "REMOTE_PORT=5900" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "DISPLAY_OPTS=disable-ticketing" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The output of the VM will be in SPICE and CG QXL used"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
unset vgaquery
vgaquery
;;
esac
}
displayquery() {
if [[ -z $display ]]
then
_info "What kind of graphics output ? (spice, vnc, egl-headless or local (default))"
read displayquery
[[ -z $displayquery ]] && displayquery=local
case $displayquery in
local)
display="-display gtk"
$ECHOCMD "VGA_DISPLAY_TYPE=gtk" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The VM will be displayed on your screen"
_info "Want a full screen graphics output ? (yes, no (default choice)"
read fullscreenquery
[[ -z $fullscreenquery ]] && fullscreenquery=N
case $fullscreenquery in
YES|yes|y|Y)
_success "The VM will be displayed in full screen mode"
$ECHOCMD "LOCAL_FULLSCREEN=yes" >> ${_FULLPATHNAME}/${_NAME}.var
;;
NO|no|n|N)
_success "The VM will be displayed standard mode"
$ECHOCMD "LOCAL_FULLSCREEN=no" >> ${_FULLPATHNAME}/${_NAME}.var
;;
*)
_success "Can't understand, fallback to no full screen"
$ECHOCMD "LOCAL_FULLSCREEN=no" >> ${_FULLPATHNAME}/${_NAME}.var
;;
esac
;;
vnc)
if [[ -n "$gl" ]]
then
_warning "OpenGL acceleration is not available in VNC"
sed -e "s/GL_ACCELERATION=YES/GL_ACCELERATION=NO/" -i ${_FULLPATHNAME}/${_NAME}.var
fi
$ECHOCMD "VGA_DISPLAY_TYPE=vnc" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "REMOTE_PORT=0:0" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "VNC_LAYOUT=fr" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "DISPLAY_OPTS=" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The output of the VM will be in VNC localhost: 0, keyboard in FR layout"
;;
spice)
if [[ -n "$gl" ]]
then
_warning "OpenGL acceleration is not available in Spice"
sed -e "s/GL_ACCELERATION=YES/GL_ACCELERATION=NO/" -i ${_FULLPATHNAME}/${_NAME}.var
fi
display="-spice port=5900,disable-ticketing"
$ECHOCMD "VGA_DISPLAY_TYPE=spice" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "REMOTE_PORT=5900" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "DISPLAY_OPTS=disable-ticketing" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The output of the VM will be in SPICE, port 5900"
;;
egl-headless)
display="-spice port=5900,disable-ticketing"
$ECHOCMD "VGA_DISPLAY_TYPE=egl-headless" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "REMOTE_PORT=5900" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "DISPLAY_OPTS=disable-ticketing" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The output of the VM will be in SPICE, port 5900, 3D acceleration"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
displayquery
;;
esac
fi
}
netquery() {
_info "What type of network card ? (virtio by default, e1000, rtl8139"
read netquery
[[ -z $netquery ]] && netquery=VIRTIO
case $netquery in
virtio|Virtio|VIRTIO)
net=virtio-net
$ECHOCMD "NETWORK_HARDWARE_TYPE=$net" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "NETWORK_TYPE=user" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The network will have $net as a device"
;;
e1000)
net=e1000
$ECHOCMD "NETWORK_HARDWARE_TYPE=$net" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "NETWORK_TYPE=user" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The network will have $net as a device"
;;
rtl8139|8139)
net=rtl8139
$ECHOCMD "NETWORK_HARDWARE_TYPE=$net" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "NETWORK_TYPE=user" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The network will have $net as a device"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
netquery
;;
esac
}
memquery() {
_info "How much memory do you want the VM to have ? (Default 2G, specify the unit M, G, T)"
read memquery
if [[ -z $memquery ]]
then
mem=2G
$ECHOCMD "SYSTEM_MEMORY_SIZE=$mem" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The VM will use $mem from RAM"
else
mem=$memquery
$ECHOCMD "SYSTEM_MEMORY_SIZE=$mem" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The VM will use $mem from RAM"
fi
}
vmfolder_check() {
[[ ! -d ${_VMFOLDER} ]] && _error "The ${_VMFOLDER} folder is not present, please create it"
}
qemu_img_check() {
_QEMU_IMG_BIN=$(which qemu-img)
[[ ${_QEMU_IMG_BIN} == '' ]] && _error "Qemu-img does not seem to be installed on your system, please install it"
}
qemu_check() {
_QEMU_BIN=$(which qemu-system-x86_64)
[[ ${_QEMU_BIN} == '' ]] && _error "Qemu-system-x86_64 does not seem to be installed on your system, please install it"
}
vmname_query() {
_info "What is the name of the virtual machine you want to create or run (Without spaces) ?"
$LSBIN --color=auto ${_VMFOLDER}
read _NAME
_success "The name of the VM will be ${_NAME}"
_FULLPATHNAME=${_VMFOLDER}/${_NAME}
_FULLISOPATH=${_VMFOLDER}/iso
}
configorstart() {
source ${_FULLPATHNAME}/${_NAME}.var 2>&1 > /dev/null
if [[ $ALREADY_RUN == yes ]]
then
startqemu
else
hdsize_query
bios_or_uefi_vm
iffirstdiskquery
memquery
cpuquery
nbcoresquery
netquery
cdromquery
vgaquery
displayquery
soundhwquery
tabletquery
startqemu
fi
}
hdsize_query() {
_info "What size disk (30G by default) (M for Megabytes, G for Gigabytes, T for Terabytes without spaces) ?"
read _SIZE
[[ -z ${_SIZE} ]] && _SIZE=30G
_success "The disk size will be ${_SIZE}"
}
bios_or_uefi_vm() {
_info "What type of VM do you want ? BIOS (by default) or UEFI :"
read _TYPE
[[ -z ${_TYPE} ]] && _TYPE=BIOS
case ${_TYPE} in
bios|BIOS)
create_vm_bios
_success "The machine will be configured in ${_TYPE}"
;;
uefi|UEFI)
create_vm_uefi
_success "The machine will be configured in ${_TYPE}"
;;
*)
_warning "The answer is not correct"
bios_or_uefi_vm
;;
esac
}
create_vm_uefi() {
local CREATE_STATE
_OVMF_CHECK=$(find /usr/share -iname "OVMF_VARS.fd")
if [[ -z ${_OVMF_CHECK} ]]
then
_error "Please install OVMF or related package to create VM with UEFI"
fi
if [[ ! -d ${_FULLPATHNAME} ]]
then
if [[ $VERBOSE == yes ]]
then
mkdir -pv ${_FULLPATHNAME}
else
mkdir -p ${_FULLPATHNAME}
fi
$ECHOCMD "ALREADY_RUN=no" > ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "MONITOR=stdio" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "MACHINE_NAME=${_NAME}" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "BIOS_TYPE_INFO=UEFI" >> ${_FULLPATHNAME}/${_NAME}.var
fi
if [[ ! -f ${_FULLPATHNAME}/${_NAME}.qcow2 ]]
then
if [[ $VERBOSE == yes ]]
then
${_QEMU_IMG_BIN} create -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}
CREATE_STATE=$?
else
${_QEMU_IMG_BIN} create -q -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}
CREATE_STATE=$?
fi
if [[ $CREATE_STATE -eq 0 ]]
then
_success "${_QEMU_IMG_BIN} create -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}"
$ECHOCMD "HDD1_NAME=${_FULLPATHNAME}/${_NAME}.qcow2" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "HDD1_SIZE_INFO=${_SIZE}" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "OVMF_VAR_DISK_INFO=${_FULLPATHNAME}/OVMF_VARS_${_NAME}.fd" >> ${_FULLPATHNAME}/${_NAME}.var
if [[ $VERBOSE == yes ]]
then
cp -v $EFIVARS ${_FULLPATHNAME}/OVMF_VARS_${_NAME}.fd
else
cp $EFIVARS ${_FULLPATHNAME}/OVMF_VARS_${_NAME}.fd
fi
else
_error "The command ${_QEMU_IMG_BIN} did not execute correctly"
fi
else
_error "VM disk exists, no creation"
fi
}
create_vm_bios() {
if [[ ! -d ${_FULLPATHNAME} ]]
then
if [[ $VERBOSE == yes ]]
then
mkdir -pv ${_FULLPATHNAME}
else
mkdir -p ${_FULLPATHNAME}
fi
$ECHOCMD "ALREADY_RUN=no" > ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "MONITOR=stdio" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "MACHINE_NAME=${_NAME}" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "BIOS_TYPE_INFO=BIOS" >> ${_FULLPATHNAME}/${_NAME}.var
else
_error "VM folder exists"
fi
if [[ ! -f ${_FULLPATHNAME}/${_NAME}.qcow2 ]]
then
if [[ $VERBOSE == yes ]]
then
${_QEMU_IMG_BIN} create -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}
CREATE_STATE=$?
else
${_QEMU_IMG_BIN} create -q -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}
CREATE_STATE=$?
fi
if [[ $CREATE_STATE -eq 0 ]]
then
_success "${_QEMU_IMG_BIN} create -f qcow2 ${_FULLPATHNAME}/${_NAME}.qcow2 ${_SIZE}"
$ECHOCMD "HDD1_NAME=${_FULLPATHNAME}/${_NAME}.qcow2" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "HDD1_SIZE_INFO=${_SIZE}" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "OVMF_VAR_DISK_INFO=NONE" >> ${_FULLPATHNAME}/${_NAME}.var
else
_error "The command ${_QEMU_IMG_BIN} did not execute correctly"
fi
else
_error "VM disk exists, no creation"
fi
}
iffirstdiskquery() {
_info "What interface for the disc 1 ? IDE (by default), virtio or NVMe"
read _IF_QUERY
[[ -z ${_IF_QUERY} ]] && _IF_QUERY=ide
case ${_IF_QUERY} in
ide|IDE)
$ECHOCMD "HDD1_CONTROLLER_TYPE=${_IF_QUERY}" >> ${_FULLPATHNAME}/${_NAME}.var
_success " The disk interface will be IDE"
;;
virtio|VIRTIO)
$ECHOCMD "HDD1_CONTROLLER_TYPE=${_IF_QUERY}" >> ${_FULLPATHNAME}/${_NAME}.var
_success "The disk interface will be VIRTIO"
;;
nvme|NVME)
$ECHOCMD "HDD1_CONTROLLER_TYPE=none,id=nvme1" >> ${_FULLPATHNAME}/${_NAME}.var
$ECHOCMD "HDD1_CONTROLLER_EXTRA=-device nvme,serial=0ABC1,drive=nvme1" >> ${_FULLPATHNAME}/${_NAME}.var
_success " The disk interface will be NVMe"
;;
exit)
exit 1
;;
*)
_warning "The answer is not correct"
iffirstdiskquery
;;
esac
}
cdromfolder_check() {
if [[ ! -d ${_FULLISOPATH} ]]
then
$ECHOCMD "The folder ${_FULLISOPATH} does not exist, please create it and put your ISOS there"
exit 1
fi
}
cdromquery() {
$LSBIN ${_FULLISOPATH}/ --color=auto
_info "Do you want to use an ISO? (nothing if no ISO)"
read cdrom
if [[ ! -z $cdrom ]]
then
if [[ -f ${_FULLISOPATH}/$cdrom ]]
then
iso="${_FULLISOPATH}/$cdrom"
$ECHOCMD "ISO_FILE=$iso" >> ${_FULLPATHNAME}/${_NAME}.var
_success "ISO file iso / $ cdrom will be used"
else
_warning "ISO file does not exist"
unset cdrom
cdromquery
fi
else
iso=""
$ECHOCMD "ISO_FILE=NONE" >> ${_FULLPATHNAME}/${_NAME}.var
_success "No CD-Rom"
fi
}
startqemu() {
START_VM_CMD=$(which startvm)
if [[ -z $START_VM_CMD ]]
then
_error "The startvm script is not present in the PATH, please adjust it."
else
source ${_FULLPATHNAME}/${_NAME}.var
$START_VM_CMD ${_NAME}
[[ $ALREADY_RUN == no ]] && sed -e "/ALREADY_RUN/s/no/yes/" -i ${_FULLPATHNAME}/${_NAME}.var
fi
}
main() {
[[ -z ${_VMFOLDER} ]] && _VMFOLDER=$HOME/VM-qemu
EFIVARS=/usr/share/ovmf/x64/OVMF_VARS.fd
LSBIN=$(which ls)
ECHOBIN=$(which echo)
ECHOCMD="$ECHOBIN -e"
qemu_img_check
qemu_check
vmfolder_check
vmname_query
cdromfolder_check
configorstart
}
RED='\033[31m'
NORMAL='\033[0m'
YELLOW='\033[33m'
GREEN='\033[32m'
printf "$YELLOW This script is obsolet and will be removed in the future, please setup-vm -c instead !!! $NORMAL \n"
sleep 3
main "$@"