#!/bin/bash set -e USAGE="USAGE: $(basename "$0") [run|edit] " GOSS_FILES_PATH="${GOSS_FILES_PATH:-.}" info() { echo -e "INFO: $*" >&2; } error() { echo -e "ERROR: $*" >&2; exit 1; } cleanup() { set +e { kill "$log_pid" && wait "$log_pid"; } 2> /dev/null rm -rf "$tmp_dir" if [[ $id ]];then info "Deleting container" docker rm -vf "$id" > /dev/null fi } run(){ # Copy in goss cp "${GOSS_PATH}" "$tmp_dir/goss" chmod 755 "$tmp_dir/goss" [[ -e "${GOSS_FILES_PATH}/goss.yaml" ]] && cp "${GOSS_FILES_PATH}/goss.yaml" "$tmp_dir" [[ -e "${GOSS_FILES_PATH}/goss_wait.yaml" ]] && cp "${GOSS_FILES_PATH}/goss_wait.yaml" "$tmp_dir" [[ ! -z "${GOSS_VARS}" ]] && [[ -e "${GOSS_FILES_PATH}/${GOSS_VARS}" ]] && cp "${GOSS_FILES_PATH}/${GOSS_VARS}" "$tmp_dir" # Switch between mount or cp files strategy 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}") docker logs -f "$id" > "$tmp_dir/docker_output.log" 2>&1 & ;; cp) info "Creating docker container" id=$(docker create ${@:2}) info "Copy goss files into container" docker cp $tmp_dir/. $id:/goss info "Starting docker container" docker start $id > /dev/null ;; *) error "Wrong goss files strategy used! Correct options are \"mount\" or \"cp\"." esac log_pid=$! info "Container ID: ${id:0:8}" } get_docker_file() { if docker exec "$id" sh -c "test -e $1" > /dev/null;then mkdir -p "${GOSS_FILES_PATH}" info "Copied '$1' from container to '${GOSS_FILES_PATH}'" docker cp "$id:$1" "${GOSS_FILES_PATH}" fi } # Main tmp_dir=$(mktemp -d /tmp/tmp.XXXXXXXXXX) chmod 777 "$tmp_dir" trap 'ret=$?;cleanup;exit $ret' EXIT GOSS_PATH="${GOSS_PATH:-$(which goss 2> /dev/null || true)}" [[ $GOSS_PATH ]] || { error "Couldn't find goss installation, please set GOSS_PATH to it"; } [[ ${GOSS_OPTS+x} ]] || GOSS_OPTS="--color --format documentation" [[ ${GOSS_WAIT_OPTS+x} ]] || GOSS_WAIT_OPTS="-r 30s -s 1s > /dev/null" GOSS_SLEEP=${GOSS_SLEEP:-0.2} 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 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 error "goss_wait.yaml never passed" fi fi fi [[ $GOSS_SLEEP ]] && { info "Sleeping for $GOSS_SLEEP"; sleep "$GOSS_SLEEP"; } # info "Container health" # if ! docker top $id; then # docker logs $id # fi info "Running Tests" if [[ -z "${GOSS_VARS}" ]]; then docker 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" fi ;; edit) run "$@" info "Run goss add/autoadd to add resources" docker exec -it "$id" sh -c 'cd /goss; PATH="/goss:$PATH" exec sh' get_docker_file "/goss/goss.yaml" get_docker_file "/goss/goss_wait.yaml" [[ ! -z "${GOSS_VARS}" ]] && get_docker_file "/goss/${GOSS_VARS}" ;; *) error "$USAGE" esac