diff --git a/.gitignore b/.gitignore index 348c7ec..f08ef08 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .shellspec-quick.log coverage +gantry-test-tmp \ No newline at end of file diff --git a/src/entrypoint.sh b/src/entrypoint.sh index 1041ba1..8c46b92 100755 --- a/src/entrypoint.sh +++ b/src/entrypoint.sh @@ -63,7 +63,7 @@ load_libraries() { _run_on_node() { local HOST_NAME= - if ! HOST_NAME=$(docker node inspect self --format "{{.Description.Hostname}}" 2>&1); then + if ! HOST_NAME=$(run_docker_cmd node inspect self --format "{{.Description.Hostname}}"); then log DEBUG "Failed to run \"docker node inspect self\": ${HOST_NAME}" return 1 fi @@ -107,6 +107,7 @@ gantry() { START_TIME=$(date +%s) [ -n "${DOCKER_HOST}" ] && log DEBUG "DOCKER_HOST=${DOCKER_HOST}" + [ -n "${DOCKER_CONFIG}" ] && log DEBUG "DOCKER_CONFIG=${DOCKER_CONFIG}" local RUN_ON_NODE= if ! RUN_ON_NODE=$(_run_on_node); then local HOST_STRING="${DOCKER_HOST:-"the current node"}" diff --git a/src/lib-common.sh b/src/lib-common.sh index 5b5ada2..0366a5e 100755 --- a/src/lib-common.sh +++ b/src/lib-common.sh @@ -434,13 +434,37 @@ eval_cmd() { return "${RETURN_VALUE}" } +# To replace "docker" command +# When the docker command returns 0: +# Echo stdout and log stderr as a warning. Return 0. +# When the docker command returns non-zero: +# Echo stdout + stderr. Return the same value from the docker command. +run_docker_cmd() { + local STDERR_STR= + local RETURN_VALUE= + # Use "3>&2 2>&1 1>&3" to swap stdout and stderr + { STDERR_STR=$(docker "${@}" 3>&2 2>&1 1>&3); } 2>&1 + RETURN_VALUE=$? + + if [ -n "${STDERR_STR}" ]; then + if [ "${RETURN_VALUE}" = 0 ]; then + log WARN "docker ${*}: ${STDERR_STR}" + else + echo "${STDERR_STR}" + fi + fi + return "${RETURN_VALUE}" +} + swarm_network_arguments() { if [ -z "${NETWORK_NAME}" ]; then echo "" return 0 fi - NETWORK_NAME=$(docker network ls --filter "name=${NETWORK_NAME}" --format '{{.Name}}') - if [ -z "${NETWORK_NAME}" ]; then + local RETURN_VALUE= + NETWORK_NAME=$(run_docker_cmd network ls --filter "name=${NETWORK_NAME}" --format '{{.Name}}') + RETURN_VALUE=$? + if [ "${RETURN_VALUE}" != "0" ] || [ -z "${NETWORK_NAME}" ]; then echo "" return 0 fi @@ -513,8 +537,8 @@ _docker_service_task_states() { local SERVICE_NAME="${1}" # We won't get the return value of the command via $? if we use "local STATES=$(command)". local STATES= - if ! STATES=$(docker service ps --no-trunc --format '[{{.Name}}][{{.Node}}] {{.CurrentState}} {{.Error}}' "${SERVICE_NAME}" 2>&1); then - echo "${STATES}" >&2 + if ! STATES=$(run_docker_cmd service ps --no-trunc --format '[{{.Name}}][{{.Node}}] {{.CurrentState}} {{.Error}}' "${SERVICE_NAME}"); then + log ERROR "${STATES}" return 1 fi local NAME_LIST= @@ -591,7 +615,7 @@ wait_service_state() { local RETURN_VALUE=0 local DOCKER_CMD_ERROR=1 local STATES= - while STATES=$(_docker_service_task_states "${SERVICE_NAME}" 2>&1); do + while STATES=$(_docker_service_task_states "${SERVICE_NAME}"); do DOCKER_CMD_ERROR=0 RETURN_VALUE=$(_all_tasks_reach_state "${WANT_STATE}" "${CHECK_FAILURES}" "${STATES}") && break local SECONDS_ELAPSED= @@ -606,7 +630,7 @@ wait_service_state() { DOCKER_CMD_ERROR=1 done if [ "${DOCKER_CMD_ERROR}" != "0" ]; then - log ERROR "Failed to obtain task states of service ${SERVICE_NAME}: ${STATES}" + log ERROR "Failed to obtain task states of service ${SERVICE_NAME}." return 1 fi local LINE= @@ -621,12 +645,10 @@ docker_service_remove() { local POST_COMMAND="${2}" ! _docker_service_exists "${SERVICE_NAME}" && return 0 log DEBUG "Removing service ${SERVICE_NAME}." - local RETURN_VALUE=0 local LOG= - if ! LOG=$(docker service rm "${SERVICE_NAME}" 2>&1); then - RETURN_VALUE=$? + if ! LOG=$(run_docker_cmd service rm "${SERVICE_NAME}"); then log ERROR "Failed to remove docker service ${SERVICE_NAME}: ${LOG}" - return "${RETURN_VALUE}" + return 1 fi if [ -n "${POST_COMMAND}" ]; then eval "${POST_COMMAND}" @@ -654,7 +676,7 @@ docker_global_job() { SERVICE_NAME=$(_get_docker_command_name_arg "${@}") log INFO "Starting global-job ${SERVICE_NAME}." local LOG= - if ! LOG=$(docker service create --mode global-job "${@}" 2>&1); then + if ! LOG=$(run_docker_cmd service create --mode global-job "${@}"); then log ERROR "Failed to create global-job ${SERVICE_NAME}: ${LOG}" return 1 fi @@ -669,7 +691,7 @@ docker_replicated_job() { # The Docker CLI does not exit on failures. log INFO "Starting replicated-job ${SERVICE_NAME}." local LOG= - if ! LOG=$(docker service create --mode replicated-job --detach "${@}" 2>&1); then + if ! LOG=$(run_docker_cmd service create --mode replicated-job --detach "${@}"); then log ERROR "Failed to create replicated-job ${SERVICE_NAME}: ${LOG}" return 1 fi @@ -682,10 +704,10 @@ docker_replicated_job() { docker_version() { local cver capi sver sapi - if ! cver=$(docker version --format '{{.Client.Version}}' 2>&1); then log ERROR "${cver}"; cver="error"; fi - if ! capi=$(docker version --format '{{.Client.APIVersion}}' 2>&1); then log ERROR "${capi}"; capi="error"; fi - if ! sver=$(docker version --format '{{.Server.Version}}' 2>&1); then log ERROR "${sver}"; sver="error"; fi - if ! sapi=$(docker version --format '{{.Server.APIVersion}}' 2>&1); then log ERROR "${sapi}"; sapi="error"; fi + if ! cver=$(run_docker_cmd version --format '{{.Client.Version}}'); then log ERROR "${cver}"; cver="error"; fi + if ! capi=$(run_docker_cmd version --format '{{.Client.APIVersion}}'); then log ERROR "${capi}"; capi="error"; fi + if ! sver=$(run_docker_cmd version --format '{{.Server.Version}}'); then log ERROR "${sver}"; sver="error"; fi + if ! sapi=$(run_docker_cmd version --format '{{.Server.APIVersion}}'); then log ERROR "${sapi}"; sapi="error"; fi echo "Docker version client ${cver} (API ${capi}) server ${sver} (API ${sapi})" } @@ -694,7 +716,7 @@ docker_version() { # return 1 when there is an error. docker_current_container_name() { local ALL_NETWORKS= - ALL_NETWORKS=$(docker network ls --format '{{.ID}}') || return 1; + ALL_NETWORKS=$(run_docker_cmd network ls --format '{{.ID}}') || return 1; [ -z "${ALL_NETWORKS}" ] && return 0; local IPS=; # Get the string after "src": @@ -702,8 +724,8 @@ docker_current_container_name() { IPS=$(ip route | grep src | sed -n -E "s/.* src (\S+).*$/\1/p"); [ -z "${IPS}" ] && return 0; local GWBRIDGE_NETWORK HOST_NETWORK; - GWBRIDGE_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^docker_gwbridge$') || return 1; - HOST_NETWORK=$(docker network ls --format '{{.ID}}' --filter 'name=^host$') || return 1; + GWBRIDGE_NETWORK=$(run_docker_cmd network ls --format '{{.ID}}' --filter 'name=^docker_gwbridge$') || return 1; + HOST_NETWORK=$(run_docker_cmd network ls --format '{{.ID}}' --filter 'name=^host$') || return 1; local NID=; for NID in ${ALL_NETWORKS}; do # The output of gwbridge does not contain the container name. It looks like gateway_8f55496ce4f1/172.18.0.5/16. @@ -711,7 +733,7 @@ docker_current_container_name() { # The output of host does not contain an IP. [ "${NID}" = "${HOST_NETWORK}" ] && continue; local ALL_LOCAL_NAME_AND_IP=; - ALL_LOCAL_NAME_AND_IP=$(docker network inspect "${NID}" --format "{{range .Containers}}{{.Name}}/{{println .IPv4Address}}{{end}}") || return 1; + ALL_LOCAL_NAME_AND_IP=$(run_docker_cmd network inspect "${NID}" --format "{{range .Containers}}{{.Name}}/{{println .IPv4Address}}{{end}}") || return 1; local NAME_AND_IP=; for NAME_AND_IP in ${ALL_LOCAL_NAME_AND_IP}; do [ -z "${NAME_AND_IP}" ] && continue; @@ -758,15 +780,15 @@ docker_run() { local RETRIES=0 local MAX_RETRIES=5 local SLEEP_SECONDS=10 - local MSG= - while ! MSG=$(docker run "${@}" 2>&1); do + local LOG= + while ! LOG=$(run_docker_cmd run "${@}"); do if [ ${RETRIES} -ge ${MAX_RETRIES} ]; then - log ERROR "Failed to run docker. Reached the max retries ${MAX_RETRIES}. ${MSG}" + log ERROR "Failed to run docker. Reached the max retries ${MAX_RETRIES}. ${LOG}" return 1 fi RETRIES=$((RETRIES + 1)) sleep ${SLEEP_SECONDS} - log WARN "Retry docker run (${RETRIES}). ${MSG}" + log WARN "Retry docker run (${RETRIES}). ${LOG}" done - echo "${MSG}" + echo "${LOG}" } diff --git a/src/lib-gantry.sh b/src/lib-gantry.sh index 3f0a21a..69d493b 100755 --- a/src/lib-gantry.sh +++ b/src/lib-gantry.sh @@ -49,7 +49,7 @@ _get_label_from_service() { local SERVICE_NAME="${1}" local LABEL="${2}" local VALUE= - if ! VALUE=$(docker service inspect -f "{{index .Spec.Labels \"${LABEL}\"}}" "${SERVICE_NAME}" 2>&1); then + if ! VALUE=$(run_docker_cmd service inspect -f "{{index .Spec.Labels \"${LABEL}\"}}" "${SERVICE_NAME}"); then log ERROR "Failed to obtain the value of label ${LABEL} from service ${SERVICE_NAME}. ${VALUE}" return 1 fi @@ -134,7 +134,7 @@ _login_registry() { local LOGIN_MSG= # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=SC2086 - if ! LOGIN_MSG=$(echo "${PASSWORD}" | docker ${AUTH_CONFIG} login --username="${USER}" --password-stdin "${HOST}" 2>&1); then + if ! LOGIN_MSG=$(echo "${PASSWORD}" | run_docker_cmd ${AUTH_CONFIG} login --username="${USER}" --password-stdin "${HOST}"); then log ERROR "Failed to login to ${REGISTRY_CONFIG_MESSAGE}. ${LOGIN_MSG}" return 1 fi @@ -364,15 +364,15 @@ _remove_container() { local IMAGE="${1}"; local STATUS="${2}"; local CIDS= - if ! CIDS=$(docker container ls --all --filter "ancestor=${IMAGE}" --filter "status=${STATUS}" --format '{{.ID}}' 2>&1); then + if ! CIDS=$(run_docker_cmd container ls --all --filter "ancestor=${IMAGE}" --filter "status=${STATUS}" --format '{{.ID}}'); then log ERROR "Failed to list ${STATUS} containers with image ${IMAGE}."; echo "${CIDS}" | log_lines ERROR return 1; fi local CID CNAME CRM_MSG for CID in ${CIDS}; do - CNAME=$(docker container inspect --format '{{.Name}}' "${CID}"); - if ! CRM_MSG=$(docker container rm "${CID}" 2>&1); then + CNAME=$(run_docker_cmd container inspect --format '{{.Name}}' "${CID}"); + if ! CRM_MSG=$(run_docker_cmd container rm "${CID}"); then log ERROR "Failed to remove ${STATUS} container ${CNAME}, which is using image ${IMAGE}."; echo "${CRM_MSG}" | log_lines ERROR continue; @@ -387,13 +387,13 @@ gantry_remove_images() { log DEBUG "$(docker_version)" local IMAGE= for IMAGE in ${IMAGES_TO_REMOVE}; do - if ! docker image inspect "${IMAGE}" 1>/dev/null 2>&1 ; then + if ! run_docker_cmd image inspect "${IMAGE}" 1>/dev/null; then log DEBUG "There is no image ${IMAGE} on the node."; continue; fi _remove_container "${IMAGE}" exited; _remove_container "${IMAGE}" dead; - if ! RMI_MSG=$(docker rmi "${IMAGE}" 2>&1); then + if ! RMI_MSG=$(run_docker_cmd rmi "${IMAGE}"); then log ERROR "Failed to remove image ${IMAGE}."; echo "${RMI_MSG}" | log_lines ERROR continue; @@ -616,7 +616,9 @@ gantry_current_service_name() { CNAME=$(_current_container_name) || return 1 [ -z "${CNAME}" ] && return 0 local SNAME= - SNAME=$(docker container inspect "${CNAME}" --format '{{range $key,$value := .Config.Labels}}{{$key}}={{println $value}}{{end}}' \ + # SC2016 (info): Expressions don't expand in single quotes, use double quotes for that. + # shellcheck disable=SC2016 + SNAME=$(run_docker_cmd container inspect "${CNAME}" --format '{{range $key,$value := .Config.Labels}}{{$key}}={{println $value}}{{end}}' \ | grep "com.docker.swarm.service.name" \ | sed -n -E "s/com.docker.swarm.service.name=(.*)$/\1/p") || return 1 _static_variable_add_unique_to_list STATIC_VAR_CURRENT_SERVICE_NAME "${SNAME}" @@ -643,19 +645,31 @@ _service_is_self() { _get_service_image() { local SERVICE_NAME="${1}" [ -z "${SERVICE_NAME}" ] && return 1 - docker service inspect -f '{{.Spec.TaskTemplate.ContainerSpec.Image}}' "${SERVICE_NAME}" + local RETURN_VALUE= + local IMAGE_WITH_DIGEST= + IMAGE_WITH_DIGEST=$(run_docker_cmd service inspect -f '{{.Spec.TaskTemplate.ContainerSpec.Image}}' "${SERVICE_NAME}") + RETURN_VALUE=$? + [ "${RETURN_VALUE}" != "0" ] && log ERROR "Failed to obtain image from service ${SERVICE_NAME}. ${IMAGE_WITH_DIGEST}" + echo "${IMAGE_WITH_DIGEST}" + return "${RETURN_VALUE}" } _get_service_previous_image() { local SERVICE_NAME="${1}" [ -z "${SERVICE_NAME}" ] && return 1 - docker service inspect -f '{{.PreviousSpec.TaskTemplate.ContainerSpec.Image}}' "${SERVICE_NAME}" + local RETURN_VALUE= + local IMAGE_WITH_DIGEST= + IMAGE_WITH_DIGEST=$(run_docker_cmd service inspect -f '{{.PreviousSpec.TaskTemplate.ContainerSpec.Image}}' "${SERVICE_NAME}") + RETURN_VALUE=$? + [ "${RETURN_VALUE}" != "0" ] && log ERROR "Failed to obtain previous image from service ${SERVICE_NAME}. ${IMAGE_WITH_DIGEST}" + echo "${IMAGE_WITH_DIGEST}" + return "${RETURN_VALUE}" } _get_service_mode() { local SERVICE_NAME="${1}" local MODE= - if ! MODE=$(docker service ls --filter "name=${SERVICE_NAME}" --format '{{.Mode}} {{.Name}}' 2>&1); then + if ! MODE=$(run_docker_cmd service ls --filter "name=${SERVICE_NAME}" --format '{{.Mode}} {{.Name}}'); then log ERROR "Failed to obtain the mode of the service ${SERVICE_NAME}: ${MODE}" return 1 fi @@ -751,13 +765,13 @@ _get_image_info() { [ -n "${MANIFEST_OPTIONS}" ] && log INFO "Adding options \"${MANIFEST_OPTIONS}\" to the command \"docker buildx imagetools inspect\"." # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=SC2086 - MSG=$(docker ${AUTH_CONFIG} buildx imagetools inspect ${MANIFEST_OPTIONS} "${IMAGE}" 2>&1); + MSG=$(run_docker_cmd ${AUTH_CONFIG} buildx imagetools inspect ${MANIFEST_OPTIONS} "${IMAGE}"); RETURN_VALUE=$? elif echo "${MANIFEST_CMD}" | grep_q_i "manifest"; then [ -n "${MANIFEST_OPTIONS}" ] && log INFO "Adding options \"${MANIFEST_OPTIONS}\" to the command \"docker manifest inspect\"." # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=SC2086 - MSG=$(docker ${AUTH_CONFIG} manifest inspect ${MANIFEST_OPTIONS} "${IMAGE}" 2>&1); + MSG=$(run_docker_cmd ${AUTH_CONFIG} manifest inspect ${MANIFEST_OPTIONS} "${IMAGE}"); RETURN_VALUE=$? elif echo "${MANIFEST_CMD}" | grep_q_i "none"; then # We should never reach here, the "none" command is already checked inside the function _inspect_image. @@ -782,10 +796,7 @@ _inspect_image() { local MANIFEST_CMD= MANIFEST_CMD=$(_read_env_or_label "${SERVICE_NAME}" "GANTRY_MANIFEST_CMD" "gantry.manifest.cmd" "buildx") local IMAGE_WITH_DIGEST= - if ! IMAGE_WITH_DIGEST=$(_get_service_image "${SERVICE_NAME}" 2>&1); then - log ERROR "Failed to obtain image from service ${SERVICE_NAME}. ${IMAGE_WITH_DIGEST}" - return 1 - fi + IMAGE_WITH_DIGEST=$(_get_service_image "${SERVICE_NAME}") || return $? local IMAGE= local DIGEST= IMAGE=$(extract_string "${IMAGE_WITH_DIGEST}" '@' 1) @@ -869,7 +880,7 @@ _inspect_service() { _get_number_of_running_tasks() { local SERVICE_NAME="${1}" local REPLICAS= - if ! REPLICAS=$(docker service ls --filter "name=${SERVICE_NAME}" --format '{{.Replicas}} {{.Name}}' 2>&1); then + if ! REPLICAS=$(run_docker_cmd service ls --filter "name=${SERVICE_NAME}" --format '{{.Replicas}} {{.Name}}'); then log ERROR "Failed to obtain task states of service ${SERVICE_NAME}: ${REPLICAS}" return 1 fi @@ -956,7 +967,7 @@ _rollback_service() { # Add "-quiet" to suppress progress output. # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=SC2086 - if ! ROLLBACK_MSG=$(docker ${AUTH_CONFIG} service update --quiet ${AUTOMATIC_OPTIONS} ${ROLLBACK_OPTIONS} --rollback "${SERVICE_NAME}" 2>&1); then + if ! ROLLBACK_MSG=$(run_docker_cmd ${AUTH_CONFIG} service update --quiet ${AUTOMATIC_OPTIONS} ${ROLLBACK_OPTIONS} --rollback "${SERVICE_NAME}"); then log ERROR "Failed to roll back ${SERVICE_NAME}. ${ROLLBACK_MSG}" return 1 fi @@ -1098,7 +1109,7 @@ _get_services_filted() { done # SC2086: Double quote to prevent globbing and word splitting. # shellcheck disable=SC2086 - if ! SERVICES=$(docker service ls --quiet ${FILTERS} --format '{{.Name}}' 2>&1); then + if ! SERVICES=$(run_docker_cmd service ls --quiet ${FILTERS} --format '{{.Name}}'); then log ERROR "Failed to obtain services list with \"${FILTERS}\". ${SERVICES}" return 1 fi diff --git a/tests/gantry_common_options_spec.sh b/tests/gantry_common_options_spec.sh index e6f8424..6b86043 100644 --- a/tests/gantry_common_options_spec.sh +++ b/tests/gantry_common_options_spec.sh @@ -102,9 +102,9 @@ Describe 'common-options' local TEST_NAME="${1}" local SERVICE_NAME="${2}" local ENV_BEFORE_RUN= - ENV_BEFORE_RUN=$(mktemp) + ENV_BEFORE_RUN=$(make_test_temp_file) local ENV_AFTER_RUN= - ENV_AFTER_RUN=$(mktemp) + ENV_AFTER_RUN=$(make_test_temp_file) reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" # There should be no warnings or errors. So it should work the same as LOG_LEVLE=NONE. diff --git a/tests/gantry_login_docker_config_spec.sh b/tests/gantry_login_docker_config_spec.sh index 0bd8ece..97afa74 100644 --- a/tests/gantry_login_docker_config_spec.sh +++ b/tests/gantry_login_docker_config_spec.sh @@ -42,7 +42,7 @@ Describe 'login-docker-config' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_docker_config_no_label() { local TEST_NAME="${1}" @@ -52,8 +52,8 @@ Describe 'login-docker-config' local USERNAME="${5}" local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" export GANTRY_TEST_DOCKER_CONFIG="${CONFIG}" export GANTRY_REGISTRY_CONFIG="${CONFIG}" @@ -91,7 +91,6 @@ Describe 'login-docker-config' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*" # Gantry adds --with-registry-auth, because DOCKER_CONFIG and the configuration name are same (default location). The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -116,7 +115,7 @@ Describe 'login-docker-config' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_docker_config_default_config() { local TEST_NAME="${1}" @@ -126,8 +125,8 @@ Describe 'login-docker-config' local USERNAME="${5}" local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; # Do not set GANTRY_AUTH_CONFIG_LABEL on the service. reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" export GANTRY_TEST_DOCKER_CONFIG="${CONFIG}" @@ -165,7 +164,6 @@ Describe 'login-docker-config' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*" # Gantry adds --with-registry-auth for using the default configuration. The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -193,7 +191,8 @@ Describe 'login-docker-config' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) + INCORRECT_CONFIG=$(get_config_name "incorrect-") TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_start() { local TEST_NAME="${1}" @@ -211,13 +210,13 @@ Describe 'login-docker-config' local REGISTRY="${4}" local USERNAME="${5}" local PASSWORD="${6}" + local INCORRECT_CONFIG="${7}" local SERVICE_NAME0="${SERVICE_NAME}-0" local SERVICE_NAME1="${SERVICE_NAME}-1" local SERVICE_NAME2="${SERVICE_NAME}-2" - local INCORRECT_CONFIG="incorrect-${CONFIG}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; local CONFIGS_FILE= - CONFIGS_FILE=$(mktemp) + CONFIGS_FILE=$(make_test_temp_file) echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD}" > "${CONFIGS_FILE}" # Set GANTRY_AUTH_CONFIG_LABEL on SERVICE_NAME1, but not on SERVICE_NAME0. # Inspection of SERVICE_NAME0 should fail (incorrect label overrides DOCKER_CONFIG). @@ -250,7 +249,7 @@ Describe 'login-docker-config' BeforeEach "test_start ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" AfterEach "test_end ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" It 'run_test' - When run test_login_docker_config_label_override "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" + When run test_login_docker_config_label_override "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" "${INCORRECT_CONFIG}" The status should be failure The stdout should satisfy display_output The stdout should satisfy spec_expect_no_message ".+" @@ -258,11 +257,11 @@ Describe 'login-docker-config' The stderr should satisfy spec_expect_no_message "${START_WITHOUT_A_SQUARE_BRACKET}" The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${AUTH_CONFIG}" The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}" - The stderr should satisfy spec_expect_message "incorrect-${AUTH_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" + The stderr should satisfy spec_expect_message "${INCORRECT_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" # Check warnings The stderr should satisfy spec_expect_message "${THERE_ARE_NUM_CONFIGURATIONS}.*" The stderr should satisfy spec_expect_message "${USER_LOGGED_INTO_DEFAULT}.*" - The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config incorrect-${AUTH_CONFIG}.*${SERVICE_NAME0}" + The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${INCORRECT_CONFIG}.*${SERVICE_NAME0}" The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${AUTH_CONFIG}.*${SERVICE_NAME1}" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config ${AUTH_CONFIG}.*${SERVICE_NAME2}" The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME0}.*" @@ -281,9 +280,6 @@ Describe 'login-docker-config' The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME1}" # Gantry adds --with-registry-auth, because DOCKER_CONFIG and the configuration name are same (default location). The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME2}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME0}.*" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME1}.*" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME2}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME0}" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME1}" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME2}" diff --git a/tests/gantry_login_negative_spec.sh b/tests/gantry_login_negative_spec.sh index 0af2a88..2985a8d 100644 --- a/tests/gantry_login_negative_spec.sh +++ b/tests/gantry_login_negative_spec.sh @@ -26,7 +26,7 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_no_login() { local TEST_NAME="${1}" @@ -55,7 +55,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" # No --with-registry-auth, because no login. The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -80,7 +79,7 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_incorrect_password() { local TEST_NAME="${1}" @@ -91,8 +90,8 @@ Describe 'login-negative' local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; local INCORRECT_PASSWORD="${PASSWORD}-incorrect-password" - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${INCORRECT_PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${INCORRECT_PASSWORD}" > "${PASS_FILE}"; docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}" reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" export GANTRY_REGISTRY_CONFIG="${CONFIG}" @@ -127,7 +126,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -149,7 +147,7 @@ Describe 'login-negative' TEST_NAME="test_login_read_only_file" IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}") SERVICE_NAME=$(get_test_service_name "${TEST_NAME}") - AUTH_CONFIG=$(mktemp -d) + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_read_only_file() { local TEST_NAME="${1}" @@ -163,8 +161,8 @@ Describe 'login-negative' # So do not run the test with a container/image. mkdir -p "${CONFIG}" chmod 444 "${CONFIG}" - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}" reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" # Use GANTRY_TEST_HOST_TO_CONTAINER to mount the file from host to the container. @@ -178,7 +176,7 @@ Describe 'login-negative' RETURN_VALUE="${?}" rm "${USER_FILE}" rm "${PASS_FILE}" - # [ -d "${CONFIG}" ] && chmod 777 "${CONFIG}" && rm -r "${CONFIG}" + [ -d "${CONFIG}" ] && chmod 777 "${CONFIG}" && rm -r "${CONFIG}" return "${RETURN_VALUE}" } BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" @@ -201,7 +199,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -226,7 +223,8 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) + INCORRECT_CONFIG=$(get_config_name "incorrect-") TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_config_mismatch_default() { local TEST_NAME="${1}" @@ -235,13 +233,13 @@ Describe 'login-negative' local REGISTRY="${4}" local USERNAME="${5}" local PASSWORD="${6}" + local INCORRECT_CONFIG="${7}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local INCORRECT_CONFIG="incorrect-${CONFIG}" - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; # Also use CONFIGS_FILE to test a explicitly-set config. local CONFIGS_FILE= - CONFIGS_FILE=$(mktemp) + CONFIGS_FILE=$(make_test_temp_file) echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD}" >> "${CONFIGS_FILE}" # The config name on the service is different from the config name used in GANTRY_REGISTRY_CONFIG docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${INCORRECT_CONFIG}" "${SERVICE_NAME}" @@ -266,7 +264,7 @@ Describe 'login-negative' BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" It 'run_test' - When run test_login_config_mismatch_default "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" + When run test_login_config_mismatch_default "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" "${INCORRECT_CONFIG}" The status should be failure The stdout should satisfy display_output The stdout should satisfy spec_expect_no_message ".+" @@ -275,12 +273,12 @@ Describe 'login-negative' The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${DEFAULT_CONFIGURATION}" The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${AUTH_CONFIG}" The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}" - The stderr should satisfy spec_expect_message "incorrect-${AUTH_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" + The stderr should satisfy spec_expect_message "${INCORRECT_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" # Check warnings The stderr should satisfy spec_expect_message "${THERE_ARE_NUM_CONFIGURATIONS}.*" The stderr should satisfy spec_expect_message "${USER_LOGGED_INTO_DEFAULT}.*" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config ${AUTH_CONFIG}.*" - The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config incorrect-${AUTH_CONFIG}.*${SERVICE_NAME}" + The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${INCORRECT_CONFIG}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_MANIFEST_FAILURE}" The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}" @@ -289,7 +287,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" # No --with-registry-auth, due to the incorrect configuration, image inspection failed, we did not reach the updating step. The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -314,7 +311,8 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) + INCORRECT_CONFIG=$(get_config_name "incorrect-") TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_config_mismatch_no_default() { local TEST_NAME="${1}" @@ -323,10 +321,10 @@ Describe 'login-negative' local REGISTRY="${4}" local USERNAME="${5}" local PASSWORD="${6}" - local INCORRECT_CONFIG="incorrect-${CONFIG}" + local INCORRECT_CONFIG="${7}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; # The config name on the service is different from the config name used in GANTRY_REGISTRY_CONFIG docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${INCORRECT_CONFIG}" "${SERVICE_NAME}" reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" @@ -347,7 +345,7 @@ Describe 'login-negative' BeforeEach "common_setup_new_image ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" AfterEach "common_cleanup ${TEST_NAME} ${IMAGE_WITH_TAG} ${SERVICE_NAME}" It 'run_test' - When run test_login_config_mismatch_no_default "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" + When run test_login_config_mismatch_no_default "${TEST_NAME}" "${SERVICE_NAME}" "${AUTH_CONFIG}" "${TEST_REGISTRY}" "${TEST_USERNAME}" "${TEST_PASSWORD}" "${INCORRECT_CONFIG}" The status should be failure The stdout should satisfy display_output The stdout should satisfy spec_expect_no_message ".+" @@ -356,13 +354,13 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${DEFAULT_CONFIGURATION}" The stderr should satisfy spec_expect_message "${LOGGED_INTO_REGISTRY}.*${TEST_REGISTRY}.*${AUTH_CONFIG}" The stderr should satisfy spec_expect_no_message "${FAILED_TO_LOGIN_TO_REGISTRY}" - The stderr should satisfy spec_expect_message "incorrect-${AUTH_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" + The stderr should satisfy spec_expect_message "${INCORRECT_CONFIG}.*${CONFIG_IS_NOT_A_DIRECTORY}" # Check warnings The stderr should satisfy spec_expect_message "${THERE_ARE_NUM_CONFIGURATIONS}.*" # This message does not present, because we don't login with the default configuration. The stderr should satisfy spec_expect_no_message "${USER_LOGGED_INTO_DEFAULT}.*" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config ${AUTH_CONFIG}.*" - The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config incorrect-${AUTH_CONFIG}.*${SERVICE_NAME}" + The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${INCORRECT_CONFIG}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_message "${SKIP_UPDATING}.*${SERVICE_NAME}.*${SKIP_REASON_MANIFEST_FAILURE}" The stderr should satisfy spec_expect_no_message "${PERFORM_UPDATING}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_SKIP_JOBS}" @@ -371,7 +369,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" # No --with-registry-auth, due to the incorrect configuration, image inspection failed, we did not reach the updating step. The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -401,7 +398,7 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_start() { local TEST_NAME="${1}" @@ -429,8 +426,8 @@ Describe 'login-negative' local SERVICE_NAME0="${SERVICE_NAME}-0" local SERVICE_NAME1="${SERVICE_NAME}-1" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; # Set GANTRY_AUTH_CONFIG_LABEL on SERVICE_NAME1, but not on SERVICE_NAME0. # Inspection of SERVICE_NAME0 should fail, because GANTRY_AUTH_CONFIG_LABEL is not found. # Inspection of SERVICE_NAME1 should pass, because configuration is set via GANTRY_AUTH_CONFIG_LABEL. @@ -486,8 +483,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME0}" # Gantry adds --with-registry-auth for finding GANTRY_AUTH_CONFIG_LABEL on the service. The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME1}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME0}.*" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME1}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME0}" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME1}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME0}" @@ -514,7 +509,7 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_REGISTRY_CONFIGS_FILE_bad_format() { local TEST_NAME="${1}" @@ -525,7 +520,7 @@ Describe 'login-negative' local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; local CONFIGS_FILE= - CONFIGS_FILE=$(mktemp) + CONFIGS_FILE=$(make_test_temp_file) # Add an extra item to the line. echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD} Extra" >> "${CONFIGS_FILE}" # Missing an item from the line. @@ -562,7 +557,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -587,7 +581,7 @@ Describe 'login-negative' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_file_not_exist() { local TEST_NAME="${1}" @@ -631,7 +625,6 @@ Describe 'login-negative' The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_NO_NEW_IMAGES}" The stderr should satisfy spec_expect_no_message "${NUM_SERVICES_UPDATING}" The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" diff --git a/tests/gantry_login_spec.sh b/tests/gantry_login_spec.sh index 7aaf316..e79ce3e 100644 --- a/tests/gantry_login_spec.sh +++ b/tests/gantry_login_spec.sh @@ -29,7 +29,7 @@ Describe 'login' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_config() { local TEST_NAME="${1}" @@ -39,8 +39,8 @@ Describe 'login' local USERNAME="${5}" local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}" reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" export GANTRY_REGISTRY_CONFIG="${CONFIG}" @@ -81,7 +81,6 @@ Describe 'login' # 2 "--with-registry-auth" for SERVICE_NAME. One is automatically added. The other is from user. The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*automatically.*${SERVICE_NAME}" The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*specified by user.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -113,8 +112,8 @@ Describe 'login' local USERNAME="${5}" local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; - local USER_FILE=; USER_FILE=$(mktemp); echo "${USERNAME}" > "${USER_FILE}"; - local PASS_FILE=; PASS_FILE=$(mktemp); echo "${PASSWORD}" > "${PASS_FILE}"; + local USER_FILE=; USER_FILE=$(make_test_temp_file); echo "${USERNAME}" > "${USER_FILE}"; + local PASS_FILE=; PASS_FILE=$(make_test_temp_file); echo "${PASSWORD}" > "${PASS_FILE}"; # Do not set GANTRY_AUTH_CONFIG_LABEL on the service. reset_gantry_env "${SUITE_NAME}" "${SERVICE_NAME}" # Do not set GANTRY_REGISTRY_CONFIG to login to the default configuration. @@ -151,7 +150,6 @@ Describe 'login' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}.*--config.*" # Gantry adds --with-registry-auth for using the default configuration. The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -176,7 +174,7 @@ Describe 'login' # When running with an Gantry image, docker buildx writes files to this folder which are owned by root. # Using a relative path, this the container will not write to the folder on the host. # So do not use an absolute path, otherwise we cannot remove this folder on the host. - AUTH_CONFIG="C$(unique_id)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_REGISTRY_CONFIGS_FILE() { local TEST_NAME="${1}" @@ -187,7 +185,7 @@ Describe 'login' local PASSWORD="${6}" check_login_input "${REGISTRY}" "${USERNAME}" "${PASSWORD}" || return 1; local CONFIGS_FILE= - CONFIGS_FILE=$(mktemp) + CONFIGS_FILE=$(make_test_temp_file) echo "# Test comments: CONFIG REGISTRY USERNAME PASSWORD" >> "${CONFIGS_FILE}" echo "${CONFIG} ${REGISTRY} ${USERNAME} ${PASSWORD}" >> "${CONFIGS_FILE}" docker_service_update --label-add "${GANTRY_AUTH_CONFIG_LABEL}=${CONFIG}" "${SERVICE_NAME}" @@ -229,7 +227,6 @@ Describe 'login' The stderr should satisfy spec_expect_message "${ADDING_OPTIONS}.*--config ${AUTH_CONFIG}.*${SERVICE_NAME}" # Gantry adds --with-registry-auth for finding GANTRY_AUTH_CONFIG_LABEL on the service. The stderr should satisfy spec_expect_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*${SERVICE_NAME}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -251,7 +248,7 @@ Describe 'login' TEST_NAME="test_login_external_config" IMAGE_WITH_TAG=$(get_image_with_tag "${SUITE_NAME}") SERVICE_NAME=$(get_test_service_name "${TEST_NAME}") - AUTH_CONFIG="$(mktemp -d)" + AUTH_CONFIG=$(get_config_name) TEST_REGISTRY=$(load_test_registry "${SUITE_NAME}") || return 1 test_login_external_config() { local TEST_NAME="${1}" @@ -301,7 +298,7 @@ Describe 'login' # No --with-registry-auth. The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS_WITH_REGISTRY_AUTH}.*" # Check the warning due to missing --with-registry-auth. - The stderr should satisfy spec_expect_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*${IMAGE_DIGEST_WARNING}" + The stderr should satisfy spec_expect_message "${SERVICE_NAME}.*${IMAGE_DIGEST_WARNING}" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" diff --git a/tests/gantry_service_single_spec.sh b/tests/gantry_service_single_spec.sh index 5e07452..9c0fd11 100644 --- a/tests/gantry_service_single_spec.sh +++ b/tests/gantry_service_single_spec.sh @@ -47,7 +47,6 @@ Describe 'service-single-service' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" The stderr should satisfy spec_expect_no_message "${SET_TIMEOUT_TO}" The stderr should satisfy spec_expect_no_message "${RETURN_VALUE_INDICATES_TIMEOUT}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_no_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -94,7 +93,6 @@ Describe 'service-single-service' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" The stderr should satisfy spec_expect_no_message "${SET_TIMEOUT_TO}" The stderr should satisfy spec_expect_no_message "${RETURN_VALUE_INDICATES_TIMEOUT}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -151,7 +149,6 @@ Describe 'service-single-service' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" The stderr should satisfy spec_expect_no_message "${SET_TIMEOUT_TO}" The stderr should satisfy spec_expect_no_message "${RETURN_VALUE_INDICATES_TIMEOUT}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" @@ -203,7 +200,6 @@ Describe 'service-single-service' The stderr should satisfy spec_expect_no_message "${ADDING_OPTIONS}" The stderr should satisfy spec_expect_no_message "${SET_TIMEOUT_TO}" The stderr should satisfy spec_expect_no_message "${RETURN_VALUE_INDICATES_TIMEOUT}" - The stderr should satisfy spec_expect_no_message "${THERE_ARE_ADDITIONAL_MESSAGES}.*${SERVICE_NAME}.*" The stderr should satisfy spec_expect_message "${UPDATED}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${NO_UPDATES}.*${SERVICE_NAME}" The stderr should satisfy spec_expect_no_message "${ROLLING_BACK}.*${SERVICE_NAME}" diff --git a/tests/spec_gantry_test_helper.sh b/tests/spec_gantry_test_helper.sh index c9c927e..493a957 100644 --- a/tests/spec_gantry_test_helper.sh +++ b/tests/spec_gantry_test_helper.sh @@ -45,7 +45,6 @@ export ADDING_OPTIONS="Adding options" export ADDING_OPTIONS_WITH_REGISTRY_AUTH="Adding options.*--with-registry-auth" export SET_TIMEOUT_TO="Set timeout to" export RETURN_VALUE_INDICATES_TIMEOUT="The return value [0-9]+ indicates the job timed out." -export THERE_ARE_ADDITIONAL_MESSAGES="There are additional messages from updating" export NUM_SERVICES_SKIP_JOBS="Skip updating [0-9]+ service\(s\) due to they are job\(s\)" export NUM_SERVICES_INSPECT_FAILURE="Failed to inspect [0-9]+ service\(s\)" export NUM_SERVICES_NO_NEW_IMAGES="No new images for [0-9]+ service\(s\)" @@ -69,6 +68,8 @@ export DONE_REMOVING_IMAGES="Done removing images" export SCHEDULE_NEXT_UPDATE_AT="Schedule next update at" export SLEEP_SECONDS_BEFORE_NEXT_UPDATE="Sleep [0-9]+ seconds before next update" +export GANTRY_TEST_TEMP_DIR="gantry-test-tmp" + test_log() { echo "${GANTRY_LOG_LEVEL}" | grep -q -i "^NONE$" && return 0; echo "${GANTRY_LOG_LEVEL}" | grep -q -i "^ERROR$" && return 0; @@ -235,7 +236,7 @@ _next_available_port() { _get_docker_config_file() { local REGISTRY="${1:?}" REGISTRY=$(echo "${REGISTRY}" | tr ':' '-') - echo "/tmp/gantry-test-docker-config-${REGISTRY}" + echo "${GANTRY_TEST_TEMP_DIR}/gantry-test-docker-config-${REGISTRY}" } _get_docker_config_argument() { @@ -249,13 +250,9 @@ _get_docker_config_argument() { _login_test_registry() { local ENFORCE_LOGIN="${1}" - local REGISTRY="${2}" - local USERNAME="${3}" - local PASSWORD="${4}" - if ! _enforce_login_enabled "${ENFORCE_LOGIN}"; then - USERNAME="username" - PASSWORD="password" - fi + local REGISTRY="${2:?}" + local USERNAME="${3:?}" + local PASSWORD="${4:?}" echo "Logging in ${REGISTRY}." local CONFIG= CONFIG=$(_get_docker_config_file "${REGISTRY}") || return 1 @@ -267,17 +264,15 @@ _logout_test_registry() { local REGISTRY="${2}" local CONFIG= CONFIG=$(_get_docker_config_file "${REGISTRY}") || return 1 - if _enforce_login_enabled "${ENFORCE_LOGIN}"; then - echo "Logging out ${REGISTRY}." - docker --config "${CONFIG}" logout - fi + echo "Logging out ${REGISTRY}." + docker --config "${CONFIG}" logout [ -d "${CONFIG}" ] && rm -r "${CONFIG}" } _get_test_registry_file() { local SUITE_NAME="${1:?}" SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-') - echo "/tmp/TEST_REGISTRY-${SUITE_NAME}" + echo "${GANTRY_TEST_TEMP_DIR}/gantry-test-registry-${SUITE_NAME}" } _remove_test_registry_file() { @@ -299,6 +294,7 @@ _store_test_registry() { echo "${TEST_REGISTRY}" > "${REGISTRY_FILE}" } + load_test_registry() { local SUITE_NAME="${1:?}" local REGISTRY_FILE= @@ -307,6 +303,20 @@ load_test_registry() { cat "${REGISTRY_FILE}" } +_get_test_registry_password_file() { + local SUITE_NAME="${1:?}" + local PASSWORD_FILE= + PASSWORD_FILE="$(_get_test_registry_file "${SUITE_NAME}")-password" || return 1 + readlink -f "${PASSWD_FILE}" +} + +_remove_test_registry_password_file() { + local SUITE_NAME="${1:?}" + local PASSWORD_FILE= + PASSWORD_FILE=$(_get_test_registry_password_file "${SUITE_NAME}") || return 1 + [ -r "${PASSWORD_FILE}" ] && rm "${PASSWORD_FILE}" +} + _start_registry() { local SUITE_NAME="${1:?}" local ENFORCE_LOGIN="${2}" @@ -314,6 +324,7 @@ _start_registry() { SUITE_NAME=$(echo "${SUITE_NAME}" | tr ' ' '-') local SUITE_NAME_LENGTH="${#SUITE_NAME}" local REGISTRY_SERVICE_NAME="gantry-test-registry-${SUITE_NAME}" + REGISTRY_SERVICE_NAME=$(_sanitize_test_service_name "${REGISTRY_SERVICE_NAME}") local REGISTRY_BASE="localhost" local REGISTRY_PORT= REGISTRY_PORT=$(_get_initial_port "${SUITE_NAME_LENGTH}") @@ -348,7 +359,7 @@ _start_registry() { -e "REGISTRY_HTTP_ADDR=${TEST_REGISTRY}" \ -e "REGISTRY_HTTP_HOST=http://${TEST_REGISTRY}" \ --stop-timeout "${TIMEOUT_SECONDS}" \ - $(_add_htpasswd "${ENFORCE_LOGIN}" "${TEST_USERNAME}" "${TEST_PASSWORD}") \ + $(_add_htpasswd "${SUITE_NAME}" "${ENFORCE_LOGIN}" "${TEST_USERNAME}" "${TEST_PASSWORD}") \ "${REGISTRY_IMAGE}" 2>&1); then local STATUS= while [ "${STATUS}" != "running" ]; do @@ -356,6 +367,7 @@ _start_registry() { done break; fi + echo "docker container run: ${CID}"; if [ "${TRIES}" -ge "${MAX_RETRIES}" ]; then echo "_start_registry Reach MAX_RETRIES ${MAX_RETRIES}" >&2 return 1 @@ -386,9 +398,11 @@ _stop_registry() { echo "Removing registry ${REGISTRY} " docker container stop "${REGISTRY_SERVICE_NAME}" 1>/dev/null 2>&1; docker container rm -f "${REGISTRY_SERVICE_NAME}" 1>/dev/null 2>&1; - _logout_test_registry "${ENFORCE_LOGIN}" "${REGISTRY}" || return 1 - _remove_test_registry_file "${SUITE_NAME}" || return 1 - return 0 + local RETURN_VALUE=0 + _logout_test_registry "${ENFORCE_LOGIN}" "${REGISTRY}" || RETURN_VALUE=1 + _remove_test_registry_file "${SUITE_NAME}" || RETURN_VALUE=1 + _remove_test_registry_password_file "${SUITE_NAME}" || RETURN_VALUE=1 + return "${RETURN_VALUE}" } _get_test_service_image() { @@ -406,7 +420,7 @@ _build_and_push_gantry_image() { IMAGE="$(_get_gantry_image "${SUITE_NAME}")" || return 1 pull_image_if_not_exist "$(_get_test_service_image)" echo "Building gantry image ${IMAGE}" - timeout 120 docker build --quiet -t "${IMAGE}" . + docker build --quiet --tag "${IMAGE}" . echo "Pushing gantry image ${IMAGE}" # SC2046 (warning): Quote this to prevent word splitting. # shellcheck disable=SC2046 @@ -417,7 +431,7 @@ _remove_gantry_image() { local SUITE_NAME="${1:?}" IMAGE="$(_get_gantry_image "${SUITE_NAME}")" || return 1 echo "Removing gantry image ${IMAGE}" - docker image rm "${IMAGE}" + docker image rm -f "${IMAGE}" } initialize_all_tests() { @@ -430,6 +444,9 @@ initialize_all_tests() { echo "==============================" echo "== Starting suite ${SUITE_NAME}" echo "==============================" + mkdir -p "${GANTRY_TEST_TEMP_DIR}" + uname --all + docker_version _init_swarm _start_registry "${SUITE_NAME}" "${ENFORCE_LOGIN}" _build_and_push_gantry_image "${SUITE_NAME}" @@ -594,6 +611,21 @@ unique_id() { echo "${PID}-${TIME_STR}-${RANDOM_STR}" } +make_test_temp_file() { + local TEMP= + TEMP=$(mktemp -p "${GANTRY_TEST_TEMP_DIR}") + TEMP=$(readlink -f "${TEMP}") + echo "${TEMP}" +} + +get_config_name() { + local BASE="${1}" + local TEMP= + TEMP="${GANTRY_TEST_TEMP_DIR}/${BASE}C$(unique_id)" + TEMP=$(readlink -f "${TEMP}") + echo "${TEMP}" +} + build_test_image() { local IMAGE_WITH_TAG="${1}" local TASK_SECONDS="${2}" @@ -609,12 +641,12 @@ build_test_image() { EXIT_CMD="sleep ${EXIT_SECONDS};" fi local FILE= - FILE=$(mktemp) + FILE=$(make_test_temp_file) echo "FROM $(_get_test_service_image)" > "${FILE}" echo "ENTRYPOINT [\"sh\", \"-c\", \"echo $(unique_id); trap \\\"${EXIT_CMD}\\\" HUP INT TERM; ${TASK_CMD}\"]" >> "${FILE}" pull_image_if_not_exist "$(_get_test_service_image)" echo "Building image ${IMAGE_WITH_TAG} from ${FILE}" - timeout 120 docker build --quiet --tag "${IMAGE_WITH_TAG}" --file "${FILE}" . + docker build --quiet --tag "${IMAGE_WITH_TAG}" --file "${FILE}" . rm "${FILE}" } @@ -646,7 +678,7 @@ wait_zero_running_tasks() { local REPLICAS= local USED_SECONDS=0 local TRIES=0 - local MAX_RETRIES=120 + local MAX_RETRIES=60 echo "Wait until ${SERVICE_NAME} has zero running tasks." while [ "${NUM_RUNS}" -ne 0 ]; do if [ -n "${TIMEOUT_SECONDS}" ] && [ "${USED_SECONDS}" -ge "${TIMEOUT_SECONDS}" ]; then @@ -709,22 +741,23 @@ _enforce_login_enabled() { } _add_htpasswd() { - local ENFORCE_LOGIN="${1}" - local USER="${2}" - local PASS="${3}" + local SUITE_NAME="${1:?}" + local ENFORCE_LOGIN="${2}" + local USER="${3}" + local PASS="${4}" if ! _enforce_login_enabled "${ENFORCE_LOGIN}"; then return 0 fi local HTTPD_IMAGE="httpd:2" # https://distribution.github.io/distribution/about/deploying/#native-basic-auth - local PASSWD= - PASSWD="$(mktemp)" + local PASSWD_FILE= + PASSWD_FILE=$(_get_test_registry_password_file "${SUITE_NAME}") pull_image_if_not_exist "${HTTPD_IMAGE}" - docker_run --entrypoint htpasswd "${HTTPD_IMAGE}" -Bbn "${USER}" "${PASS}" > "${PASSWD}" - echo "--mount type=bind,source=${PASSWD},target=${PASSWD} \ + docker_run --entrypoint htpasswd "${HTTPD_IMAGE}" -Bbn "${USER}" "${PASS}" > "${PASSWD_FILE}" + echo "--mount type=bind,source=${PASSWD_FILE},target=${PASSWD_FILE} \ -e REGISTRY_AUTH=htpasswd \ -e REGISTRY_AUTH_HTPASSWD_REALM=RegistryRealm \ - -e REGISTRY_AUTH_HTPASSWD_PATH=${PASSWD} " + -e REGISTRY_AUTH_HTPASSWD_PATH=${PASSWD_FILE} " } _wait_service_state() { @@ -767,7 +800,7 @@ start_replicated_service() { # * Add --rollback-monitor=1s: needs to exam the effect. # SC2046 (warning): Quote this to prevent word splitting. # shellcheck disable=SC2046 - timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ + timeout 60 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ --name "${SERVICE_NAME}" \ --restart-condition "on-failure" \ --restart-max-attempts 5 \ @@ -779,7 +812,7 @@ start_replicated_service() { --mode=replicated \ --detach=true \ "${IMAGE_WITH_TAG}"; - _wait_service_state "${SERVICE_NAME}" "Running" 120 + _wait_service_state "${SERVICE_NAME}" "Running" 60 } start_multiple_replicated_services() { @@ -808,7 +841,7 @@ start_global_service() { # Do not add --detach, because we want to wait for the job finishes. # SC2046 (warning): Quote this to prevent word splitting. # shellcheck disable=SC2046 - timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ + timeout 60 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ --name "${SERVICE_NAME}" \ --restart-condition "on-failure" \ --restart-max-attempts 5 \ @@ -831,7 +864,7 @@ _start_replicated_job() { # Always add --detach=true, do not wait for the job finishes. # SC2046 (warning): Quote this to prevent word splitting. # shellcheck disable=SC2046 - timeout 120 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ + timeout 60 docker $(_get_docker_config_argument "${IMAGE_WITH_TAG}") service create --quiet \ --name "${SERVICE_NAME}" \ --restart-condition "on-failure" \ --restart-max-attempts 5 \ @@ -842,7 +875,7 @@ _start_replicated_job() { --detach=true \ "${IMAGE_WITH_TAG}"; # wait until the job is running - _wait_service_state "${SERVICE_NAME}" "Running" 120 + _wait_service_state "${SERVICE_NAME}" "Running" 60 } stop_service() { @@ -917,7 +950,7 @@ _add_file_to_mount_options() { TARGET=$(readlink -f "${HOST_PATH}") local READONLY= READONLY=$(_get_file_readonly "${HOST_PATH}") - MOUNT_OPTIONS="${MOUNT_OPTIONS} --mount type=bind,source=${HOST_PATH},target=${TARGET},readonly=${READONLY}" + MOUNT_OPTIONS="${MOUNT_OPTIONS} --mount type=bind,source=${TARGET},target=${TARGET},readonly=${READONLY}" fi echo "${MOUNT_OPTIONS}" } @@ -947,8 +980,9 @@ stop_gantry_container() { } _run_gantry_container() { - local STACK="${1}" - local SUT_REPO_TAG="${2}" + local SUITE_NAME="${1}" + local STACK="${2}" + local SUT_REPO_TAG="${3}" pull_image_if_not_exist "${SUT_REPO_TAG}" local SERVICE_NAME= SERVICE_NAME=$(_get_gantry_sut_name "${STACK}") @@ -1051,7 +1085,7 @@ run_gantry() { local SUT_REPO_TAG= SUT_REPO_TAG="$(_get_sut_image "${SUITE_NAME}")" if [ -n "${SUT_REPO_TAG}" ]; then - _run_gantry_container "${STACK}" "${SUT_REPO_TAG}" + _run_gantry_container "${SUITE_NAME}" "${STACK}" "${SUT_REPO_TAG}" RETURN_VALUE=$? else [ -n "${GANTRY_TEST_DOCKER_CONFIG}" ] && export DOCKER_CONFIG="${GANTRY_TEST_DOCKER_CONFIG}"