diff options
Diffstat (limited to '')
-rwxr-xr-x | src/VBox/ValidationKit/testboxscript/linux/setup-routines.sh | 162 | ||||
-rwxr-xr-x | src/VBox/ValidationKit/testboxscript/linux/testboxscript-service.sh | 501 |
2 files changed, 663 insertions, 0 deletions
diff --git a/src/VBox/ValidationKit/testboxscript/linux/setup-routines.sh b/src/VBox/ValidationKit/testboxscript/linux/setup-routines.sh new file mode 100755 index 00000000..387f8691 --- /dev/null +++ b/src/VBox/ValidationKit/testboxscript/linux/setup-routines.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# $Id: setup-routines.sh $ +## @file +# VirtualBox Validation Kit - TestBoxScript Service Setup. +# + +# +# Copyright (C) 2006-2019 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL) only, as it comes in the "COPYING.CDDL" file of the +# VirtualBox OSE distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# + + +# Load the routines we share with the linux installer. +if test ! -r "${DIR}/linux/setup-installer-routines.sh" -a -r "${DIR}/../../Installer/linux/routines.sh"; then + . "${DIR}/../../Installer/linux/routines.sh" +else + . "${DIR}/linux/setup-installer-routines.sh" +fi + + +os_load_config() { + if [ -d /etc/conf.d/ ]; then + MY_CONFIG_FILE="/etc/conf.d/testboxscript" + elif [ -d /etc/default/ ]; then + MY_CONFIG_FILE="/etc/default/testboxscript" + else + echo "Port me!" + exit 1; + fi + if [ -r "${MY_CONFIG_FILE}" ]; then + . "${MY_CONFIG_FILE}" + fi +} + +os_install_service() { + # + # Install the runlevel script. + # + install_init_script "${TESTBOXSCRIPT_DIR}/testboxscript/linux/testboxscript-service.sh" "testboxscript-service" + set +e + delrunlevel "testboxscript-service" > /dev/null 2>&1 + addrunlevel "testboxscript-service" 90 10 + set -e + + # + # Install the configuration file. + # + echo "# Generated by $0." > "${MY_CONFIG_FILE}" + for var in ${TESTBOXSCRIPT_CFG_NAMES}; + do + varcfg=TESTBOXSCRIPT_${var} + vardef=TESTBOXSCRIPT_DEFAULT_${var} + if [ "${!varcfg}" = "${!vardef}" ]; then + echo "# using default value: ${varcfg}=${!varcfg}" >> "${MY_CONFIG_FILE}" + else + echo "${varcfg}=${!varcfg}" >> "${MY_CONFIG_FILE}" + fi + done + + # Work around a bug with arrays in old bash versions. + if [ ${#TESTBOXSCRIPT_ENVVARS[@]} -ne 0 ]; then + set | sed -n -e '/^TESTBOXSCRIPT_ENVVARS=/p' >> "${MY_CONFIG_FILE}" + fi + return 0; +} + +os_enable_service() { + start_init_script testboxscript-service + return 0; +} + +os_disable_service() { + stop_init_script testboxscript-service 2>&1 || true # Ignore + return 0; +} + +os_add_user() { + ADD_GROUPS="" + if ! grep -q wheel /etc/group; then + ADD_GROUPS="-G wheel" + fi + set -e + useradd -m -U -p password -s /bin/bash ${ADD_GROUPS} "${TESTBOXSCRIPT_USER}" + set +e + return 0; +} + +check_for_cifs() { + test -x /sbin/mount.cifs -o -x /usr/sbin/mount.cifs + grep -wq cifs /proc/filesystems || modprobe cifs; + # Note! If modprobe doesn't work above, /sbin and /usr/sbin are probably missing from the search PATH. + return 0; +} + +## +# Test if core dumps are enabled. See https://wiki.ubuntu.com/Apport! +# +test_coredumps() { + if test "`lsb_release -is`" = "Ubuntu"; then + if grep -q "apport" /proc/sys/kernel/core_pattern; then + if grep -q "#.*problem_types" /etc/apport/crashdb.conf; then + echo "It looks like core dumps are properly configured, good!" + else + echo "Warning: Core dumps will be not always generated!" + fi + else + echo "Warning: Apport not installed! This package is required for core dump handling!" + fi + fi +} + +## +# Test if unattended updates are disabled. See +# http://ask.xmodulo.com/disable-automatic-updates-ubuntu.html +test_unattended_updates_disabled() { + if grep "APT::Periodic::Unattended-Upgrade.*1" /etc/apt/apt.conf.d/* 2>/dev/null; then + echo "Unattended updates enabled?" + return 1 + fi + if grep "APT::Periodic::Update-Package-List.*1" /etc/apt/apt.conf.d/* 2>/dev/null; then + echo "Unattended package updates enabled?" + return 1 + fi +} + +os_final_message() { + cat <<EOF + +Additional things to do:" + 1. Check if the proxy settings are appropriate for reaching the test + manager host. Python does not support domain matches starting with ".". + + For Debian and Ubuntu: check /etc/environment. + For EL: check /etc/profile and/or the files in /etc/profile.d/. + + 2. If the system should be doing RAM disk based testing, add the following + (or something similar, adapted to the system) to /etc/fstab: + + tmpfs /var/tmp/testbox-1000 tmpfs defaults,size=16G 0 0 + +After making such adjustments, it's the easiest solution to reboot the testbox. + +Enjoy! +EOF +} + diff --git a/src/VBox/ValidationKit/testboxscript/linux/testboxscript-service.sh b/src/VBox/ValidationKit/testboxscript/linux/testboxscript-service.sh new file mode 100755 index 00000000..61c93365 --- /dev/null +++ b/src/VBox/ValidationKit/testboxscript/linux/testboxscript-service.sh @@ -0,0 +1,501 @@ +#!/bin/sh +## @file +# VirtualBox Validation Kit - TestBoxScript service init script. +# + +# +# Copyright (C) 2006-2019 Oracle Corporation +# +# This file is part of VirtualBox Open Source Edition (OSE), as +# available from http://www.virtualbox.org. This file is free software; +# you can redistribute it and/or modify it under the terms of the GNU +# General Public License (GPL) as published by the Free Software +# Foundation, in version 2 as it comes in the "COPYING" file of the +# VirtualBox OSE distribution. VirtualBox OSE is distributed in the +# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. +# +# The contents of this file may alternatively be used under the terms +# of the Common Development and Distribution License Version 1.0 +# (CDDL) only, as it comes in the "COPYING.CDDL" file of the +# VirtualBox OSE distribution, in which case the provisions of the +# CDDL are applicable instead of those of the GPL. +# +# You may elect to license modified versions of this file under the +# terms and conditions of either the GPL or the CDDL or both. +# + +# chkconfig: 35 35 65 +# description: TestBoxScript service +# +### BEGIN INIT INFO +# Provides: testboxscript-service +# Required-Start: $network +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Description: TestBoxScript service +### END INIT INFO + + +PATH=$PATH:/bin:/sbin:/usr/sbin + +# +# Load config and set up defaults. +# +service_name="testboxscript" + +[ -r /etc/default/${service_name} ] && . /etc/default/${service_name} +[ -r /etc/conf.d/${service_name} ] && . /etc/conf.d/${service_name} + +if [ -z "${TESTBOXSCRIPT_DIR}" ]; then + TESTBOXSCRIPT_DIR="/opt/testboxscript" +fi +if [ -z "${TESTBOXSCRIPT_USER}" ]; then + TESTBOXSCRIPT_USER="vbox" +fi +binary="${TESTBOXSCRIPT_DIR}/testboxscript/testboxscript.py" +binary_real="${TESTBOXSCRIPT_DIR}/testboxscript/testboxscript_real.py" + + + +# +# Detect and abstract distro +# +[ -f /etc/debian_release -a -f /lib/lsb/init-functions ] || NOLSB=yes + +system=unknown +if [ -f /etc/redhat-release ]; then + system=redhat + PIDFILE="/var/run/${service_name}-service.pid" +elif [ -f /etc/SuSE-release ]; then + system=suse + PIDFILE="/var/lock/subsys/${service_name}-service" +elif [ -f /etc/debian_version ]; then + system=debian + PIDFILE="/var/run/${service_name}-service" +elif [ -f /etc/gentoo-release ]; then + system=gentoo + PIDFILE="/var/run/${service_name}-service" +elif [ -f /etc/arch-release ]; then + system=arch + PIDFILE="/var/run/${service_name}-service" +elif [ -f /etc/slackware-version ]; then + system=slackware + PIDFILE="/var/run/${service_name}-service" +elif [ -f /etc/lfs-release ]; then + system=lfs + PIDFILE="/var/run/${service_name}-service.pid" +else + system=other + if [ -d /var/run -a -w /var/run ]; then + PIDFILE="/var/run/${service_name}-service" + fi +fi + + +# +# Generic implementation. +# + +## Query daemon status. +# $1 = daemon-user; $2 = binary name +# returns 0 if running, 1 if started but no longer running, 3 if not started. +# When 0 is return the pid variable contains a list of relevant pids. +my_query_status() { + a_USER="$1"; + a_BINARY="$2"; + pid=""; + if [ -f "${PIDFILE}" -a -s "${PIDFILE}" ]; then + MY_LINE=""; + read MY_LINE < "${PIDFILE}"; + for MY_PID in `echo $MY_LINE | sed -e 's/[^0123456789 ]/ /g'`; + do + if [ "`stat -c '%U' /proc/$MY_PID 2> /dev/null `" = "$a_USER" ]; then + pid="${pid} ${MY_PID}"; + fi + done + if [ -n "${pid}" ]; then + RETVAL=0; + else + RETVAL=1; + fi + else + RETVAL=3 + fi + return $RETVAL; +} + +## Starts detached daeamon in screen. +# $1 = daemon-user; $2+ = daemon and its arguments +my_start_daemon() { + a_USER="$1" + shift + if touch "${PIDFILE}" && chown "${a_USER}" -- "${PIDFILE}"; then + ARGS="" + while [ $# -gt 0 ]; + do + ARGS="$ARGS '$1'"; + shift + done + ARGS="$ARGS --pidfile '$PIDFILE'"; + su - "${a_USER}" -c "screen -S ${service_name} -d -m ${ARGS} "; + RETVAL=$?; + if [ $RETVAL -eq 0 ]; then + sleep 0.6; + if [ ! -s "$PIDFILE" ]; then sleep 1; fi + if [ ! -s "$PIDFILE" ]; then sleep 2; fi + if [ ! -s "$PIDFILE" ]; then sleep 3; fi + if [ -s "$PIDFILE" ]; then + RETVAL=0; + else + RETVAL=1; + fi + else + fail_msg "su failed with exit code $RETVAL"; + fi + else + fail_msg "Failed to create pid file and change it's ownership to ${a_USER}." + RETVAL=1; + fi + return $RETVAL; +} + +## Stops the daemon. +# $1 = daemon-user; $2 = binary name +my_stop_daemon() { + a_USER="$1"; + a_BINARY="$2"; + my_query_status "$a_USER" "$a_BINARY" + RETVAL=$? + if [ $RETVAL -eq 0 -a -n "$pid" ]; then + kill $pid; + fi + sleep 0.6 + if my_query_status "$a_USER" "$a_BINARY"; then sleep 1; fi + if my_query_status "$a_USER" "$a_BINARY"; then sleep 2; fi + if my_query_status "$a_USER" "$a_BINARY"; then sleep 3; fi + if ! my_query_status "$a_USER" "$a_BINARY"; then + rm -f -- "${PIDFILE}" + return 0; + fi + return 1; +} + +if [ -z "$NOLSB" ]; then + . /lib/lsb/init-functions + fail_msg() { + echo "" + log_failure_msg "$1" + } + succ_msg() { + log_success_msg " done." + } + begin_msg() { + log_daemon_msg "$@" + } +else + fail_msg() { + echo " ...fail!" + echo "$@" + } + succ_msg() { + echo " ...done." + } + begin_msg() { + echo -n "$1" + } +fi + +# +# System specific overrides. +# + +if [ "$system" = "redhat" ]; then + . /etc/init.d/functions + if [ -n "$NOLSB" ]; then + fail_msg() { + echo_failure + echo + } + succ_msg() { + echo_success + echo + } + begin_msg() { + echo -n "$1" + } + fi +fi + +if [ "$system" = "suse" ]; then + . /etc/rc.status + if [ -n "$NOLSB" ]; then + fail_msg() { + rc_failed 1 + rc_status -v + } + succ_msg() { + rc_reset + rc_status -v + } + begin_msg() { + echo -n "$1" + } + fi +fi + +if [ "$system" = "debian" ]; then + # Share my_start_daemon and my_stop_daemon with gentoo + if [ -n "$NOLSB" ]; then + fail_msg() { + echo " ...fail!" + } + succ_msg() { + echo " ...done." + } + begin_msg() { + echo -n "$1" + } + fi +fi + +if [ "$system" = "gentoo" ]; then + if [ -f /sbin/functions.sh ]; then + . /sbin/functions.sh + elif [ -f /etc/init.d/functions.sh ]; then + . /etc/init.d/functions.sh + fi + # Share my_start_daemon and my_stop_daemon with debian. + if [ -n "$NOLSB" ]; then + if [ "`which $0`" = "/sbin/rc" ]; then + shift + fi + fi +fi + +if [ "$system" = "debian" -o "$system" = "gentoo" ]; then + #my_start_daemon() { + # usr="$1" + # shift + # bin="$1" + # shift + # echo usr=$usr + # start-stop-daemon --start --background --pidfile "${PIDFILE}" --make-pidfile --chuid "${usr}" --user "${usr}" \ + # --exec $bin -- $@ + #} + my_stop_daemon() { + a_USER="$1" + a_BINARY="$2" + start-stop-daemon --stop --user "${a_USER}" --pidfile "${PIDFILE}" + RETVAL=$? + rm -f "${PIDFILE}" + return $RETVAL + } +fi + +if [ "$system" = "arch" ]; then + USECOLOR=yes + . /etc/rc.d/functions + if [ -n "$NOLSB" ]; then + fail_msg() { + stat_fail + } + succ_msg() { + stat_done + } + begin_msg() { + stat_busy "$1" + } + fi +fi + +if [ "$system" = "lfs" ]; then + . /etc/rc.d/init.d/functions + if [ -n "$NOLSB" ]; then + fail_msg() { + echo_failure + } + succ_msg() { + echo_ok + } + begin_msg() { + echo $1 + } + fi +fi + +# +# Implement the actions. +# +check_single_user() { + if [ -n "$2" ]; then + fail_msg "TESTBOXSCRIPT_USER must not contain multiple users!" + exit 1 + fi +} + +# +# Open ports at the firewall: +# 6000..6100 / TCP for VRDP +# 5000..5032 / TCP for netperf +# 5000..5032 / UDP for netperf +# +set_iptables() { + if [ -x /sbin/iptables ]; then + I="/sbin/iptables -j ACCEPT -A INPUT -m state --state NEW" + if ! /sbin/iptables -L INPUT | grep -q "testsuite vrdp"; then + $I -m tcp -p tcp --dport 6000:6100 -m comment --comment "testsuite vrdp" + fi + if ! /sbin/iptables -L INPUT | grep -q "testsuite perftcp"; then + $I -m tcp -p tcp --dport 5000:5032 -m comment --comment "testsuite perftcp" + fi + if ! /sbin/iptables -L INPUT | grep -q "testsuite perfudp"; then + $I -m udp -p udp --dport 5000:5032 -m comment --comment "testsuite perfudp" + fi + fi +} + + +start() { + if [ ! -f "${PIDFILE}" ]; then + begin_msg "Starting TestBoxScript"; + + # + # Verify config and installation. + # + if [ ! -d "$TESTBOXSCRIPT_DIR" -o ! -r "$binary" -o ! -r "$binary_real" ]; then + fail_msg "Cannot find TestBoxScript installation under '$TESTBOXSCRIPT_DIR'!" + exit 0; + fi + ## @todo check ownership (for upgrade purposes) + check_single_user $TESTBOXSCRIPT_USER + + # + # Open some ports in the firewall + # Allows to access VMs remotely by VRDP, netperf + # + set_iptables + + # + # Set execute bits to make installation (unzip) easier. + # + chmod a+x > /dev/null 2>&1 \ + "${binary}" \ + "${binary_real}" \ + "${TESTBOXSCRIPT_DIR}/linux/amd64/TestBoxHelper" \ + "${TESTBOXSCRIPT_DIR}/linux/x86/TestBoxHelper" + + # + # Start the daemon as the specified user. + # + PARAMS="" + if [ "${TESTBOXSCRIPT_HWVIRT}" = "yes" ]; then PARAMS="${PARAMS} --hwvirt"; fi + if [ "${TESTBOXSCRIPT_HWVIRT}" = "no" ]; then PARAMS="${PARAMS} --no-hwvirt"; fi + if [ "${TESTBOXSCRIPT_NESTED_PAGING}" = "yes" ]; then PARAMS="${PARAMS} --nested-paging"; fi + if [ "${TESTBOXSCRIPT_NESTED_PAGING}" = "no" ]; then PARAMS="${PARAMS} --no-nested-paging"; fi + if [ "${TESTBOXSCRIPT_IOMMU}" = "yes" ]; then PARAMS="${PARAMS} --io-mmu"; fi + if [ "${TESTBOXSCRIPT_IOMMU}" = "no" ]; then PARAMS="${PARAMS} --no-io-mmu"; fi + if [ -n "${TESTBOXSCRIPT_SYSTEM_UUID}" ]; then PARAMS="${PARAMS} --system-uuid '${TESTBOXSCRIPT_SYSTEM_UUID}'"; fi + if [ -n "${TESTBOXSCRIPT_TEST_MANAGER}" ]; then PARAMS="${PARAMS} --test-manager '${TESTBOXSCRIPT_TEST_MANAGER}'"; fi + if [ -n "${TESTBOXSCRIPT_SCRATCH_ROOT}" ]; then PARAMS="${PARAMS} --scratch-root '${TESTBOXSCRIPT_SCRATCH_ROOT}'"; fi + + if [ -n "${TESTBOXSCRIPT_BUILDS_PATH}" ]; then PARAMS="${PARAMS} --builds-path '${TESTBOXSCRIPT_BUILDS_PATH}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_TYPE}" ]; then PARAMS="${PARAMS} --builds-server-type '${TESTBOXSCRIPT_BUILDS_TYPE}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_NAME}" ]; then PARAMS="${PARAMS} --builds-server-name '${TESTBOXSCRIPT_BUILDS_NAME}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_SHARE}" ]; then PARAMS="${PARAMS} --builds-server-share '${TESTBOXSCRIPT_BUILDS_SHARE}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_USER}" ]; then PARAMS="${PARAMS} --builds-server-user '${TESTBOXSCRIPT_BUILDS_USER}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_PASSWD}" ]; then PARAMS="${PARAMS} --builds-server-passwd '${TESTBOXSCRIPT_BUILDS_PASSWD}'"; fi + if [ -n "${TESTBOXSCRIPT_BUILDS_MOUNTOPT}" ]; then PARAMS="${PARAMS} --builds-server-mountopt '${TESTBOXSCRIPT_BUILDS_MOUNTOPT}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_PATH}" ]; then PARAMS="${PARAMS} --testrsrc-path '${TESTBOXSCRIPT_TESTRSRC_PATH}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_TYPE}" ]; then PARAMS="${PARAMS} --testrsrc-server-type '${TESTBOXSCRIPT_TESTRSRC_TYPE}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_NAME}" ]; then PARAMS="${PARAMS} --testrsrc-server-name '${TESTBOXSCRIPT_TESTRSRC_NAME}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_SHARE}" ]; then PARAMS="${PARAMS} --testrsrc-server-share '${TESTBOXSCRIPT_TESTRSRC_SHARE}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_USER}" ]; then PARAMS="${PARAMS} --testrsrc-server-user '${TESTBOXSCRIPT_TESTRSRC_USER}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_PASSWD}" ]; then PARAMS="${PARAMS} --testrsrc-server-passwd '${TESTBOXSCRIPT_TESTRSRC_PASSWD}'"; fi + if [ -n "${TESTBOXSCRIPT_TESTRSRC_MOUNTOPT}" ]; then PARAMS="${PARAMS} --testrsrc-server-mountopt '${TESTBOXSCRIPT_TESTRSRC_MOUNTOPT}'"; fi + + if [ -n "${TESTBOXSCRIPT_PYTHON}" ]; then + my_start_daemon "${TESTBOXSCRIPT_USER}" "${TESTBOXSCRIPT_PYTHON}" "${binary}" ${PARAMS} + else + my_start_daemon "${TESTBOXSCRIPT_USER}" "${binary}" ${PARAMS} + fi + RETVAL=$? + + if [ $RETVAL -eq 0 ]; then + succ_msg + else + fail_msg + fi + else + succ_msg "Already running." + RETVAL=0 + fi + return $RETVAL +} + +stop() { + if [ -f "${PIDFILE}" ]; then + begin_msg "Stopping TestBoxScript"; + my_stop_daemon "${TESTBOXSCRIPT_USER}" "${binary}" + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + succ_msg + else + fail_msg + fi + else + RETVAL=0 + fi + return $RETVAL +} + +restart() { + stop && sleep 1 && start +} + +status() { + echo -n "Checking for TestBoxScript" + my_query_status "${TESTBOXSCRIPT_USER}" "${binary}" + RETVAL=$? + if [ ${RETVAL} -eq 0 ]; then + echo " ...running" + elif [ ${RETVAL} -eq 3 ]; then + echo " ...stopped" + elif [ ${RETVAL} -eq 1 ]; then + echo " ...started but not running" + else + echo " ...unknown status '${RETVAL}'" + fi +} + + +# +# main(). +# +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + force-reload) + restart + ;; + status) + status + ;; + setup) + ;; + cleanup) + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 +esac + +exit $RETVAL + |