diff --git a/nlvmi b/nlvmi index d4069e0..beb6d80 100755 --- a/nlvmi +++ b/nlvmi @@ -20,7 +20,6 @@ if [ $U != "root" ]; then /usr/bin/wrap-nlvmi $A $B $C && exit fi - if [ ! -d $RUNDIRECTORY ]; then if [ $LOGLEVEL -gt "1" ]; then echo "creating $RUNDIRECTORY"; fi; mkdir -p $RUNDIRECTORY; chown root:nlvmi -R $RUNDIRECTORY; chmod g+w $RUNDIRECTORY; fi #checking database @@ -106,14 +105,38 @@ function createdb { function createkey { openssl req -nodes -x509 -sha256 -newkey rsa:4096 -keyout "/etc/nlvmi/nlvmi_priv.key" -out "/etc/nlvmi/nlvmi_sign.crt" -days 9999 -subj "/CN=nlvmi_signing" } + +#check if VM is running +function checkvm { + if [ -z $1 ]; then echo "checkvm needs one argument!"; exit 1; fi + sqlite3 $SQLITEFILE "SELECT connectstring from vms LEFT JOIN servers ON vms.server = servers.hostname WHERE vmname='$1'" | while read line; do + CONN=$line + if [ ! -z $CONN ]; then + su nlvmi -c "ssh $CONN \"RPID=\\\$(<\\\"$RUNDIRECTORY/$1.pid\\\"); ps -ef | grep -v grep | grep \\\$RPID | grep qemu\"" &>/dev/null && echo "VM is running" || echo "VM is not running" + else + ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null && echo "VM is running" || echo "VM is not running" + + fi + done +} + + + #autostart VMs function vmautostart { - if [ $DATABASETYPE == "sqlite" ]; then - sqlite3 $SQLITEFILE "SELECT id FROM vms WHERE autostart=1" | while read line; do - IFS='|' read -r -a array <<< "$line" - vmstart ${array[0]} + if [ -z $MASTERSERVER ]; then + for startfile in /home/nlvmi/start*.tmp; do + vmname=`echo $startfile | cut -d "." -f1 | rev | cut -d "/" -f 1 | rev | sed 's/start//g'` + checkvm ${vmname} | grep "is not running" >/dev/null && sh $startfile; + done + else + for startsign in /home/nlvmli/start*.tmp.sha512; do + startfile=`echo $startsign | cut -d "." -f 1-2` + vmname=`echo $startfile | cut -d "." -f1 | rev | cut -d "/" -f1 | rev | sed 's/start//g'` + checkvm ${vmname} | grep "is not running" >/dev/null && if [ -e $startfile ]; then + openssl dgst -sha512 -verify <(openssl x509 -in "/etc/nlvmi/nlvmi_sign.crt" -pubkey -noout) -signature $startsign $startfile >/dev/null && /bin/bash $2 || echo "signature failed!!" + fi done - fi } @@ -124,7 +147,7 @@ function vmstart { sqlite3 $SQLITEFILE "SELECT * FROM vms LEFT JOIN servers on vms.server = servers.hostname WHERE vms.id=$1" | while read line; do IFS='|' read -r -a array <<< "$line" #prepare tmpfile - TMPF=/home/nlvmi/${array[1]}.tmp + TMPF=/home/nlvmi/start${array[1]}.tmp rm $TMPF &>/dev/null #add user if necessary echo "if ! \`id -u ${array[2]} &>/dev/null\`; then useradd ${array[2]} -d /run/nlvmi -g nlvmi -M -s /bin/false -G kvm; fi" >>$TMPF @@ -145,13 +168,13 @@ function vmstart { if [ ! -z ${array[19]} ]; then CDROM="-cdrom ${array[19]}"; fi if [ ! -z ${array[20]} ]; then TAPDEV1="-netdev tap,ifname=${array[20]},script=no,id=net0"; echo "tunctl -t ${array[20]} -u ${array[2]} && ifconfig ${array[20]} up" >>$TMPF; fi if [ ! -z ${array[21]} ]; then MACADDR1="-net nic,macaddr=${array[21]},model=virtio,netdev=net0"; fi - if [ ! -z ${array[22]} ]; then BRDEV1="${array[22]}"; echo "brctl addif ${array[22]} ${array[20]}" >>$TMPF; fi + if [ ! -z ${array[22]} ]; then BRDEV1="${array[22]}"; echo "/sbin/brctl addif ${array[22]} ${array[20]}" >>$TMPF; fi if [ ! -z ${array[23]} ]; then TAPDEV2="-netdev tap,ifname=${array[23]},script=no,id=net1"; echo "tunctl -t ${array[23]} -u ${array[2]} && ifconfig ${array[23]} up" >>$TMPF; fi if [ ! -z ${array[24]} ]; then MACADDR2="-net nic,macaddr=${array[24]},model=virtio,netdev=net1"; fi - if [ ! -z ${array[25]} ]; then BRDEV2="${array[25]}"; echo "brctl addif ${array[25]} ${array[23]}" >>$TMPF; fi + if [ ! -z ${array[25]} ]; then BRDEV2="${array[25]}"; echo "/sbin/brctl addif ${array[25]} ${array[23]}" >>$TMPF; fi if [ ! -z ${array[26]} ]; then TAPDEV3="-netdev tap,ifname=${array[26]},script=no,id=net2"; echo "tunctl -t ${array[26]} -u ${array[2]} && ifconfig ${array[26]} up" >>$TMPF; fi if [ ! -z ${array[27]} ]; then MACADDR3="-net nic,macaddr=${array[27]},model=virtio,netdev=net2"; fi - if [ ! -z ${array[28]} ]; then BRDEV3="${array[28]}"; echo "brctl addif ${array[28]} ${array[26]}" >>$TMPF; fi + if [ ! -z ${array[28]} ]; then BRDEV3="${array[28]}"; echo "/sbin/brctl addif ${array[28]} ${array[26]}" >>$TMPF; fi if [ ! -z ${array[30]} ]; then WEBSOCK=",websocket=${array[30]}"; else WEBSOCK=""; fi if [ ! -z ${array[31]} ]; then VNCPASS=",password"; fi if [ ! -z ${array[29]} ]; then VNCPORT="-vnc :${array[29]}$WEBSOCK$VNCPASS"; fi @@ -166,11 +189,15 @@ function vmstart { openssl dgst -sha512 -sign "/etc/nlvmi/nlvmi_priv.key" -out /home/nlvmi/${array[1]}.tmp.sha512 $TMPF su nlvmi -c "scp $TMPF* ${array[34]}:/home/nlvmi/" su nlvmi -c "ssh ${array[34]} \"/usr/bin/nlvmi remote $TMPF run\"" - su nlvmi -c "ssh ${array[34]} \"rm $TMPF $TMPF.sha512\"" + if [ ${array[12]} == "0" ]; then + su nlvmi -c "ssh ${array[34]} \"rm $TMPF $TMPF.sha512\"" + fi rm $TMPF $TMPF.sha512 else /bin/bash $TMPF - rm $TMPF + if [ ${array[12]} == "0" ]; then + rm $TMPF + fi fi done export VMFOUND="yes" @@ -191,7 +218,7 @@ function vmstop { STOPPED="no" COUNTER=0 while [ $STOPPED = "no" ]; do - if [ $COUNTER == 2 ]; then + if [ $COUNTER == 10 ]; then if [ -z ${array[2]} ]; then kill `cat $RUNDIRECTORY/${array[1]}.pid` echo "${array[1]} forcefully killed!"; @@ -201,7 +228,6 @@ function vmstop { echo "kill \$(<\"$RUNDIRECTORY/${array[1]}.pid\")" >$TMPF openssl dgst -sha512 -sign "/etc/nlvmi/nlvmi_priv.key" -out $TMPF.sha512 $TMPF su nlvmi -c "scp $TMPF* ${array[2]}:/home/nlvmi/" -# su nlvmi -c "ssh ${array[2]} \"echo \\\"kill \\\$(<\\\"$RUNDIRECTORY/${array[1]}.pid\\\")\\\" >/home/nlvmi/${array[1]}.tmp\"" su nlvmi -c "ssh ${array[2]} \"/usr/bin/nlvmi remote /home/nlvmi/${array[1]}.tmp stop\"" su nlvmi -c "ssh ${array[2]} \"rm $TMPF $TMPF.sha512\"" rm $TMPF $TMPF.sha512 @@ -216,25 +242,31 @@ function vmstop { done } -#stopall -function stopall { - sqlite3 $SQLITEFILE "SELECT id,vmname FROM vms" | while read line; do - IFS='|' read -r -a array <<< "$line" - ps -ef | grep `cat $RUNDIRECTORY/${array[1]}.pid` | grep -v grep >/dev/null && (vmstop ${array[1]} &) + +#stop local vm +function vmlocalstop { + if [ ! -e $RUNDIRECTORY/$1.pid ]; then echo "pidfile $RUNDIRECTORY/$1.pid does not exist"; exit 1; fi + echo "system_powerdown" | socat - unix-connect:$RUNDIRECTORY/$1.mon >/dev/null + sleep 5s + STOPPED="no" + COUNTER=0 + while [ $STOPPED = "no" ]; do + if [ $COUNTER == 10 ]; then + kill `cat $RUNDIRECTORY/$1.pid` + echo "$1 forcefully killed!"; + STOPPED="yes" + fi + ((COUNTER++)) + ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null || STOPPED="yes" + sleep 1s done } -#check if VM is running -function checkvm { - if [ -z $1 ]; then echo "checkvm needs one argument!"; exit 1; fi - sqlite3 $SQLITEFILE "SELECT connectstring from vms LEFT JOIN servers ON vms.server = servers.hostname WHERE vmname='$1'" | while read line; do - CONN=$line - if [ ! -z $CONN ]; then - su nlvmi -c "ssh $CONN \"RPID=\\\$(<\\\"$RUNDIRECTORY/$1.pid\\\"); ps -ef | grep -v grep | grep \\\$RPID | grep qemu\"" &>/dev/null && echo "VM is running" || echo "VM is not running" - else - ps -ef | grep `cat $RUNDIRECTORY/$1.pid` | grep -v grep >/dev/null && echo "VM is running" || echo "VM is not running" - - fi +#stopall local vms +function stopall { + for vms in $RUNDIRECTORY/*.pid; do + vmname=`echo ${vms} | rev | cut -d "/" -f1 | rev | sed 's/.pid//g'` + vmlocalstop ${vmname} done } @@ -255,7 +287,6 @@ function listdir { #mainloop if [ $# -gt 0 ]; then -#echo $1 $2 $3 if [ $1 == "createdb" ]; then createdb elif [ $1 == "autostart" ]; then @@ -295,7 +326,6 @@ if [ $# -gt 0 ]; then if `echo $SSH_CLIENT | grep "$MASTERSERVER " &>/dev/null`; then if [ -e $2 ]; then openssl dgst -sha512 -verify <(openssl x509 -in "/etc/nlvmi/nlvmi_sign.crt" -pubkey -noout) -signature $2.sha512 $2 >/dev/null && /bin/bash $2 || echo "signature failed!!" -# /bin/bash $2; fi else echo "not allowed"; diff --git a/web/index.php b/web/index.php index 667a367..937b7b0 100644 --- a/web/index.php +++ b/web/index.php @@ -287,6 +287,13 @@ if (isset($_SESSION['username'])){ exit; } } + if ($rkey == "autostart"){ + if ($rvalue == "on"){ + $rvalue = "1"; + } else { + $rvalue = "0"; + } + } $rvalue = clean($_REQUEST[$rkey]); if ($rvalue == "x86_64"){ $rvalue = "qemu-system-x86_64"; @@ -308,6 +315,7 @@ if (isset($_SESSION['username'])){ exit; } elseif ($_REQUEST['mode']=="editvm"){ $sql="UPDATE vms SET "; + $autostartfound = "0"; foreach(array_keys($_REQUEST) as $rkey){ if (($rkey!="mode")&&($rkey!="editid")&&($rkey!="rand")){ $rvalue = clean($_REQUEST[$rkey]); @@ -318,6 +326,14 @@ if (isset($_SESSION['username'])){ exit; } } + if ($rkey == "autostart"){ + $autostartfound = "1"; + if ($rvalue == "on"){ + $rvalue = "1"; + } else { + $rvalue = "0"; + } + } if ($rvalue == "x86_64"){ $rvalue = "qemu-system-x86_64"; } elseif ((preg_match('/no drive/', $rvalue))||($rvalue == "no cdrom")){ @@ -326,7 +342,11 @@ if (isset($_SESSION['username'])){ $sql .= " $rkey='$rvalue',"; } } - $sql = rtrim($sql, ','); + if ($autostartfound == "0"){ + $sql .= " autostart='0'"; + } else { + $sql = rtrim($sql, ','); + } $eid=clean($_REQUEST['editid']); $sql .= " WHERE id='$eid'"; $res = $db_handle->exec($sql);