diff --git a/cmd/postgres_exporter/tests/docker-postgres-replication/docker-entrypoint.sh b/cmd/postgres_exporter/tests/docker-postgres-replication/docker-entrypoint.sh index 8a8d9f356..5a0b20d89 100755 --- a/cmd/postgres_exporter/tests/docker-postgres-replication/docker-entrypoint.sh +++ b/cmd/postgres_exporter/tests/docker-postgres-replication/docker-entrypoint.sh @@ -36,12 +36,12 @@ if [ "$1" = 'postgres' ]; then if [ "x$REPLICATE_FROM" == "x" ]; then eval "gosu postgres initdb $POSTGRES_INITDB_ARGS" else - until /bin/ping -c 1 -W 1 ${REPLICATE_FROM} + until ping -c 1 -W 1 "${REPLICATE_FROM}" do echo "Waiting for master to ping..." sleep 1s done - until gosu postgres pg_basebackup -h ${REPLICATE_FROM} -D ${PGDATA} -U ${POSTGRES_USER} -vP -w + until gosu postgres pg_basebackup -h "${REPLICATE_FROM}" -D "${PGDATA}" -U "${POSTGRES_USER}" -vP -w do echo "Waiting for master to connect..." sleep 1s @@ -84,10 +84,13 @@ if [ "$1" = 'postgres' ]; then -o "-c listen_addresses='localhost'" \ -w start + # shellcheck disable=SC2086 : ${POSTGRES_USER:=postgres} + # shellcheck disable=SC2086 : ${POSTGRES_DB:=$POSTGRES_USER} export POSTGRES_USER POSTGRES_DB + # shellcheck disable=SC2191 psql=( psql -v ON_ERROR_STOP=1 ) if [ "$POSTGRES_DB" != 'postgres' ]; then @@ -112,6 +115,7 @@ if [ "$1" = 'postgres' ]; then psql+=( --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" ) echo + # shellcheck disable=SC1090 for f in /docker-entrypoint-initdb.d/*; do case "$f" in *.sh) echo "$0: running $f"; . "$f" ;; diff --git a/cmd/postgres_exporter/tests/docker-postgres-replication/setup-replication.sh b/cmd/postgres_exporter/tests/docker-postgres-replication/setup-replication.sh index 460c54891..ea3a794b2 100755 --- a/cmd/postgres_exporter/tests/docker-postgres-replication/setup-replication.sh +++ b/cmd/postgres_exporter/tests/docker-postgres-replication/setup-replication.sh @@ -1,8 +1,8 @@ #!/bin/bash -if [ "x$REPLICATE_FROM" == "x" ]; then +if [[ -z "$REPLICATE_FROM" ]]; then -cat >> ${PGDATA}/postgresql.conf <> "${PGDATA}/postgresql.conf" < ${PGDATA}/recovery.conf < "${PGDATA}/recovery.conf" <&2 -echo "Test Binary: $test_binary" 1>&2 - -[ -z "$postgres_exporter" ] && echo "Missing exporter binary" && exit 1 -[ -z "$test_binary" ] && echo "Missing test binary" && exit 1 - -cd $DIR - -VERSIONS=( \ - 9.1 \ - 9.2 \ - 9.3 \ - 9.4 \ - 9.5 \ - 9.6 \ - 10 \ +declare -a VERSIONS=( + 9.1 + 9.2 + 9.3 + 9.4 + 9.5 + 9.6 + 10 ) +# START OF FUNCTIONS + wait_for_postgres(){ local ip=$1 local port=$2 - if [ -z $ip ]; then + if [[ -z ${ip} ]]; then echo "No IP specified." 1>&2 exit 1 fi - - if [ -z $port ]; then + + if [[ -z ${port} ]]; then echo "No port specified." 1>&2 exit 1 fi - + + # shellcheck disable=SC2155 local wait_start=$(date +%s) echo "Waiting for postgres to start listening..." - while ! pg_isready --host=$ip --port=$port &> /dev/null; do - if [ $(( $(date +%s) - $wait_start )) -gt $TIMEOUT ]; then + while ! pg_isready --host="${ip}" --port="${port}" &> /dev/null; do + if [[ $(( $(date +%s) - wait_start )) -gt ${TIMEOUT} ]]; then echo "Timed out waiting for postgres to start!" 1>&2 - exit 1 + exit 1 fi sleep 1 done } wait_for_exporter() { + # shellcheck disable=SC2155 local wait_start=$(date +%s) echo "Waiting for exporter to start..." - while ! nc -z localhost $exporter_port ; do - if [ $(( $(date +%s) - $wait_start )) -gt $TIMEOUT ]; then + while ! nc -z localhost ${exporter_port} ; do + if [[ $(( $(date +%s) - wait_start )) -gt ${TIMEOUT} ]]; then echo "Timed out waiting for exporter!" 1>&2 exit 1 fi @@ -76,101 +97,105 @@ smoketest_postgres() { local CONTAINER_NAME=postgres_exporter-test-smoke local TIMEOUT=30 local IMAGE_NAME=postgres - - local CUR_IMAGE=$IMAGE_NAME:$version - + + local CUR_IMAGE=${IMAGE_NAME}:${version} + echo "#######################" echo "Standalone Postgres $version" echo "#######################" - local docker_cmd="docker run -d -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD $CUR_IMAGE" - echo "Docker Cmd: $docker_cmd" - - CONTAINER_NAME=$($docker_cmd) - standalone_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_NAME) - trap "docker logs $CONTAINER_NAME ; docker kill $CONTAINER_NAME ; docker rm -v $CONTAINER_NAME; exit 1" EXIT INT TERM - wait_for_postgres $standalone_ip 5432 + local docker_cmd="docker run -d -e POSTGRES_PASSWORD=${POSTGRES_PASSWORD} -p 127.0.0.1:55432:5432 ${CUR_IMAGE}" + echo "Docker Cmd: ${docker_cmd}" + CONTAINER_NAME=$( ${docker_cmd} ) + trap 'docker logs ${CONTAINER_NAME} ; + docker kill ${CONTAINER_NAME} ; + docker rm -v ${CONTAINER_NAME}; exit 1' EXIT INT TERM + wait_for_postgres localhost 55432 # Run the test binary. - DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$standalone_ip:5432/?sslmode=disable" $test_binary || exit $? + DATA_SOURCE_NAME="postgresql://postgres:${POSTGRES_PASSWORD}@localhost:55432/?sslmode=disable" \ + ${test_binary} --log.level=debug || exit $? # Extract a raw metric list. - DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$standalone_ip:5432/?sslmode=disable" $postgres_exporter --log.level=debug --web.listen-address=:$exporter_port & + DATA_SOURCE_NAME="postgresql://postgres:${POSTGRES_PASSWORD}@localhost:55432/?sslmode=disable" \ + ${postgres_exporter} --log.level=debug --web.listen-address=:${exporter_port} & exporter_pid=$! + # shellcheck disable=SC2064 trap "docker logs $CONTAINER_NAME ; docker kill $CONTAINER_NAME ; docker rm -v $CONTAINER_NAME; kill $exporter_pid; exit 1" EXIT INT TERM wait_for_exporter # Dump the metrics to a file. - wget -q -O - http://localhost:$exporter_port/metrics 1> $METRICS_DIR/.metrics.single.$version.prom - if [ "$?" != "0" ]; then - echo "Failed on postgres $version ($DOCKER_IMAGE)" 1>&2 - kill $exporter_pid - exit 1 - fi - - # HACK test: check pg_up is a 1 - TODO: expand integration tests to include metric consumption - if ! grep 'pg_up.* 1' $METRICS_DIR/.metrics.single.$version.prom ; then - echo "pg_up metric was not 1 despite exporter and database being up" - kill $exporter_pid - exit 1 - fi - - kill $exporter_pid - docker kill $CONTAINER_NAME - docker rm -v $CONTAINER_NAME + wget -q -O - \ + http://localhost:${exporter_port}/metrics \ + 1>"${METRICS_DIR}/.metrics.single.${version}.prom" || + { + echo "Failed on postgres ${version} (${DOCKER_IMAGE})" 1>&2 + kill ${exporter_pid} + exit 1 + } + + kill ${exporter_pid} + docker kill "${CONTAINER_NAME}" + docker rm -v "${CONTAINER_NAME}" trap - EXIT INT TERM - + echo "#######################" - echo "Replicated Postgres $version" + echo "Replicated Postgres ${version}" echo "#######################" old_pwd=$(pwd) - cd docker-postgres-replication + cd docker-postgres-replication || exit 1 + - VERSION=$version p2 -t Dockerfile.p2 -o Dockerfile - if [ "$?" != "0" ]; then - echo "Templating failed" 1>&2 - exit 1 - fi + VERSION=${version} p2 -t Dockerfile.p2 -o Dockerfile || { + echo "Templating failed" 1>&2 ; + exit 1 ; + } + trap "docker-compose logs; docker-compose down ; docker-compose rm -v; exit 1" EXIT INT TERM - local compose_cmd="POSTGRES_PASSWORD=$POSTGRES_PASSWORD docker-compose up -d --force-recreate --build" - echo "Compose Cmd: $compose_cmd" - eval $compose_cmd - + local compose_cmd="POSTGRES_PASSWORD=${POSTGRES_PASSWORD} docker-compose up -d --force-recreate --build" + echo "Compose Cmd: ${compose_cmd}" + eval "${compose_cmd}" + master_container=$(docker-compose ps -q pg-master) slave_container=$(docker-compose ps -q pg-slave) - master_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $master_container) - slave_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $slave_container) - echo "Got master IP: $master_ip" - wait_for_postgres $master_ip 5432 - wait_for_postgres $slave_ip 5432 - - DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$master_ip:5432/?sslmode=disable" $test_binary || exit $? - - DATA_SOURCE_NAME="postgresql://postgres:$POSTGRES_PASSWORD@$master_ip:5432/?sslmode=disable" $postgres_exporter --log.level=debug --web.listen-address=:$exporter_port & + master_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${master_container}") + slave_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' "${slave_container}") + echo "Got master IP: ${master_ip}" + wait_for_postgres "${master_ip}" 5432 + wait_for_postgres "${slave_ip}" 5432 + + DATA_SOURCE_NAME="postgresql://postgres:${POSTGRES_PASSWORD}@${master_ip}:5432/?sslmode=disable" ${test_binary} --log.level=debug || exit $? + + DATA_SOURCE_NAME="postgresql://postgres:${POSTGRES_PASSWORD}@${master_ip}:5432/?sslmode=disable" ${postgres_exporter} --log.level=debug --web.listen-address=:${exporter_port} & exporter_pid=$! - trap "docker-compose logs; docker-compose down ; docker-compose rm -v ; kill $exporter_pid; exit 1" EXIT INT TERM + # shellcheck disable=SC2064 + trap "docker-compose logs; docker-compose down ; docker-compose rm -v ; kill ${exporter_pid}; exit 1" EXIT INT TERM wait_for_exporter - wget -q -O - http://localhost:$exporter_port/metrics 1> $METRICS_DIR/.metrics.replicated.$version.prom - if [ "$?" != "0" ]; then - echo "Failed on postgres $version ($DOCKER_IMAGE)" 1>&2 - exit 1 - fi + wget -q -O - \ + http://localhost:${exporter_port}/metrics \ + 1>"${METRICS_DIR}/.metrics.replicated.${version}.prom" || + { + echo "Failed on postgres ${version} (${DOCKER_IMAGE})" 1>&2 ; + exit 1 ; + } - kill $exporter_pid + kill ${exporter_pid} docker-compose down docker-compose rm -v trap - EXIT INT TERM - - cd $old_pwd + + cd "${old_pwd}" || exit 1 } +### START OF MAIN PROGRAM + # Start pulling the docker images in advance -for version in ${VERSIONS[@]}; do - docker pull postgres:$version > /dev/null & +for version in "${VERSIONS[@]}"; do + docker pull "postgres:${version}" > /dev/null & done -for version in ${VERSIONS[@]}; do - echo "Testing postgres version $version" - smoketest_postgres $version +for version in "${VERSIONS[@]}"; do + echo "Testing postgres version ${version}" + smoketest_postgres "${version}" done diff --git a/postgres_exporter_integration_test_script b/postgres_exporter_integration_test_script index ebaf83d91..499ad46c2 100755 --- a/postgres_exporter_integration_test_script +++ b/postgres_exporter_integration_test_script @@ -10,9 +10,9 @@ shift echo "Test Binary: $test_binary" 1>&2 echo "Coverage File: $output_cov" 1>&2 -echo "mode: count" > $output_cov +echo "mode: count" > "${output_cov}" test_cov=$(mktemp) -$test_binary -test.coverprofile=$test_cov $@ || exit 1 -tail -n +2 $test_cov >> $output_cov -rm -f $test_cov +${test_binary} -test.coverprofile="${test_cov}" "$@" +tail -n +2 "${test_cov}" >> "${output_cov}" +rm -f "${test_cov}" diff --git a/postgres_metrics_added_and_removed b/postgres_metrics_added_and_removed index d33618904..f3e1684ce 100755 --- a/postgres_metrics_added_and_removed +++ b/postgres_metrics_added_and_removed @@ -7,5 +7,5 @@ version=$2 old_version=$3 new_version=$4 -comm -23 $old_version $new_version > .metrics.${type}.${version}.removed -comm -13 $old_version $new_version > .metrics.${type}.${version}.added +comm -23 "${old_version}" "${new_version}" > ".metrics.${type}.${version}.removed" +comm -13 "${old_version}" "${new_version}" > ".metrics.${type}.${version}.added" diff --git a/postgres_metrics_parse_script b/postgres_metrics_parse_script index 393e39a1a..a499fb668 100755 --- a/postgres_metrics_parse_script +++ b/postgres_metrics_parse_script @@ -7,10 +7,9 @@ for raw_prom in $(echo .*.prom) ; do # Strip, sort and deduplicate the label names - cat $raw_prom | grep -v '#' | \ + grep -v "#" "${raw_prom}" | \ rev | cut -d' ' -f2- | \ rev | cut -d'{' -f1 | \ sort | \ - uniq > ${raw_prom}.unique - + uniq > "${raw_prom}.unique" done