aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevan Carpenter <git@dvn.me>2020-05-13 18:16:53 +0100
committerDevan Carpenter <git@dvn.me>2020-05-13 18:19:25 +0100
commit69b57fece34a50bb9cf88f45a6be9c81d6edc194 (patch)
tree7da3d59000c12ba15708b604248c9dfa1e29a3dd
downloadansible-gitlab-runner-69b57fece34a50bb9cf88f45a6be9c81d6edc194.tar.gz
ansible-gitlab-runner-69b57fece34a50bb9cf88f45a6be9c81d6edc194.zip
Initial setup of a gitlab-runner playbook
-rw-r--r--.gitlab-ci.yml10
-rw-r--r--README.md3
-rw-r--r--local.yml7
-rw-r--r--roles/gitlab-runner/handlers/main.yml7
-rw-r--r--roles/gitlab-runner/tasks/main.yml56
-rw-r--r--roles/gitlab-runner/templates/base.sh13
-rw-r--r--roles/gitlab-runner/templates/cleanup.sh9
-rw-r--r--roles/gitlab-runner/templates/config.sh10
-rw-r--r--roles/gitlab-runner/templates/gitlab-runner.toml23
-rw-r--r--roles/gitlab-runner/templates/gitlab-runners-network.xml12
-rw-r--r--roles/gitlab-runner/templates/gitlab_runner.fact5
-rw-r--r--roles/gitlab-runner/templates/prepare.sh85
-rw-r--r--roles/gitlab-runner/templates/run.sh10
-rwxr-xr-xroles/kvm/files/create-debian-vm.sh46
-rw-r--r--roles/kvm/handlers/main.yml2
-rw-r--r--roles/kvm/tasks/main.yml46
-rw-r--r--roles/kvm/templates/gateway.xml162
-rw-r--r--roles/kvm/templates/libvirt-default-uri.sh2
18 files changed, 508 insertions, 0 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..072476e
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,10 @@
1stages:
2 - test
3
4test:
5 stage: test
6 image: python:latest
7 before_script:
8 - pip install ansible==2.6.2
9 script:
10 - ansible-playbook --syntax-check -v local.yml
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e3fc0ea
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
1# Ansible Gitlab Runner
2
3An `ansible-pull` repo to configure a Gitlab Runner using a custom KVM executor
diff --git a/local.yml b/local.yml
new file mode 100644
index 0000000..5dd4a53
--- /dev/null
+++ b/local.yml
@@ -0,0 +1,7 @@
1---
2- hosts: localhost
3
4 roles:
5 - kvm
6 - role: gitlab-runner
7 when: ansible_local is defined and ansible_local.gitlab_runner is defined and ansible_local.gitlab_runner.registration_token is defined
diff --git a/roles/gitlab-runner/handlers/main.yml b/roles/gitlab-runner/handlers/main.yml
new file mode 100644
index 0000000..3f26db6
--- /dev/null
+++ b/roles/gitlab-runner/handlers/main.yml
@@ -0,0 +1,7 @@
1- name: reload systemd
2 command: systemctl daemon-reload
3
4- name: restart gitlab-runner
5 service:
6 name: gitlab-runner
7 state: restarted
diff --git a/roles/gitlab-runner/tasks/main.yml b/roles/gitlab-runner/tasks/main.yml
new file mode 100644
index 0000000..0465b3d
--- /dev/null
+++ b/roles/gitlab-runner/tasks/main.yml
@@ -0,0 +1,56 @@
1- name: Install depends
2 apt:
3 name: [apt-transport-https]
4 state: present
5
6- name: Add GitLab apt signing key
7 apt_key:
8 id: F6403F6544A38863DAA0B6E03F01618A51312F3F
9 url: https://packages.gitlab.com/gpg.key
10
11- name: Add GitLab apt repo to souces.list
12 apt_repository:
13 codename: "{{ ansible_distribution_release }}"
14 repo: "deb https://packages.gitlab.com/runner/gitlab-runner/debian/ {{ ansible_distribution_release }} main"
15 update_cache: yes
16
17- name: Install GitLab Runner
18 apt:
19 name: gitlab-runner
20
21- name: Get a token for the runner
22 uri:
23 url: "https://{{ ansible_local.gitlab_runner.gitlab_domain }}/api/v4/runners"
24 method: POST
25 body_format: form-urlencoded
26 body:
27 name: "{{ ansible_fqdn }}"
28 description: "virtual machine on {{ ansible_fqdn }}"
29 token: "{{ ansible_local.gitlab_runner.registration_token }}"
30 tag_list: "kvm"
31 status_code: 201
32 return_content: yes
33 register: runner_token
34 when: ansible_local.gitlab_runner.runner_token is not defined
35
36- name: Store the token
37 template:
38 src: gitlab_runner.fact
39 dest: /etc/ansible/facts.d/gitlab_runner.fact
40 when: ansible_local.gitlab_runner.runner_token is not defined
41
42- name: Reread facts
43 setup: {}
44 when: ansible_local.gitlab_runner.runner_token is not defined
45
46- name: Install gitlab custom executor scripts
47 template:
48 src: "{{ item }}.sh"
49 dest: "/etc/gitlab-runner/{{ item }}.sh"
50 mode: "0755"
51 with_items: [config, prepare, run, cleanup]
52
53- name: Configure the gitlab runner
54 template:
55 src: gitlab-runner.toml
56 dest: /etc/gitlab-runner/config.toml
diff --git a/roles/gitlab-runner/templates/base.sh b/roles/gitlab-runner/templates/base.sh
new file mode 100644
index 0000000..9a40bf2
--- /dev/null
+++ b/roles/gitlab-runner/templates/base.sh
@@ -0,0 +1,13 @@
1#!/bin/bash
2set -euo pipefail
3VM_IMAGES_PATH="/var/lib/libvirt/images"
4BASE_VM_IMAGE="$VM_IMAGES_PATH/gitlab-job.qcow2"
5VM_ID="runner-$CUSTOM_ENV_CI_RUNNER_ID-project-$CUSTOM_ENV_CI_PROJECT_ID-concurrent-$CUSTOM_ENV_CI_CONCURRENT_PROJECT_ID-job-$CUSTOM_ENV_CI_JOB_ID"
6VM_IMAGE="$VM_IMAGES_PATH/$VM_ID.qcow2"
7VM_HOSTNAME="runner-${CUSTOM_ENV_CI_JOB_ID}"
8IMAGE_HOST="127.0.0.1"
9export LIBVIRT_DEFAULT_URI="qemu:///system"
10
11_get_vm_ip() {
12 virsh -q domifaddr --source agent "$VM_ID" 2> /dev/null | awk '{print $4}' | sed -E 's|/([0-9]+)?$||' | grep '172.18' || true
13}
diff --git a/roles/gitlab-runner/templates/cleanup.sh b/roles/gitlab-runner/templates/cleanup.sh
new file mode 100644
index 0000000..42071b2
--- /dev/null
+++ b/roles/gitlab-runner/templates/cleanup.sh
@@ -0,0 +1,9 @@
1{% include "base.sh" %}
2
3# Destroy VM.
4virsh shutdown "$VM_ID" || true
5
6# Undefine VM.
7virsh undefine "$VM_ID" || true
8
9rm -fv /tmp/${VM_ID}_ed25519 /tmp/${VM_ID}_ed25519.pub ${VM_IMAGES_PATH}/${VM_ID}*
diff --git a/roles/gitlab-runner/templates/config.sh b/roles/gitlab-runner/templates/config.sh
new file mode 100644
index 0000000..3c0fe60
--- /dev/null
+++ b/roles/gitlab-runner/templates/config.sh
@@ -0,0 +1,10 @@
1#!/usr/bin/env bash
2
3cat << EOS
4{
5 "driver": {
6 "name": "entanglement.garden driver",
7 "version": "v0.0.1"
8 }
9}
10EOS
diff --git a/roles/gitlab-runner/templates/gitlab-runner.toml b/roles/gitlab-runner/templates/gitlab-runner.toml
new file mode 100644
index 0000000..3edcfcb
--- /dev/null
+++ b/roles/gitlab-runner/templates/gitlab-runner.toml
@@ -0,0 +1,23 @@
1concurrent = 5
2check_interval = 0
3
4[session_server]
5 session_timeout = 1800
6
7[[runners]]
8 name = "{{ ansible_fqdn }}"
9 url = "https://{{ ansible_local.gitlab_runner.gitlab_domain }}"
10 token = "{{ ansible_local.gitlab_runner.runner_token }}"
11 executor = "custom"
12 builds_dir = "/home/debian/builds"
13 cache_dir = "/home/debian/.cache"
14
15 [runners.custom]
16 config_exec = "/etc/gitlab-runner/config.sh"
17 prepare_exec = "/etc/gitlab-runner/prepare.sh"
18 run_exec = "/etc/gitlab-runner/run.sh"
19 cleanup_exec = "/etc/gitlab-runner/cleanup.sh"
20
21 [runners.cache]
22 [runners.cache.s3]
23 [runners.cache.gcs]
diff --git a/roles/gitlab-runner/templates/gitlab-runners-network.xml b/roles/gitlab-runner/templates/gitlab-runners-network.xml
new file mode 100644
index 0000000..15183af
--- /dev/null
+++ b/roles/gitlab-runner/templates/gitlab-runners-network.xml
@@ -0,0 +1,12 @@
1<network>
2 <name>gitlab-runners</name>
3 <forward mode='nat' />
4 <bridge stp='on' delay='0'/>
5 <mac address='52:54:00:01:61:fd'/>
6 <ip address='192.168.42.1' netmask='255.255.255.0'>
7 <dhcp>
8 <range start='192.168.42.2' end='192.168.42.254'/>
9 </dhcp>
10 </ip>
11</network>
12
diff --git a/roles/gitlab-runner/templates/gitlab_runner.fact b/roles/gitlab-runner/templates/gitlab_runner.fact
new file mode 100644
index 0000000..319e7c7
--- /dev/null
+++ b/roles/gitlab-runner/templates/gitlab_runner.fact
@@ -0,0 +1,5 @@
1{
2 "registration_token": "{{ ansible_local.gitlab_runner.registration_token }}",
3 "runner_token": "{{ runner_token.content | from_json | json_query('token') }}",
4 "gitlab_domain": "{{ ansible_local.gitlab_runner.gitlab_domain }}"
5}
diff --git a/roles/gitlab-runner/templates/prepare.sh b/roles/gitlab-runner/templates/prepare.sh
new file mode 100644
index 0000000..8b01997
--- /dev/null
+++ b/roles/gitlab-runner/templates/prepare.sh
@@ -0,0 +1,85 @@
1{% include 'base.sh' %}
2
3# trap any error, and mark it as a system failure.
4trap "exit $SYSTEM_FAILURE_EXIT_CODE" ERR
5
6#pushd /var/lib/libvirt/images
7#if ! curl -s http://${IMAGE_HOST}/gitlab-job/SHA256SUMS | grep -E "gitlab-job.qcow2$" | sha256sum -c ; then
8# wget -qO gitlab-job.qcow2.xz http://${IMAGE_HOST}/gitlab-job/gitlab-job.qcow2.xz
9# curl -s http://${IMAGE_HOST}/gitlab-job/SHA256SUMS | grep -E "gitlab-job.qcow2.xz$" | sha256sum -c
10# rm gitlab-job.qcow2 || true
11# unxz -v gitlab-job.qcow2.xz
12#fi
13#popd
14
15# Copy base disk to use for Job.
16cp "$BASE_VM_IMAGE" "$VM_IMAGE"
17
18tempconfig=$(mktemp -td cloudinit.XXXXX)
19echo "instance-id: ${VM_HOSTNAME}" >> $tempconfig/meta-data
20echo "local-hostname: ${VM_HOSTNAME}" >> $tempconfig/meta-data
21
22ssh-keygen -t ed25519 -f /tmp/${VM_ID}_ed25519 -qN ""
23
24cat > $tempconfig/user-data <<EOF
25#cloud-config
26ssh_authorized_keys:
27 - $(cat /tmp/${VM_ID}_ed25519.pub)
28EOF
29
30genisoimage -output "${VM_IMAGES_PATH}/${VM_ID}-cloudinit.iso" -volid cidata -joliet -r "${tempconfig}"
31
32
33# Install the VM
34virt-install \
35 --name "$VM_ID" \
36 --os-variant debian10 \
37 --disk "$VM_IMAGE" \
38 --disk "${VM_IMAGES_PATH}/${VM_ID}-cloudinit.iso,device=cdrom" \
39 --import \
40 --vcpus=2 \
41 --ram=2048 \
42 --network bridge=brlan,model=virtio \
43 --graphics none \
44 --noautoconsole
45
46# Wait for VM to get IP
47echo 'Waiting for VM to get IP'
48for i in $(seq 1 300); do
49 VM_IP=$(_get_vm_ip)
50
51 if [ -n "$VM_IP" ]; then
52 echo "VM got IP: $VM_IP"
53 break
54 fi
55
56 if [ "$i" == "300" ]; then
57 echo 'Waited 5 minutes for VM to start, exiting...'
58 # Inform GitLab Runner that this is a system failure, so it
59 # should be retried.
60 exit "$SYSTEM_FAILURE_EXIT_CODE"
61 fi
62
63 sleep 1
64done
65
66ssh-keygen -R "$VM_IP" || true
67
68# Wait for ssh to become available
69echo "Waiting for sshd to be available"
70for i in $(seq 1 300); do
71 if ssh -i /tmp/${VM_ID}_ed25519 -o StrictHostKeyChecking=no debian@"$VM_IP" >/dev/null 2>/dev/null; then
72 break
73 fi
74
75 if [ "$i" == "300" ]; then
76 echo 'Waited 5 minutes for sshd to start, exiting...'
77 # Inform GitLab Runner that this is a system failure, so it
78 # should be retried.
79 exit "$SYSTEM_FAILURE_EXIT_CODE"
80 fi
81
82 sleep 1
83done
84
85rm -rf "$tempconfig"
diff --git a/roles/gitlab-runner/templates/run.sh b/roles/gitlab-runner/templates/run.sh
new file mode 100644
index 0000000..b4a79cf
--- /dev/null
+++ b/roles/gitlab-runner/templates/run.sh
@@ -0,0 +1,10 @@
1{% include "base.sh" %}
2
3VM_IP=$(_get_vm_ip)
4
5ssh -i /tmp/${VM_ID}_ed25519 -o StrictHostKeyChecking=no debian@"$VM_IP" /bin/bash < "${1}"
6if [ $? -ne 0 ]; then
7 # Exit using the variable, to make the build as failure in GitLab
8 # CI.
9 exit "$BUILD_FAILURE_EXIT_CODE"
10fi
diff --git a/roles/kvm/files/create-debian-vm.sh b/roles/kvm/files/create-debian-vm.sh
new file mode 100755
index 0000000..4f59dd5
--- /dev/null
+++ b/roles/kvm/files/create-debian-vm.sh
@@ -0,0 +1,46 @@
1#!/bin/bash
2set -euo pipefail
3hostname=${1:-}
4if [[ -z ${hostname} ]]; then
5 echo -n "Enter hostname: "
6 read hostname
7fi
8
9disk_prefix="/var/lib/libvirt/images/${hostname}"
10
11tempconfig=$(mktemp -td cloudinit.XXXXX)
12
13echo "instance-id: $hostname" >> $tempconfig/meta-data
14echo "local-hostname: $hostname" >> $tempconfig/meta-data
15
16cat > $tempconfig/user-data <<EOF
17#cloud-config
18users:
19 - default
20 - name: dvn
21 groups: systemd-journal
22 shell: /bin/bash
23 sudo: ALL=(ALL) NOPASSWD:ALL
24 ssh_authorized_keys: # These SSH keys will be overwritten by ansible-pull when the VM first boots
25 - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILL6PhAcMxsc4GhRuQYRMwchcig5qTDQQFZBQzxFTmxI
26package_update: true
27packages:
28 - ansible
29 - git
30runcmd:
31 - ansible-pull -U "https://git.gnunet.org/ansible-basic.git"
32 - run-ansible-pull nodisown
33power_state:
34 mode: reboot
35EOF
36
37pushd ${tempconfig}
38genisoimage -output "${disk_prefix}-cloudinit.iso" -volid cidata -joliet -r user-data meta-data
39popd
40rm -rf ${tempconfig}
41
42cp /var/installmedia/debian-10-openstack-amd64.qcow2 "${disk_prefix}.qcow2"
43
44qemu-img resize "${disk_prefix}.qcow2" 20G
45
46virt-install --rng /dev/random --connect qemu:///system --virt-type=kvm --import --name "${hostname}" --ram 1024 --vcpus 1 --disk "${disk_prefix}.qcow2,format=qcow2,bus=virtio" --disk "${disk_prefix}-cloudinit.iso,device=cdrom" --network bridge=brlan,model=virtio --console pty,target_type=serial --os-type=linux --os-variant=debian9 --noautoconsole
diff --git a/roles/kvm/handlers/main.yml b/roles/kvm/handlers/main.yml
new file mode 100644
index 0000000..09dc6ad
--- /dev/null
+++ b/roles/kvm/handlers/main.yml
@@ -0,0 +1,2 @@
1- name: reboot
2 command: reboot
diff --git a/roles/kvm/tasks/main.yml b/roles/kvm/tasks/main.yml
new file mode 100644
index 0000000..681cc58
--- /dev/null
+++ b/roles/kvm/tasks/main.yml
@@ -0,0 +1,46 @@
1- name: Install kvm
2 apt:
3 name:
4 - qemu-kvm
5 - libvirt-clients
6 - qemu-utils
7 - libvirt-daemon-system
8 - genisoimage
9 - virtinst
10 - qemu-utils
11
12- name: Put us in the kvm groups
13 user:
14 append: yes ## Don't set these as our *only* groups!
15 groups: libvirt,libvirt-qemu,kvm
16 name: "{{ item }}"
17 with_items:
18 - dvn
19
20- name: Create /var/installmedia
21 file:
22 path: /var/installmedia
23 state: directory
24
25- name: Download the latest debian cloud image
26 get_url:
27 url: https://cdimage.debian.org/cdimage/openstack/current/debian-10.1.0-openstack-amd64.qcow2
28 dest: /var/installmedia/debian-10-openstack-amd64.qcow2
29 checksum: sha256:b97489ea8f64bba8609042d6387053056b67518b2c7c9a7c67602a94e5ee1642
30
31- name: Install create-debian-vm.sh
32 copy:
33 src: create-debian-vm.sh
34 dest: /usr/local/bin/create-debian-vm
35 mode: 0755
36
37- name: Set permissions and ownership on /var/lib/libvirt/images
38 file:
39 path: /var/lib/libvirt/images
40 group: libvirt
41 mode: "0775"
42
43- name: Configure virsh for local administration
44 template:
45 src: libvirt-default-uri.sh
46 dest: /etc/profile.d/libvirt-default-uri.sh
diff --git a/roles/kvm/templates/gateway.xml b/roles/kvm/templates/gateway.xml
new file mode 100644
index 0000000..30919db
--- /dev/null
+++ b/roles/kvm/templates/gateway.xml
@@ -0,0 +1,162 @@
1<domain type='qemu' id='4'>
2 <name>gateway</name>
3 <memory unit='KiB'>1048576</memory>
4 <currentMemory unit='KiB'>1048576</currentMemory>
5 <vcpu placement='static'>2</vcpu>
6 <resource>
7 <partition>/machine</partition>
8 </resource>
9 <os>
10 <type arch='x86_64' machine='pc-i440fx-2.8'>hvm</type>
11 <boot dev='hd'/>
12 </os>
13 <features>
14 <acpi/>
15 <apic/>
16 <vmport state='off'/>
17 </features>
18 <clock offset='utc'>
19 <timer name='rtc' tickpolicy='catchup'/>
20 <timer name='pit' tickpolicy='delay'/>
21 <timer name='hpet' present='no'/>
22 </clock>
23 <on_poweroff>destroy</on_poweroff>
24 <on_reboot>restart</on_reboot>
25 <on_crash>restart</on_crash>
26 <pm>
27 <suspend-to-mem enabled='no'/>
28 <suspend-to-disk enabled='no'/>
29 </pm>
30 <devices>
31 <emulator>/usr/bin/qemu-system-x86_64</emulator>
32 <disk type='file' device='disk'>
33 <driver name='qemu' type='qcow2'/>
34 <source file='/var/lib/libvirt/images/gateway.qcow2'/>
35 <backingStore/>
36 <target dev='vda' bus='virtio'/>
37 <alias name='virtio-disk0'/>
38 <address type='pci' domain='0x0000' bus='0x00' slot='0x08' function='0x0'/>
39 </disk>
40 <disk type='file' device='cdrom'>
41 <driver name='qemu' type='raw'/>
42 <source file='/var/lib/libvirt/images/gateway-cloudinit.iso'/>
43 <backingStore/>
44 <target dev='hda' bus='ide'/>
45 <readonly/>
46 <alias name='ide0-0-0'/>
47 <address type='drive' controller='0' bus='0' target='0' unit='0'/>
48 </disk>
49 <controller type='usb' index='0' model='ich9-ehci1'>
50 <alias name='usb'/>
51 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x7'/>
52 </controller>
53 <controller type='usb' index='0' model='ich9-uhci1'>
54 <alias name='usb'/>
55 <master startport='0'/>
56 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0' multifunction='on'/>
57 </controller>
58 <controller type='usb' index='0' model='ich9-uhci2'>
59 <alias name='usb'/>
60 <master startport='2'/>
61 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x1'/>
62 </controller>
63 <controller type='usb' index='0' model='ich9-uhci3'>
64 <alias name='usb'/>
65 <master startport='4'/>
66 <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x2'/>
67 </controller>
68 <controller type='pci' index='0' model='pci-root'>
69 <alias name='pci.0'/>
70 </controller>
71 <controller type='ide' index='0'>
72 <alias name='ide'/>
73 <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
74 </controller>
75 <controller type='virtio-serial' index='0'>
76 <alias name='virtio-serial0'/>
77 <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
78 </controller>
79 <interface type='bridge'>
80 <mac address='52:54:00:0e:ea:c1'/>
81 <source bridge='brlan'/>
82 <target dev='vnet0'/>
83 <model type='virtio'/>
84 <alias name='net0'/>
85 <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
86 </interface>
87 <interface type='bridge'>
88 <mac address='52:54:00:29:0c:ad'/>
89 <source bridge='brwan'/>
90 <target dev='vnet1'/>
91 <model type='virtio'/>
92 <alias name='net1'/>
93 <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
94 </interface>
95 <serial type='pty'>
96 <source path='/dev/pts/1'/>
97 <target port='0'/>
98 <alias name='serial0'/>
99 </serial>
100 <console type='pty' tty='/dev/pts/1'>
101 <source path='/dev/pts/1'/>
102 <target type='serial' port='0'/>
103 <alias name='serial0'/>
104 </console>
105 <channel type='unix'>
106 <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-4-gateway/org.qemu.guest_agent.0'/>
107 <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
108 <alias name='channel0'/>
109 <address type='virtio-serial' controller='0' bus='0' port='1'/>
110 </channel>
111 <channel type='spicevmc'>
112 <target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
113 <alias name='channel1'/>
114 <address type='virtio-serial' controller='0' bus='0' port='2'/>
115 </channel>
116 <input type='tablet' bus='usb'>
117 <alias name='input0'/>
118 <address type='usb' bus='0' port='1'/>
119 </input>
120 <input type='mouse' bus='ps2'>
121 <alias name='input1'/>
122 </input>
123 <input type='keyboard' bus='ps2'>
124 <alias name='input2'/>
125 </input>
126 <graphics type='spice' port='5900' autoport='yes' listen='127.0.0.1'>
127 <listen type='address' address='127.0.0.1'/>
128 <image compression='off'/>
129 </graphics>
130 <sound model='ich6'>
131 <alias name='sound0'/>
132 <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
133 </sound>
134 <video>
135 <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primary='yes'/>
136 <alias name='video0'/>
137 <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
138 </video>
139 <redirdev bus='usb' type='spicevmc'>
140 <alias name='redir0'/>
141 <address type='usb' bus='0' port='2'/>
142 </redirdev>
143 <redirdev bus='usb' type='spicevmc'>
144 <alias name='redir1'/>
145 <address type='usb' bus='0' port='3'/>
146 </redirdev>
147 <memballoon model='virtio'>
148 <alias name='balloon0'/>
149 <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
150 </memballoon>
151 <rng model='virtio'>
152 <backend model='random'>/dev/random</backend>
153 <alias name='rng0'/>
154 <address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
155 </rng>
156 </devices>
157 <seclabel type='none' model='none'/>
158 <seclabel type='dynamic' model='dac' relabel='yes'>
159 <label>+64055:+64055</label>
160 <imagelabel>+64055:+64055</imagelabel>
161 </seclabel>
162</domain>
diff --git a/roles/kvm/templates/libvirt-default-uri.sh b/roles/kvm/templates/libvirt-default-uri.sh
new file mode 100644
index 0000000..2b293da
--- /dev/null
+++ b/roles/kvm/templates/libvirt-default-uri.sh
@@ -0,0 +1,2 @@
1#!/bin/sh
2export LIBVIRT_DEFAULT_URI=qemu:///system