summaryrefslogtreecommitdiffstats
path: root/controller
diff options
context:
space:
mode:
authorPavel Raiskup <praiskup@redhat.com>2014-10-22 08:54:05 +0200
committerPavel Raiskup <praiskup@redhat.com>2014-10-22 08:54:05 +0200
commit2422a081a5be0d5ac5afb122361bc283da67341f (patch)
treecb255582060af6547dd9318c56ba0e8c761846a1 /controller
parent922089746e1029de9be986672fcdeb6bc82e18d7 (diff)
downloadpostgresql-setup-tests-2422a081a5be0d5ac5afb122361bc283da67341f.tar.gz
postgresql-setup-tests-2422a081a5be0d5ac5afb122361bc283da67341f.tar.xz
postgresql-setup-tests-2422a081a5be0d5ac5afb122361bc283da67341f.zip
big reorg: prepare for generalization
Try to split into three separate components -> controller, tester, and 'tasks' (postgresql-tasks in our case). The controller component is the main part which is able to run the task remotely. Tester is more-like library for 'tasks' component (should be reusable on the raw git level). * controller: Almost separated component. * postgresql-tasks: Likewise. * tester: Likewise.
Diffstat (limited to 'controller')
-rw-r--r--controller/ansible/dummy-wrapper.yml7
-rw-r--r--controller/ansible/fedora.yml64
-rw-r--r--controller/ansible/include/additional-packages.yml6
-rw-r--r--controller/ansible/include/beakerlib.yml1
-rw-r--r--controller/ansible/include/download-results.yml5
-rw-r--r--controller/ansible/include/prepare-testenv.yml3
-rwxr-xr-xcontroller/ansible/run_include19
-rwxr-xr-xcontroller/ansible_helpers/wait-for-ssh11
-rw-r--r--controller/config/.gitignore2
-rw-r--r--controller/config/config.sh.template36
-rw-r--r--controller/config/hosts.template2
-rw-r--r--controller/config/os/EXAMPLE.sh20
-rwxr-xr-xcontroller/controller (renamed from controller)5
-rwxr-xr-xcontroller/get_machine85
-rw-r--r--controller/parse_credsfile14
-rw-r--r--controller/private/os/EXAMPLE.yml7
-rwxr-xr-xcontroller/result_stats74
-rw-r--r--controller/result_templates/html.tmpl42
-rwxr-xr-xcontroller/run_remote101
19 files changed, 503 insertions, 1 deletions
diff --git a/controller/ansible/dummy-wrapper.yml b/controller/ansible/dummy-wrapper.yml
new file mode 100644
index 0000000..524b0ea
--- /dev/null
+++ b/controller/ansible/dummy-wrapper.yml
@@ -0,0 +1,7 @@
+- name: "dummy-wrapper"
+ hosts: "{{ target }}"
+ remote_user: root
+ gather_facts: False
+
+ tasks:
+ - include: "{{ include_file }}"
diff --git a/controller/ansible/fedora.yml b/controller/ansible/fedora.yml
new file mode 100644
index 0000000..cc64eac
--- /dev/null
+++ b/controller/ansible/fedora.yml
@@ -0,0 +1,64 @@
+- name: self-standing testsuite
+ remote_user: root
+ gather_facts: False
+ hosts: localhost
+ vars_files:
+ - "{{ opt_credsfile }}"
+
+ tasks:
+ - name: generate builder name
+ local_action: shell echo `dd if=/dev/urandom bs=1k count=10 | md5sum ; echo DBTESTS`
+ register: vm_name
+
+ - debug: msg="osusername={{ os_username }}"
+
+ - name: spin it up
+ local_action: nova_compute auth_url={{os_auth_url}}
+ flavor_id={{os_flavor_id}} image_id="{{ os_image_id }}" key_name={{ os_keypair }}
+ login_password={{os_nova_password}} login_tenant_name="{{os_tenant_name}}"
+ login_username={{os_username}} security_groups={{os_security_group}}
+ wait=yes name="{{vm_name.stdout}}" wait_for=600
+ register: nova
+
+ - debug: msg="{{ nova.info.addresses }}"
+
+ # This is ugly as hell... Hopefully nothing will be changing.
+ - local_action: command echo "{{ nova.info.addresses[os_network_dev][1].addr }}"
+ register: machine_ip
+
+ - debug: msg="{{ machine_ip.stdout }}"
+
+ - name: wait for the host to be hot
+ local_action: wait_for host={{ machine_ip.stdout }} port=22 delay=5 timeout=600
+
+ - local_action: shell ../ansible_helpers/wait-for-ssh "root@{{ machine_ip.stdout }}"
+
+ - name: add it to the special group
+ local_action: add_host hostname={{ machine_ip.stdout }}
+ groupname=temp_group
+
+- hosts: temp_group
+ user: root
+ gather_facts: False
+ tasks:
+ - copy: src={{ opt_workdir }}/{{ opt_testsuite_name }}.tar.gz
+ dest=/root/{{ opt_testsuite_name }}.tar.gz
+
+ - include: include/beakerlib.yml
+
+ - include: include/prepare-testenv.yml
+
+ - include: include/additional-packages.yml
+ when: dtf_rpm_files_list is defined
+
+ - shell: cd /root && tar -xf {{ opt_testsuite_name }}.tar.gz
+
+ - shell: cd /root/{{ opt_testsuite_name }}&& ./run &>/var/tmp/dtf-run.overview
+ register: test_result
+ ignore_errors: yes
+
+ - include: include/download-results.yml
+
+ - name: stop the vm
+ shell: echo "not implemented yet"
+ when: test_result.rc == 0
diff --git a/controller/ansible/include/additional-packages.yml b/controller/ansible/include/additional-packages.yml
new file mode 100644
index 0000000..f821255
--- /dev/null
+++ b/controller/ansible/include/additional-packages.yml
@@ -0,0 +1,6 @@
+- local_action: shell cat "{{ dtf_rpm_files_list }}" | xargs -n 100
+ register: additional_packages
+
+- debug: msg="{{ additional_packages.stdout }}"
+
+- shell: yum install -y {{ additional_packages.stdout }}
diff --git a/controller/ansible/include/beakerlib.yml b/controller/ansible/include/beakerlib.yml
new file mode 100644
index 0000000..0461f25
--- /dev/null
+++ b/controller/ansible/include/beakerlib.yml
@@ -0,0 +1 @@
+- yum: conf_file=https://beaker-project.org/yum/beaker-server-Fedora.repo state=present name=beakerlib
diff --git a/controller/ansible/include/download-results.yml b/controller/ansible/include/download-results.yml
new file mode 100644
index 0000000..4404e08
--- /dev/null
+++ b/controller/ansible/include/download-results.yml
@@ -0,0 +1,5 @@
+- shell: cp -f /var/tmp/dtf-run.overview /var/tmp/dtf/
+
+- shell: cd /var/tmp ; tar -czf dtf.tar.gz dtf
+
+- fetch: src=/var/tmp/dtf.tar.gz dest="{{ opt_workdir }}/" flat=yes
diff --git a/controller/ansible/include/prepare-testenv.yml b/controller/ansible/include/prepare-testenv.yml
new file mode 100644
index 0000000..a63e51a
--- /dev/null
+++ b/controller/ansible/include/prepare-testenv.yml
@@ -0,0 +1,3 @@
+- yum: state=present name=postgresql-server
+
+- yum: state=present name=postgresql-upgrade
diff --git a/controller/ansible/run_include b/controller/ansible/run_include
new file mode 100755
index 0000000..4e84c7d
--- /dev/null
+++ b/controller/ansible/run_include
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+export ANSIBLE_HOST_KEY_CHECKING=False
+
+workdir="$(dirname "${BASH_SOURCE[0]}")"
+workdir=$(readlink -f "$workdir")
+
+export playbook=$(readlink -f "$1")
+
+( set -x
+ cd "$workdir"
+
+ ansible-playbook -i "$workdir/../config/hosts" \
+ --extra-vars "include_file=$playbook" \
+ --extra-vars "script_name=dummy" \
+ --extra-vars "opt_workdir=/tmp/dtf-$(date +%H%M%S%N)" \
+ --extra-vars "target=host" \
+ "dummy-wrapper.yml"
+)
diff --git a/controller/ansible_helpers/wait-for-ssh b/controller/ansible_helpers/wait-for-ssh
new file mode 100755
index 0000000..eb3880a
--- /dev/null
+++ b/controller/ansible_helpers/wait-for-ssh
@@ -0,0 +1,11 @@
+#!/bin/bash -x
+
+where="$1"
+
+test -z "$where" && echo >&2 "no host specified" && exit 1
+
+while [ 1 ]; do
+ ssh -o StrictHostKeyChecking=no -q $where exit &>/dev/null && exit 0
+done
+
+exit 1
diff --git a/controller/config/.gitignore b/controller/config/.gitignore
new file mode 100644
index 0000000..57c4fcb
--- /dev/null
+++ b/controller/config/.gitignore
@@ -0,0 +1,2 @@
+*.sh
+hosts
diff --git a/controller/config/config.sh.template b/controller/config/config.sh.template
new file mode 100644
index 0000000..94cbe22
--- /dev/null
+++ b/controller/config/config.sh.template
@@ -0,0 +1,36 @@
+# OpenStack ID
+# ------------
+#
+# By default, based on DTF_OPENSTACK_ID content the corresponding OpenStack
+# configuration is used. You may have multiple OpenStack instances configured -
+# this option selects one. Based on the OpenStack ID (say 'EXAMPLE'), those
+# configuration-like files are used:
+#
+# * private/os/'EXAMPLE'.yml
+# File having OpenStack credentials in ansible variable file (YAML file
+# with "key: value" lines). See the ./private/os/EXAMPLE.yml for
+# variables you should set up. Keep this file secret.
+#
+# * config/os/'EXAMPLE'.sh
+# This file must contain configuration for specific OpenStack instance.
+# Usually information about available images, flavors, networking, etc.
+# The template file config/os/EXAMPLE.sh may be used when configuring your
+# testing environment.
+
+export DTF_OPENSTACK_ID=dropbear
+
+# Result Database
+# ---------------
+# Directory where the testsuite should keep its (persistent) results. Make sure
+# that this directory is backed up.
+
+export DTF_DATABASE=/var/lib/dtf_results
+
+# Presenter place
+# ---------------
+# For now, only static results are available. DTF_PRESENTER_PLACE must contain
+# rsync-compatible destination (it may be place accessible via ssh+rsync). It
+# is expected that some httpd server is able to read the directory with results
+# and publish them as static directory structure over http://.
+
+export DTF_PRESENTER_PLACE=user@example.org:/var/www/html/my_project/dtf
diff --git a/controller/config/hosts.template b/controller/config/hosts.template
new file mode 100644
index 0000000..6850700
--- /dev/null
+++ b/controller/config/hosts.template
@@ -0,0 +1,2 @@
+[host]
+10.64.27.30
diff --git a/controller/config/os/EXAMPLE.sh b/controller/config/os/EXAMPLE.sh
new file mode 100644
index 0000000..b5ba270
--- /dev/null
+++ b/controller/config/os/EXAMPLE.sh
@@ -0,0 +1,20 @@
+## THIS IS EXAMPLE OPENSTACK DTF CONFIGURATION ##
+
+# variable declarations, should be C&Ped
+declare -A os_flavor_ids os_image_ids
+export os_flavor_ids=[]
+export os_image_ids=[]
+
+# connection info about particular OpenStack instance
+
+# which ssh keys should be uploaded to created VMs
+export os_keypair="keypair-id"
+# group of firewall rules to be set on VMs
+export os_security_group=test_group
+# the name of network connection as is presented by ansible
+export os_network_dev=network_name
+
+# per-distribution dictionary with images/flavors
+os_flavor_ids["fedora20"]="2"
+os_image_ids["fedora20"]="0461eef2-5921-4c01-95a6-6edf96d41b89"
+
diff --git a/controller b/controller/controller
index 7f628d6..e0cffe9 100755
--- a/controller
+++ b/controller/controller
@@ -7,7 +7,7 @@
# (still) local variables
distro=fedora
-distro_ver=20
+distro_ver=21
arch=x86_64
starttime=$(date -u +%Y%m%d_%H%M%S_%N)
@@ -55,11 +55,14 @@ prereq_resultdir
workdir=$(mktemp -d "/var/tmp/dtf_postgresql_setup-XXXXXX")
+# cp /var/tmp/dtf_postgresql_setup-yK12r7/dtf.tar.gz "$workdir"
./run_remote \
--distro="$distro" \
--distro-version="$distro_ver" \
--workdir="$workdir" \
--openstack-instance="$DTF_OPENSTACK_ID" \
+ "$(test -f additional_packages \
+ && echo '--extra-rpms-file=additional_packages')" \
|| die "can not perform run_remote"
resultdir="$DTF_DATABASE/$distro/$distro_ver/$arch"
diff --git a/controller/get_machine b/controller/get_machine
new file mode 100755
index 0000000..7d4e619
--- /dev/null
+++ b/controller/get_machine
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+die() { echo "$@" ; exit 1 ; }
+info() { echo " * $@" ; }
+
+opt_openstack_instance=os1
+opt_distro=fedora
+opt_distro_version=20
+
+function show_help()
+{
+cat <<EOHELP >&2
+Usage: $0 OPTION
+
+Script is aimed to help sysadmin.
+
+Options:
+ --distro=NAME Distro name, like fedora
+ --distro-version=VERSION E.g. 20 for Fedora 20
+ --openstack-instance=ID
+EOHELP
+test -n "$1" && exit "$1"
+}
+
+boot()
+(
+ set -o pipefail
+ nova boot "$1" --poll \
+ --image "$2" \
+ --flavor "$3" \
+ --security-groups "$os_security_group" \
+ --key-name "$os_keypair" \
+ | grep "| id " | cut -d\| -f 3 | xargs -n 1
+)
+
+get_ip()
+(
+ id="$1"
+ set -o pipefail
+ nova show "$id" | grep ' network ' \
+ | cut -d\| -f 3 | cut -d, -f2 | xargs -n 1
+)
+
+
+longopts="distro:,distro-version:,openstack-instance:"
+ARGS=$(getopt -o "" -l "help,$longopts" -n "$0" -- "$@") \
+ || exit 1
+eval set -- "$ARGS"
+
+while true; do
+ case "$1" in
+ --distro|--distro-version|--openstack-instance)
+ opt=$(sed -e 's/^--//' -e 's/[^[a-zA-Z0-9]/_/g'<<<"$1")
+ eval "opt_$opt=\"${2,,}\""
+ shift 2
+ ;;
+
+ --help)
+ show_help 0
+ ;;
+
+ --)
+ shift
+ break;
+ esac
+done
+
+. ./parse_credsfile "$opt_openstack_instance" || exit 1
+. ./config/os/"$opt_openstack_instance.sh" || exit 1
+
+image_version=$opt_distro$opt_distro_version
+image=${os_image_ids[$image_version]}
+flavor=${os_flavor_ids[$image_version]}
+
+test -z "$image" && die "no image for '$image_version'"
+test -z "$flavor" && die "no flavor for '$image_version'"
+
+info "booting machine $image_version from $image"
+
+machine=$(boot "testing-$image" "$image" "$flavor")
+
+info "machine id: $machine"
+
+ip=$(get_ip "$machine")
+info "ip: $ip"
diff --git a/controller/parse_credsfile b/controller/parse_credsfile
new file mode 100644
index 0000000..df2a6bf
--- /dev/null
+++ b/controller/parse_credsfile
@@ -0,0 +1,14 @@
+credsfile="private/os/$1.yml"
+
+while read line; do
+ if [[ "$line" =~ ^([a-zA-Z0-9_]*):\ ?(.*)$ ]]; then
+ key="${BASH_REMATCH[1]}"
+ if test "$key" = os_nova_password; then
+ key=os_password
+ fi
+ eval set ${BASH_REMATCH[2]}
+ eval export "${key^^}"="\"$@\""
+ fi
+done < "$credsfile"
+
+# vi: syntax=sh
diff --git a/controller/private/os/EXAMPLE.yml b/controller/private/os/EXAMPLE.yml
new file mode 100644
index 0000000..d44cbac
--- /dev/null
+++ b/controller/private/os/EXAMPLE.yml
@@ -0,0 +1,7 @@
+## THIS IS EXAMPLE OPENSTACK CREDENTIALS FILE ##
+---
+os_auth_url: http://openstack-controller.example.com:5000/v2.0
+os_tenant_id: 8289c1553643c7adf3476fb6234562c0
+os_tenant_name: Example Develpoment Group
+os_username: jdoe
+os_nova_password: plainPasswordKeepSecrete
diff --git a/controller/result_stats b/controller/result_stats
new file mode 100755
index 0000000..a92d6d6
--- /dev/null
+++ b/controller/result_stats
@@ -0,0 +1,74 @@
+#!/bin/perl
+
+use strict;
+use warnings;
+use utf8;
+
+use Data::Dumper;
+use File::Basename;
+use Cwd;
+use Encode 'encode_utf8';
+
+# teplates
+use Text::Xslate;
+
+# yaml (quick) parser
+use YAML::Syck;
+
+our $srcdir = dirname(__FILE__);
+
+sub html_printer
+{
+ my $results = $_[0];
+ my $task_ids = $_[1];
+
+ my $xslate = Text::Xslate->new(path => ["$srcdir/result_templates"]);
+
+ my $content = $xslate->render("html.tmpl", {
+ results => $results,
+ task_ids => $task_ids,
+ });
+ print encode_utf8($content);
+}
+
+my $workdir = $ARGV[0];
+
+my $data = [];
+
+my $task_ids = {};
+
+# go through *each* result directory
+my $olddir = getcwd;
+for (`find "$workdir" -maxdepth 1 -type d -name 'result_*'`) {
+ chomp;
+ chdir $_;
+
+ my $run_results = {};
+ $run_results->{dirname} = basename($_);
+ $run_results->{tasks} = {};
+ $run_results->{exit_status} = 0;
+
+ # go through each task
+ for (`find -maxdepth 1 -type f -name '*.result'`) {
+ chomp;
+
+ (my $task_id = $_) =~ s/\.result$//;
+ $task_id =~ s/.*\///;
+ $task_ids->{$task_id} = 1;
+
+ my $yaml_file = $_;
+ open my $fd, '<', $yaml_file
+ or die "can't open yaml file '$yaml_file'";
+
+ my $config = YAML::Syck::LoadFile($fd);
+ if ($config->{exit_status} != 0) {
+ $run_results->{exit_status} = 1;
+ }
+ $run_results->{tasks}->{$task_id} = $config;
+ }
+
+ push @{$data}, $run_results;
+}
+chdir $olddir;
+
+html_printer $data, $task_ids;
diff --git a/controller/result_templates/html.tmpl b/controller/result_templates/html.tmpl
new file mode 100644
index 0000000..8a09ad7
--- /dev/null
+++ b/controller/result_templates/html.tmpl
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<meta name="keywords" content="" />
+<title>Results</title>
+<link href="https://praiskup.fedorapeople.org/staticdata/patternfly-1.1/css/patternfly.css" rel="stylesheet" media="screen, print">
+</head>
+<body>
+<div class="table-responsive">
+<table class="table table-condensed table-hover">
+<thead>
+ <tr>
+ <th>Run time</th>
+: for $task_ids.keys() -> $task_id {
+ <th><: $task_id :></th>
+: }
+ </tr>
+</thead><tbody>
+: for $results -> $result {
+ : if ($result.exit_status) {
+ <tr class="danger">
+ : } else {
+ <tr>
+ : }
+ <td><: $result.dirname :></td>
+ : for $task_ids.keys() -> $task_id {
+ : if (not defined($result.tasks[$task_id].exit_status)) {
+ <td>NOT AVAILABLE</td>
+ : } elsif ($result.tasks[$task_id].exit_status == 0) {
+ <td>OK</td>
+ : } else {
+ <td class="danger">FAIL</td>
+ : }
+ : }
+ <tr>
+:}
+</tbody>
+</table>
+</div>
+</body>
+</html>
diff --git a/controller/run_remote b/controller/run_remote
new file mode 100755
index 0000000..0f7ccc3
--- /dev/null
+++ b/controller/run_remote
@@ -0,0 +1,101 @@
+#!/bin/bash
+
+. config/config.sh || {
+ echo >&2 "sorry, but config/config.sh not found"
+ exit 1
+}
+
+longopts="verbose,help,force,testid:,listonly"
+
+run_playbook=${run_playbook-ansible/fedora.yml}
+
+opt_workdir=/var/tmp/dbt-results
+opt_distro=fedora
+opt_openstack_instance="$DTF_OPENSTACK_ID"
+opt_distro_ver=20
+opt_extra_rpms=
+opt_taskdir=
+
+die() { echo >&2 "$@" ; exit 1 ; }
+
+longopts="distro:,distro-version:,workdir:,openstack-instance:,extra-rpms-file:"
+longopts+=",taskdir:"
+ARGS=$(getopt -o "v" -l "$longopts" -n "getopt" -- "$@") \
+ || exit 1
+eval set -- "$ARGS"
+
+while true; do
+ case "$1" in
+ --taskdir)
+ opt=$(sed -e 's/^--//' -e 's/[^[a-zA-Z0-9]/_/g'<<<"$1")
+ eval "opt_$opt=\"${2,,}\""
+ shift 2
+ ;;
+
+ --distro)
+ opt_distro="$2"
+ shift 2
+ ;;
+
+ --distro-version)
+ opt_distro_ver="$2"
+ shift 2
+ ;;
+
+ --openstack-instance)
+ opt_openstack_instance="$2"
+ shift 2
+ ;;
+
+ --workdir)
+ # where the remote results are fetched into
+ opt_workdir="$2"
+ shift 2
+ ;;
+
+ --extra-rpms-file)
+ opt_extra_rpms="$(readlink -f "$2")"
+ shift 2
+ ;;
+
+ --)
+ shift
+ break
+ ;;
+ esac
+done
+
+test -z "$opt_taskdir" && die "you must specify --taskdir"
+
+credsfile="$(readlink -f "./private/os/$opt_openstack_instance.yml")"
+test -z "$credsfile" && die "--ansible-creds option must be specified"
+test ! -f "$credsfile" && die "file $credsfile not found"
+
+config_os_file="$(readlink -f "./config/os/$opt_openstack_instance.sh")"
+test ! -r "$config_os_file" && die "file $config_os_file not found"
+. "$config_os_file"
+
+config_os_id="$opt_distro$opt_distro_ver"
+
+tarball()
+(
+ testsuite_name="$(basename "$opt_taskdir")"
+ echo "$testsuite_name"
+ "$opt_taskdir/run" --dist | gzip > "$opt_workdir/$testsuite_name.tar.gz"
+)
+
+testsuite_name="$(tarball)" || die "can not create dist tarball"
+
+export ANSIBLE_HOST_KEY_CHECKING=False
+ansible-playbook "$run_playbook" \
+ --extra-vars "opt_distro=$opt_distro" \
+ --extra-vars "opt_distro_ver=$opt_distro_ver" \
+ --extra-vars "opt_workdir=$opt_workdir" \
+ --extra-vars "opt_credsfile=$credsfile" \
+ --extra-vars "os_flavor_id=${os_flavor_ids[$config_os_id]}" \
+ --extra-vars "os_image_id=${os_image_ids[$config_os_id]}" \
+ --extra-vars "os_keypair=${os_keypair}" \
+ --extra-vars "os_security_group=${os_security_group}" \
+ --extra-vars "os_network_dev=${os_network_dev}" \
+ --extra-vars "opt_testsuite_name=${testsuite_name}" \
+ --extra-vars "${opt_extra_rpms:+dtf_rpm_files_list=$opt_extra_rpms}"