aboutsummaryrefslogtreecommitdiff
path: root/kvm-manager
blob: 6250fe1a9ee8e211e91e74cb9a8f1bbeb05f83d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/bin/sh

set -e

# Author: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
# Date: 2011-01-26
# License: GPL v3+

## expect to pull these values from the environment:
# VMNAME=snapper
# OWNER=jrollins
# TAP=tap0
# RAM=512
# MAC=52:54:00:12:34:56
# HDA=/path/to/disk0 # optional
# HDB=/path/to/disk1 # optional
# HDC=/path/to/disk2 # optional
# HDD=/path/to/disk3 # optional

if [ -z "$VMNAME" ] ; then
    exit 1
fi

###################
OWNERGROUP=$(groups "$OWNER" | cut -f1 -d\  )
OWNERHOME=$(getent passwd "$OWNER" | cut -f6 -d: )

up() {
# bring up the network tap:
    modprobe -v tun
    tunctl -u "$OWNER" -t "$TAP"
    ip link set "$TAP" up
    brctl addif br0 "$TAP"
    
    chpst -u "$OWNER:$OWNERGROUP" mkdir -p "$OWNERHOME/vms/$VMNAME"

    CDISO="$OWNERHOME/vms/$VMNAME/cd.iso"
    NETBOOT="$OWNERHOME/vms/$VMNAME/netboot"
    KVMARGS=
    
    BOOTCHOICE=c

    if [ -e "$NETBOOT" ] ; then
	BOOTCHOICE=n
    elif [ -e "$CDISO" ] && [ -e $(readlink -f "$CDISO") ] ; then
	KVMARGS="-cdrom $CDISO"
        BOOTCHOICE=d
    fi

    # set up the disks, if needed:
    [ -z "$HDA" ] || KVMARGS="$KVMARGS -drive file=$HDA,if=virtio,id=hda,boot=on,format=raw"
    [ -z "$HDB" ] || KVMARGS="$KVMARGS -drive file=$HDB,if=virtio,id=hdb,format=raw"
    [ -z "$HDC" ] || KVMARGS="$KVMARGS -drive file=$HDC,if=virtio,id=hdc,format=raw"
    [ -z "$HDD" ] || KVMARGS="$KVMARGS -drive file=$HDD,if=virtio,id=hdd,format=raw"

    LOGNAME="$OWNERHOME/vms/$VMNAME/console"
    ln -sfT "$LOGNAME" ./servicelog
    if [ -e "$LOGNAME" ] ; then
	chpst -u "$OWNER" mv "$LOGNAME" "$LOGNAME".$(date +%F_%T%z|tr : .)
    fi
    
    MONITORNAME="$OWNERHOME/vms/$VMNAME/monitor.socket"
    CONSOLENAME="$OWNERHOME/vms/$VMNAME/console.socket"

    kvmsend() {
        socat STDIO "UNIX:$MONITORNAME" <<EOF
$1
EOF
    }

    chpst -u "$OWNER:$OWNERGROUP" \
        /usr/bin/screen -D -m -L -c /etc/screenrc.kvm-manager -S "$VMNAME" -t "$VMNAME" socat STDIO,raw,echo=0 "UNIX-LISTEN:${CONSOLENAME}" &

    # HACKERY: give a pause for the socket to get set up: 
    sleep 2

    chpst -u "$OWNER:$OWNERGROUP:kvm" \
        /usr/bin/kvm $KVMARGS \
        -M "${MACHINE:-pc}" \
        -enable-kvm \
        -nodefaults \
        -nographic \
        -name "$VMNAME" \
        -m "$RAM" \
        -boot "$BOOTCHOICE" \
        -chardev "socket,id=monitor,path=$MONITORNAME,server,nowait" -mon chardev=monitor,mode=readline \
        -rtc base=utc \
        -usb \
        -device virtio-balloon-pci,id=balloon0,bus=pci.0 \
        -chardev "socket,id=serial0,path=$CONSOLENAME,nowait" -device isa-serial,chardev=serial0 \
        -smp "${SMP:-1},maxcpus=${MAXCPUS:-8}" \
        -device "virtio-net-pci,vlan=0,id=net0,mac=$MAC,bus=pci.0" \
        -net "tap,ifname=$TAP,script=no,downscript=no,vlan=0,name=hostnet0" &


    set +e
    # handle regular signals
    trap 'kvmsend system_reset; wait %2' HUP
    trap 'kvmsend system_powerdown; wait %2' TERM
    trap 'kvmsend cont; wait %2' CONT
 # use SIGINT instead of SIGSTOP for freezing the guest because
 # trapping SIGSTOP is undefined:
 # http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_28
    trap 'kvmsend stop; wait %2' INT
    trap 'kill %1 ; kill %2' EXIT

    wait %2
}


down() {
    brctl delif br0 "$TAP"
    ip link set "$TAP" down
    tunctl -d "$TAP"
# no need to lock up the block device as well, since the owner might
# prefer to manipulate the disk directly.
}

log() {
    LOGDIR="$OWNERHOME/vms/$VMNAME/servicelog"
    chpst -u "$OWNER" mkdir -p "$LOGDIR"
    exec chpst -u "$OWNER" svlogd -tt "$LOGDIR"
}

case "$1" in
    up|down|log)
	"$1"
	;;
    *)
	echo "Usage: $0 [up|down]" >&2
	exit 1
	;;
esac