From KVM
[edit]
goal
start the tap network adapter and virtual machine with one command like: kvm-manager start similarly, stop or kill the virtual machine like: kvm-manager stop
[edit]
how
having a directory containing everything about the virtual machine, for example:
/var/guest/my-workstation conf override hda hdb /var/guest/my-workstation/run monitor pid
this form a convention. the script will look for your settings in the file called "conf", and will load additional overwriting settings in "override" file. hda is the first disk image, hdb is the second disk image. everything generated when the vm is running will put in "run" directory.
[edit]
example
to be continued...
[edit]
kvm-manager.sh
#!/bin/sh
### expected directory structure
DIR_BASE=`pwd $`
FILE_HDA=${DIR_BASE}/hda
FILE_CONF=${DIR_BASE}/conf
FILE_OVERRIDE=${DIR_BASE}/override
### run directory will be auto-created with following files
DIR_RUN=${DIR_BASE}/run
FILE_MONITOR=${DIR_RUN}/monitor
FILE_PID=${DIR_RUN}/pid
FILE_OUT=${DIR_RUN}/out
### user-defined variables in ./kvm.conf
#GUEST_ID [required] generate the mac and tap name
#GUEST_MEMORY [optional] in mega-bytes, default to 1024
GUEST_MEMORY=1024
if [ -f ${FILE_CONF} ]
then
. ${FILE_CONF}
else
echo "file ${FILE_CONF} not exists"
exit 1
fi
### generated variables
TAP_NAME=tap${GUEST_ID}
MAC_ADDR=00:16:3e:${GUEST_ID}:00:01
VNC_DISPLAY=3${GUEST_ID}00
VNC_PORT=`expr ${VNC_DISPLAY} + 5900`
GUEST_IP=10.18.18.1${GUEST_ID}
### options for kvm
OPT_BOOT="-boot c"
OPT_CDROM=""
OPT_STD_VGA="-std-vga"
OPT_USBDEVICE="-usbdevice tablet"
OPT_NO_ACPI=""
OPT_CPU="-cpu qemu64"
OPT_NIC="-net nic,macaddr=${MAC_ADDR},model=rtl8139"
OPT_DRIVE=""
OPT_HDB=""
OPT_VNC="-vnc :${VNC_DISPLAY}"
OPT_HDA="-hda ${FILE_HDA}"
OPT_SMP="-smp 4"
OPT_SERIAL=""
if [ -f ${FILE_OVERRIDE} ]
then
. ${FILE_OVERRIDE}
fi
### network
start_net() {
echo "start network adapter ${TAP_NAME}"
sudo tunctl -u twer -t ${TAP_NAME}
sudo ifconfig ${TAP_NAME} 0.0.0.0 promisc up
sudo brctl addif br0 ${TAP_NAME}
}
stop_net() {
echo "stop network adapter ${TAP_NAME}"
sudo tunctl -d ${TAP_NAME}
}
check_net_status() {
NET_STATUS=`ifconfig | grep ${TAP_NAME}`
if test "${NET_STATUS}" = ""
then
echo "network adapter ${TAP_NAME} has not been started"
else
echo "network adapter ${TAP_NAME} has been started"
fi
}
## virtual machine
start_vm_sliently() {
echo "start virtual machine"
sudo modprobe kvm
sudo modprobe kvm_intel
if ! [ -d /dev/km ]
then
sleep 1
fi
sudo chmod 666 /dev/kvm
sudo chmod 666 /dev/net/tun
if ! [ -d ${DIR_RUN} ]
then
mkdir ${DIR_RUN}
fi
qemu-system-x86_64 \
${OPT_HDA} \
${OPT_HDB} \
${OPT_DRIVE} \
${OPT_CPU} \
${OPT_SMP} \
${OPT_CDROM} \
-m ${GUEST_MEMORY} \
${OPT_BOOT} \
${OPT_USBDEVICE} \
${OPT_NIC} \
${OPT_SERIAL} \
-net tap,ifname=${TAP_NAME} \
-k en-us \
${OPT_STD_VGA} \
-monitor unix:${FILE_MONITOR},server,nowait \
-pidfile ${FILE_PID} \
${OPT_NO_ACPI} \
${OPT_VNC} &
# check if the pid file created successfully
if [ ! -f ${FILE_PID} ]
then
sleep 1
fi
if [ ! -f ${FILE_PID} ]
then
return 1
fi
# check if the process started successfully
if [ ! -d /proc/`cat ${FILE_PID}` ]
then
return 1
fi
}
start_vm() {
start_vm_sliently
# if start_vm_sliently return -1
if test $? -eq -1
then
echo "startup failed. check ${FILE_OUT}"
exit 1
else
echo "startup successfully"
fi
}
send_cmd() {
QEMU_MONITOR_COMMAND=$1
echo "${QEMU_MONITOR_COMMAND}" | socat - UNIX-CONNECT:${FILE_MONITOR}
}
get_vm_pid_to() {
ACTION_TO_DO=$1
# check if pid file there
if [ ! -f ${FILE_PID} ]
then
echo "${FILE_PID} not found, can not ${ACTION_TO_DO}"
exit 1
fi
VM_PID=`cat ${FILE_PID}`
}
check_vm_status() {
get_vm_pid_to "check vm status"
if [ -d /proc/${VM_PID} ]
then
echo "vm is running at process id ${VM_PID}"
else
echo "vm is not running"
fi
}
stop_vm() {
echo "stop virtual machine"
get_vm_pid_to "stop vm"
# check if monitor file there
if [ ! -e ${FILE_MONITOR} ]
then
echo "${FILE_MONITOR} not found, can not stop vm"
exit 1
fi
# if the process is still running
# send command quit to its monitor, and wait
if [ -d /proc/${VM_PID} ]
then
send_cmd "quit"
fi
# check if the process is still running
if [ -d /proc/${VM_PID} ]
then
sleep 1
fi
if [ ! -d /proc/${VM_PID} ]
then
# yes, done
rm ${FILE_PID}
rm ${FILE_MONITOR}
echo "vm stopped successfully"
else
# no, something wrong there...
echo "failed to stop vm"
exit 1
fi
}
kill_vm() {
echo "kill virtual machine"
get_vm_pid_to "kill vm"
# if the process is still running, kill it
if [ -d /proc/${VM_PID} ]
then
kill ${VM_PID}
fi
rm ${FILE_PID}
rm ${FILE_MONITOR}
echo "vm killed"
}
### Main switch
case "$1" in
start-net)
start_net
;;
start-vm)
start_vm
;;
start)
start_net
start_vm
;;
status)
check_net_status
check_vm_status
;;
cad)
send_cmd "sendkey ctrl-alt-delete"
;;
vnc)
vncviewer localhost:${VNC_PORT} &
;;
rdesktop)
rdesktop $2 $3 ${GUEST_IP} &
;;
ssh)
ssh ${GUEST_IP}
;;
ping)
ping ${GUEST_IP}
;;
halt)
ssh twer@${GUEST_IP} sudo halt
;;
reset)
send_cmd "system_reset"
;;
stop-vm)
stop_vm
;;
stop-net)
stop_net
;;
stop)
stop_vm
stop_net
;;
kill)
kill_vm
sleep 1
stop_net
;;
*)
echo "You need to specify a action, available actions are:"
echo "[start-net] start network of the virtual machine"
echo "[start-vm] start virtual machine itself"
echo "[start] start both"
echo "[status] check the status of network and virtual machine"
echo "[cad] ctrl-alt-delete"
echo "[vnc] use vinagre to view the vnc of the guest"
echo "[rdesktop] remote desktop to the guest"
echo "[ssh] ssh to the guest"
echo "[ping] ping guest"
echo "[halt] ssh to the guest and halt the guest"
echo "[reset] reset the virtual machine"
echo "[stop-vm] power off vritual machine"
echo "[stop-net] stop network of the virtual machine"
echo "[stop] stop both"
echo "[kill] kill the viritual machine and network"
exit 1
;;
esac
exit
[edit]
kvm-manager.sh for wireless interface
#!/bin/bash
######################
## Default settings ##
######################
## Directory and files
if ! [ -d $2 ]
then
DIR_BASE=`pwd $`
else
DIR_BASE=$2
fi
FILE_HDA=${DIR_BASE}/hda
FILE_CONF=${DIR_BASE}/conf
### run directory will be auto-created with following files
DIR_RUN=${DIR_BASE}/run
FILE_MONITOR=${DIR_RUN}/monitor
FILE_PID=${DIR_RUN}/pid
FILE_OUT=${DIR_RUN}/out
GUEST_ID=0
GUEST_MEMORY=1024
GUEST_IP=192.168.1.97
HOST_IP=192.168.1.90/24
HOST_INTERFACE=wlan0
### generated variables
TAP_NAME=tap${GUEST_ID}
#MAC_ADDR=00:16:3e:${GUEST_ID}:00:01
#VNC_DISPLAY=3${GUEST_ID}00
#VNC_PORT=`expr ${VNC_DISPLAY} + 5900`
### options for kvm
#OPT_BOOT="-boot c"
OPT_BOOT=""
#OPT_CDROM="-cdrom /media/cdrom"
OPT_CDROM=""
#OPT_STD_VGA="-std-vga"
OPT_STD_VGA=""
#OPT_USBDEVICE="-usbdevice tablet"
OPT_USBDEVICE=""
#OPT_NO_ACPI="-no-acpi"
OPT_NO_ACPI=""
#OPT_CPU="-cpu qemu64"
OPT_CPU=""
#OPT_NIC="-net nic,macaddr=${MAC_ADDR},model=rtl8139"
OPT_NIC="-net nic"
#OPT_DRIVE="-drive <drive>"
OPT_DRIVE=""
#OPT_HDB="-hdb <hdb>"
OPT_HDB=""
#OPT_VNC="-vnc :${VNC_DISPLAY}"
OPT_VNC=""
#OPT_HDA="-hda <hda>"
OPT_HDA="-hda ${FILE_HDA}"
#OPT_SMP="-smp 4"
OPT_SMP=""
OPT_SERIAL=""
OPT_OTHER=""
if [ -f ${FILE_CONF} ]
then
. ${FILE_CONF}
fi
### wireless network
start_net() {
echo "start network adapter ${TAP_NAME}"
sysctl net.ipv4.ip_forward=1
tunctl -b -t ${TAP_NAME} -u `whoami`
ip link set ${TAP_NAME} up
ip addr add ${HOST_IP} dev ${TAP_NAME}
parprouted ${HOST_INTERFACE} ${TAP_NAME}
echo "network adapter ${TAP_NAME} is started with as ip ${GUEST_IP}"
}
stop_net() {
echo "stop network adapter ${TAP_NAME}"
tunctl -d ${TAP_NAME}
}
check_net_status() {
NET_STATUS=`ifconfig | grep ${TAP_NAME}`
if test "${NET_STATUS}" = ""
then
echo "network adapter ${TAP_NAME} has not been started"
else
echo "network adapter ${TAP_NAME} has been started"
fi
}
## virtual machine
start_vm_sliently() {
echo "start virtual machine"
if ! [ -d ${DIR_RUN} ]
then
mkdir ${DIR_RUN}
fi
kvm \
${OPT_HDA} \
${OPT_HDB} \
${OPT_DRIVE} \
${OPT_CPU} \
${OPT_SMP} \
${OPT_CDROM} \
-m ${GUEST_MEMORY} \
${OPT_BOOT} \
${OPT_USBDEVICE} \
${OPT_NIC} \
${OPT_SERIAL} \
-net tap,ifname=${TAP_NAME},script=no \
-k fr \
${OPT_STD_VGA} \
-monitor unix:${FILE_MONITOR},server,nowait \
-pidfile ${FILE_PID} \
${OPT_NO_ACPI} \
${OPT_VNC} \
${OPT_OTHER} &
# check if the pid file created successfully
if [ ! -f ${FILE_PID} ]
then
sleep 1
fi
if [ ! -f ${FILE_PID} ]
then
return 1
fi
# check if the process started successfully
if [ ! -d /proc/`cat ${FILE_PID}` ]
then
return 1
fi
}
start_vm() {
start_vm_sliently
# if start_vm_sliently return -1
if test $? -eq -1
then
echo "startup failed. check ${FILE_OUT}"
exit 1
else
echo "startup successfully"
fi
}
send_cmd() {
QEMU_MONITOR_COMMAND=$1
echo "${QEMU_MONITOR_COMMAND}" | socat - UNIX-CONNECT:${FILE_MONITOR}
}
get_vm_pid_to() {
ACTION_TO_DO=$1
# check if pid file there
if [ ! -f ${FILE_PID} ]
then
echo "${FILE_PID} not found, can not ${ACTION_TO_DO}"
exit 1
fi
VM_PID=`cat ${FILE_PID}`
}
check_vm_status() {
get_vm_pid_to "check vm status"
if [ -d /proc/${VM_PID} ]
then
echo "vm is running at process id ${VM_PID}"
else
echo "vm is not running"
fi
}
kill_vm() {
echo "kill virtual machine"
get_vm_pid_to "kill vm"
# if the process is still running, kill it
if [ -d /proc/${VM_PID} ]
then
kill ${VM_PID}
fi
rm ${FILE_PID}
rm ${FILE_MONITOR}
echo "vm killed"
}
detect_module() {
. /lib/lsb/init-functions
# Figure out which module we need.
if grep -q ^flags.*\\\<vmx\\\> /proc/cpuinfo
then
module=kvm_intel
elif grep -q ^flags.*\\\<svm\\\> /proc/cpuinfo
then
module=kvm_amd
else
module=
fi
}
start_kvm() {
detect_module
if [ -z "$module" ]
then
log_failure_msg "Your system does not have the CPU extensions required to use KVM. Not doing anything."
exit 0
fi
if modprobe "$module"
then
log_success_msg "Loading kvm module $module"
else
log_failure_msg "Module $module failed to load"
exit 1
fi
}
stop_kvm() {
detect_module
if [ -z "$module" ]
then
exit 0
fi
if lsmod | grep -q "$module"
then
if rmmod "$module"
then
log_success_msg "Succesfully unloaded kvm module $module"
rmmod kvm
else
log_failure_msg "Failed to remove $module"
exit 1
fi
else
log_failure_msg "Module $module not loaded"
fi
}
### Main switch
case "$1" in
start-kvm)
start_kvm
;;
start-net)
start_net
;;
start-vm)
start_vm
;;
start)
start_net
start_vm
;;
status)
check_net_status
check_vm_status
;;
cad)
send_cmd "sendkey ctrl-alt-delete"
;;
vnc)
vncviewer localhost:${VNC_PORT} &
;;
rdesktop)
rdesktop $2 $3 ${GUEST_IP} &
;;
ssh)
ssh ${GUEST_IP}
;;
ping)
ping ${GUEST_IP}
;;
halt)
ssh root@${GUEST_IP} halt
;;
reset)
send_cmd "system_reset"
;;
stop-vm)
stop_vm
;;
stop-net)
stop_net
;;
stop)
stop_vm
stop_net
;;
stop-kvm)
stop_kvm
;;
kill)
kill_vm
sleep 1
stop_net
;;
*)
echo "KVM manager version 0.1, Samuel Bally"
echo "usage: kvm-manager [options] [path]"
echo ""
echo "Standard options:"
echo "You need to specify a action, available actions are:"
echo "[start-kvm] start kvm module"
echo "[start-net] start network of the virtual machine"
echo "[start-vm] start virtual machine itself"
echo "[start] start both"
echo "[status] check the status of network and virtual machine"
echo "[cad] ctrl-alt-delete"
echo "[vnc] use vinagre to view the vnc of the guest"
echo "[rdesktop] remote desktop to the guest"
echo "[ssh] ssh to the guest"
echo "[ping] ping guest"
echo "[halt] ssh to the guest and halt the guest"
echo "[reset] reset the virtual machine"
echo "[stop-vm] power off vritual machine"
echo "[stop-net] stop network of the virtual machine"
echo "[stop-kvm] stop kvm module"
echo "[stop] stop both"
echo "[kill] kill the viritual machine and network"
echo ""
echo "Config file:"
echo "create a conf file in your vm directory for change default settings"
echo "conf varialbles:"
echo "DIR_RUN"
echo "FILE_MONITOR"
echo "FILE_PID"
echo "FILE_OUT"
echo "GUEST_ID"
echo "GUEST_MEMORY"
echo "GUEST_IP"
echo "HOST_IP"
echo "HOST_INTERFACE"
echo "OPT_BOOT"
echo "OPT_CDROM"
echo "OPT_STD_VGA"
echo "OPT_USBDEVICE"
echo "OPT_NO_ACPI"
echo "OPT_CPU"
echo "OPT_NIC"
echo "OPT_DRIVE"
echo "OPT_HDB"
echo "OPT_VNC"
echo "OPT_HDA"
echo "OPT_SMP"
echo "OPT_SERIAL"
echo "OPT_OTHER"
exit 1
;;
esac
exit

