Skip to content

Commit

Permalink
Add support for podman as the container backend (#748)
Browse files Browse the repository at this point in the history
The `CONTAINER_RUNTIME` environment variable can be used to control container
runtime. Can be `docker` or `podman`. Defaults to `docker`.

To be able to use `podman` as the container backend `podman run` needs to run
a command which does not finish. Commonly `sleep infinity` is used for that.

Provide enough documentation to understand the feature for the users.

Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
  • Loading branch information
thrix authored Apr 8, 2022
1 parent 70b4af2 commit a2153db
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 20 deletions.
3 changes: 3 additions & 0 deletions extras/dgoss/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,6 @@ Strategy used for copying goss files into the docker container. If set to `'moun

##### CONTAINER_LOG_OUTPUT
Location of the file that contains tested container logs. Logs are retained only if the variable is set to a non-empty string. (Default `''`)

##### CONTAINER_RUNTIME
Container runtime to use - `docker` or `podman`. Defaults to `docker`. Note that `podman` requires a run command to keep the container running. This defaults to `sleep infinity` in case only an image is passed to `dgoss` commands.
49 changes: 29 additions & 20 deletions extras/dgoss/dgoss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ set -e
USAGE="USAGE: $(basename "$0") [run|edit] <docker_run_params>"
GOSS_FILES_PATH="${GOSS_FILES_PATH:-.}"

# Container runtime
CONTAINER_RUNTIME="${CONTAINER_RUNTIME:-docker}"

info() {
echo -e "INFO: $*" >&2;
}
Expand All @@ -22,7 +25,7 @@ cleanup() {
rm -rf "$tmp_dir"
if [[ $id ]];then
info "Deleting container"
docker rm -vf "$id" > /dev/null
$CONTAINER_RUNTIME rm -vf "$id" > /dev/null
fi
}

Expand All @@ -38,21 +41,25 @@ run(){
GOSS_FILES_STRATEGY=${GOSS_FILES_STRATEGY:="mount"}
case "$GOSS_FILES_STRATEGY" in
mount)
info "Starting docker container"
id=$(docker run -d -v "$tmp_dir:/goss:z" "${@:2}")
info "Starting $CONTAINER_RUNTIME container"
if [ "$CONTAINER_RUNTIME" == "podman" -a $# == 2 ]; then
id=$($CONTAINER_RUNTIME run -d -v "$tmp_dir:/goss:z" "${@:2}" sleep infinity)
else
id=$($CONTAINER_RUNTIME run -d -v "$tmp_dir:/goss:z" "${@:2}")
fi
;;
cp)
info "Creating docker container"
id=$(docker create "${@:2}")
info "Creating $CONTAINER_RUNTIME container"
id=$($CONTAINER_RUNTIME create "${@:2}")
info "Copy goss files into container"
docker cp $tmp_dir/. $id:/goss
info "Starting docker container"
docker start $id > /dev/null
$CONTAINER_RUNTIME cp $tmp_dir/. $id:/goss
info "Starting $CONTAINER_RUNTIME container"
$CONTAINER_RUNTIME start $id > /dev/null
;;
*) error "Wrong goss files strategy used! Correct options are \"mount\" or \"cp\"."
esac

docker logs -f "$id" > "$tmp_dir/docker_output.log" 2>&1 &
$CONTAINER_RUNTIME logs -f "$id" > "$tmp_dir/docker_output.log" 2>&1 &
log_pid=$!
info "Container ID: ${id:0:8}"
}
Expand All @@ -62,9 +69,9 @@ get_docker_file() {
local src=$2 # Source file path (in the container)
local dst=$3 # Destination file path

if docker exec "${cid}" sh -c "test -e ${src}" > /dev/null; then
if $CONTAINER_RUNTIME exec "${cid}" sh -c "test -e ${src}" > /dev/null; then
mkdir -p "${GOSS_FILES_PATH}"
docker cp "${cid}:${src}" "${dst}"
$CONTAINER_RUNTIME cp "${cid}:${src}" "${dst}"
info "Copied '${src}' from container to '${dst}'"
fi
}
Expand All @@ -80,40 +87,42 @@ GOSS_PATH="${GOSS_PATH:-$(which goss 2> /dev/null || true)}"
[[ ${GOSS_WAIT_OPTS+x} ]] || GOSS_WAIT_OPTS="-r 30s -s 1s > /dev/null"
GOSS_SLEEP=${GOSS_SLEEP:-0.2}

[[ $CONTAINER_RUNTIME =~ ^(docker|podman)$ ]] || { error "Runtime must be one of docker or podman"; }

case "$1" in
run)
run "$@"
if [[ -e "${GOSS_FILES_PATH}/goss_wait.yaml" ]]; then
info "Found goss_wait.yaml, waiting for it to pass before running tests"
if [[ -z "${GOSS_VARS}" ]]; then
if ! docker exec "$id" sh -c "/goss/goss -g /goss/goss_wait.yaml validate $GOSS_WAIT_OPTS"; then
docker logs $id >&2
if ! $CONTAINER_RUNTIME exec "$id" sh -c "/goss/goss -g /goss/goss_wait.yaml validate $GOSS_WAIT_OPTS"; then
$CONTAINER_RUNTIME logs $id >&2
error "goss_wait.yaml never passed"
fi
else
if ! docker exec "$id" sh -c "/goss/goss -g /goss/goss_wait.yaml --vars='/goss/${GOSS_VARS}' validate $GOSS_WAIT_OPTS"; then
docker logs $id >&2
if ! $CONTAINER_RUNTIME exec "$id" sh -c "/goss/goss -g /goss/goss_wait.yaml --vars='/goss/${GOSS_VARS}' validate $GOSS_WAIT_OPTS"; then
$CONTAINER_RUNTIME logs $id >&2
error "goss_wait.yaml never passed"
fi
fi
fi
[[ $GOSS_SLEEP ]] && { info "Sleeping for $GOSS_SLEEP"; sleep "$GOSS_SLEEP"; }
info "Container health"
if [ "true" != "$(docker inspect -f '{{.State.Running}}' $id)" ]; then
docker logs $id >&2
if [ "true" != "$($CONTAINER_RUNTIME inspect -f '{{.State.Running}}' $id)" ]; then
$CONTAINER_RUNTIME logs $id >&2
error "the container failed to start"
fi
info "Running Tests"
if [[ -z "${GOSS_VARS}" ]]; then
docker exec "$id" sh -c "/goss/goss -g /goss/goss.yaml validate $GOSS_OPTS"
$CONTAINER_RUNTIME exec "$id" sh -c "/goss/goss -g /goss/goss.yaml validate $GOSS_OPTS"
else
docker exec "$id" sh -c "/goss/goss -g /goss/goss.yaml --vars='/goss/${GOSS_VARS}' validate $GOSS_OPTS"
$CONTAINER_RUNTIME exec "$id" sh -c "/goss/goss -g /goss/goss.yaml --vars='/goss/${GOSS_VARS}' validate $GOSS_OPTS"
fi
;;
edit)
run "$@"
info "Run goss add/autoadd to add resources"
docker exec -it "$id" sh -c 'cd /goss; PATH="/goss:$PATH" exec sh'
$CONTAINER_RUNTIME exec -it "$id" sh -c 'cd /goss; PATH="/goss:$PATH" exec sh'
get_docker_file "$id" "/goss/goss.yaml" "${GOSS_FILES_PATH}/${GOSS_FILE:-goss.yaml}"
get_docker_file "$id" "/goss/goss_wait.yaml" "${GOSS_FILES_PATH}/goss_wait.yaml"
[[ ! -z "${GOSS_VARS}" ]] && get_docker_file "$id" "/goss/${GOSS_VARS}" "${GOSS_FILES_PATH}/${GOSS_VARS}"
Expand Down

0 comments on commit a2153db

Please sign in to comment.