diff options
Diffstat (limited to 'evergreen')
-rwxr-xr-x | evergreen/selinux_run_test.sh | 78 | ||||
-rwxr-xr-x | evergreen/selinux_test_executor.sh | 102 | ||||
-rwxr-xr-x | evergreen/selinux_test_setup.sh | 44 |
3 files changed, 224 insertions, 0 deletions
diff --git a/evergreen/selinux_run_test.sh b/evergreen/selinux_run_test.sh new file mode 100755 index 00000000000..318d73adbe2 --- /dev/null +++ b/evergreen/selinux_run_test.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Notes on how to run this manually: +# - repo must be unpacked into source tree +# +# export ssh_key=$HOME/.ssh/id_rsa +# export hostname=ec2-3-91-230-150.compute-1.amazonaws.com +# export user=ec2-user +# export bypass_prelude=yes +# export workdir="$(dirname $(pwd) | tee /dev/stderr)" +# export src="$(basename $(pwd) | tee /dev/stderr)" +# export test_list='jstests/selinux/*.js' +# export pkg_variant=mongodb-enterprise +# evergreen/selinux_run_test.sh + +set -o errexit + +DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)" +if [ "$bypass_prelude" != "yes" ]; then + . "$DIR/prelude.sh" + activate_venv + src="src" +fi + +set -o xtrace + +if [ "$hostname" == "" ]; then + hostname="$(tr -d '"[]{}' < "$workdir"/$src/hosts.yml | cut -d , -f 1 | awk -F : '{print $2}')" +fi + +if [ "$user" == "" ]; then + user=$USER +fi + +host="${user}@${hostname}" +python="${python:-python3}" + +if [ "$ssh_key" == "" ]; then + ssh_key="$workdir/selinux.pem" + "$workdir"/$src/buildscripts/yaml_key_value.py --yamlFile="$workdir"/expansions.yml \ + --yamlKey=__project_aws_ssh_key_value > "$ssh_key" + chmod 600 "$ssh_key" + result="$(openssl rsa -in "$ssh_key" -check -noout | tee /dev/stderr)" + if [ "$result" != "RSA key ok" ]; then + exit 1 + fi +fi + +attempts=0 +connection_attempts=50 + +# Check for remote connectivity +set +o errexit +ssh_options="-i $ssh_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no" +while ! ssh $ssh_options -o ConnectTimeout=10 "$host" echo "I am working"; do + if [ "$attempts" -ge "$connection_attempts" ]; then exit 1; fi + ((attempts++)) + printf "SSH connection attempt %d/%d failed. Retrying...\n" "$attempts" "$connection_attempts" + sleep 10 +done + +set -o errexit +echo "===> Copying sources to target..." +rsync -ar -e "ssh $ssh_options" \ + --exclude 'tmp' --exclude 'build' --exclude '.*' \ + "$workdir"/$src/* "$host": + +echo "===> Configuring target machine..." +ssh $ssh_options "$host" evergreen/selinux_test_setup.sh + +echo "===> Executing tests..." +list="$( + cd src + for x in $test_list; do echo "$x"; done +)" +for test in $list; do + ssh $ssh_options "$host" evergreen/selinux_test_executor.sh "$test" +done diff --git a/evergreen/selinux_test_executor.sh b/evergreen/selinux_test_executor.sh new file mode 100755 index 00000000000..1ba889a1c80 --- /dev/null +++ b/evergreen/selinux_test_executor.sh @@ -0,0 +1,102 @@ +#!/bin/bash + +set -o errexit +set -o xtrace + +function print() { + echo "$@" >&2 +} + +function monitor_log() { + sed "s!^!mongod| $(date '+%F %H-%M-%S') !" <(sudo --non-interactive tail -f /var/log/mongodb/mongod.log) +} + +TEST_PATH="$1" +if [ ! -f "$TEST_PATH" ]; then + print "No test supplied or test file not found. Run:" + print " $(basename "${BASH_SOURCE[0]}") <path>" + exit 1 +fi + +# test file is even good before going on +if ! mongo --nodb --norc --quiet "$TEST_PATH"; then + print "File $TEST_PATH has syntax errors" + exit 1 +fi + +# stop mongod, zero mongo log, clean up database, set all booleans to off +sudo --non-interactive bash -c ' + systemctl stop mongod + + rm -f /var/log/mongodb/mongod.log + touch /var/log/mongodb/mongod.log + chown mongod /var/log/mongodb/mongod.log + + rm -rf /var/lib/mongo/* + + rm -rf /etc/sysconfig/mongod /etc/mongod + + setsebool mongod_can_connect_snmp off + setsebool mongod_can_connect_ldap off + setsebool mongod_can_use_kerberos off +' + +# create mongo config +mongo --nodb --norc --quiet --eval=' + assert(load("'"$TEST_PATH"'")); + const test = new TestDefinition(); + print(typeof(test.config) === "string" ? test.config : JSON.stringify(test.config, null, 2)); +' | sudo --non-interactive tee /etc/mongod.conf + +# setup +mongo --nodb --norc --quiet --eval=' + assert(load("'"$TEST_PATH"'")); + const test = new TestDefinition(); + jsTest.log("Running setup()"); + test.setup(); +' + +# start log monitor, also kill it on exit +monitor_log & +MONITORPID="$!" +trap "sudo --non-interactive pkill -P $MONITORPID" SIGINT SIGTERM ERR EXIT + +# start mongod and if it won't come up, log SELinux errors +ts="$(date --utc --date='1 seconds ago' '+%x %H:%M:%S')" +tsj="$(date --utc --date='1 seconds ago' +'%Y-%m-%d %H:%M:%S')" +sudo --non-interactive systemctl start mongod \ + && sudo --non-interactive systemctl status mongod || ( + set +o errexit + echo "=== SELinux errors:" + sudo --non-interactive ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts $ts + echo "=== journalctl --unit=mongod:" + sudo --non-interactive journalctl --no-pager --since="$tsj" --unit=mongod --unit=systemd --catalog + echo "=== /var/log/mongodb/mongod.log:" + sudo --non-interactive cat /var/log/mongodb/mongod.log + echo "==== FAIL: mongod service was not started successfully" + exit 1 +) + +# run test and teardown +mongo --norc --gssapiServiceName=mockservice --eval=' + assert(load("'"$TEST_PATH"'")); + // name is such to prevent collisions + const test_812de7ce = new TestDefinition(); + try { + jsTest.log("Running test"); + test_812de7ce.run(); + } finally { + test_812de7ce.teardown(); + } +' || ( + echo "==== FAIL: test returned result: $?" + echo "=== SELinux errors:" + set +o errexit + sudo --non-interactive ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts $ts + echo "=== /var/log/mongodb/mongod.log:" + sudo --non-interactive cat /var/log/mongodb/mongod.log + exit 1 +) + +set +o xtrace +echo "SUCCESS: $TEST_PATH" diff --git a/evergreen/selinux_test_setup.sh b/evergreen/selinux_test_setup.sh new file mode 100755 index 00000000000..ef2e70df2a9 --- /dev/null +++ b/evergreen/selinux_test_setup.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +# This script is loaded on the target machine, which is running tests +# Purpose: install mongod and shell from packages + +set -o xtrace +set -o errexit + +function apply_selinux_policy() { + echo "==== Applying SELinux policy now" + rm -rf mongodb-selinux + git clone https://github.com/mongodb/mongodb-selinux + cd mongodb-selinux + make + sudo make install +} + +# on evergreen images /tmp is usually linked to /data/tmp, which interferes +# with selinux, as it does not recognize it as tmp_t domain +if [ -L /tmp ]; then + sudo --non-interactive rm /tmp + sudo --non-interactive mkdir /tmp + sudo --non-interactive systemctl start tmp.mount +fi + +# selinux policy should work both when applied before and after install +# we will randomly apply it before or after installation is completed +SEORDER="$(($RANDOM % 2))" +if [ "$SEORDER" == "0" ]; then + apply_selinux_policy +fi + +# install shell using yum, so that dependencies are pulled +pkg="$(find "$HOME"/repo -name 'mongodb-*-shell-*.x86_64.rpm' | tee /dev/stderr)" +sudo --non-interactive yum install --assumeyes "$pkg" \ + || if [ "$?" -gt "1" ]; then exit 1; fi # exit code 1 is OK + +pkg="$(find "$HOME"/repo -name 'mongodb-*-server-*.x86_64.rpm' | tee /dev/stderr)" +sudo --non-interactive rpm --install --verbose --verbose --hash --nodeps "$pkg" \ + || if [ "$?" -gt "1" ]; then exit 1; fi # exit code 1 is OK + +if [ "$SEORDER" == "1" ]; then + apply_selinux_policy +fi |