aboutsummaryrefslogtreecommitdiff
path: root/kvm-manager
blob: f38ddc5094620f883341d6c10aed440ece2a34af (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
#!/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: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,server,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" &

    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:${CONSOLENAME},retry=30" &

    set +e
    # handle regular signals
    trap 'kvmsend system_reset; wait %1' HUP
    trap 'kvmsend system_powerdown; wait %1' TERM
    trap 'kvmsend cont; wait %1' 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 %1' INT
    trap 'kill %1 ; kill %2' EXIT

    wait %1
}


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