Commit 4d8dfa12 authored by Holger Levsen's avatar Holger Levsen

drop lvc stuff, now that openqa.debian.net is getting into shape

Signed-off-by: Holger Levsen's avatarHolger Levsen <holger@layer-acht.org>
parent 213675aa
......@@ -244,9 +244,6 @@ See link:https://jenkins.debian.net/userContent/thanks.html[THANKS].
== License
* everything except features and bin/libvirt_cucumber_tests:
** GPLv2, see link:https://anonscm.debian.org/git/qa/jenkins.debian.net.git/LICENSE[LICENSE].
* features and bin/libvirt_cucumber_tests:
** GPLv3+
// vim: set filetype=asciidoc:
cleanup /srv/lvc on pb10
cleanup that code in update_jdn.sh
cleanup LVC in bin/d-i_build.sh
cleanup THANKS.head for pb10
cleanup job-cfg/d-i.yaml.py (search for lvc)
#!/bin/bash
# Copyright 2015-2016 Holger Levsen <holger@layer-acht.org>
# Copyright 2015-2017 Holger Levsen <holger@layer-acht.org>
# 2016 Phil Hands <phil@hands.com>
# released under the GPLv=2
# based on an idea by Peter Palfrader (see bin/jenkins_node_wrapper.sh)
......@@ -10,13 +10,6 @@ set -e
# don't try to run on test system
if [ "$HOSTNAME" = "jenkins-test-vm" ] ; then
case $JOB_NAME in
lvc_*)
exec /srv/jenkins/bin/lvc.sh "$@"
echo "$(date -u) - running on $HOSTNAME, This should not happen."
exit 1
;;
esac
echo "$(date -u) - running on $HOSTNAME, exiting successfully and cleanly immediatly."
exit 0
fi
......
......@@ -72,13 +72,6 @@ elif [[ "$*" =~ ^rebootstrap_.* ]] ; then
REBOOTSTRAPSH="/srv/jenkins/bin/rebootstrap.sh $@"
export LC_ALL=C
exec $REBOOTSTRAPSH; croak "Exec failed";
elif [[ "$*" =~ ^lvc_.* ]] ; then
export JOB_NAME=$1 ; shift
export EXECUTOR_NUMBER=$1 ; shift
export TRIGGERING_BRANCH=${1#*=} ; shift
export WORKSPACE=/var/lib/jenkins/jobs/$JOB_NAME/workspace
COMMAND="/srv/jenkins/bin/lvc.sh $@"
exec $COMMAND; croak "Exec failed";
elif [ "$*" = "reproducible_html_nodes_info" ] ; then
exec /srv/jenkins/bin/reproducible_info.sh ; croak "Exec failed";
elif [ "$1" = "/srv/jenkins/bin/reproducible_build.sh" ] && ( [ "$2" = "1" ] || [ "$2" = "2" ] ) ; then
......
#!/bin/bash
# Copyright 2012-2015 Holger Levsen <holger@layer-acht.org>
# Copyright 2016 Philip Hands <phil@hands.com>
# released under the GPLv=2
DEBUG=false
. /srv/jenkins/bin/common-functions.sh
common_init "$@"
# $1 = wget url/jigdo url
URL=$1 ; shift
replace_origin_pu() {
PREFIX=$1 ; shift
BRANCH=$1 ; shift
expr "$BRANCH" : 'origin/pu/' >/dev/null || return 1
echo "${PREFIX}pu_${BRANCH#origin/pu/}"
}
# if $URL is set to "use_TRIGGERING_BRANCH" then use the contents of $TRIGGERING_BRANCH to work out the locally built ISO name
if [ "use_TRIGGERING_BRANCH" = "$URL" ] ; then
if PU_ISO="$(replace_origin_pu "/srv/d-i/isos/mini-gtk-" $TRIGGERING_BRANCH).iso" ; then
[ -f "$PU_ISO" ] || {
echo "looks like we're meant to be testing '$PU_ISO', but it's missing"
exit 1
}
URL=$PU_ISO
echo "using locally built ISO image: URL='$URL'"
else
echo "URL='$URL' but TRIGGERING_BRANCH='$TRIGGERING_BRANCH' -- aborting"
exit 1
fi
fi
cleanup_all() {
find . -name \*.vlog.png -print0 | xargs -0 -r rm
#echo "Trying to preserve last screenshot…"
#LAST_SCREENSHOT=$(ls -t1 $RESULTS/*.png | head -1)
#if [ -e "$LAST_SCREENSHOT" ] ; then
# cp $LAST_SCREENSHOT $WORKSPACE/screenshot.png
# convert $WORKSPACE/screenshot.png -adaptive-resize 128x96 $WORKSPACE/screenshot-thumb.png
#fi
}
fetch_if_newer() {
url="$2"
file="$1"
if [ -f $url ] ; then
echo "the URL turns out to be a local path ($url) -- linking"
ln -sf $url $file
return
fi
echo "Downloading $url"
curlopts="-L -s -S"
if [ -f "$file" ] ; then
ls -l $file
echo "File exists, will only re-download if a newer one is available..."
curlopts="$curlopts -z $file"
fi
curl $curlopts -o $file.new $url
if [ -e $file.new ] ; then
mv -f $file.new $file
fi
}
discard_snapshots() {
domain=$1 ; shift
# if more parameters are provided, discard any snapshot younger than the files/dirs listed
# otherwise, get rid of all of them (hence the [ -z "$1" ] below)
sudo /usr/bin/virsh -q snapshot-list $domain | \
while read snap date time tz state ; do
if [ -z "$1" ] || [ "$(find "$@" -newermt "$date $time $tz" -print -quit)" ] ; then
sudo /usr/bin/virsh snapshot-delete $domain $snap
fi
done
}
#
# define workspace + results
#
if [ -z "$WORKSPACE" ] ; then
WORKSPACE=$PWD
fi
RESULTS=$WORKSPACE/results
IMAGE=$WORKSPACE/$(basename $URL)
LIBVIRT_DOMAIN_NAME="lvcVM-$JOB_NAME"
rm -rf $RESULTS $WORKSPACE/screenshot{,-thumb}.png
mkdir -p $RESULTS
trap cleanup_all INT TERM EXIT
#
# install image preparation
#
if [ ! -z "$NETBOOT" ] ; then
#
# if there is a netboot installer tarball...
#
fetch_if_newer "$NETBOOT" "$URL"
sha256sum "$NETBOOT"
# try to extract, otherwise clean up and abort
if ! tar -zxvf "$NETBOOT" ; then
echo "tarball seems corrupt; deleting it"
rm -f "$NETBOOT"
exit 1
fi
elif [ ! -z "$IMAGE" ] ; then
#
# if there is a CD image...
#
fetch_if_newer "$IMAGE" "$URL"
# is this really an .iso?
if [ $(file -L "$IMAGE" | grep -cE '(ISO 9660|DOS/MBR boot sector)') -eq 1 ] ; then
# yes, so let's md5sum and mount it
md5sum $IMAGE
# sudo mkdir -p $IMAGE_MNT
# grep -q $IMAGE_MNT /proc/mounts && sudo umount -l $IMAGE_MNT
# sleep 1
# sudo mount -o loop,ro $IMAGE $IMAGE_MNT
else
# something went wrong
figlet "no .iso"
echo "ERROR: no valid .iso found"
if [ $(file "$IMAGE" | grep -c "HTML document") -eq 1 ] ; then
mv "$IMAGE" "$IMAGE.html"
lynx --dump "$IMAGE.html"
rm "$IMAGE.html"
fi
exit 1
fi
else
#
# else netboot gtk
#
fetch_if_newer "$KERNEL" "$URL/$KERNEL"
fetch_if_newer "$INITRD" "$URL/$INITRD"
fi
# discard any snapshots to ensure a clean run (we used to do this conditionally here, but that proved confusing)
discard_snapshots $LIBVIRT_DOMAIN_NAME
echo "Debug log available at runtime at https://jenkins.debian.net/view/lvc/job/$JOB_NAME/ws/results/debug.log"
/srv/jenkins/cucumber/bin/run_test_suite --capture-all --keep-snapshots --vnc-server-only --iso $IMAGE --tmpdir $WORKSPACE --old-iso $IMAGE -- --format pretty --format pretty_debug --out $RESULTS/debug.log /srv/jenkins/cucumber/features/step_definitions /srv/jenkins/cucumber/features/support "${@}" || {
RETVAL=$?
# it may make sense to keep snapshots on failure, so subsequent tests are quicker -- only if we stop discarding them above though
discard_snapshots $LIBVIRT_DOMAIN_NAME
exit $RETVAL
}
# FIXME -- decide here if we need to keep any snapshots, and put them somewhere safe for other jobs to find
discard_snapshots $LIBVIRT_DOMAIN_NAME
cleanup_all
# don't cleanup twice
trap - INT TERM EXIT
Key names:
http://doc.sikuli.org/keys.html
Running the thing by hand:
./bin/lvc/run_test_suite --view --iso /var/lib/libvirt/images/debian-8.3.0-amd64-i386-netinst.iso --old-iso /var/lib/libvirt/images/debian-8.3.0-amd64-i386-netinst.iso DebianLive/apt.feature
FIXME - we don't need the OLD_ISO stuff -- make it so that it still works when not specified, so we can push the change upwards
FIXME - we need to be able to run multiple VMs in parallel, and so multiple jobs
FIXME - the VM's network currnetly needs to be started by hand
To do Git push we can use:
curl 'http://46.16.73.145:8080/git/notifyCommit?url=git://git.debian.org/git/d-i/preseed'
or
curl 'https://jenkins.debian.net/git/notifyCommit?url=git://git.debian.org/git/d-i/preseed'
Workflow:
update in local git, then run lvc-kick (FIXME add lvc-kick to git)
use the web interface to build the job (FIXME see if we can nudge the job from lvc-kick)
ssh -Y -C -L 5900:localhost:5900 jekinstest
Then we can look at the install (if the --vnc-server-only option has been passed to cucumber ... see bin/lvc.sh) with this:
xvncviewer -ViewOnly localhost:0
(you should make sure to use -ViewOnly, since any mouse movement can affect the ability of Sikuli to recognise things on the screen)
(run from the local system, which gets forwarded via the ssh connection)
When the install fails, you should get a screenshot of the last moment -- that can be grabbed and cut down for the next match)
It seems that including a colour transition, such as the edge of a frame, in the thing you're looking for makes life easier for sikuli to find it, but may make it more fragile, we'll see)
At present, sadly the tesseract OCR stuff spews vast numbers of vlog messages, making it unusable -- this has been fixed upstream (in sikuli IIRC, or maybe cucumber -- something that's now version 1.x but which has not yet hit Debian ... we can use that once it's packaged)
#!/bin/bash
set -e
set -u
set -o pipefail
NAME=$(basename ${0})
GENERAL_DEPENDENCIES="
cucumber
devscripts
dnsmasq-base
gawk
git
i18nspector
libav-tools
libcap2-bin
libsikuli-script-java
libvirt-clients
libvirt-daemon-system
libvirt-dev
libvirt0
openssh-server
ovmf
pry
python-jabberbot
python-potr
qemu-kvm
qemu-system-x86
redir
ruby-guestfs
ruby-json
ruby-libvirt
ruby-net-irc
ruby-packetfu
ruby-rb-inotify
ruby-rjb
ruby-rspec
ruby-test-unit
seabios
tcpdump
unclutter
virt-viewer
xvfb
"
usage() {
echo "Usage: $NAME [OPTION]... [--] [CUCUMBER_ARGS]...
Sets up an appropriate environment and invokes cucumber. Note that this script
must be run from the Tails source directory root.
Options for '@product' features:
--artifacts-base-uri URI
Pretend that the artifact is located at URI when printing
its location during a scenario failure. This is useful if
you intend to serve the artifacts via the web, for
instance.
--capture Captures failed scenarios into videos stored in the
temporary directory (see --tmpdir below) using x264
encoding. Requires x264.
--capture-all Keep videos for all scenarios, including those that
succeed (implies --capture).
--interactive-debugging
On failure, pause test suite until pressing Enter. Also
offer the option to open an interactive Ruby shell (pry)
in the Cucumber world's context.
--keep-snapshots Don't ever delete any snapshots (including ones marked as
temporary). This can be a big time saver when debugging new
features.
--retry-find Print a warning whenever Sikuli fails to find an image
and allow *one* retry after pressing ENTER. This is useful
for updating outdated images.
--tmpdir Directory where various temporary files are written
during a test, e.g. VM snapshots and memory dumps,
failure screenshots, pcap files and disk images
(default is TMPDIR in the environment, and if unset,
/tmp/DebianToaster).
--view Shows the test session in a windows. Requires x11vnc
and tigervnc-viewer.
--vnc-server-only Starts a VNC server for the test session. Requires x11vnc.
--iso IMAGE Test '@product' features using IMAGE.
--old-iso IMAGE For some '@product' features (e.g. usb_install) we need
an older version of Tails, which this options sets to
IMAGE. If none is given, it defaults to the same IMAGE
given by --iso, which will be good enough for most testing
purposes.
Note that '@source' features has no relevant options.
CUCUMBER_ARGS can be used to specify which features to be run, but also any
cucumber option, although then you must pass \`--\` first to let this wrapper
script know that we're done with *its* options. For debugging purposes, a
'debug' formatter has been added so pretty debugging can be enabled with
\`--format debug\`. You could even combine the default (pretty) formatter with
pretty debugging printed to a file with \`--format pretty --format debug
--out debug.log\`.
"
}
error() {
echo "${NAME}: error: ${*}" >&2
usage
exit 1
}
package_installed() {
local ret
set +o pipefail
if dpkg -s "${1}" 2>/dev/null | grep -q "^Status:.*installed"; then
ret=0
else
ret=1
fi
set -o pipefail
return ${ret}
}
check_dependencies() {
while [ -n "${1:-}" ]; do
if ! which "${1}" >/dev/null && ! package_installed "${1}" ; then
error "'${1}' is missing, please install it and run again."
fi
shift
done
}
display_in_use() {
[ -e "/tmp/.X${1#:}-lock" ] || [ -e "/tmp/.X11-unix/X${1#:}" ]
}
next_free_display() {
display_nr=0
while display_in_use ":${display_nr}"; do
display_nr=$((display_nr+1))
done
echo ":${display_nr}"
}
test_suite_cleanup() {
(kill -0 ${XVFB_PID} 2>/dev/null && kill ${XVFB_PID}) || /bin/true
}
start_xvfb() {
Xvfb $TARGET_DISPLAY -screen 0 1024x768x24+32 >/dev/null 2>&1 &
XVFB_PID=$!
# Wait for Xvfb to run on TARGET_DISPLAY
until display_in_use $TARGET_DISPLAY; do
sleep 1
done
echo "Virtual X framebuffer started on display ${TARGET_DISPLAY}"
# Hide the mouse cursor so it won't mess up Sikuli's screen scanning
unclutter -display $TARGET_DISPLAY -root -idle 0 >/dev/null 2>&1 &
}
start_vnc_server() {
check_dependencies x11vnc
VNC_SERVER_PORT="$(x11vnc -listen localhost -display ${TARGET_DISPLAY} \
-bg -nopw -forever 2>&1 | \
grep -m 1 "^PORT=[0-9]\+" | sed 's/^PORT=//')"
echo "VNC server running on: localhost:${VNC_SERVER_PORT}"
}
start_vnc_viewer() {
check_dependencies tigervnc-viewer
xtigervncviewer -nojpeg -viewonly localhost:${VNC_SERVER_PORT} 1>/dev/null 2>&1 &
}
capture_session() {
check_dependencies libvpx1
echo "Capturing guest display into ${CAPTURE_FILE}"
avconv -f x11grab -s 1024x768 -r 5 -i ${TARGET_DISPLAY}.0 -an \
-vcodec libvpx -y "${CAPTURE_FILE}" >/dev/null 2>&1 &
}
# main script
# Unset all environment variables used by this script to pass options
# to cucumber, except TMPDIR since we explicitly want to support
# setting it that way.
ARTIFACTS_BASE_URI=
CAPTURE=
CAPTURE_ALL=
LOG_FILE=
VNC_VIEWER=
VNC_SERVER=
INTERACTIVE_DEBUGGING=
KEEP_SNAPSHOTS=
SIKULI_RETRY_FINDFAILED=
ISO=
OLD_ISO=
LONGOPTS="artifacts-base-uri:,view,vnc-server-only,capture,capture-all,help,tmpdir:,keep-snapshots,retry-find,iso:,old-iso:,interactive-debugging"
OPTS=$(getopt -o "" --longoptions $LONGOPTS -n "${NAME}" -- "$@")
eval set -- "$OPTS"
while [ $# -gt 0 ]; do
case $1 in
--artifacts-base-uri)
shift
export ARTIFACTS_BASE_URI="${1}"
;;
--view)
VNC_VIEWER=yes
VNC_SERVER=yes
;;
--vnc-server-only)
VNC_VIEWER=
VNC_SERVER=yes
;;
--capture)
check_dependencies x264
export CAPTURE="yes"
;;
--capture-all)
check_dependencies x264
export CAPTURE="yes"
export CAPTURE_ALL="yes"
;;
--interactive-debugging)
export INTERACTIVE_DEBUGGING="yes"
;;
--keep-snapshots)
export KEEP_SNAPSHOTS="yes"
;;
--retry-find)
export SIKULI_RETRY_FINDFAILED="yes"
;;
--tmpdir)
shift
export TMPDIR="$(readlink -f $1)"
;;
--iso)
shift
export ISO="$(readlink -f $1)"
;;
--old-iso)
shift
export OLD_ISO="$(readlink -f $1)"
;;
--help)
usage
exit 0
;;
--)
shift
break
;;
esac
shift
done
trap "test_suite_cleanup" EXIT HUP INT QUIT TERM
check_dependencies ${GENERAL_DEPENDENCIES}
TARGET_DISPLAY=$(next_free_display)
start_xvfb
if [ -n "${VNC_SERVER:-}" ]; then
start_vnc_server
fi
if [ -n "${VNC_VIEWER:-}" ]; then
start_vnc_viewer
fi
export SIKULI_HOME="/usr/share/java"
export SIKULI_IMAGE_PATH="/srv/jenkins/cucumber/features/images/"
export RUBYLIB="/srv/jenkins"
export VM_XML_PATH="/srv/jenkins/cucumber/features/domains"
export DISPLAY=${TARGET_DISPLAY}
check_dependencies cucumber
# cludge ruby to stop buffering output
RUBY_STDOUT_SYNC=$TMPDIR/.stdout-sync.rb
echo STDOUT.sync = true > $RUBY_STDOUT_SYNC
export RUBYOPT="-r $RUBY_STDOUT_SYNC"
unset http_proxy
echo "PWD = $(pwd)"
[ -e features ] || ln -s /srv/jenkins/cucumber/features
cucumber ${@}
CAPTURE: false
CAPTURE_ALL: false
INTERACTIVE_DEBUGGING: false
MAX_NEW_TOR_CIRCUIT_RETRIES: 10
SIKULI_RETRY_FINDFAILED: false
TMPDIR: "/tmp/DebianToaster"
Unsafe_SSH_private_key: |
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAvMUNgUUM/kyuo26m+Xw7igG6zgGFMFbS3u8m5StGsJOn7zLi
J8P5Mml/R+4tdOS6owVU4RaZTPsNZZK/ClYmOPhmNvJ04pVChk2DZ8AARg/TANj3
qjKs3D+MeKbk1bt6EsA55kgGsTUky5Ti8cc2Wna25jqjagIiyM822PGG9mmI6/zL
YR6QLUizNaciXrRM3Q4R4sQkEreVlHeonPEiGUs9zx0swCpLtPM5UIYte1PVHgkw
ePsU6vM8UqVTK/VwtLLgLanXnsMFuzq7DTAXPq49+XSFNq4JlxbEF6+PQXZvYZ5N
eW00Gq7NSpPP8uoHr6f1J+mMxxnM85jzYtRx+QIDAQABAoIBAA8Bs1MlhCTrP67q
awfGYo1UGd+qq0XugREL/hGV4SbEdkNDzkrO/46MaHv1aVOzo0q2b8r9Gu7NvoDm
q51Mv/kjdizEFZq1tvYqT1n+H4dyVpnopbe4E5nmy2oECokbQFchRPkTnMSVrvko
OupxpdaHPX8MBlW1GcLRBlE00j/gfK1SXX5rcxkF5EHVND1b6iHddTPearDbU8yr
wga1XO6WeohAYzqmGtMD0zk6lOk0LmnTNG6WvHiFTAc/0yTiKub6rNOIEMS/82+V
l437H0hKcIN/7/mf6FpqRNPJTuhOVFf+L4G/ZQ8zHoMGVIbhuTiIPqZ/KMu3NaUF
R634jckCgYEA+jJ31hom/d65LfxWPkmiSkNTEOTfjbfcgpfc7sS3enPsYnfnmn5L
O3JJzAKShSVP8NVuPN5Mg5FGp9QLKrN3kV6QWQ3EnqeW748DXMU6zKGJQ5wo7ZVm
w2DhJ/3PAuBTL/5X4mjPQL+dr86Aq2JBDC7LHJs40I8O7UbhnsdMxKcCgYEAwSXc
3znAkAX8o2g37RiAl36HdONgxr2eaGK7OExp03pbKmoISw6bFbVpicBy6eTytn0A
2PuFcBKJRfKrViHyiE8UfAJ31JbUaxpg4bFF6UEszN4CmgKS8fnwEe1aX0qSjvkE
NQSuhN5AfykXY/1WVIaWuC500uB7Ow6M16RDyF8CgYEAqFTeNYlg5Hs+Acd9SukF
rItBTuN92P5z+NUtyuNFQrjNuK5Nf68q9LL/Hag5ZiVldHZUddVmizpp3C6Y2MDo
WEDUQ2Y0/D1rGoAQ1hDIb7bbAEcHblmPSzJaKirkZV4B+g9Yl7bGghypfggkn6o6
c3TkKLnybrdhZpjC4a3bY48CgYBnWRYdD27c4Ycz/GDoaZLs/NQIFF5FGVL4cdPR
pPl/IdpEEKZNWwxaik5lWedjBZFlWe+pKrRUqmZvWhCZruJyUzYXwM5Tnz0b7epm
+Q76Z1hMaoKj27q65UyymvkfQey3ucCpic7D45RJNjiA1R5rbfSZqqnx6BGoIPn1
rLxkKwKBgDXiWeUKJCydj0NfHryGBkQvaDahDE3Yigcma63b8vMZPBrJSC4SGAHJ
NWema+bArbaF0rKVJpwvpkZWGcr6qRn94Ts0kJAzR+VIVTOjB9sVwdxjadwWHRs5
kKnpY0tnSF7hyVRwN7GOsNDJEaFjCW7k4+55D2ZNBy2iN3beW8CZ
-----END RSA PRIVATE KEY-----
Unsafe_SSH_public_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8xQ2BRQz+TK6jbqb5fDuKAbrOAYUwVtLe7yblK0awk6fvMuInw/kyaX9H7i105LqjBVThFplM+w1lkr8KViY4+GY28nTilUKGTYNnwABGD9MA2PeqMqzcP4x4puTVu3oSwDnmSAaxNSTLlOLxxzZadrbmOqNqAiLIzzbY8Yb2aYjr/MthHpAtSLM1pyJetEzdDhHixCQSt5WUd6ic8SIZSz3PHSzAKku08zlQhi17U9UeCTB4+xTq8zxSpVMr9XC0suAtqdeewwW7OrsNMBc+rj35dIU2rgmXFsQXr49Bdm9hnk15bTQars1Kk8/y6gevp/Un6YzHGczzmPNi1HH5 amnesia@amnesia"
<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
<target dev='hdc' bus='sata'/>
<readonly/>
</disk>
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<memory unit='KiB'>1310720</memory>
<currentMemory unit='KiB'>1310720</currentMemory>
<vcpu>2</vcpu>
<os>
<type arch='x86_64' machine='pc-q35-2.8'>hvm</type>
<boot dev='cdrom'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<cpu mode='custom' match='exact'>
<model fallback='allow'>kvm64</model>
</cpu>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<controller type='usb' index='0' model='ich9-ehci1'/>
<controller type='usb' index='0' model='ich9-uhci1'/>
<controller type='usb' index='0' model='ich9-uhci2'/>
<controller type='usb' index='0' model='ich9-uhci3'/>
<controller type='sata' index='0'/>
<controller type='virtio-serial' index='0'/>
<interface type='network'>
<alias name='net0'/>
<!-- <mac address='52:54:00:ac:dd:ee'/> -->
<source network='lvcNET'/>
<model type='virtio'/>
<link state='up'/>
</interface>
<!-- FIXME need to uniquify the port, based on EXECUTOR_NUMBER -->
<serial type='tcp'>
<source mode="bind" host='127.0.0.1' service='1337'/>
<target port='0'/>
</serial>
<input type='tablet' bus='usb'/>
<channel type='spicevmc'>
<target type='virtio' name='com.redhat.spice.0'/>
</channel>
<graphics type='spice' port='-1' tlsPort='-1' autoport='yes'>
<mouse mode='client'/>
</graphics>
<sound model='ich6'/>
<video>
<model type='qxl' ram='65536' vram='131072' vgamem='16384' heads='1'/>
</video>
<memballoon model='virtio'/>
<rng model='virtio'>
<backend model='random'>/dev/random</backend>
</rng>
</devices>
</domain>
<network>
<forward mode='nat'/>
<bridge name='virbr10' stp='on' delay='0' />
<ip address='10.2.1.1' netmask='255.255.255.0'>
<dhcp>
<range start='10.2.1.2' end='10.2.1.254' />
<!-- <host mac="52:54:00:ac:dd:ee" name="amnesia" ip="10.2.1.2" /> -->
<!-- <host mac="52:54:00:11:22:33" name="amnesia" ip="10.2.1.3" /> -->
</dhcp>
</ip>
<ip family="ipv6" address="fc00::1" prefix="7" />
</network>
<disk type='file' device='disk'>
<driver name='qemu' type=''/>
<source file=''/>