This commit is contained in:
Shiz 2017-03-29 05:07:26 +02:00
commit 9d700833ef
13 changed files with 224 additions and 0 deletions

14
LICENSE Normal file
View File

@ -0,0 +1,14 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

34
README.md Normal file
View File

@ -0,0 +1,34 @@
# vm-utils
Scripts to manage QEMU-based VMs.
## Why?
I didn't like libvirt.
## Installation
Copy the `vm` folder to your `/etc`, or elsewhere and adjust the `rootdir=` statements in the `scripts/` files.
Optionally, make symlinks for `vm-<script>` to `/etc/vm/scripts/<script>` in your `/usr/local/bin`.
You're gonna want to have `tmux` and `qemu-system-x86_64` installed, as well as KVM (`CONFIG_KVM`) and macvtap (`CONFIG_MACVLAN`) support in your kernel.
## Setup
These scripts presumes a setup like Online.net, where IPv4s are directly routed to your machine and a macvtap interface can accept them,
while an IPv6 prefix is delegated to your machine and you have to explicitly route it through a normal tap interface - hence the dual NICs in the VMs.
## Overview
* `machines.d`: Main VM configurations for QEMU;
* `conf`: VM configurations for `vm-utils`;
* `include`: Include files for VM configurations;
* `scripts`: Various scripts to automate VM management:
- `start`: Start a VM named by `machines.d/<name>.conf`;
- `stop`: Stop a VM named by `machines.d/<name>conf`;
- `attach`: Attach to management console of VM named by `machines.d/<name.conf>`;
- `launch`: Launch VM in current terminal session and attach to management console; used by `start`
- `ifup`/`ifup6`/`ifdown`: Network interface management scripts;
## License
WTFPL; see `LICENSE` for details.

3
vm/conf/example.conf Normal file
View File

@ -0,0 +1,3 @@
net_mac 52:54:00:aa:bb:cc
net_ipv4 1.2.3.4/32
net_ipv6 fe80::/64

10
vm/include/common.conf Normal file
View File

@ -0,0 +1,10 @@
name $name
machine q35,accel=kvm
enable-kvm
cpu host
nographic
drive file=/var/vm/disks/$name.qcow2,if=virtio,format=qcow2,cache=none
net nic,vlan=0,model=virtio,macaddr=$conf_net_mac
net tap,vlan=0,fd=3
net nic,vlan=1,model=virtio
net tap,vlan=1,ifname=vm-$name-6,script=$rootdir/scripts/ifup6,downscript=$rootdir/scripts/ifdown

View File

@ -0,0 +1,4 @@
!include common.conf
smp cores=2
m 2G
vnc localhost:0

8
vm/scripts/attach Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
set -e
rootdir=/etc/vm
name="$1"
. "$rootdir/utils.sh"
tmux attach -t vm-"$name"

20
vm/scripts/ifdown Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
set -e
rootdir=/etc/vm
device="$1"
name="${device#vm-}"
name="${name%-*}"
. "$rootdir/utils.sh"
file=$(basename "$name.conf")
conf=$(resolve_includes "$rootdir/conf" "$rootdir/conf/$file")
# Set configuration
while read -r k v ; do
eval "conf_$k=$v"
done <<EOF
$conf
EOF
ip link del "$device"

25
vm/scripts/ifup Executable file
View File

@ -0,0 +1,25 @@
#!/bin/sh
set -e
rootdir=/etc/vm
name="$1"
device="$2"
. "$rootdir/utils.sh"
# Read files
file=$(basename "$name.conf")
conf=$(resolve_includes "$rootdir/conf" "$rootdir/conf/$file")
# Set configuration
while read -r k v ; do
eval "conf_$k=$v"
done <<EOF
$conf
EOF
if ! test -e /sys/class/net/"$device" ; then
ip link add link eth0 name "$device" address "$conf_net_mac" type macvtap mode bridge
#sysctl net.ipv6.conf."$device".forwarding=1
#ip -6 route add "$conf_net_ipv6" dev "$device"-6
fi
echo /dev/tap$(cat /sys/class/net/"$device"/ifindex)

22
vm/scripts/ifup6 Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
set -e
rootdir=/etc/vm
device="$1"
name="${device#vm-}"
name="${name%-*}"
. "$rootdir/utils.sh"
# Read files
file=$(basename "$name.conf")
conf=$(resolve_includes "$rootdir/conf" "$rootdir/conf/$file")
# Set configuration
while read -r k v ; do
eval "conf_$k=$v"
done <<EOF
$conf
EOF
ip -6 addr add dev "$device" fe80::1/64 scope link
ip -6 route add "$conf_net_ipv6" dev "$device"

40
vm/scripts/launch Executable file
View File

@ -0,0 +1,40 @@
#!/bin/sh
set -e
rootdir=/etc/vm
name="$1"
. "$rootdir/utils.sh"
# Read files.
file=$(basename "$name.conf")
conf=$(resolve_includes "$rootdir/conf" "$rootdir/conf/$file")
params=$(resolve_includes "$rootdir/include" "$rootdir/machines.d/$file")
# Set configuration
while read -r k v ; do
eval "conf_$k=$v"
done <<EOF
$conf
EOF
# Expand parameters.
params=$(expand "$params")
# Build command line.
set -- qemu-system-x86_64
while read -r k v ; do
set -- "$@" "-$k"
if test -n "$v" ; then
set -- "$@" "$v"
fi
done <<EOF
$params
EOF
# Setup interface.
tapdev=$("$rootdir/scripts/ifup" "$name" vm-"$name")
test $? -ne 0 && exit 1
# Launch qemu.
exec "$@" 3<>"$tapdev"

6
vm/scripts/start Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
name="$1"
rootdir=/etc/vm
tmux new-session -ds vm-"$name" "exec $rootdir/scripts/launch $1"

6
vm/scripts/stop Executable file
View File

@ -0,0 +1,6 @@
#!/bin/sh
set -e
name="$1"
tmux kill-session -t vm-"$name"

32
vm/utils.sh Normal file
View File

@ -0,0 +1,32 @@
#!/bin/sh
resolve_includes() {
local rootdir="$1"
local conf=$(cat "$2")
local k
local v
test -z "$conf" && exit 1
while test "${conf#*!include}" != "$conf" ; do
conf=$(printf "%s\n" "$conf" | while read -r k v; do
case "$k" in
!include)
local file=$(basename "$v")
cat "$rootdir/$file"
;;
*)
printf "%s %s\n" "$k" "$v"
;;
esac
done)
done
echo "$conf"
}
expand() {
local data="$1"
local newline="$(printf '\n ')"
newline=${newline% }
eval "cat <<EOF${newline}${data}${newline}"
}