summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2015-07-03 22:14:26 +0300
committerLars Wirzenius <liw@liw.fi>2015-07-03 22:14:26 +0300
commit662fac8a7a4877876769d01c3f3c8a4480963c17 (patch)
tree768b9657827b36ef960a6d16ecd0ad42d2ab89b1
parent2869f07a36149688615bc71757240947b448fe1f (diff)
downloadansibleness-662fac8a7a4877876769d01c3f3c8a4480963c17.tar.gz
Add preliminary README and VM creation script
-rw-r--r--README50
-rw-r--r--create-vm48
2 files changed, 98 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..468e738
--- /dev/null
+++ b/README
@@ -0,0 +1,50 @@
+Managing my virtual machines
+============================
+
+I have a laptop with 16 GiB RAM, which is enough to run a few virtual
+machines. I make use of this to run VMs as, for example, workers for
+my CI setup, such that I have two or three versions of Debian
+(oldstable, stable, unstable) and two CPU architectures (i386, amd64).
+This lets me test the software I develop on a large fraction of the
+environments in which my users run it on.
+
+I have a few other VMs as well. Managing all of these would be tricky,
+but I've gathered some tools for this:
+
+* The actual virtualisation is KVM, managed by libvirt. This is less
+ invasive than running OpenStack of similar cloud services on my
+ laptop.
+
+* I use Ansible for configuration management. It's easy to use, and
+ doesn't require Ruby or running an agent on each machine.
+
+* I create each VM from a base image. The base images are created by
+ vmdebootstrap, a tool I wrote and that Neil Williams now maintains.
+ The base images have a minimal install, with a user `ansible` that
+ is allowed passwordless sudo, and an `authorized_keys` file that
+ allows my Ansible to log into them and do things.
+
+The creation of a new VM is a somewhat intricate process:
+
+* Create a new LV of the same size as the base images.
+
+* Unpack the correct base image onto the LV. The base images are
+ stored compressed in an archive location.
+
+* Create the VM, with `virt-install`. This chooses a random MAC
+ address for the new VM, and also starts it.
+
+* Find the new VM's MAC address in the
+ `/var/lib/libvirt/dnsmasq/default.leases` file, and pick out the IP
+ address given to it.
+
+* Add to `/etc/hosts` a line that gives the VM's IP address a name
+ that's the new VM's hostname.
+
+* Log into the new VM, with ssh, and change the hostname. Then reboot.
+
+All of the above is automated into a script.
+
+After this, the new VM can be managed by Ansible. Ansible gets run
+manually after the VM creation script, and after I've added the new VM
+to my Ansible config.
diff --git a/create-vm b/create-vm
new file mode 100644
index 0000000..1be7694
--- /dev/null
+++ b/create-vm
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# Create a new VM for liw.
+
+set -eu
+
+# Command line parameters: name of VM and base image (no .img.xz suffix).
+name="$1"
+base="$2"
+
+# Where are the base images?
+imagedir="/big/base-images"
+
+# How large are the (uncompressed) images?
+imagesize="4G"
+
+# What volume group should we use?
+vg="exolobe1-vg"
+
+# Create new LV.
+lvcreate --name "$name" --size "$imagesize" "$vg"
+lvpath="/dev/$vg/$name"
+
+# Copy uncompressed image to LV.
+unxz < "$imagedir/$base.img.xz" | pv --size "$size" > "$lvpath"
+
+# Create VM.
+virt-install -c qemu:///system \
+ --name="$name" \
+ --memory=512 \
+ --cpu=host-model-only \
+ --import \
+ --os-variant=debianwheezy \
+ --disk="path=$lvpath,cache=none" \
+ --network=network=default \
+ --graphics=spice
+
+# Get the MAC address.
+mac="$(virsh dumpxml "$name" | sed -n "/<mac address=/s/^.*'\(.*\)'.*/\1/p")"
+
+# Get IP address related to the MAC address. Append that to /etc/hosts.
+leases=/var/lib/libvirt/dnsmasq/default.leases
+ip="$(awk -v "mac=$mac" '$2 == mac { print $3 }' "$leases")"
+echo "$ip $name" >> /etc/hosts
+
+# Log into VM, change hostname and reboot.
+echo "$name" ssh "ansible@$name" tee /etc/hostname
+ssh "ansible@$name" reboot