-
Notifications
You must be signed in to change notification settings - Fork 365
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ci(podman): add state tests in simple container #273
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: CI | ||
|
||
on: [push, pull_request, workflow_dispatch] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
strategy: | ||
matrix: | ||
img: | ||
- opensuse.leap | ||
- debian.11 | ||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Test | ||
run: | | ||
cd t && \ | ||
make test_container | ||
env: | ||
T_IMAGE: ${{ matrix.img }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!lib/test-in-container-systemd.sh mariadb | ||
|
||
set -ex | ||
|
||
salt-call --local state.apply 'mysql' | ||
salt-call --local state.apply 'mysql.remove_test_database' | ||
|
||
mysql -e 'select user(), current_user(), version()' | ||
|
||
service mysql status | ||
|
||
echo success |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The precommit fails on this file |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!lib/test-in-container-systemd.sh mariadb-client | ||
|
||
set -ex | ||
|
||
######################### | ||
# workaround for https://github.com/saltstack-formulas/mysql-formula/issues/267 | ||
( grep -qi debian /etc/*release && mkdir -p /etc/mysql ) || \ | ||
( grep -qi suse /etc/*release && mkdir -p /etc/my.cnf.d ) || \ | ||
: | ||
######################### | ||
|
||
salt-call --local state.apply 'mysql.client' | ||
|
||
mariadb -V || mysql -V | ||
|
||
# check mysqld service is not installed | ||
rc=0 | ||
service mysql status || rc=$? | ||
test $rc -gt 0 | ||
|
||
rc=0 | ||
service mysql status || rc=$? | ||
test $rc -gt 0 | ||
|
||
rc=0 | ||
service mariadb status || rc=$? | ||
test $rc -gt 0 | ||
|
||
echo success |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The precommit fails on this file |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
#!lib/test-in-container-systemd.sh mariadb | ||
|
||
set -ex | ||
|
||
# hack the pillar | ||
mkdir -p /srv/pillar | ||
echo " | ||
mysql: | ||
server: | ||
mysqld: | ||
max_allowed_packet: 1111040 | ||
database: | ||
- testdb | ||
user: | ||
myuser1: | ||
password: 'mypass123' | ||
host: localhost | ||
databases: | ||
- database: testdb | ||
grants: ['all'] | ||
" > /srv/pillar/testdata.sls | ||
|
||
echo ' | ||
{{ saltenv }}: | ||
"*": | ||
- testdata | ||
' >> /srv/pillar/top.sls | ||
|
||
|
||
salt-call --local pillar.get mysql:user:myuser1:password | ||
salt-call --local pillar.item mysql:user:myuser1:password | grep mypass123 | ||
|
||
pass=$(echo $(salt-call --local pillar.get mysql:user:myuser1:password) | tail -n 1 | grep -Eo '[^ ]+$') | ||
test "$pass" == mypass123 | ||
|
||
salt-call --local state.apply 'mysql' | ||
salt-call --local state.apply 'mysql.remove_test_database' | ||
|
||
set -a | ||
shopt -s expand_aliases | ||
alias sql="mariadb -h 127.0.0.1 -umyuser1 -p$pass -e" | ||
( | ||
|
||
sql 'select user(), current_user(), version()' | ||
|
||
packet="$(sql 'show variables like "max_allowed_packet"' -Nb)" | ||
test 1111040 == ${packet//[!0-9]/} | ||
|
||
echo test access denied to mysql database | ||
rc=0 | ||
sql 'select user, host from mysql.user' || rc=$? | ||
test "$rc" -gt 0 | ||
|
||
echo test wrong password is denied | ||
rc=0 | ||
sql 'select user(), current_user(), version()' -p"wrongpassword" || rc=$? | ||
test "$rc" -gt 0 | ||
) | ||
|
||
service mariadb status || service mysql status | ||
|
||
echo success |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
|
||
|
||
test_container: | ||
( for f in *.sh; do ./$$f && continue; echo FAIL $$f; exit 1 ; done ) | ||
|
||
test_container_fast: | ||
( for f in *.sh; do T_CACHE_PACKAGES=1 ./$$f && continue; echo FAIL $$f; exit 1 ; done ) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
Scripts to test SLS changes in podman containers | ||
------------------- | ||
|
||
The goal is to cover following workflow: | ||
|
||
* Change files related to an individual state. | ||
* Spawn a container with a local standalone salt node and apply the states. | ||
* Check basic bash commands to verify outcome. | ||
|
||
The test is set of bash commands. | ||
The script relies on shebang to prepare an image and spawn a container with the sls files. | ||
It is also ready to test salt states using set of commands `salt-call --local`. | ||
|
||
###### Example: Run test for mysql states: | ||
|
||
```bash | ||
cd t | ||
./01-smoke-server.sh | ||
``` | ||
|
||
#### Challenge 1: By default, a container is destroyed when the test finishes. | ||
|
||
This is to simplify re-run of tests and do not flood machine with leftover containers after tests. | ||
To make sure container stays around after faiure - set environment variable *T_PAUSE_ON_FAILURE* to 1 | ||
|
||
###### Example: Connect to the container after test failure | ||
|
||
```bash | ||
> # terminal 1 | ||
> echo fail >> 01-smoke-server.sh | ||
> T_PAUSE_ON_FAILURE=1 ./01-smoke-server.sh | ||
... | ||
bash: line 18: fail: command not found | ||
Test failed, press any key to finish | ||
``` | ||
The terminal will wait for any input to finish the test and clean up the container. | ||
Now use another terminal window to check the running podman container and get into it for eventual troubleshooting: | ||
|
||
```bash | ||
> # terminal 2 | ||
> podman ps | ||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | ||
2a37d23503fa localhost/mysql.formula.t38c8b1d778efa61c676f1aa99b2aded5.image:latest 4 minutes ago Up 4 minutes ago mysql.formula.t38c8b1d778efa61c676f1aa99b2aded5.01-smoke-server.sh | ||
> # use copy container id to start bash in it (hint: or bash completion should work for container name as well) | ||
> podman exec -it mysql.formuls.t38c8b1d778efa61c676f1aa99b2aded5.01-smoke-server.sh bash | ||
2a37d23503fa:/opt/project # ls | ||
bin encrypted_pillar_recipients ENCRYPTION.md FORMULAS.yaml gpgkeys pillar README.md salt t test | ||
2a37d23503fa:/opt/project # # now we are inside the container and can troubleshoot outcome of salt commands | ||
2a37d23503fa:/opt/project # rcmysql status | ||
* mariadb.service - MariaDB database server | ||
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; disabled; vendor preset: disabled) | ||
Active: active (running) since Fri 2023-03-17 12:45:24 UTC; 10min ago | ||
``` | ||
|
||
#### Challenge 2: Vary OS in container. | ||
|
||
Create new file Dockerfile.%osname% similar to existing Docker files in t/lib. | ||
Use environment variable T_IMAGE=%osname% to let scripts use corresponding Dockerfile. | ||
By default tests are run with t/Dockerfile.opensuse.leap | ||
|
||
#### Challenge 3: Cache packages inside test image. | ||
|
||
(Currently works only with default docker image, i.e. T_IMAGE is empty). | ||
Downloading and installing packages may be time consuming, so sometimes it may be advantageous to have an option to pre-install required packages inside image, in which the test will be run. (So the test will concentrate on verifying other aspects of salt states, without spending time on installing packages). | ||
At the same time the CI needs to verify salt states related to installation, so it must run the test without such caching. | ||
Such caching is implemented as optional parameters to shebang command in the test scripts. These parameters are ignored unless global variable *T_CACHE_PACKAGES* is set to 1. | ||
|
||
```bash | ||
> # check parameter in shebang: | ||
> head -n 1 01-smoke-server.sh | ||
#!lib/test-in-container-systemd.sh mariadb | ||
> # run the test in a container with preinstalled mariadb package as specified above: | ||
> T_CACHE_PACKAGES=1 ./01-smoke-server.sh | ||
> # run the test in a container without preinstalled mariadb package (will take longer, but will verify package installation as part of test) | ||
> ./01-smoke-server.sh | ||
``` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
FROM debian:11 | ||
ENV container podman | ||
|
||
ENV LANG en_US.UTF-8 | ||
|
||
# these are needed to run test | ||
RUN apt-get -y update && apt-get -y upgrade | ||
RUN apt-get -y install systemd salt-minion curl sudo | ||
|
||
##DUMMY | ||
|
||
RUN mkdir -p /srv/salt/ && \ | ||
sed -i 's^\#*\s*file_client: .*$^file_client: local\nsystemd.scope: False\nenable_fqdns_grains: False^' /etc/salt/minion | ||
|
||
ADD mysql /srv/salt/mysql | ||
|
||
WORKDIR /opt/project | ||
|
||
ENTRYPOINT ["/bin/systemd"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
FROM registry.opensuse.org/opensuse/leap | ||
ENV container podman | ||
|
||
ENV LANG en_US.UTF-8 | ||
|
||
RUN test ! -f /var/log/zypper.log || mv /var/log/zypper.log /var/log/zypper.log.preinstalled | ||
|
||
# these are needed to run test | ||
RUN zypper -vvvn install systemd salt-minion sudo | ||
|
||
##DUMMY | ||
|
||
RUN mkdir -p /srv/salt/ && \ | ||
sed -i 's^\#*\s*file_client: .*$^file_client: local\nsystemd.scope: False\nenable_fqdns_grains: False^' /etc/salt/minion && \ | ||
sed -i '/pam_systemd.so/d' /etc/pam.d/common-session-pc # delete pam_systemd , otherwise sudo will hang | ||
|
||
ADD mysql /srv/salt/mysql | ||
|
||
WORKDIR /opt/project | ||
|
||
ENTRYPOINT ["/usr/lib/systemd/systemd"] |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The precommit fails on this file |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#!/bin/bash | ||
# | ||
# Copyright (C) 2023 SUSE LLC | ||
# | ||
# 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/>. | ||
|
||
last=${@:$#} # last parameter | ||
other=${*%${!#}} # all parameters except the last | ||
|
||
testcase=$last | ||
|
||
set -euo pipefail | ||
PODMAN=podman | ||
image=${T_IMAGE-opensuse.leap} | ||
( | ||
PODMAN_info="$($PODMAN info >/dev/null 2>&1)" || $PODMAN info | ||
[ -n "$testcase" ] || (echo No testcase provided; exit 1) | ||
[ -f "$testcase" ] || (echo Cannot find file "$testcase"; exit 1 ) | ||
) >&2 | ||
|
||
thisdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" | ||
basename=$(basename "$testcase") | ||
basename=${basename,,} | ||
basename=${basename//:/_} | ||
|
||
othermd5= | ||
test -z "$other" || othermd5=($(echo "$other" | md5sum -)) | ||
|
||
ident=mysql.formula.t$othermd5 | ||
containername="$ident.${basename,,}" | ||
|
||
# we use variable T_CACHE_PACKAGES to speedup testing and make sure that | ||
( | ||
if test -z "$other" || \ | ||
test "${T_IMAGE-}" != "" || \ | ||
test "${T_CACHE_PACKAGES:-}" != 1 | ||
then | ||
cat $thisdir/Dockerfile.${image} | ||
else | ||
ar="" | ||
in="zypper -vvvn in " | ||
for pkg in $other vim; do | ||
if [[ $pkg == *:* ]]; then | ||
n=${pkg//*:} | ||
ar="$ar zypper -n ar http://download.opensuse.org/repositories/$pkg/\\\\\$releasever/ $n;" | ||
in="$in $n" | ||
else | ||
in="$in $pkg" | ||
fi | ||
done | ||
test -z "$ar" || ar="$ar zypper --gpg-auto-import-keys ref; " | ||
|
||
sed "s,\#\#DUMMY,RUN $ar $in,g" $thisdir/Dockerfile.${T_IMAGE} | ||
fi | ||
|
||
) | cat | $PODMAN build -t $ident.image -f - $thisdir/../.. | ||
|
||
map_port="" | ||
[ -z "${EXPOSE_PORT:-}" ] || map_port="-p $EXPOSE_PORT:80" | ||
$PODMAN run --privileged --rm $map_port --name "$containername" -d -v"$thisdir/../..":/opt/project --add-host localhost:127.0.0.1 -- $ident.image | ||
|
||
in_cleanup=0 | ||
|
||
ret=111 | ||
|
||
function cleanup { | ||
[ "$in_cleanup" != 1 ] || return | ||
in_cleanup=1 | ||
if [ "$ret" != 0 ] && [ -n "${T_PAUSE_ON_FAILURE-}" ]; then | ||
read -rsn1 -p"Test failed, press any key to finish";echo | ||
fi | ||
[ "$ret" == 0 ] || echo FAIL $basename | ||
$PODMAN stop -t 0 "$containername" >&/dev/null || : | ||
} | ||
|
||
trap cleanup INT TERM EXIT | ||
counter=1 | ||
|
||
# wait container start | ||
until [ $counter -gt 10 ]; do | ||
sleep 0.5 | ||
$PODMAN exec "$containername" pwd >& /dev/null && break | ||
((counter++)) | ||
done | ||
|
||
$PODMAN exec "$containername" pwd >& /dev/null || (echo Cannot start container; exit 1 ) >&2 | ||
|
||
echo "$*" | ||
# [ -z $initscript ] || echo "bash -xe /opt/project/t/$initscript" | $PODMAN exec -i "$containername" bash -x | ||
|
||
set +e | ||
$PODMAN exec -e TESTCASE="$testcase" -i "$containername" bash -xe < "$testcase" | ||
ret=$? | ||
( exit $ret ) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The precommit fails on this file