# HG changeset patch # User Heiko Schlittermann # Date 1231961170 -3600 # Node ID ed2b863f938f50640da73175df20f3553ffce1c3 # Parent b4e073b1250e08b81b3b65c8c067bc4b402e435b finally renamed to kvmtool. diff -r b4e073b1250e -r ed2b863f938f kvmc --- a/kvmc Wed Jan 14 20:24:32 2009 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -#! /bin/bash -# $Id$ -# $URL$ -# status: in development -# 2008 Heiko Schlittermann - -# Should be written in Perl! - -# Structure of virtual machine directories -# $BASE (see below, hard coded into this script) -# | -# +-- -# | +--conf -# | | +--options -# | | +--id -# | +--var -# | | +--pid -# | | +--running_options -# | +-- -# | +-- .... -# | +-- -# | -# +-- -# | .... -# +-- - - -action="${1?}"; shift # mandatory -vm="$1" ; shift # optional - -# no user service able parts below - -PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin -unset ${!LC_*} LANG CDPATH - -ME=$(basename $0) -BASE=/kvm -KVM=$(command -v kvm) -NC=$(command -v nc) -FUSER=$(command -v fuser) -VNCVIEWER=$(command -v vncviewer) -TIMEOUT=30 - - -for f in "/etc/$ME.conf" ~/.$ME; do test -r "$f" && source "$f"; done - - -die() { echo $ME: "$@" >&2; exit 1; } -warn() { echo $ME: "$@" >&2; } -silently() { "$@" &>/dev/null; } - -debug() { echo "DEBUG: $@" >&2; } - -unique_ids() { - local dups=$(cat $BASE/*/conf/id 2>/dev/null | sort -n | uniq -c \ - | egrep -v '^[[:space:]]+1 ' | tr -s ' ' | cut -f2 -d:) - test "$dups" || return 0 - ERR="$dups" && return 1 -} - -convert_dirs() { - for dir in $BASE/*; do - test -d $dir/kvm || test -d $dir/conf || continue - local old=$dir/kvm - local new=$dir/conf - test -d $old && mv $old $new - test -f $new/cmdline && mv $new/cmdline $new/options - done -} - -monitor() { - local port=$1; shift - local command="$1"; shift - - # check, if the monitor is available, kill if somebody - # else is using it - local client=$(netstat -tn | egrep ":$port[[:space:]]+EST" | tr -s ' ' | cut -f4 -d' ') - test "${client%:*}" = 127.0.0.1 && fuser -k ${client#*:}/tcp - - local pid0 pid1 - ( - local a=$tmp/a.fifo; mkfifo $a - trap "rm -v $a" EXIT - exec 10<>$a - $NC localhost $port <&10 | { - read || exit # banner - while read -d' '; do test "$REPLY" = "(qemu)" && break; done - echo "$command" >&10 - while read -d' '; do test "$REPLY" = "(qemu)" && break; done - } - ) & pid0=$! - ( sleep $TIMEOUT; kill $pid0 ) & pid1=$! - wait $pid0 - silently kill $pid0 $pid1 -} - -### MAIN - -# sanity -test -x "$NC" || die "need nc (netcat)" -test -x "$KVM" || die "need kvm/qemu/kqemu" -test -x "$FUSER" || die "need fuser" -test -d "$BASE" || die "base dir $BASE does not exist" -test -d "$BASE/$vm" || die "vm $vm does not exist" - -unique_ids || die "duplicate ids (id: $ERR)" -convert_dirs - -trap 'test "$TMP" && rm -fr $TMP' EXIT - -for vm in ${vm:-$(echo $BASE/*)}; do - vm=$(basename $vm) - conf=$BASE/$vm/conf - var=$BASE/$vm/var - - tmp=$(mktemp -d) - TMP="$TMP $tmp" - - test -d $conf || continue - test -f $conf/id || { warn "need id file (vm: $vm)" && continue; } - test -f $conf/options || { warn "need options file (vm: $vm)" && continue; } - test -d $var || mkdir $var || exit 2 - - id=$(cat $conf/id) - port=$((4000 + id)) - pid=$(cat $var/pid 2>/dev/null) - - case "$action" in - - start) - echo "starting $vm" - options="$(grep -v '^#' $conf/options) \ - -pidfile var/pid \ - -name "$vm" \ - -vnc :$id \ - -monitor tcp:localhost:$port,server,nowait \ - $@" - options=$(echo "" $options) # shorten it - echo "$options" > $var/running_options - test -f $var/frozen && options="$options $(cat $var/frozen)" - - if silently fuser $var/pid; then - echo "running, pid: $pid, display :$id, monitor tcp:127.0.0.1:$port" - else - ( cd $BASE/$vm && $KVM $options -daemonize ) - pid=$(cat $var/pid 2>/dev/null) - test "$pid" || { warn "serious problem ($vm), no pid" && continue; } - echo "started, pid: $pid, display :$id, monitor tcp:127.0.0.1:$port" - fi - - test "$DISPLAY" && test "$VNCVIEWER" && test -t \ - && ( silently exec $VNCVIEWER :$id $var/frozen - } & - ;; - qemu) - echo "DO *NOT* USE \"quit\", use ^C for exiting!" - $NC localhost $port - ;; - - list) - echo "$vm:" $(silently fuser $var/pid \ - && echo "running (pid: $pid)" \ - || echo "not running") - ;; - - *) die "unknown command \"$action\"" - ;; - - esac - -done - -wait - -# vim:ts=4 sw=4 et: diff -r b4e073b1250e -r ed2b863f938f kvmtool --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kvmtool Wed Jan 14 20:26:10 2009 +0100 @@ -0,0 +1,201 @@ +#! /bin/bash +# $Id$ +# $URL$ +# status: in development +# 2008 Heiko Schlittermann + +# Should be written in Perl! + +# Structure of virtual machine directories +# $BASE (see below, hard coded into this script) +# | +# +-- +# | +--conf +# | | +--options +# | | +--id +# | +--var +# | | +--pid +# | | +--running_options +# | +-- +# | +-- .... +# | +-- +# | +# +-- +# | .... +# +-- + + +action="${1?}"; shift # mandatory +vm="$1" ; shift # optional + +# no user service able parts below + +PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +unset ${!LC_*} LANG CDPATH + +ME=$(basename $0) +BASE=/kvm +KVM=$(command -v kvm) +NC=$(command -v nc) +FUSER=$(command -v fuser) +VNCVIEWER=$(command -v vncviewer) +TIMEOUT=30 + + +for f in "/etc/$ME.conf" ~/.$ME; do test -r "$f" && source "$f"; done + + +die() { echo $ME: "$@" >&2; exit 1; } +warn() { echo $ME: "$@" >&2; } +silently() { "$@" &>/dev/null; } + +debug() { echo "DEBUG: $@" >&2; } + +unique_ids() { + local dups=$(cat $BASE/*/conf/id 2>/dev/null | sort -n | uniq -c \ + | egrep -v '^[[:space:]]+1 ' | tr -s ' ' | cut -f2 -d:) + test "$dups" || return 0 + ERR="$dups" && return 1 +} + +convert_dirs() { + for dir in $BASE/*; do + test -d $dir/kvm || test -d $dir/conf || continue + local old=$dir/kvm + local new=$dir/conf + test -d $old && mv $old $new + test -f $new/cmdline && mv $new/cmdline $new/options + done +} + +monitor() { + local port=$1; shift + local command="$1"; shift + + # check, if the monitor is available, kill if somebody + # else is using it + local client=$(netstat -tn | egrep ":$port[[:space:]]+EST" | tr -s ' ' | cut -f4 -d' ') + test "${client%:*}" = 127.0.0.1 && fuser -k ${client#*:}/tcp + + local pid0 pid1 + ( + local a=$tmp/a.fifo; mkfifo $a + trap "rm -v $a" EXIT + exec 10<>$a + $NC localhost $port <&10 | { + read || exit # banner + while read -d' '; do test "$REPLY" = "(qemu)" && break; done + echo "$command" >&10 + while read -d' '; do test "$REPLY" = "(qemu)" && break; done + } + ) & pid0=$! + ( sleep $TIMEOUT; kill $pid0 ) & pid1=$! + wait $pid0 + silently kill $pid0 $pid1 +} + +### MAIN + +# sanity +test -x "$NC" || die "need nc (netcat)" +test -x "$KVM" || die "need kvm/qemu/kqemu" +test -x "$FUSER" || die "need fuser" +test -d "$BASE" || die "base dir $BASE does not exist" +test -d "$BASE/$vm" || die "vm $vm does not exist" + +unique_ids || die "duplicate ids (id: $ERR)" +convert_dirs + +trap 'test "$TMP" && rm -fr $TMP' EXIT + +for vm in ${vm:-$(echo $BASE/*)}; do + vm=$(basename $vm) + conf=$BASE/$vm/conf + var=$BASE/$vm/var + + tmp=$(mktemp -d) + TMP="$TMP $tmp" + + test -d $conf || continue + test -f $conf/id || { warn "need id file (vm: $vm)" && continue; } + test -f $conf/options || { warn "need options file (vm: $vm)" && continue; } + test -d $var || mkdir $var || exit 2 + + id=$(cat $conf/id) + port=$((4000 + id)) + pid=$(cat $var/pid 2>/dev/null) + + case "$action" in + + start) + echo "starting $vm" + options="$(grep -v '^#' $conf/options) \ + -pidfile var/pid \ + -name "$vm" \ + -vnc :$id \ + -monitor tcp:localhost:$port,server,nowait \ + $@" + options=$(echo "" $options) # shorten it + echo "$options" > $var/running_options + test -f $var/frozen && options="$options $(cat $var/frozen)" + + if silently fuser $var/pid; then + echo "running, pid: $pid, display :$id, monitor tcp:127.0.0.1:$port" + else + ( cd $BASE/$vm && $KVM $options -daemonize ) + pid=$(cat $var/pid 2>/dev/null) + test "$pid" || { warn "serious problem ($vm), no pid" && continue; } + echo "started, pid: $pid, display :$id, monitor tcp:127.0.0.1:$port" + fi + + test "$DISPLAY" && test "$VNCVIEWER" && test -t \ + && ( silently exec $VNCVIEWER :$id $var/frozen + } & + ;; + qemu) + echo "DO *NOT* USE \"quit\", use ^C for exiting!" + $NC localhost $port + ;; + + list) + echo "$vm:" $(silently fuser $var/pid \ + && echo "running (pid: $pid)" \ + || echo "not running") + ;; + + *) die "unknown command \"$action\"" + ;; + + esac + +done + +wait + +# vim:ts=4 sw=4 et: