1 #! /bin/bash -e |
|
2 |
|
3 # global stuff |
|
4 |
|
5 |
|
6 ME=${0##*/} |
|
7 NODE=$(uname -n) |
|
8 KVMTAB=/etc/kvmtab |
|
9 KVM_OPTS_BUILTIN='-drive file=/dev/drbd$ID,cache=none,aio=native,if=virtio,index=0 |
|
10 -boot order=c |
|
11 -m 512 |
|
12 -net nic,macaddr=$MAC,model=virtio |
|
13 -net tap,ifname=tap$ID,script=no |
|
14 -k de' |
|
15 |
|
16 function die() { echo $0: "$@" >&2; exit 1; } |
|
17 |
|
18 function machine() { |
|
19 |
|
20 local cmd="$1"; shift |
|
21 local NAME="$1"; shift |
|
22 |
|
23 # we need the username |
|
24 id -u "kvm-$NAME" >/dev/null |
|
25 |
|
26 local HOST ID MAC CONFIG MONITOR KVM_OPTS |
|
27 |
|
28 # could use grep... |
|
29 while read name HOST ID MAC CONFIG; do |
|
30 [ "$name" = "$NAME" ] && break |
|
31 done <$KVMTAB |
|
32 |
|
33 test -n "$ID" || die "no ID found in $KVMTAB" |
|
34 test -n "$MAC" || die "no MAC found in $KVMTAB" |
|
35 test "$NODE" = "$HOST" || die "$NAME should run on $HOST, not on $NODE" |
|
36 |
|
37 CONFIG=${CONFIG:-builtin} |
|
38 MONITOR=$((4000 + ID)) |
|
39 |
|
40 case "$cmd" in |
|
41 start) |
|
42 echo "starting (k)vm-$NAME (id $ID)" |
|
43 echo "switch drbd$ID device into primary state" |
|
44 if test "$CONFIG" != builtin; then |
|
45 echo "using config from $CONFIG" |
|
46 KVM_OPTS= |
|
47 source "$CONFIG" |
|
48 echo "using config $CONFIG" |
|
49 test "$KVM_OPTS" || die "$CONFIG should set KVM_OPTS" |
|
50 else |
|
51 echo "using builtin config" |
|
52 KVM_OPTS=$KVM_OPTS_BUILTIN |
|
53 fi |
|
54 eval KVM_OPTS=\"-name $NAME -vnc :$ID $KVM_OPTS -monitor tcp:127.0.0.1:$MONITOR,server,nowait\" |
|
55 drbdadm primary drbd$ID |
|
56 tunctl -u kvm-$NAME -t tap$ID |
|
57 brctl delif br0 tap$ID &> /dev/null || true |
|
58 brctl addif br0 tap$ID &> /dev/null || true |
|
59 ip link set tap$ID up |
|
60 chown kvm-$NAME /dev/drbd$ID |
|
61 chgrp kvm /dev/drbd$ID |
|
62 chmod u=rw,go= /dev/drbd$ID |
|
63 su -s /bin/sh - kvm-$NAME -c "kvm $KVM_OPTS -daemonize $*" |
|
64 ;; |
|
65 stop) |
|
66 echo "stopping (k)vm-$NAME" |
|
67 echo system_powerdown | nc 0 $MONITOR |
|
68 ip link set tap$ID down |
|
69 brctl delif br0 tap$ID |
|
70 # 'device is held open by someone' :( |
|
71 sleep 1 |
|
72 echo "switch drbd$ID into secondary role" |
|
73 drbdadm secondary drbd$ID |
|
74 ;; |
|
75 restart) |
|
76 $0 stop $NAME |
|
77 sleep 3 |
|
78 $0 start $NAME |
|
79 ;; |
|
80 *) die "bad usage" |
|
81 ;; |
|
82 esac |
|
83 } |
|
84 |
|
85 ## MAIN |
|
86 |
|
87 # some option handling - currently just options for help and manpage |
|
88 tmp=$(getopt --name $0 -o hmv -l help,man,version -- "$@") || exec pod2usage $0 |
|
89 eval set -- $tmp |
|
90 while true; do |
|
91 opt="$1"; shift; |
|
92 case "$opt" in |
|
93 -h|--help) exec pod2usage -verbose 1 -exit 0 $0 |
|
94 ;; |
|
95 -m|--man) if perldoc -V >/dev/null; then |
|
96 pod2usage -verbose 2 -exit 0 $0 |
|
97 else |
|
98 pod2man --section 8 $0 | man -l - |
|
99 exit |
|
100 fi |
|
101 ;; |
|
102 -v|--version) |
|
103 echo "$ME: [% VERSION %], built: [% BUILDINFO %]" |
|
104 exit 0 |
|
105 ;; |
|
106 --) break |
|
107 ;; |
|
108 esac |
|
109 done |
|
110 |
|
111 |
|
112 # "kvmtool start" or "kvmtool start all" will try to start |
|
113 # all the vm's we find in /etc/kvmtab; if called "kvmtool start <vm>" it |
|
114 # will try to start the the vm called 'vm' |
|
115 if [[ "$ME" == *$ME ]]; then |
|
116 cmd="$1"; shift |
|
117 |
|
118 if test $# = 0 || ( test $# = 1 && test $1 = 'all' ); then |
|
119 vms=$(egrep "^[[:alnum:]_-]+[[:space:]]+$NODE\b" $KVMTAB | tr -s '\t ' ' ' | cut -f1 -d' ') |
|
120 else |
|
121 vms="$@" |
|
122 fi |
|
123 fi |
|
124 |
|
125 |
|
126 # - below we only go for a single machine |
|
127 |
|
128 for vm in $vms; do |
|
129 machine $cmd $vm |
|
130 done |
|
131 |
|
132 |
|
133 exit |
|
134 |
|
135 =pod |
|
136 |
|
137 =head1 NAME |
|
138 |
|
139 kvmtool - helper to start virtual machines |
|
140 |
|
141 =head1 SYNOPSIS |
|
142 |
|
143 kvmtool {start|stop|restart} [machine...] |
|
144 kvmtool-MACHINE {start|stop|restart} |
|
145 |
|
146 =head1 DESCRIPTION |
|
147 |
|
148 This small tool helps to start the virtual machines known in F</etc/kvmtab>. |
|
149 If just called as C<kvmtool start> or C<kvmtool start all> it starts all |
|
150 machines that should run on the current host. If called as C<kvmtool start |
|
151 xxx>, it tries to start machine C<xxx>, but this may fail, if the F<kvmtab> |
|
152 lists this machine for another host. |
|
153 |
|
154 =head1 OPTIONS |
|
155 |
|
156 Currently there are no options at all. The only exceptions are B<-h>|B<--help> |
|
157 and B<-m>|B<--man>. |
|
158 |
|
159 =head1 FILES |
|
160 |
|
161 /etc/kvmtab - list of machines, hosts to run on, MAC address, optional config file |
|
162 |
|
163 =cut |
|
164 |
|
165 # vim:sts=4 sw=4 aw ai sm: |
|