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