|
|
df396a |
#!/bin/bash
|
|
|
c5011b |
|
|
|
c5011b |
# Script to test the openSUSE infrastructure Salt code in a local container
|
|
|
c5011b |
# Copyright (C) 2017-2024 openSUSE contributors
|
|
|
c5011b |
#
|
|
|
c5011b |
# This program is free software: you can redistribute it and/or modify
|
|
|
c5011b |
# it under the terms of the GNU General Public License as published by
|
|
|
c5011b |
# the Free Software Foundation, either version 3 of the License, or
|
|
|
c5011b |
# (at your option) any later version.
|
|
|
c5011b |
#
|
|
|
c5011b |
# This program is distributed in the hope that it will be useful,
|
|
|
c5011b |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
c5011b |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
c5011b |
# GNU General Public License for more details.
|
|
|
c5011b |
#
|
|
|
c5011b |
# You should have received a copy of the GNU General Public License
|
|
|
c5011b |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Theo Chatzimichos |
96429a |
|
|
Theo Chatzimichos |
96429a |
help() {
|
|
|
c5011b |
echo 'Run tests on your workstation.'
|
|
|
c5011b |
echo 'Do NOT run this as root.'
|
|
Theo Chatzimichos |
96429a |
echo
|
|
Theo Chatzimichos |
96429a |
echo "Arguments:"
|
|
|
c5011b |
echo '-h - Print this text.'
|
|
|
c5011b |
echo
|
|
|
c5011b |
echo '-c - Use the specified existing container instead of instantiating a new one.'
|
|
|
c5011b |
echo '-k - Path to a public SSH key to use for authentication. If not specified, an insecure key will be used.'
|
|
|
c5011b |
echo '-p - Preserve container after tests finished running.'
|
|
|
b748c8 |
echo '-s - Test full highstates. This takes a lot of time!'
|
|
Theo Chatzimichos |
96429a |
echo
|
|
Theo Chatzimichos |
96429a |
}
|
|
Theo Chatzimichos |
96429a |
|
|
|
c5011b |
print() {
|
|
|
c5011b |
printf '==> %s\n' "$1"
|
|
|
c5011b |
}
|
|
|
c5011b |
|
|
|
c5011b |
pprint() {
|
|
|
df396a |
printf '==> %s %s ...\n' "$1" "$(gum style --foreground \#96cb5c "$2")"
|
|
|
c5011b |
}
|
|
|
c5011b |
|
|
|
c5011b |
fail() {
|
|
|
c5011b |
echo "$1"
|
|
|
c5011b |
exit 1
|
|
|
c5011b |
}
|
|
|
c5011b |
|
|
|
c5011b |
pfail() {
|
|
|
c5011b |
printf '! %s\n' "$(gum style --foreground \#d11137 FAILED)"
|
|
|
c5011b |
exit 1
|
|
|
c5011b |
}
|
|
Theo Chatzimichos |
96429a |
|
|
|
df396a |
[ "$(id -u)" = 0 ] && help && exit 1
|
|
|
df396a |
[ "$1" = '--help' ] && help && exit
|
|
Theo Chatzimichos |
96429a |
|
|
|
c5011b |
CONTAINER=''
|
|
|
c5011b |
CONTAINER_ARGS=()
|
|
|
c5011b |
SSH_ARGS=( '-t' '-oStrictHostKeyChecking=no' '-oUserKnownHostsFile=/dev/null' '-oLogLevel=ERROR' '-lchecker' )
|
|
|
c5011b |
PRESERVE=false
|
|
|
b748c8 |
HIGHSTATE=false
|
|
|
c5011b |
|
|
|
b748c8 |
while getopts h:c:k:p:s arg; do
|
|
|
c5011b |
case "$arg" in
|
|
Theo Chatzimichos |
96429a |
h) help && exit ;;
|
|
|
c5011b |
c) CONTAINER="${OPTARG}" ;;
|
|
|
c5011b |
k) PUBKEY=${OPTARG} ;;
|
|
|
c5011b |
p) CONTAINER_ARGS+=('--rm') ; PRESERVE=true ;;
|
|
|
b748c8 |
s) HIGHSTATE=true ;;
|
|
Theo Chatzimichos |
96429a |
*) help && exit 1 ;;
|
|
Theo Chatzimichos |
96429a |
esac
|
|
Theo Chatzimichos |
96429a |
done
|
|
Theo Chatzimichos |
96429a |
|
|
|
c5011b |
print 'Pre-flight check ...'
|
|
|
c215e0 |
test -f encrypted_pillar_recipients || fail 'Please run this script from the salt.git repository root.'
|
|
|
c5011b |
command -v podman >/dev/null || fail 'Please install Podman first.'
|
|
|
c5011b |
command -v ssh >/dev/null || fail 'Please install the OpenSSH client first.'
|
|
|
c5011b |
command -v rsync >/dev/null || fail 'Please install rsync first.'
|
|
|
c5011b |
getent hosts ipv6-localhost >/dev/null || fail 'Please ensure ipv6-localhost maps to ::1 (default on openSUSE).'
|
|
|
c5011b |
if [ -z "$PUBKEY" ] || ! file -bL "$PUBKEY" | grep -q 'OpenSSH .* public key'
|
|
|
c5011b |
then
|
|
|
c5011b |
fail 'Please provide a public OpenSSH key using -k.'
|
|
|
c5011b |
fi
|
|
Theo Chatzimichos |
96429a |
|
|
|
c5011b |
set -Cu
|
|
Theo Chatzimichos |
96429a |
|
|
|
c5011b |
if [ -z "$CONTAINER" ]
|
|
|
c5011b |
then
|
|
|
c5011b |
print 'Pulling container ...'
|
|
|
c5011b |
podman pull -q registry.opensuse.org/opensuse/infrastructure/containers/heroes-salt-development-systemd \
|
|
|
c5011b |
|| fail 'Failed to pull container'
|
|
|
c5011b |
|
|
|
c5011b |
print 'Preparing ...'
|
|
|
c5011b |
PORT=2222
|
|
|
c5011b |
while [ -n "$(ss -Htlno state listening sport = $PORT)" ]
|
|
|
c5011b |
do
|
|
|
c5011b |
PORT=$((PORT+1))
|
|
|
c5011b |
done
|
|
|
c5011b |
echo "$PORT"
|
|
|
c5011b |
|
|
|
c5011b |
print 'Starting ...'
|
|
|
c5011b |
CONTAINER=$( \
|
|
|
df396a |
podman run -de SSH_KEY="$(cat "$PUBKEY")" --health-interval 10s --health-start-period 15s "${CONTAINER_ARGS[@]}" -p "[::1]:$PORT:22" -v .:/home/geeko/salt-workspace:ro \
|
|
|
c5011b |
registry.opensuse.org/opensuse/infrastructure/containers/heroes-salt-development-systemd:latest \
|
|
|
c5011b |
)
|
|
|
c5011b |
timeout 90 podman wait --condition healthy "$CONTAINER" >/dev/null \
|
|
|
c5011b |
|| fail 'Failed to start container'
|
|
|
c5011b |
podman logs "$CONTAINER"
|
|
|
c5011b |
else
|
|
|
c5011b |
print "Preparing container $CONTAINER ..."
|
|
|
c5011b |
set -e
|
|
|
df396a |
podman ps | grep -q "$CONTAINER" || podman start "$CONTAINER"
|
|
|
c5011b |
timeout 60 podman wait --condition healthy "$CONTAINER" >/dev/null \
|
|
|
c5011b |
|| fail 'Failed to start container'
|
|
|
df396a |
PORT="$(podman inspect -f '{{(index (index .NetworkSettings.Ports "22/tcp") 0).HostPort}}' "$CONTAINER" || echo null)"
|
|
|
df396a |
if [ "$PORT" = 'null' ] || ! podman ps | grep -q "$CONTAINER"
|
|
|
c5011b |
then
|
|
|
c5011b |
fail 'Cannot work with the specified container.'
|
|
|
c5011b |
fi
|
|
|
c5011b |
podman exec "$CONTAINER" test -f /var/adm/firstboot-ok || fail 'Existing container was not set up correctly or does not use the expected image.'
|
|
|
df396a |
podman exec "$CONTAINER" sh -c "echo $(cat "$PUBKEY") >> /home/checker/.ssh/authorized_keys"
|
|
|
c5011b |
set +e
|
|
|
c5011b |
fi
|
|
|
c5011b |
|
|
|
c5011b |
SSH_ARGS+=("-p$PORT")
|
|
|
df396a |
SSH="ssh ${SSH_ARGS[*]}"
|
|
|
c5011b |
RSYNC_ARGS=('-l' '-r' '-e' "$SSH")
|
|
|
c5011b |
SSH="$SSH ipv6-localhost"
|
|
|
c5011b |
|
|
|
c5011b |
$SSH true || fail 'Container connection failed.'
|
|
|
c5011b |
$SSH sudo install -do checker /srv/salt-formulas /srv/salt-testbed || fail 'Failed to create directories.'
|
|
|
c5011b |
|
|
|
c5011b |
rsync "${RSYNC_ARGS[@]}" . ipv6-localhost:/srv/salt-testbed || fail 'Failed to transfer repository.'
|
|
|
c5011b |
|
|
|
c5011b |
$SSH sh <<-EOS || echo 'Test suite returned with errors.'
|
|
|
c5011b |
$(typeset -f pprint)
|
|
|
c5011b |
$(typeset -f pfail)
|
|
|
c5011b |
pushd /srv/salt-testbed >/dev/null
|
|
|
c5011b |
|
|
|
c5011b |
pprint 'Preparing test environment'
|
|
|
c5011b |
sudo bin/prepare_test_env.sh -g -s || pfail
|
|
|
b748c8 |
sudo sed -i 's/download-prg.infra.opensuse.org/download.opensuse.org/' /etc/zypp/repos.d/*
|
|
|
c5011b |
|
|
|
c5011b |
pprint Testing: validate
|
|
|
c5011b |
bin/test_validate.sh || pfail
|
|
|
c5011b |
|
|
|
c5011b |
pprint Testing: show_highstate
|
|
|
c5011b |
sudo bin/test_show_highstate.sh || pfail
|
|
|
c5011b |
|
|
|
df396a |
if [ "$HIGHSTATE" = 'true' ]
|
|
|
b748c8 |
then
|
|
|
b748c8 |
pprint Testing: highstate
|
|
|
b748c8 |
sudo bin/test_highstate.sh
|
|
|
b748c8 |
fi
|
|
|
b748c8 |
|
|
|
c5011b |
popd >/dev/null
|
|
|
c5011b |
pprint 'All tests' completed
|
|
|
c5011b |
EOS
|
|
|
c5011b |
|
|
|
df396a |
if [ "$PRESERVE" = 'false' ]
|
|
|
c5011b |
then
|
|
|
c5011b |
print 'Removing container ...'
|
|
|
c5011b |
podman stop "$CONTAINER" >/dev/null || fail 'Failed to stop container.'
|
|
|
c5011b |
podman rm "$CONTAINER" >/dev/null || fail 'Failed to remove container.'
|
|
|
c5011b |
fi
|
|
|
c5011b |
|
|
|
c5011b |
echo Bye.
|