[master 1/7] Move kickstart test support files into a separate directory.
dashea
installerbot-noreply at redhat.com
Thu Sep 3 22:08:45 UTC 2015
From: David Shea <dshea at redhat.com>
This way tests/kickstart_tests contains only the kickstart tests, the
shell scripts for the kickstart tests, functions.sh, and a scripts
directory that has everything else.
---
tests/Makefile.am | 5 +-
tests/kickstart_tests/kstest-runner | 309 ---------------------
tests/kickstart_tests/make-addon-pkgs.py | 119 --------
tests/kickstart_tests/proxy-auth.ks | 2 +-
tests/kickstart_tests/proxy-cmdline.ks | 2 +-
tests/kickstart_tests/proxy-common.ks | 79 ------
tests/kickstart_tests/proxy-kickstart.ks | 2 +-
tests/kickstart_tests/run_kickstart_tests.sh | 199 -------------
tests/kickstart_tests/run_one_ks.sh | 157 -----------
tests/kickstart_tests/run_report.sh | 26 --
tests/kickstart_tests/scripts/kstest-runner | 309 +++++++++++++++++++++
tests/kickstart_tests/scripts/make-addon-pkgs.py | 119 ++++++++
tests/kickstart_tests/scripts/proxy-common.ks | 79 ++++++
.../kickstart_tests/scripts/run_kickstart_tests.sh | 199 +++++++++++++
tests/kickstart_tests/scripts/run_one_ks.sh | 157 +++++++++++
tests/kickstart_tests/scripts/run_report.sh | 26 ++
16 files changed, 894 insertions(+), 895 deletions(-)
delete mode 100755 tests/kickstart_tests/kstest-runner
delete mode 100755 tests/kickstart_tests/make-addon-pkgs.py
delete mode 100644 tests/kickstart_tests/proxy-common.ks
delete mode 100755 tests/kickstart_tests/run_kickstart_tests.sh
delete mode 100755 tests/kickstart_tests/run_one_ks.sh
delete mode 100755 tests/kickstart_tests/run_report.sh
create mode 100755 tests/kickstart_tests/scripts/kstest-runner
create mode 100755 tests/kickstart_tests/scripts/make-addon-pkgs.py
create mode 100644 tests/kickstart_tests/scripts/proxy-common.ks
create mode 100755 tests/kickstart_tests/scripts/run_kickstart_tests.sh
create mode 100755 tests/kickstart_tests/scripts/run_one_ks.sh
create mode 100755 tests/kickstart_tests/scripts/run_report.sh
diff --git a/tests/Makefile.am b/tests/Makefile.am
index f3c1e80..c55e082 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -53,8 +53,7 @@ dist_check_SCRIPTS = $(srcdir)/glade/*.py \
install/run_install_test.sh \
$(srcdir)/kickstart_tests/*.ks \
$(srcdir)/kickstart_tests/*.sh \
- $(srcdir)/kickstart_tests/*.py \
- $(srcdir)/kickstart_tests/kstest-runner \
+ $(srcdir)/kickstart_tests/scripts/* \
$(srcdir)/gui/*.ks \
$(srcdir)/gui/*.sh \
$(srcdir)/gui/inside/*.py \
@@ -72,7 +71,7 @@ TESTS = nosetests.sh \
gettext/contexts.py \
storage/run_storage_tests.py \
glade/run_glade_tests.sh \
- kickstart_tests/run_kickstart_tests.sh
+ kickstart_tests/scripts/run_kickstart_tests.sh
clean-local:
-rm -rf pylint/.pylint.d
diff --git a/tests/kickstart_tests/kstest-runner b/tests/kickstart_tests/kstest-runner
deleted file mode 100755
index 196aa36..0000000
--- a/tests/kickstart_tests/kstest-runner
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/python3
-#
-# kstest-runner - LMC-like program that only does what's necessary for running
-# kickstart-based tests in anaconda
-#
-# Copyright (C) 2011-2015 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Author(s): Brian C. Lane <bcl at redhat.com>
-# Chris Lumens <clumens at redhat.com>
-#
-import logging
-log = logging.getLogger("livemedia-creator")
-
-import os
-import sys
-import uuid
-import tempfile
-import subprocess
-from time import sleep
-import argparse
-
-# Use the Lorax treebuilder branch for iso creation
-from pylorax.treebuilder import udev_escape
-from pylorax.executils import execWithRedirect
-
-from pylorax import setup_logging
-from pylorax.monitor import LogMonitor
-from pylorax.mount import IsoMountpoint
-
-import libvirt
-
-class InstallError(Exception):
- pass
-
-class VirtualInstall(object):
- """
- Run virt-install using an iso and a kickstart
- """
- def __init__(self, iso, ks_paths, disk_paths,
- kernel_args=None, memory=1024, vnc=None,
- log_check=None, virtio_host="127.0.0.1", virtio_port=6080):
- """
- Start the installation
-
- :param iso: Information about the iso to use for the installation
- :type iso: IsoMountpoint
- :param list ks_paths: Paths to kickstart files. All are injected, the
- first one is the one executed.
- :param list disk_paths: Paths to pre-existing disk images.
- :param str kernel_args: Extra kernel arguments to pass on the kernel cmdline
- :param int memory: Amount of RAM to assign to the virt, in MiB
- :param str vnc: Arguments to pass to virt-install --graphics
- :param log_check: Method that returns True if the installation fails
- :type log_check: method
- :param str virtio_host: Hostname to connect virtio log to
- :param int virtio_port: Port to connect virtio log to
- """
- self.virt_name = "LiveOS-"+str(uuid.uuid4())
- # add --graphics none later
- # add whatever serial cmds are needed later
- args = ["-n", self.virt_name,
- "-r", str(memory),
- "--noreboot",
- "--noautoconsole"]
-
- args.append("--graphics")
- if vnc:
- args.append(vnc)
- else:
- args.append("none")
-
- for ks in ks_paths:
- args.append("--initrd-inject")
- args.append(ks)
-
- for disk in disk_paths:
- args.append("--disk")
- args.append("path={0}".format(disk))
-
- if iso.stage2:
- disk_opts = "path={0},device=cdrom,readonly=on,shareable=on".format(iso.iso_path)
- args.append("--disk")
- args.append(disk_opts)
-
- extra_args = "ks=file:/{0}".format(os.path.basename(ks_paths[0]))
- if not vnc:
- extra_args += " inst.cmdline"
- if kernel_args:
- extra_args += " " + kernel_args
- if iso.stage2:
- extra_args += " stage2=hd:CDLABEL={0}".format(udev_escape(iso.label))
- args.append("--extra-args")
- args.append(extra_args)
-
- args.append("--location")
- args.append(iso.mount_dir)
-
- channel_args = "tcp,host={0}:{1},mode=connect,target_type=virtio" \
- ",name=org.fedoraproject.anaconda.log.0".format(
- virtio_host, virtio_port)
- args.append("--channel")
- args.append(channel_args)
-
- log.info("Running virt-install.")
- try:
- execWithRedirect("virt-install", args, raise_err=True)
- except subprocess.CalledProcessError as e:
- raise InstallError("Problem starting virtual install: %s" % e)
-
- conn = libvirt.openReadOnly(None)
- dom = conn.lookupByName(self.virt_name)
-
- # TODO: If vnc has been passed, we should look up the port and print that
- # for the user at this point
- while dom.isActive() and not log_check():
- sys.stdout.write(".")
- sys.stdout.flush()
- sleep(10)
- print()
-
- if log_check():
- log.info("Installation error detected. See logfile.")
- else:
- log.info("Install finished. Or at least virt shut down.")
-
- def destroy(self, poolName):
- """
- Make sure the virt has been shut down and destroyed
-
- Could use libvirt for this instead.
- """
- log.info("Shutting down %s", self.virt_name)
- subprocess.call(["virsh", "destroy", self.virt_name])
- subprocess.call(["virsh", "undefine", self.virt_name])
- subprocess.call(["virsh", "pool-destroy", poolName])
- subprocess.call(["virsh", "pool-undefine", poolName])
-
-def virt_install(opts, install_log):
- """
- Use virt-install to install to a disk image
-
- :param opts: options passed to livemedia-creator
- :type opts: argparse options
- :param str install_log: The path to write the log from virt-install
-
- This uses virt-install with a boot.iso and a kickstart to create a disk
- image.
- """
- iso_mount = IsoMountpoint(opts.iso, opts.location)
- log_monitor = LogMonitor(install_log, timeout=opts.timeout)
-
- kernel_args = ""
- if opts.kernel_args:
- kernel_args += opts.kernel_args
- if opts.proxy:
- kernel_args += " proxy=" + opts.proxy
-
- try:
- virt = VirtualInstall(iso_mount, opts.ks, opts.disk_paths,
- kernel_args, opts.ram, opts.vnc,
- log_check = log_monitor.server.log_check,
- virtio_host = log_monitor.host,
- virtio_port = log_monitor.port)
-
- virt.destroy(os.path.basename(opts.tmp))
- log_monitor.shutdown()
- except InstallError as e:
- log.error("VirtualInstall failed: %s", e)
- raise
- finally:
- log.info("unmounting the iso")
- iso_mount.umount()
-
- if log_monitor.server.log_check():
- if not log_monitor.server.error_line and opts.timeout:
- msg = "virt_install failed due to timeout"
- else:
- msg = "virt_install failed on line: %s" % log_monitor.server.error_line
- raise InstallError(msg)
-
-
-def make_image(opts):
- """
- Install to a disk image
-
- :param opts: options passed to livemedia-creator
- :type opts: argparse options
- :param str ks: Path to the kickstart to use for the installation
-
- Use virt-install or anaconda to install to a disk image.
- """
- try:
- install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
- log.info("install_log = %s", install_log)
-
- virt_install(opts, install_log)
- except InstallError as e:
- log.error("Install failed: %s", e)
-
- if not opts.keep_image:
- log.info("Removing bad disk image")
-
- for image in opts.disk_paths:
- if os.path.exists(image):
- os.unlink(image)
-
- raise
-
- log.info("Disk Image install successful")
-
-def main():
- parser = argparse.ArgumentParser(description="Run anaconda's kickstart-based tests",
- fromfile_prefix_chars="@")
-
- parser.add_argument("--iso", type=os.path.abspath,
- help="Anaconda installation .iso path to use for virt-install")
- parser.add_argument("--ks", action="append", type=os.path.abspath,
- help="Kickstart file defining the install.")
- parser.add_argument("--disk", action="append", type=os.path.abspath, dest="disk_paths",
- help="Pre-existing disk image to use for destination.")
-
- parser.add_argument("--proxy",
- help="proxy URL to use for the install")
- parser.add_argument("--location", default=None, type=os.path.abspath,
- help="location of iso directory tree with initrd.img "
- "and vmlinuz. Used to run virt-install with a "
- "newer initrd than the iso.")
-
- parser.add_argument("--logfile", default="./livemedia.log",
- type=os.path.abspath,
- help="Path to logfile")
- parser.add_argument("--tmp", default="/var/tmp", type=os.path.abspath,
- help="Top level temporary directory")
-
- image_group = parser.add_argument_group("disk/fs image arguments")
- image_group.add_argument("--keep-image", action="store_true",
- help="Keep raw disk image after .iso creation")
-
- # Group of arguments to pass to virt-install
- virt_group = parser.add_argument_group("virt-install arguments")
- virt_group.add_argument("--ram", metavar="MEMORY", type=int, default=1024,
- help="Memory to allocate for installer in megabytes.")
- virt_group.add_argument("--vnc",
- help="Passed to --graphics command")
- virt_group.add_argument("--kernel-args",
- help="Additional argument to pass to the installation kernel")
-
- parser.add_argument("--timeout", default=None, type=int,
- help="Cancel installer after X minutes")
-
- opts = parser.parse_args()
-
- setup_logging(opts.logfile, log)
-
- log.debug( opts )
-
- # Check for invalid combinations of options, print all the errors and exit.
- errors = []
- if opts.ks and not os.path.exists(opts.ks[0]):
- errors.append("kickstart file (%s) is missing." % opts.ks[0])
-
- if opts.iso and not os.path.exists(opts.iso):
- errors.append("The iso %s is missing." % opts.iso)
-
- if not opts.iso:
- errors.append("virt install needs an install iso.")
-
- if not os.path.exists("/usr/bin/virt-install"):
- errors.append("virt-install needs to be installed.")
-
- if os.getuid() != 0:
- errors.append("You need to run this as root")
-
- if errors:
- list(log.error(e) for e in errors)
- sys.exit(1)
-
- tempfile.tempdir = opts.tmp
-
- # Make the image.
- try:
- make_image(opts)
- except InstallError as e:
- log.error("ERROR: Image creation failed: %s", e)
- sys.exit(1)
-
- log.info("SUMMARY")
- log.info("-------")
- log.info("Logs are in %s", os.path.abspath(os.path.dirname(opts.logfile)))
- log.info("Disk image(s) at %s", ",".join(opts.disk_paths))
- log.info("Results are in %s", opts.tmp)
-
- sys.exit( 0 )
-
-if __name__ == '__main__':
- main()
diff --git a/tests/kickstart_tests/make-addon-pkgs.py b/tests/kickstart_tests/make-addon-pkgs.py
deleted file mode 100755
index e38cb7a..0000000
--- a/tests/kickstart_tests/make-addon-pkgs.py
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/python3
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): David Shea <dshea at redhat.com>
-
-# This script creates all the packages used by nfs-repo-and-addon.ks.
-# The packages are created in two directories, http and nfs. After all the rpms
-# are made just copy everything to the locations set in $KSTEST_ADDON_HTTP_REPO
-# and $KSTEST_ADDON_NFS_REPO.
-#
-# This script imports things from tests/lib/mkdud.py, so tests/lib needs to be
-# in $PYTHONPATH.
-
-# Ignore interuptible calls
-# pylint: disable=interruptible-system-call
-
-import os
-from subprocess import check_call
-from mkdud import make_rpm
-import rpmfluff
-
-# Start with http
-os.mkdir('http')
-
-# Empty package to be added to @core
-pkg = rpmfluff.SimpleRpmBuild('testpkg-http-core', '1.0', '1')
-make_rpm(pkg, 'http')
-
-# Another empty package
-pkg = rpmfluff.SimpleRpmBuild('testpkg-http-addon', '1.0', '1')
-make_rpm(pkg, 'http')
-
-# Three packages with marker files
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share1', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-1/http',
- rpmfluff.SourceFile('http', ''))
-make_rpm(pkg, 'http')
-
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share2', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-2/http',
- rpmfluff.SourceFile('http', ''))
-make_rpm(pkg, 'http')
-
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share3', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-3/http',
- rpmfluff.SourceFile('http', ''))
-make_rpm(pkg, 'http')
-
-# Create a comps file and create the repo
-with open('http/comps.xml', 'wt') as comps:
- comps.write('''<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
-<comps>
- <group>
- <id>core</id>
- <packagelist>
- <packagereq type="mandatory">testpkg-http-core</packagereq>
- </packagelist>
- </group>
-</comps>''')
-
-check_call(['createrepo_c', '-g', 'comps.xml', 'http'])
-
-# Do the same thing again for nfs
-os.mkdir('nfs')
-
-# Empty package to be added to @core
-pkg = rpmfluff.SimpleRpmBuild('testpkg-nfs-core', '1.0', '1')
-make_rpm(pkg, 'nfs')
-
-# Another empty package
-pkg = rpmfluff.SimpleRpmBuild('testpkg-nfs-addon', '1.0', '1')
-make_rpm(pkg, 'nfs')
-
-# Three packages with marker files
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share1', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-1/nfs',
- rpmfluff.SourceFile('nfs', ''))
-make_rpm(pkg, 'nfs')
-
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share2', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-2/nfs',
- rpmfluff.SourceFile('nfs', ''))
-make_rpm(pkg, 'nfs')
-
-pkg = rpmfluff.SimpleRpmBuild('testpkg-share3', '1.0', '1')
-pkg.add_installed_file('/usr/share/testpkg-3/nfs',
- rpmfluff.SourceFile('nfs', ''))
-make_rpm(pkg, 'nfs')
-
-# Create a comps file and create the repo
-with open('nfs/comps.xml', 'wt') as comps:
- comps.write('''<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
-<comps>
- <group>
- <id>core</id>
- <packagelist>
- <packagereq type="mandatory">testpkg-nfs-core</packagereq>
- </packagelist>
- </group>
-</comps>''')
-
-check_call(['createrepo_c', '-g', 'comps.xml', 'nfs'])
diff --git a/tests/kickstart_tests/proxy-auth.ks b/tests/kickstart_tests/proxy-auth.ks
index 199530f..874dd45 100644
--- a/tests/kickstart_tests/proxy-auth.ks
+++ b/tests/kickstart_tests/proxy-auth.ks
@@ -19,7 +19,7 @@ shutdown
%end
# Start the proxy server
-%include proxy-common.ks
+%include scripts/proxy-common.ks
# Set a password on the proxy server
%pre
diff --git a/tests/kickstart_tests/proxy-cmdline.ks b/tests/kickstart_tests/proxy-cmdline.ks
index 8252d43..7519724 100644
--- a/tests/kickstart_tests/proxy-cmdline.ks
+++ b/tests/kickstart_tests/proxy-cmdline.ks
@@ -18,7 +18,7 @@ shutdown
%end
# Run the proxy
-%include proxy-common.ks
+%include scripts/proxy-common.ks
%post --nochroot
# Look for the following as evidence that a proxy was used:
diff --git a/tests/kickstart_tests/proxy-common.ks b/tests/kickstart_tests/proxy-common.ks
deleted file mode 100644
index a95097a..0000000
--- a/tests/kickstart_tests/proxy-common.ks
+++ /dev/null
@@ -1,79 +0,0 @@
-# Start a super-simple proxy server on localhost
-# A list of proxied requests will be saved to /tmp/proxy.log
-%pre --erroronfail
-# Write the proxy script to a file in /tmp
-cat - << "EOF" > /tmp/proxy-test.py
-from http.server import SimpleHTTPRequestHandler
-import socketserver
-from urllib.request import urlopen
-import os
-from base64 import b64decode
-
-import logging
-log = logging.getLogger("proxy_test")
-log_handler = logging.FileHandler('/tmp/proxy.log')
-log.setLevel(logging.INFO)
-log.addHandler(log_handler)
-
-class ProxyHandler(SimpleHTTPRequestHandler):
- def send_authenticate(self):
- self.send_response(407)
- self.send_header('Proxy-Authenticate', 'Basic realm=proxy-test')
- self.end_headers()
-
- def authenticate(self):
- # If there is no /tmp/proxy.password file, anything goes
- if not os.path.exists('/tmp/proxy.password'):
- return True
-
- # If there is no Authorization header, send a 407, Proxy authentication required
- authorization = self.headers['Proxy-Authorization']
- if not authorization:
- self.send_authenticate()
- return False
-
- # Parse the Authorization header. It should be "Basic" followed
- # user:pass encoded in base64
- if not authorization.startswith('Basic'):
- self.send_authenticate()
- return False
-
- try:
- client_auth = b64decode(authorization.split()[1])
- except IndexError:
- self.send_authenticate()
- return False
-
- with open('/tmp/proxy.password', 'rb') as f:
- server_auth = f.readline().strip()
-
- if client_auth != server_auth:
- self.send_authenticate()
- return False
-
- return True
-
- def do_GET(self):
- if not self.authenticate():
- return
-
- # Log the path then proxy the request via urllib
- log.info(self.path)
- data = urlopen(self.path).read()
- self.send_response(200)
- self.send_header('Content-Length', str(len(data)))
- self.end_headers()
- self.wfile.write(data)
-
-class ProxyServer(socketserver.TCPServer):
- allow_reuse_address = True
-
- def __init__(self):
- socketserver.TCPServer.__init__(self, ('', 8080), ProxyHandler)
-
-ProxyServer().serve_forever()
-EOF
-
-# Run the server in the background and exit
-python3 /tmp/proxy-test.py > /dev/null 2>&1 &
-%end
diff --git a/tests/kickstart_tests/proxy-kickstart.ks b/tests/kickstart_tests/proxy-kickstart.ks
index 317ef63..6708c88 100644
--- a/tests/kickstart_tests/proxy-kickstart.ks
+++ b/tests/kickstart_tests/proxy-kickstart.ks
@@ -19,7 +19,7 @@ shutdown
%end
# Start the proxy server
-%include proxy-common.ks
+%include scripts/proxy-common.ks
%post --nochroot
# Look for the following as evidence that a proxy was used:
diff --git a/tests/kickstart_tests/run_kickstart_tests.sh b/tests/kickstart_tests/run_kickstart_tests.sh
deleted file mode 100755
index 0b03a2f..0000000
--- a/tests/kickstart_tests/run_kickstart_tests.sh
+++ /dev/null
@@ -1,199 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2014, 2015 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Chris Lumens <clumens at redhat.com>
-
-# This script runs the entire kickstart_tests suite. It is an interface
-# between "make check" (which is why it takes environment variables instead
-# of arguments) and livemedia-creator. Each test consists of a kickstart
-# file that specifies most everything about the installation, and a shell
-# script that does validation and specifies kernel boot parameters. lmc
-# then fires up a VM and watches for tracebacks or stuck installs.
-#
-# A boot ISO is required, which should be specified with TEST_BOOT_ISO=.
-#
-# The number of jobs corresponds to the number of VMs that will be started
-# simultaneously. Each one wants about 2 GB of memory. The default is
-# two simultaneous jobs, but you can control this with TEST_JOBS=. It is
-# suggested you not run out of memory.
-#
-# You can control what logs are held onto after the test is complete via the
-# KEEPIT= variable, explained below. By default, nothing is kept.
-#
-# Finally, you can run tests across multiple computers at the same time by
-# putting all the hostnames into TEST_REMOTES= as a space separated list.
-# Do not add localhost manually, as it will always be added for you. You
-# must create a user named kstest on each remote system, allow that user to
-# sudo to root for purposes of running livemedia-creator, and have ssh keys
-# set up so that the user running this script can login to the remote systems
-# as kstest without a password. TEST_JOBS= applies on a per-system basis.
-# KEEPIT= controls how much will be kept on the master system (where "make
-# check" is run). All results will be removed from the slave systems.
-
-# The boot.iso location can come from one of two different places:
-# (1) $TEST_BOOT_ISO, if this script is being called from "make check"
-# (2) The command line, if this script is being called directly. That will
-# be checked below.
-IMAGE="${TEST_BOOT_ISO}"
-
-# Possible values for this parameter:
-# 0 - Keep nothing (the default)
-# 1 - Keep log files
-# 2 - Keep log files and disk images (will take up a lot of space)
-KEEPIT=${KEEPIT:-0}
-
-TESTTYPE=""
-
-while getopts ":i:k:t:" opt; do
- case $opt in
- i)
- # If this wasn't set from the environment, set it from the command line
- # here. If it never gets set, we'll catch that later and error out.
- IMAGE=$OPTARG
- ;;
-
- k)
- # This overrides either the $KEEPIT environment variable, or the default
- # setting from above.
- KEEPIT=$OPTARG
- ;;
-
- t)
- # Only run tests that have TESTTYPE=<this value> in them. Tests can have
- # more than one type. We'll do a pretty stupid test for it.
- TESTTYPE=$OPTARG
- ;;
-
- *)
- echo "Usage: run_kickstart_tests.sh [-i boot.iso] [-k 0|1|2] [tests]"
- exit 1
- ;;
- esac
-done
-
-if [[ ! -e "${IMAGE}" ]]; then
- echo "Required boot.iso does not exist; skipping."
- exit 77
-fi
-
-shift $((OPTIND - 1))
-
-# This is for environment variables that parallel needs to pass to
-# remote systems.
-#
-# NOTE: You will also need to add these to the list in /etc/sudoers
-# if you are using env_reset there, or they will not get passed from
-# this script to parallel.
-env_args=$(printenv | while read line; do
- v="$(echo $line | cut -d'=' -f1)"
- [[ "${v}" =~ ^KSTEST_ ]] && echo "--env ${v}"
- done)
-
-# We get the list of tests from one of two places:
-# (1) From the command line, all the other arguments.
-# (2) By applying any TESTTYPE given on the command line.
-# (3) From finding all scripts in kickstart_tests/ that are executable and are
-# not support files.
-if [[ $# != 0 ]]; then
- tests="$*"
-else
- tests=$(find kickstart_tests -name '*sh' -a -perm -o+x -a \! -wholename 'kickstart_tests/run_*.sh')
-
- newtests=""
- if [[ "$TESTTYPE" != "" ]]; then
- for f in ${tests}; do
- if [[ "$(grep "TESTTYPE=" ${f})" =~ "${TESTTYPE}" ]]; then
- newtests+="${f} "
- fi
- done
-
- tests="${newtests}"
- fi
-fi
-
-if [[ "${tests}" == "" ]]; then
- echo "No tests provided; skipping."
- exit 77
-fi
-
-if [[ "$TEST_REMOTES" != "" ]]; then
- _IMAGE=kickstart_tests/$(basename ${IMAGE})
-
- # (1) Copy everything to the remote systems. We do this ourselves because
- # parallel doesn't like globs, and we need to put the boot image somewhere
- # that qemu on the remote systems can read.
- for remote in ${TEST_REMOTES}; do
- scp -r kickstart_tests kstest@${remote}:
- scp ${IMAGE} kstest@${remote}:kickstart_tests/
- done
-
- # (1a) We also need to copy the provided image to under kickstart_tests/ on
- # the local system too. This is because parallel will attempt to run the
- # same command line on every system and that requires the image to also be
- # in the same location.
- cp ${IMAGE} ${_IMAGE}
-
- # (2) Run parallel. We always add the local system to the list of machines
- # being passed to parallel. Don't add it yourself.
- remote_args="--sshlogin :"
- for remote in ${TEST_REMOTES}; do
- remote_args="${remote_args} --sshlogin kstest@${remote}"
- done
-
- parallel --no-notice ${remote_args} \
- ${env_args} --jobs ${TEST_JOBS:-2} \
- sudo PYTHONPATH=$PYTHONPATH kickstart_tests/run_one_ks.sh -i ${_IMAGE} -k ${KEEPIT} {} ::: ${tests}
- rc=$?
-
- # (3) Get all the results back from the remote systems, which will have already
- # applied the KEEPIT setting. However if KEEPIT is 0 (meaning, don't save
- # anything) there's no point in trying. We do this ourselves because, again,
- # parallel doesn't like globs.
- #
- # We also need to clean up the stuff we copied over in step 1, and then clean up
- # the results from the remotes too. We don't want to keep things scattered all
- # over the place.
- for remote in ${TEST_REMOTES}; do
- if [[ ${KEEPIT} > 0 ]]; then
- scp -r kstest@${remote}:/var/tmp/kstest-\* /var/tmp/
- fi
-
- ssh kstest@${remote} sudo rm -rf kickstart_tests /var/tmp/kstest-\*
- done
-
- # (3a) And then also remove the copy of the image we made earlier.
- rm ${_IMAGE}
-
- # (4) Exit the subshell defined by "find ... | " way up at the top. The exit
- # code will be caught outside and converted into the overall exit code.
- exit ${rc}
-else
- parallel --no-notice ${env_args} --jobs ${TEST_JOBS:-2} \
- sudo PYTHONPATH=$PYTHONPATH kickstart_tests/run_one_ks.sh -i ${IMAGE} -k ${KEEPIT} {} ::: ${tests}
-
- # For future expansion - any cleanup code can go in between the variable
- # setting and the exit, like in the other branch of the if-else above.
- rc=$?
- exit ${rc}
-fi
-
-# Catch the exit code of the subshell and return it. This is structured for
-# future expansion, too. Any extra global cleanup code can go in between the
-# variable setting and the exit.
-rc=$?
-exit ${rc}
diff --git a/tests/kickstart_tests/run_one_ks.sh b/tests/kickstart_tests/run_one_ks.sh
deleted file mode 100755
index cf48f4b..0000000
--- a/tests/kickstart_tests/run_one_ks.sh
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2015 Red Hat, Inc.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions of
-# the GNU General Public License v.2, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY expressed or implied, including the implied warranties of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details. You should have received a copy of the
-# GNU General Public License along with this program; if not, write to the
-# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
-# source code or documentation are not subject to the GNU General Public
-# License and may only be used or replicated with the express permission of
-# Red Hat, Inc.
-#
-# Red Hat Author(s): Chris Lumens <clumens at redhat.com>
-
-# This script runs a single kickstart test on a single system. It takes
-# command line arguments instead of environment variables because it is
-# designed to be driven by run_kickstart_tests.sh via parallel. It is
-# not for direct use, though as long as you pass the right arguments there's
-# no reason it couldn't work.
-
-# Possible return values:
-# 0 - Everything worked
-# 1 - Test failed for unspecified reasons
-# 2 - Test failed due to time out
-# 77 - Something needed by the test doesn't exist, so skip
-
-IMAGE=
-KEEPIT=0
-
-cleanup() {
- d=$1
-
- # Always remove the copy of the boot.iso.
- rm ${d}/$(basename ${IMAGE})
-
- if [[ ${KEEPIT} == 2 ]]; then
- return
- elif [[ ${KEEPIT} == 1 ]]; then
- rm -f ${d}/disk-*.img ${d}/*ks
- elif [[ ${KEEPIT} == 0 ]]; then
- rm -rf ${d}
- fi
-}
-
-runone() {
- t=$1
-
- export KSTESTDIR=$(pwd)/kickstart_tests
-
- ks=${t/.sh/.ks}
- . $t
-
- name=$(basename ${t%.sh})
-
- echo
- echo ===========================================================================
- echo ${ks} on $(hostname)
- echo ===========================================================================
-
- # qemu user needs to be able to read the directory and the boot.iso, so put that
- # into this directory as well. It will get deleted later, regardless of the
- # KEEPIT setting.
- tmpdir=$(mktemp -d --tmpdir=/var/tmp kstest-${name}.XXXXXXXX)
- chmod 755 ${tmpdir}
- cp ${IMAGE} ${tmpdir}
-
- ksfile=$(prepare ${ks} ${tmpdir})
- if [[ $? != 0 ]]; then
- echo RESULT:${name}:FAILED:Test prep failed: ${ksfile}
- cleanup ${tmpdir}
- return 1
- fi
-
- kargs=$(kernel_args)
- if [[ "${kargs}" != "" ]]; then
- kargs="--kernel-args \"$kargs\""
- fi
-
- disks=$(prepare_disks ${tmpdir})
- disk_args=$(for d in $disks; do echo --disk $d; done)
-
- echo "PYTHONPATH=$PYTHONPATH"
- eval ${KSTESTDIR}/kstest-runner ${kargs} \
- --iso "${tmpdir}/$(basename ${IMAGE})" \
- --ks ${ksfile} \
- --tmp ${tmpdir} \
- --logfile ${tmpdir}/livemedia.log \
- --ram 2048 \
- --vnc vnc \
- --timeout 60 \
- ${disk_args}
- if [[ -f ${tmpdir}/virt-install.log && "$(grep CRIT ${tmpdir}/virt-install.log)" != "" ]]; then
- echo RESULT:${name}:FAILED:$(grep CRIT ${tmpdir}/virt-install.log)
- cleanup ${tmpdir}
- return 1
- elif [[ -f ${tmpdir}/livemedia.log ]]; then
- if [[ "$(grep 'due to timeout' ${tmpdir}/livemedia.log)" != "" ]]; then
- echo RESULT:${name}:FAILED:Test timed out.
- cleanup ${tmpdir}
- return 2
- fi
-
- result=$(validate ${tmpdir})
- if [[ $? != 0 ]]; then
- echo RESULT:${name}:FAILED:"${result}"
- cleanup ${tmpdir}
- return 1
- fi
- fi
-
- echo RESULT:${name}:SUCCESS
- cleanup ${tmpdir}
- return 0
-}
-
-# Have to be root to run this test, as it requires creating disk images.
-if [[ ${EUID} != 0 ]]; then
- echo "You must be root to run this test."
- exit 77
-fi
-
-while getopts ":i:k:" opt; do
- case $opt in
- i)
- IMAGE=$OPTARG
- ;;
-
- k)
- KEEPIT=$OPTARG
- ;;
-
- *)
- echo "Usage: run_one_ks.sh -i ISO [-k KEEPIT] ks-test.sh"
- exit 1
- ;;
- esac
-done
-
-shift $((OPTIND - 1))
-
-if [[ ! -e "${IMAGE}" ]]; then
- echo "Required boot.iso does not exist."
- exit 77
-fi
-
-if [[ $# == 0 || ! -x $1 ]]; then
- echo "Test not provided or is not executable."
- exit 1
-fi
-
-runone $1
diff --git a/tests/kickstart_tests/run_report.sh b/tests/kickstart_tests/run_report.sh
deleted file mode 100755
index b62b128..0000000
--- a/tests/kickstart_tests/run_report.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/gawk -f
-
-BEGIN {
- printf("\n\n\n%-30s | %-10s | %s\n", "TEST", "RESULT", "EXPLANATION");
- printf("-------------------------------+------------+--------------------------------------------------------\n");
- FS=":"
-}
-/^RESULT:/ { if ($4 == "Test timed out.") {
- result = "TIMED OUT";
- explanation = "";
- } else if (match($0, "Traceback")) {
- result = "FAILED";
- explanation = "Traceback";
- } else if (match($0, "SUCCESS")) {
- result = $3;
- explanation = "";
- } else {
- result = $3;
- explanation = substr($0, index($0, $4), 55);
- }
-
- printf("%-30s | %-10s | %s\n", $2, result, explanation);
- }
-END {
- printf("\n\n");
-}
diff --git a/tests/kickstart_tests/scripts/kstest-runner b/tests/kickstart_tests/scripts/kstest-runner
new file mode 100755
index 0000000..196aa36
--- /dev/null
+++ b/tests/kickstart_tests/scripts/kstest-runner
@@ -0,0 +1,309 @@
+#!/usr/bin/python3
+#
+# kstest-runner - LMC-like program that only does what's necessary for running
+# kickstart-based tests in anaconda
+#
+# Copyright (C) 2011-2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Author(s): Brian C. Lane <bcl at redhat.com>
+# Chris Lumens <clumens at redhat.com>
+#
+import logging
+log = logging.getLogger("livemedia-creator")
+
+import os
+import sys
+import uuid
+import tempfile
+import subprocess
+from time import sleep
+import argparse
+
+# Use the Lorax treebuilder branch for iso creation
+from pylorax.treebuilder import udev_escape
+from pylorax.executils import execWithRedirect
+
+from pylorax import setup_logging
+from pylorax.monitor import LogMonitor
+from pylorax.mount import IsoMountpoint
+
+import libvirt
+
+class InstallError(Exception):
+ pass
+
+class VirtualInstall(object):
+ """
+ Run virt-install using an iso and a kickstart
+ """
+ def __init__(self, iso, ks_paths, disk_paths,
+ kernel_args=None, memory=1024, vnc=None,
+ log_check=None, virtio_host="127.0.0.1", virtio_port=6080):
+ """
+ Start the installation
+
+ :param iso: Information about the iso to use for the installation
+ :type iso: IsoMountpoint
+ :param list ks_paths: Paths to kickstart files. All are injected, the
+ first one is the one executed.
+ :param list disk_paths: Paths to pre-existing disk images.
+ :param str kernel_args: Extra kernel arguments to pass on the kernel cmdline
+ :param int memory: Amount of RAM to assign to the virt, in MiB
+ :param str vnc: Arguments to pass to virt-install --graphics
+ :param log_check: Method that returns True if the installation fails
+ :type log_check: method
+ :param str virtio_host: Hostname to connect virtio log to
+ :param int virtio_port: Port to connect virtio log to
+ """
+ self.virt_name = "LiveOS-"+str(uuid.uuid4())
+ # add --graphics none later
+ # add whatever serial cmds are needed later
+ args = ["-n", self.virt_name,
+ "-r", str(memory),
+ "--noreboot",
+ "--noautoconsole"]
+
+ args.append("--graphics")
+ if vnc:
+ args.append(vnc)
+ else:
+ args.append("none")
+
+ for ks in ks_paths:
+ args.append("--initrd-inject")
+ args.append(ks)
+
+ for disk in disk_paths:
+ args.append("--disk")
+ args.append("path={0}".format(disk))
+
+ if iso.stage2:
+ disk_opts = "path={0},device=cdrom,readonly=on,shareable=on".format(iso.iso_path)
+ args.append("--disk")
+ args.append(disk_opts)
+
+ extra_args = "ks=file:/{0}".format(os.path.basename(ks_paths[0]))
+ if not vnc:
+ extra_args += " inst.cmdline"
+ if kernel_args:
+ extra_args += " " + kernel_args
+ if iso.stage2:
+ extra_args += " stage2=hd:CDLABEL={0}".format(udev_escape(iso.label))
+ args.append("--extra-args")
+ args.append(extra_args)
+
+ args.append("--location")
+ args.append(iso.mount_dir)
+
+ channel_args = "tcp,host={0}:{1},mode=connect,target_type=virtio" \
+ ",name=org.fedoraproject.anaconda.log.0".format(
+ virtio_host, virtio_port)
+ args.append("--channel")
+ args.append(channel_args)
+
+ log.info("Running virt-install.")
+ try:
+ execWithRedirect("virt-install", args, raise_err=True)
+ except subprocess.CalledProcessError as e:
+ raise InstallError("Problem starting virtual install: %s" % e)
+
+ conn = libvirt.openReadOnly(None)
+ dom = conn.lookupByName(self.virt_name)
+
+ # TODO: If vnc has been passed, we should look up the port and print that
+ # for the user at this point
+ while dom.isActive() and not log_check():
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ sleep(10)
+ print()
+
+ if log_check():
+ log.info("Installation error detected. See logfile.")
+ else:
+ log.info("Install finished. Or at least virt shut down.")
+
+ def destroy(self, poolName):
+ """
+ Make sure the virt has been shut down and destroyed
+
+ Could use libvirt for this instead.
+ """
+ log.info("Shutting down %s", self.virt_name)
+ subprocess.call(["virsh", "destroy", self.virt_name])
+ subprocess.call(["virsh", "undefine", self.virt_name])
+ subprocess.call(["virsh", "pool-destroy", poolName])
+ subprocess.call(["virsh", "pool-undefine", poolName])
+
+def virt_install(opts, install_log):
+ """
+ Use virt-install to install to a disk image
+
+ :param opts: options passed to livemedia-creator
+ :type opts: argparse options
+ :param str install_log: The path to write the log from virt-install
+
+ This uses virt-install with a boot.iso and a kickstart to create a disk
+ image.
+ """
+ iso_mount = IsoMountpoint(opts.iso, opts.location)
+ log_monitor = LogMonitor(install_log, timeout=opts.timeout)
+
+ kernel_args = ""
+ if opts.kernel_args:
+ kernel_args += opts.kernel_args
+ if opts.proxy:
+ kernel_args += " proxy=" + opts.proxy
+
+ try:
+ virt = VirtualInstall(iso_mount, opts.ks, opts.disk_paths,
+ kernel_args, opts.ram, opts.vnc,
+ log_check = log_monitor.server.log_check,
+ virtio_host = log_monitor.host,
+ virtio_port = log_monitor.port)
+
+ virt.destroy(os.path.basename(opts.tmp))
+ log_monitor.shutdown()
+ except InstallError as e:
+ log.error("VirtualInstall failed: %s", e)
+ raise
+ finally:
+ log.info("unmounting the iso")
+ iso_mount.umount()
+
+ if log_monitor.server.log_check():
+ if not log_monitor.server.error_line and opts.timeout:
+ msg = "virt_install failed due to timeout"
+ else:
+ msg = "virt_install failed on line: %s" % log_monitor.server.error_line
+ raise InstallError(msg)
+
+
+def make_image(opts):
+ """
+ Install to a disk image
+
+ :param opts: options passed to livemedia-creator
+ :type opts: argparse options
+ :param str ks: Path to the kickstart to use for the installation
+
+ Use virt-install or anaconda to install to a disk image.
+ """
+ try:
+ install_log = os.path.abspath(os.path.dirname(opts.logfile))+"/virt-install.log"
+ log.info("install_log = %s", install_log)
+
+ virt_install(opts, install_log)
+ except InstallError as e:
+ log.error("Install failed: %s", e)
+
+ if not opts.keep_image:
+ log.info("Removing bad disk image")
+
+ for image in opts.disk_paths:
+ if os.path.exists(image):
+ os.unlink(image)
+
+ raise
+
+ log.info("Disk Image install successful")
+
+def main():
+ parser = argparse.ArgumentParser(description="Run anaconda's kickstart-based tests",
+ fromfile_prefix_chars="@")
+
+ parser.add_argument("--iso", type=os.path.abspath,
+ help="Anaconda installation .iso path to use for virt-install")
+ parser.add_argument("--ks", action="append", type=os.path.abspath,
+ help="Kickstart file defining the install.")
+ parser.add_argument("--disk", action="append", type=os.path.abspath, dest="disk_paths",
+ help="Pre-existing disk image to use for destination.")
+
+ parser.add_argument("--proxy",
+ help="proxy URL to use for the install")
+ parser.add_argument("--location", default=None, type=os.path.abspath,
+ help="location of iso directory tree with initrd.img "
+ "and vmlinuz. Used to run virt-install with a "
+ "newer initrd than the iso.")
+
+ parser.add_argument("--logfile", default="./livemedia.log",
+ type=os.path.abspath,
+ help="Path to logfile")
+ parser.add_argument("--tmp", default="/var/tmp", type=os.path.abspath,
+ help="Top level temporary directory")
+
+ image_group = parser.add_argument_group("disk/fs image arguments")
+ image_group.add_argument("--keep-image", action="store_true",
+ help="Keep raw disk image after .iso creation")
+
+ # Group of arguments to pass to virt-install
+ virt_group = parser.add_argument_group("virt-install arguments")
+ virt_group.add_argument("--ram", metavar="MEMORY", type=int, default=1024,
+ help="Memory to allocate for installer in megabytes.")
+ virt_group.add_argument("--vnc",
+ help="Passed to --graphics command")
+ virt_group.add_argument("--kernel-args",
+ help="Additional argument to pass to the installation kernel")
+
+ parser.add_argument("--timeout", default=None, type=int,
+ help="Cancel installer after X minutes")
+
+ opts = parser.parse_args()
+
+ setup_logging(opts.logfile, log)
+
+ log.debug( opts )
+
+ # Check for invalid combinations of options, print all the errors and exit.
+ errors = []
+ if opts.ks and not os.path.exists(opts.ks[0]):
+ errors.append("kickstart file (%s) is missing." % opts.ks[0])
+
+ if opts.iso and not os.path.exists(opts.iso):
+ errors.append("The iso %s is missing." % opts.iso)
+
+ if not opts.iso:
+ errors.append("virt install needs an install iso.")
+
+ if not os.path.exists("/usr/bin/virt-install"):
+ errors.append("virt-install needs to be installed.")
+
+ if os.getuid() != 0:
+ errors.append("You need to run this as root")
+
+ if errors:
+ list(log.error(e) for e in errors)
+ sys.exit(1)
+
+ tempfile.tempdir = opts.tmp
+
+ # Make the image.
+ try:
+ make_image(opts)
+ except InstallError as e:
+ log.error("ERROR: Image creation failed: %s", e)
+ sys.exit(1)
+
+ log.info("SUMMARY")
+ log.info("-------")
+ log.info("Logs are in %s", os.path.abspath(os.path.dirname(opts.logfile)))
+ log.info("Disk image(s) at %s", ",".join(opts.disk_paths))
+ log.info("Results are in %s", opts.tmp)
+
+ sys.exit( 0 )
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/kickstart_tests/scripts/make-addon-pkgs.py b/tests/kickstart_tests/scripts/make-addon-pkgs.py
new file mode 100755
index 0000000..e38cb7a
--- /dev/null
+++ b/tests/kickstart_tests/scripts/make-addon-pkgs.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python3
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): David Shea <dshea at redhat.com>
+
+# This script creates all the packages used by nfs-repo-and-addon.ks.
+# The packages are created in two directories, http and nfs. After all the rpms
+# are made just copy everything to the locations set in $KSTEST_ADDON_HTTP_REPO
+# and $KSTEST_ADDON_NFS_REPO.
+#
+# This script imports things from tests/lib/mkdud.py, so tests/lib needs to be
+# in $PYTHONPATH.
+
+# Ignore interuptible calls
+# pylint: disable=interruptible-system-call
+
+import os
+from subprocess import check_call
+from mkdud import make_rpm
+import rpmfluff
+
+# Start with http
+os.mkdir('http')
+
+# Empty package to be added to @core
+pkg = rpmfluff.SimpleRpmBuild('testpkg-http-core', '1.0', '1')
+make_rpm(pkg, 'http')
+
+# Another empty package
+pkg = rpmfluff.SimpleRpmBuild('testpkg-http-addon', '1.0', '1')
+make_rpm(pkg, 'http')
+
+# Three packages with marker files
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share1', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-1/http',
+ rpmfluff.SourceFile('http', ''))
+make_rpm(pkg, 'http')
+
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share2', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-2/http',
+ rpmfluff.SourceFile('http', ''))
+make_rpm(pkg, 'http')
+
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share3', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-3/http',
+ rpmfluff.SourceFile('http', ''))
+make_rpm(pkg, 'http')
+
+# Create a comps file and create the repo
+with open('http/comps.xml', 'wt') as comps:
+ comps.write('''<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
+<comps>
+ <group>
+ <id>core</id>
+ <packagelist>
+ <packagereq type="mandatory">testpkg-http-core</packagereq>
+ </packagelist>
+ </group>
+</comps>''')
+
+check_call(['createrepo_c', '-g', 'comps.xml', 'http'])
+
+# Do the same thing again for nfs
+os.mkdir('nfs')
+
+# Empty package to be added to @core
+pkg = rpmfluff.SimpleRpmBuild('testpkg-nfs-core', '1.0', '1')
+make_rpm(pkg, 'nfs')
+
+# Another empty package
+pkg = rpmfluff.SimpleRpmBuild('testpkg-nfs-addon', '1.0', '1')
+make_rpm(pkg, 'nfs')
+
+# Three packages with marker files
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share1', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-1/nfs',
+ rpmfluff.SourceFile('nfs', ''))
+make_rpm(pkg, 'nfs')
+
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share2', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-2/nfs',
+ rpmfluff.SourceFile('nfs', ''))
+make_rpm(pkg, 'nfs')
+
+pkg = rpmfluff.SimpleRpmBuild('testpkg-share3', '1.0', '1')
+pkg.add_installed_file('/usr/share/testpkg-3/nfs',
+ rpmfluff.SourceFile('nfs', ''))
+make_rpm(pkg, 'nfs')
+
+# Create a comps file and create the repo
+with open('nfs/comps.xml', 'wt') as comps:
+ comps.write('''<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
+<comps>
+ <group>
+ <id>core</id>
+ <packagelist>
+ <packagereq type="mandatory">testpkg-nfs-core</packagereq>
+ </packagelist>
+ </group>
+</comps>''')
+
+check_call(['createrepo_c', '-g', 'comps.xml', 'nfs'])
diff --git a/tests/kickstart_tests/scripts/proxy-common.ks b/tests/kickstart_tests/scripts/proxy-common.ks
new file mode 100644
index 0000000..a95097a
--- /dev/null
+++ b/tests/kickstart_tests/scripts/proxy-common.ks
@@ -0,0 +1,79 @@
+# Start a super-simple proxy server on localhost
+# A list of proxied requests will be saved to /tmp/proxy.log
+%pre --erroronfail
+# Write the proxy script to a file in /tmp
+cat - << "EOF" > /tmp/proxy-test.py
+from http.server import SimpleHTTPRequestHandler
+import socketserver
+from urllib.request import urlopen
+import os
+from base64 import b64decode
+
+import logging
+log = logging.getLogger("proxy_test")
+log_handler = logging.FileHandler('/tmp/proxy.log')
+log.setLevel(logging.INFO)
+log.addHandler(log_handler)
+
+class ProxyHandler(SimpleHTTPRequestHandler):
+ def send_authenticate(self):
+ self.send_response(407)
+ self.send_header('Proxy-Authenticate', 'Basic realm=proxy-test')
+ self.end_headers()
+
+ def authenticate(self):
+ # If there is no /tmp/proxy.password file, anything goes
+ if not os.path.exists('/tmp/proxy.password'):
+ return True
+
+ # If there is no Authorization header, send a 407, Proxy authentication required
+ authorization = self.headers['Proxy-Authorization']
+ if not authorization:
+ self.send_authenticate()
+ return False
+
+ # Parse the Authorization header. It should be "Basic" followed
+ # user:pass encoded in base64
+ if not authorization.startswith('Basic'):
+ self.send_authenticate()
+ return False
+
+ try:
+ client_auth = b64decode(authorization.split()[1])
+ except IndexError:
+ self.send_authenticate()
+ return False
+
+ with open('/tmp/proxy.password', 'rb') as f:
+ server_auth = f.readline().strip()
+
+ if client_auth != server_auth:
+ self.send_authenticate()
+ return False
+
+ return True
+
+ def do_GET(self):
+ if not self.authenticate():
+ return
+
+ # Log the path then proxy the request via urllib
+ log.info(self.path)
+ data = urlopen(self.path).read()
+ self.send_response(200)
+ self.send_header('Content-Length', str(len(data)))
+ self.end_headers()
+ self.wfile.write(data)
+
+class ProxyServer(socketserver.TCPServer):
+ allow_reuse_address = True
+
+ def __init__(self):
+ socketserver.TCPServer.__init__(self, ('', 8080), ProxyHandler)
+
+ProxyServer().serve_forever()
+EOF
+
+# Run the server in the background and exit
+python3 /tmp/proxy-test.py > /dev/null 2>&1 &
+%end
diff --git a/tests/kickstart_tests/scripts/run_kickstart_tests.sh b/tests/kickstart_tests/scripts/run_kickstart_tests.sh
new file mode 100755
index 0000000..904f90f
--- /dev/null
+++ b/tests/kickstart_tests/scripts/run_kickstart_tests.sh
@@ -0,0 +1,199 @@
+#!/bin/bash
+#
+# Copyright (C) 2014, 2015 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Chris Lumens <clumens at redhat.com>
+
+# This script runs the entire kickstart_tests suite. It is an interface
+# between "make check" (which is why it takes environment variables instead
+# of arguments) and livemedia-creator. Each test consists of a kickstart
+# file that specifies most everything about the installation, and a shell
+# script that does validation and specifies kernel boot parameters. lmc
+# then fires up a VM and watches for tracebacks or stuck installs.
+#
+# A boot ISO is required, which should be specified with TEST_BOOT_ISO=.
+#
+# The number of jobs corresponds to the number of VMs that will be started
+# simultaneously. Each one wants about 2 GB of memory. The default is
+# two simultaneous jobs, but you can control this with TEST_JOBS=. It is
+# suggested you not run out of memory.
+#
+# You can control what logs are held onto after the test is complete via the
+# KEEPIT= variable, explained below. By default, nothing is kept.
+#
+# Finally, you can run tests across multiple computers at the same time by
+# putting all the hostnames into TEST_REMOTES= as a space separated list.
+# Do not add localhost manually, as it will always be added for you. You
+# must create a user named kstest on each remote system, allow that user to
+# sudo to root for purposes of running livemedia-creator, and have ssh keys
+# set up so that the user running this script can login to the remote systems
+# as kstest without a password. TEST_JOBS= applies on a per-system basis.
+# KEEPIT= controls how much will be kept on the master system (where "make
+# check" is run). All results will be removed from the slave systems.
+
+# The boot.iso location can come from one of two different places:
+# (1) $TEST_BOOT_ISO, if this script is being called from "make check"
+# (2) The command line, if this script is being called directly. That will
+# be checked below.
+IMAGE="${TEST_BOOT_ISO}"
+
+# Possible values for this parameter:
+# 0 - Keep nothing (the default)
+# 1 - Keep log files
+# 2 - Keep log files and disk images (will take up a lot of space)
+KEEPIT=${KEEPIT:-0}
+
+TESTTYPE=""
+
+while getopts ":i:k:t:" opt; do
+ case $opt in
+ i)
+ # If this wasn't set from the environment, set it from the command line
+ # here. If it never gets set, we'll catch that later and error out.
+ IMAGE=$OPTARG
+ ;;
+
+ k)
+ # This overrides either the $KEEPIT environment variable, or the default
+ # setting from above.
+ KEEPIT=$OPTARG
+ ;;
+
+ t)
+ # Only run tests that have TESTTYPE=<this value> in them. Tests can have
+ # more than one type. We'll do a pretty stupid test for it.
+ TESTTYPE=$OPTARG
+ ;;
+
+ *)
+ echo "Usage: run_kickstart_tests.sh [-i boot.iso] [-k 0|1|2] [tests]"
+ exit 1
+ ;;
+ esac
+done
+
+if [[ ! -e "${IMAGE}" ]]; then
+ echo "Required boot.iso does not exist; skipping."
+ exit 77
+fi
+
+shift $((OPTIND - 1))
+
+# This is for environment variables that parallel needs to pass to
+# remote systems.
+#
+# NOTE: You will also need to add these to the list in /etc/sudoers
+# if you are using env_reset there, or they will not get passed from
+# this script to parallel.
+env_args=$(printenv | while read line; do
+ v="$(echo $line | cut -d'=' -f1)"
+ [[ "${v}" =~ ^KSTEST_ ]] && echo "--env ${v}"
+ done)
+
+# We get the list of tests from one of two places:
+# (1) From the command line, all the other arguments.
+# (2) By applying any TESTTYPE given on the command line.
+# (3) From finding all scripts in kickstart_tests/ that are executable and are
+# not support files.
+if [[ $# != 0 ]]; then
+ tests="$*"
+else
+ tests=$(find kickstart_tests -name '*sh' -a -perm -o+x -a \! -wholename 'kickstart_tests/run_*.sh')
+
+ newtests=""
+ if [[ "$TESTTYPE" != "" ]]; then
+ for f in ${tests}; do
+ if [[ "$(grep "TESTTYPE=" ${f})" =~ "${TESTTYPE}" ]]; then
+ newtests+="${f} "
+ fi
+ done
+
+ tests="${newtests}"
+ fi
+fi
+
+if [[ "${tests}" == "" ]]; then
+ echo "No tests provided; skipping."
+ exit 77
+fi
+
+if [[ "$TEST_REMOTES" != "" ]]; then
+ _IMAGE=kickstart_tests/$(basename ${IMAGE})
+
+ # (1) Copy everything to the remote systems. We do this ourselves because
+ # parallel doesn't like globs, and we need to put the boot image somewhere
+ # that qemu on the remote systems can read.
+ for remote in ${TEST_REMOTES}; do
+ scp -r kickstart_tests kstest@${remote}:
+ scp ${IMAGE} kstest@${remote}:kickstart_tests/
+ done
+
+ # (1a) We also need to copy the provided image to under kickstart_tests/ on
+ # the local system too. This is because parallel will attempt to run the
+ # same command line on every system and that requires the image to also be
+ # in the same location.
+ cp ${IMAGE} ${_IMAGE}
+
+ # (2) Run parallel. We always add the local system to the list of machines
+ # being passed to parallel. Don't add it yourself.
+ remote_args="--sshlogin :"
+ for remote in ${TEST_REMOTES}; do
+ remote_args="${remote_args} --sshlogin kstest@${remote}"
+ done
+
+ parallel --no-notice ${remote_args} \
+ ${env_args} --jobs ${TEST_JOBS:-2} \
+ sudo PYTHONPATH=$PYTHONPATH kickstart_tests/scripts/run_one_ks.sh -i ${_IMAGE} -k ${KEEPIT} {} ::: ${tests}
+ rc=$?
+
+ # (3) Get all the results back from the remote systems, which will have already
+ # applied the KEEPIT setting. However if KEEPIT is 0 (meaning, don't save
+ # anything) there's no point in trying. We do this ourselves because, again,
+ # parallel doesn't like globs.
+ #
+ # We also need to clean up the stuff we copied over in step 1, and then clean up
+ # the results from the remotes too. We don't want to keep things scattered all
+ # over the place.
+ for remote in ${TEST_REMOTES}; do
+ if [[ ${KEEPIT} > 0 ]]; then
+ scp -r kstest@${remote}:/var/tmp/kstest-\* /var/tmp/
+ fi
+
+ ssh kstest@${remote} sudo rm -rf kickstart_tests /var/tmp/kstest-\*
+ done
+
+ # (3a) And then also remove the copy of the image we made earlier.
+ rm ${_IMAGE}
+
+ # (4) Exit the subshell defined by "find ... | " way up at the top. The exit
+ # code will be caught outside and converted into the overall exit code.
+ exit ${rc}
+else
+ parallel --no-notice ${env_args} --jobs ${TEST_JOBS:-2} \
+ sudo PYTHONPATH=$PYTHONPATH kickstart_tests/scripts/run_one_ks.sh -i ${IMAGE} -k ${KEEPIT} {} ::: ${tests}
+
+ # For future expansion - any cleanup code can go in between the variable
+ # setting and the exit, like in the other branch of the if-else above.
+ rc=$?
+ exit ${rc}
+fi
+
+# Catch the exit code of the subshell and return it. This is structured for
+# future expansion, too. Any extra global cleanup code can go in between the
+# variable setting and the exit.
+rc=$?
+exit ${rc}
diff --git a/tests/kickstart_tests/scripts/run_one_ks.sh b/tests/kickstart_tests/scripts/run_one_ks.sh
new file mode 100755
index 0000000..2ed2b36
--- /dev/null
+++ b/tests/kickstart_tests/scripts/run_one_ks.sh
@@ -0,0 +1,157 @@
+#!/bin/bash
+#
+# Copyright (C) 2015 Red Hat, Inc.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details. You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Chris Lumens <clumens at redhat.com>
+
+# This script runs a single kickstart test on a single system. It takes
+# command line arguments instead of environment variables because it is
+# designed to be driven by run_kickstart_tests.sh via parallel. It is
+# not for direct use, though as long as you pass the right arguments there's
+# no reason it couldn't work.
+
+# Possible return values:
+# 0 - Everything worked
+# 1 - Test failed for unspecified reasons
+# 2 - Test failed due to time out
+# 77 - Something needed by the test doesn't exist, so skip
+
+IMAGE=
+KEEPIT=0
+
+cleanup() {
+ d=$1
+
+ # Always remove the copy of the boot.iso.
+ rm ${d}/$(basename ${IMAGE})
+
+ if [[ ${KEEPIT} == 2 ]]; then
+ return
+ elif [[ ${KEEPIT} == 1 ]]; then
+ rm -f ${d}/disk-*.img ${d}/*ks
+ elif [[ ${KEEPIT} == 0 ]]; then
+ rm -rf ${d}
+ fi
+}
+
+runone() {
+ t=$1
+
+ export KSTESTDIR=$(pwd)/kickstart_tests
+
+ ks=${t/.sh/.ks}
+ . $t
+
+ name=$(basename ${t%.sh})
+
+ echo
+ echo ===========================================================================
+ echo ${ks} on $(hostname)
+ echo ===========================================================================
+
+ # qemu user needs to be able to read the directory and the boot.iso, so put that
+ # into this directory as well. It will get deleted later, regardless of the
+ # KEEPIT setting.
+ tmpdir=$(mktemp -d --tmpdir=/var/tmp kstest-${name}.XXXXXXXX)
+ chmod 755 ${tmpdir}
+ cp ${IMAGE} ${tmpdir}
+
+ ksfile=$(prepare ${ks} ${tmpdir})
+ if [[ $? != 0 ]]; then
+ echo RESULT:${name}:FAILED:Test prep failed: ${ksfile}
+ cleanup ${tmpdir}
+ return 1
+ fi
+
+ kargs=$(kernel_args)
+ if [[ "${kargs}" != "" ]]; then
+ kargs="--kernel-args \"$kargs\""
+ fi
+
+ disks=$(prepare_disks ${tmpdir})
+ disk_args=$(for d in $disks; do echo --disk $d; done)
+
+ echo "PYTHONPATH=$PYTHONPATH"
+ eval ${KSTESTDIR}/scripts/kstest-runner ${kargs} \
+ --iso "${tmpdir}/$(basename ${IMAGE})" \
+ --ks ${ksfile} \
+ --tmp ${tmpdir} \
+ --logfile ${tmpdir}/livemedia.log \
+ --ram 2048 \
+ --vnc vnc \
+ --timeout 60 \
+ ${disk_args}
+ if [[ -f ${tmpdir}/virt-install.log && "$(grep CRIT ${tmpdir}/virt-install.log)" != "" ]]; then
+ echo RESULT:${name}:FAILED:$(grep CRIT ${tmpdir}/virt-install.log)
+ cleanup ${tmpdir}
+ return 1
+ elif [[ -f ${tmpdir}/livemedia.log ]]; then
+ if [[ "$(grep 'due to timeout' ${tmpdir}/livemedia.log)" != "" ]]; then
+ echo RESULT:${name}:FAILED:Test timed out.
+ cleanup ${tmpdir}
+ return 2
+ fi
+
+ result=$(validate ${tmpdir})
+ if [[ $? != 0 ]]; then
+ echo RESULT:${name}:FAILED:"${result}"
+ cleanup ${tmpdir}
+ return 1
+ fi
+ fi
+
+ echo RESULT:${name}:SUCCESS
+ cleanup ${tmpdir}
+ return 0
+}
+
+# Have to be root to run this test, as it requires creating disk images.
+if [[ ${EUID} != 0 ]]; then
+ echo "You must be root to run this test."
+ exit 77
+fi
+
+while getopts ":i:k:" opt; do
+ case $opt in
+ i)
+ IMAGE=$OPTARG
+ ;;
+
+ k)
+ KEEPIT=$OPTARG
+ ;;
+
+ *)
+ echo "Usage: run_one_ks.sh -i ISO [-k KEEPIT] ks-test.sh"
+ exit 1
+ ;;
+ esac
+done
+
+shift $((OPTIND - 1))
+
+if [[ ! -e "${IMAGE}" ]]; then
+ echo "Required boot.iso does not exist."
+ exit 77
+fi
+
+if [[ $# == 0 || ! -x $1 ]]; then
+ echo "Test not provided or is not executable."
+ exit 1
+fi
+
+runone $1
diff --git a/tests/kickstart_tests/scripts/run_report.sh b/tests/kickstart_tests/scripts/run_report.sh
new file mode 100755
index 0000000..b62b128
--- /dev/null
+++ b/tests/kickstart_tests/scripts/run_report.sh
@@ -0,0 +1,26 @@
+#!/bin/gawk -f
+
+BEGIN {
+ printf("\n\n\n%-30s | %-10s | %s\n", "TEST", "RESULT", "EXPLANATION");
+ printf("-------------------------------+------------+--------------------------------------------------------\n");
+ FS=":"
+}
+/^RESULT:/ { if ($4 == "Test timed out.") {
+ result = "TIMED OUT";
+ explanation = "";
+ } else if (match($0, "Traceback")) {
+ result = "FAILED";
+ explanation = "Traceback";
+ } else if (match($0, "SUCCESS")) {
+ result = $3;
+ explanation = "";
+ } else {
+ result = $3;
+ explanation = substr($0, index($0, $4), 55);
+ }
+
+ printf("%-30s | %-10s | %s\n", $2, result, explanation);
+ }
+END {
+ printf("\n\n");
+}
--
To view this commit on github, visit https://github.com/rhinstaller/anaconda/commit/4248347cb77bfa5bffc1b25052f27eaaeaca5474
More information about the anaconda-patches
mailing list