diff options
-rw-r--r-- | .cirrus.yml | 33 | ||||
-rw-r--r-- | cmd/podman/common.go | 10 | ||||
-rw-r--r-- | cmd/podman/create.go | 2 | ||||
-rw-r--r-- | cmd/podman/run.go | 1 | ||||
-rw-r--r-- | cmd/podman/shared/intermediate.go | 10 | ||||
-rw-r--r-- | cmd/podman/utils.go | 16 | ||||
-rw-r--r-- | completions/bash/podman | 2 | ||||
-rwxr-xr-x | contrib/cirrus/build_vm_images.sh | 39 | ||||
-rwxr-xr-x | contrib/cirrus/check_image.sh | 6 | ||||
-rw-r--r-- | contrib/cirrus/lib.sh | 17 | ||||
-rw-r--r-- | contrib/cirrus/packer/fedora_base-setup.sh | 3 | ||||
-rw-r--r-- | contrib/cirrus/packer/fedora_setup.sh | 3 | ||||
-rw-r--r-- | contrib/cirrus/packer/ubuntu_setup.sh | 3 | ||||
-rw-r--r-- | contrib/imgprune/Dockerfile | 7 | ||||
-rw-r--r-- | contrib/imgprune/README.md | 11 | ||||
-rwxr-xr-x | contrib/imgprune/entrypoint.sh | 67 | ||||
-rw-r--r-- | contrib/imgts/Dockerfile | 4 | ||||
-rwxr-xr-x | contrib/imgts/entrypoint.sh | 47 | ||||
-rw-r--r-- | contrib/imgts/lib_entrypoint.sh | 44 | ||||
-rw-r--r-- | docs/podman-create.1.md | 10 | ||||
-rw-r--r-- | docs/podman-run.1.md | 10 | ||||
-rw-r--r-- | test/e2e/common_test.go | 2 | ||||
-rw-r--r-- | test/e2e/healthcheck_run_test.go | 10 | ||||
-rw-r--r-- | test/e2e/run_test.go | 6 |
24 files changed, 290 insertions, 73 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index 04d535356..70c3cb3da 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -31,9 +31,9 @@ env: #### #### Cache-image names to test with ### - FEDORA_CACHE_IMAGE_NAME: "fedora-30-libpod-5744029755506688" - PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-5744029755506688" - UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-5744029755506688" + FEDORA_CACHE_IMAGE_NAME: "fedora-30-libpod-5925244995371008" + PRIOR_FEDORA_CACHE_IMAGE_NAME: "fedora-29-libpod-5925244995371008" + UBUNTU_CACHE_IMAGE_NAME: "ubuntu-18-libpod-5925244995371008" #### #### Variables for composing new cache-images (used in PR testing) from @@ -263,7 +263,7 @@ meta_task: cpu: 1 memory: 1 - env: + env: &meta_env_vars # Space-separated list of images used by this repository state IMGNAMES: >- ${FEDORA_CACHE_IMAGE_NAME} @@ -279,6 +279,31 @@ meta_task: timeout_in: 10m + # Cirrus-CI ignores entrypoint defined in image + script: '/usr/local/bin/entrypoint.sh |& ${TIMESTAMP}' + + +# Remove old and disused images based on labels set by meta_task +image_prune_task: + + # Do not run this frequently + only_if: $CIRRUS_BRANCH == 'master' + + depends_on: + - "meta" + + container: + image: "quay.io/libpod/imgprune:latest" # see contrib/imgprune + cpu: 1 + memory: 1 + + env: + <<: *meta_env_vars + GCPJSON: ENCRYPTED[4c11d8e09c904c30fc70eecb95c73dec0ddf19976f9b981a0f80f3f6599e8f990bcef93c253ac0277f200850d98528e7] + GCPNAME: ENCRYPTED[7f54557ba6e5a437f11283a53e71baec9ca546f48a9835538cc54d297f79968eb1337d4596a1025b14f9d1c5723fbd29] + + timeout_in: 10m + script: '/usr/local/bin/entrypoint.sh |& ${TIMESTAMP}' diff --git a/cmd/podman/common.go b/cmd/podman/common.go index 96a1c2244..15f753d55 100644 --- a/cmd/podman/common.go +++ b/cmd/podman/common.go @@ -244,23 +244,23 @@ func getCreateFlags(c *cliconfig.PodmanCommand) { "help", false, "", ) createFlags.String( - "healthcheck-command", "", + "health-cmd", "", "set a healthcheck command for the container ('none' disables the existing healthcheck)", ) createFlags.String( - "healthcheck-interval", cliconfig.DefaultHealthCheckInterval, + "health-interval", cliconfig.DefaultHealthCheckInterval, "set an interval for the healthchecks (a value of disable results in no automatic timer setup)", ) createFlags.Uint( - "healthcheck-retries", cliconfig.DefaultHealthCheckRetries, + "health-retries", cliconfig.DefaultHealthCheckRetries, "the number of retries allowed before a healthcheck is considered to be unhealthy", ) createFlags.String( - "healthcheck-start-period", cliconfig.DefaultHealthCheckStartPeriod, + "health-start-period", cliconfig.DefaultHealthCheckStartPeriod, "the initialization time needed for a container to bootstrap", ) createFlags.String( - "healthcheck-timeout", cliconfig.DefaultHealthCheckTimeout, + "health-timeout", cliconfig.DefaultHealthCheckTimeout, "the maximum time allowed to complete the healthcheck before an interval is considered failed", ) createFlags.StringP( diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 93141a800..262cdffe4 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -40,7 +40,7 @@ func init() { getCreateFlags(&createCommand.PodmanCommand) flags := createCommand.Flags() flags.SetInterspersed(false) - + flags.SetNormalizeFunc(aliasFlags) } func createCmd(c *cliconfig.CreateValues) error { diff --git a/cmd/podman/run.go b/cmd/podman/run.go index 76ab3d944..4836c99dc 100644 --- a/cmd/podman/run.go +++ b/cmd/podman/run.go @@ -34,6 +34,7 @@ func init() { runCommand.SetUsageTemplate(UsageTemplate()) flags := runCommand.Flags() flags.SetInterspersed(false) + flags.SetNormalizeFunc(aliasFlags) flags.Bool("sig-proxy", true, "Proxy received signals to the process") getCreateFlags(&runCommand.PodmanCommand) markFlagHiddenForRemoteClient("authfile", flags) diff --git a/cmd/podman/shared/intermediate.go b/cmd/podman/shared/intermediate.go index 855f84086..8337dc647 100644 --- a/cmd/podman/shared/intermediate.go +++ b/cmd/podman/shared/intermediate.go @@ -399,11 +399,11 @@ func NewIntermediateLayer(c *cliconfig.PodmanCommand, remote bool) GenericCLIRes m["gidmap"] = newCRStringSlice(c, "gidmap") m["group-add"] = newCRStringSlice(c, "group-add") m["help"] = newCRBool(c, "help") - m["healthcheck-command"] = newCRString(c, "healthcheck-command") - m["healthcheck-interval"] = newCRString(c, "healthcheck-interval") - m["healthcheck-retries"] = newCRUint(c, "healthcheck-retries") - m["healthcheck-start-period"] = newCRString(c, "healthcheck-start-period") - m["healthcheck-timeout"] = newCRString(c, "healthcheck-timeout") + m["healthcheck-command"] = newCRString(c, "health-cmd") + m["healthcheck-interval"] = newCRString(c, "health-interval") + m["healthcheck-retries"] = newCRUint(c, "health-retries") + m["healthcheck-start-period"] = newCRString(c, "health-start-period") + m["healthcheck-timeout"] = newCRString(c, "health-timeout") m["hostname"] = newCRString(c, "hostname") m["http-proxy"] = newCRBool(c, "http-proxy") m["image-volume"] = newCRString(c, "image-volume") diff --git a/cmd/podman/utils.go b/cmd/podman/utils.go index 0790f673a..c0ddaba4e 100644 --- a/cmd/podman/utils.go +++ b/cmd/podman/utils.go @@ -47,3 +47,19 @@ func markFlagHidden(flags *pflag.FlagSet, flag string) { logrus.Errorf("unable to mark flag '%s' as hidden: %q", flag, err) } } + +func aliasFlags(f *pflag.FlagSet, name string) pflag.NormalizedName { + switch name { + case "healthcheck-command": + name = "health-cmd" + case "healthcheck-interval": + name = "health-interval" + case "healthcheck-retries": + name = "health-retries" + case "healthcheck-start-period": + name = "health-start-period" + case "healthcheck-timeout": + name = "health-timeout" + } + return pflag.NormalizedName(name) +} diff --git a/completions/bash/podman b/completions/bash/podman index 2b9254d47..0703029ea 100644 --- a/completions/bash/podman +++ b/completions/bash/podman @@ -1812,10 +1812,10 @@ _podman_container_run() { --health-interval --health-retries --health-timeout + --health-start-period " boolean_options="$boolean_options --detach -d - --no-healthcheck --rm --sig-proxy=false " diff --git a/contrib/cirrus/build_vm_images.sh b/contrib/cirrus/build_vm_images.sh index f5d53a92e..74b10158c 100755 --- a/contrib/cirrus/build_vm_images.sh +++ b/contrib/cirrus/build_vm_images.sh @@ -3,7 +3,8 @@ set -e source $(dirname $0)/lib.sh -ENV_VARS='PACKER_BUILDS BUILT_IMAGE_SUFFIX UBUNTU_BASE_IMAGE FEDORA_BASE_IMAGE PRIOR_FEDORA_BASE_IMAGE SERVICE_ACCOUNT GCE_SSH_USERNAME GCP_PROJECT_ID PACKER_VER SCRIPT_BASE PACKER_BASE' +BASE_IMAGE_VARS='FEDORA_BASE_IMAGE PRIOR_FEDORA_BASE_IMAGE UBUNTU_BASE_IMAGE' +ENV_VARS="PACKER_BUILDS BUILT_IMAGE_SUFFIX $BASE_IMAGE_VARS SERVICE_ACCOUNT GCE_SSH_USERNAME GCP_PROJECT_ID PACKER_VER SCRIPT_BASE PACKER_BASE CIRRUS_BUILD_ID CIRRUS_CHANGE_IN_REPO" req_env_var $ENV_VARS # Must also be made available through make, into packer process export $ENV_VARS @@ -24,6 +25,20 @@ then fi cd "$GOSRC/$PACKER_BASE" +# Add/update labels on base-images used in this build to prevent premature deletion +ARGS=" +" +for base_image_var in $BASE_IMAGE_VARS +do + # See entrypoint.sh in contrib/imgts and contrib/imgprune + # These updates can take a while, run them in the background, check later + gcloud compute images update "$image" \ + --update-labels=last-used=$(date +%s) \ + --update-labels=build-id=$CIRRUS_BUILD_ID \ + --update-labels=repo-ref=$CIRRUS_CHANGE_IN_REPO \ + --update-labels=project=$GCP_PROJECT_ID \ + ${!base_image_var} & +done make libpod_images \ PACKER_BUILDS=$PACKER_BUILDS \ @@ -33,9 +48,31 @@ make libpod_images \ PACKER_BASE=$PACKER_BASE \ BUILT_IMAGE_SUFFIX=$BUILT_IMAGE_SUFFIX +# Separate PR-produced images from those produced on master. +if [[ "${CIRRUS_BRANCH:-}" == "master" ]] +then + POST_MERGE_BUCKET_SUFFIX="-master" +else + POST_MERGE_BUCKET_SUFFIX="" +fi + # When successful, upload manifest of produced images using a filename unique # to this build. URI="gs://packer-import${POST_MERGE_BUCKET_SUFFIX}/manifest${BUILT_IMAGE_SUFFIX}.json" gsutil cp packer-manifest.json "$URI" +# Ensure any background 'gcloud compute images update' processes finish +set +e # need 'wait' exit code to avoid race +while [[ -n "$(jobs)" ]] +do + wait -n + RET=$? + if [[ "$RET" -eq "127" ]] || \ # Avoid TOCTOU race w/ jobs + wait + [[ "$RET" -eq "0" ]] + then + continue + fi + die $RET "Required base-image metadata update failed" +done + echo "Finished. A JSON manifest of produced images is available at $URI" diff --git a/contrib/cirrus/check_image.sh b/contrib/cirrus/check_image.sh index 67e807d61..690a38119 100755 --- a/contrib/cirrus/check_image.sh +++ b/contrib/cirrus/check_image.sh @@ -36,4 +36,10 @@ do "$(systemctl list-unit-files --no-legend $REQ_UNIT)" = "$REQ_UNIT enabled" || let "RET+=1" done +# Exits zero if any unit matching pattern is running +UNIT_STATUS=$(systemctl is-active $EVIL_UNITS; echo $?) +item_test "No interfering background units are active:" \ + "$UNIT_STATUS" -ne "0" || let "RET+=1" + +echo "Total failed tests: $RET" exit $RET diff --git a/contrib/cirrus/lib.sh b/contrib/cirrus/lib.sh index 4acdb460a..a9da3f4ce 100644 --- a/contrib/cirrus/lib.sh +++ b/contrib/cirrus/lib.sh @@ -78,6 +78,9 @@ ROOTLESS_ENV_RE='(CIRRUS_.+)|(ROOTLESS_.+)|(.+_IMAGE.*)|(.+_BASE)|(.*DIRPATH)|(. # Unsafe env. vars for display SECRET_ENV_RE='(IRCID)|(ACCOUNT)|(^GC[EP]..+)|(SSH)' +# Names of systemd units which should never be running +EVIL_UNITS="cron crond atd apt-daily-upgrade apt-daily fstrim motd-news systemd-tmpfiles-clean" + SPECIALMODE="${SPECIALMODE:-none}" TEST_REMOTE_CLIENT="${TEST_REMOTE_CLIENT:-false}" export CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-podman} @@ -350,6 +353,20 @@ remove_packaged_podman_files(){ done } +systemd_banish(){ + echo "Disabling periodic services that could destabilize testing:" + set +e # Not all of these exist on every platform + for unit in $EVIL_UNITS + do + ooe.sh sudo systemctl stop $unit + ooe.sh sudo systemctl disable $unit + ooe.sh sudo systemctl disable $unit.timer + ooe.sh sudo systemctl mask $unit + ooe.sh sudo systemctl mask $unit.timer + done + set -e +} + _finalize(){ set +e # Don't fail at the very end set +e # make errors non-fatal diff --git a/contrib/cirrus/packer/fedora_base-setup.sh b/contrib/cirrus/packer/fedora_base-setup.sh index a425b2b57..788a54c34 100644 --- a/contrib/cirrus/packer/fedora_base-setup.sh +++ b/contrib/cirrus/packer/fedora_base-setup.sh @@ -27,6 +27,9 @@ ooe.sh systemctl enable rngd echo "Setting cloud-init service to start after google-network-daemon.service" cp -v $GOSRC/$PACKER_BASE/cloud-init/fedora/cloud-init.service /etc/systemd/system/ +# Ensure there are no disruptive periodic services enabled by default in image +systemd_banish + rh_finalize echo "SUCCESS!" diff --git a/contrib/cirrus/packer/fedora_setup.sh b/contrib/cirrus/packer/fedora_setup.sh index eb95db907..1e25a1a3c 100644 --- a/contrib/cirrus/packer/fedora_setup.sh +++ b/contrib/cirrus/packer/fedora_setup.sh @@ -76,6 +76,9 @@ ooe.sh sudo dnf install -y \ xz \ zip +# Ensure there are no disruptive periodic services enabled by default in image +systemd_banish + sudo /tmp/libpod/hack/install_catatonit.sh rh_finalize diff --git a/contrib/cirrus/packer/ubuntu_setup.sh b/contrib/cirrus/packer/ubuntu_setup.sh index 6209f2f89..dba191ad2 100644 --- a/contrib/cirrus/packer/ubuntu_setup.sh +++ b/contrib/cirrus/packer/ubuntu_setup.sh @@ -100,6 +100,9 @@ ooe.sh sudo update-grub sudo /tmp/libpod/hack/install_catatonit.sh ooe.sh sudo make -C /tmp/libpod install.libseccomp.sudo +# Ensure there are no disruptive periodic services enabled by default in image +systemd_banish + ubuntu_finalize echo "SUCCESS!" diff --git a/contrib/imgprune/Dockerfile b/contrib/imgprune/Dockerfile new file mode 100644 index 000000000..26329e828 --- /dev/null +++ b/contrib/imgprune/Dockerfile @@ -0,0 +1,7 @@ +FROM libpod/imgts:latest + +RUN yum -y update && \ + yum clean all + +COPY /contrib/imgprune/entrypoint.sh /usr/local/bin/entrypoint.sh +RUN chmod 755 /usr/local/bin/entrypoint.sh diff --git a/contrib/imgprune/README.md b/contrib/imgprune/README.md new file mode 100644 index 000000000..48abc2028 --- /dev/null +++ b/contrib/imgprune/README.md @@ -0,0 +1,11 @@ +![PODMAN logo](../../logo/podman-logo-source.svg) + +A container image for maintaining the collection of +VM images used by CI/CD on this project and several others. +Acts upon metadata maintained by the imgts container. + +Example build (from repository root): + +```bash +sudo podman build -t $IMAGE_NAME -f contrib/imgprune/Dockerfile . +``` diff --git a/contrib/imgprune/entrypoint.sh b/contrib/imgprune/entrypoint.sh new file mode 100755 index 000000000..a4b77523b --- /dev/null +++ b/contrib/imgprune/entrypoint.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +set -e + +source /usr/local/bin/lib_entrypoint.sh + +req_env_var GCPJSON GCPNAME GCPPROJECT IMGNAMES + +gcloud_init + +# For safety's sake + limit nr background processes +PRUNE_LIMIT=10 +THEFUTURE=$(date --date='+1 hour' +%s) +TOO_OLD='90 days ago' +THRESHOLD=$(date --date="$TOO_OLD" +%s) +# Format Ref: https://cloud.google.com/sdk/gcloud/reference/topic/formats +FORMAT='value[quote](name,selfLink,creationTimestamp,labels)' +PROJRE="/v1/projects/$GCPPROJECT/global/" +BASE_IMAGE_RE='cloud-base' +RECENTLY=$(date --date='30 days ago' --iso-8601=date) +EXCLUDE="$IMGNAMES $IMAGE_BUILDER_CACHE_IMAGE_NAME" # whitespace separated values +# Filter Ref: https://cloud.google.com/sdk/gcloud/reference/topic/filters +FILTER="selfLink~$PROJRE AND creationTimestamp<$RECENTLY AND NOT name=($EXCLUDE)" +TODELETE=$(mktemp -p '' todelete.XXXXXX) + +echo "Searching images for pruning candidates older than $TOO_OLD ($THRESHOLD):" +$GCLOUD compute images list --format="$FORMAT" --filter="$FILTER" | \ + while read name selfLink creationTimestamp labels + do + created_ymd=$(date --date=$creationTimestamp --iso-8601=date) + last_used=$(egrep --only-matching --max-count=1 'last-used=[[:digit:]]+' <<< $labels || true) + markmsgpfx="Marking $name (created $created_ymd) for deletion" + if [[ -z "$last_used" ]] + then # image pre-dates addition of tracking labels + echo "$markmsgpfx: Missing 'last-used' metadata, labels: '$labels'" + echo "$name" >> $TODELETE + continue + fi + + last_used_timestamp=$(date --date=@$(cut -d= -f2 <<< $last_used || true) +%s || true) + last_used_ymd=$(date --date=@$last_used_timestamp --iso-8601=date) + if [[ -z "$last_used_timestamp" ]] || [[ "$last_used_timestamp" -ge "$THEFUTURE" ]] + then + echo "$markmsgpfx: Missing or invalid last-used timestamp: '$last_used_timestamp'" + echo "$name" >> $TODELETE + continue + fi + + if [[ "$last_used_timestamp" -le "$THRESHOLD" ]] + then + echo "$markmsgpfx: Used over $TOO_OLD on $last_used_ymd" + echo "$name" >> $TODELETE + continue + fi + + echo "NOT $markmsgpfx: last used on $last_used_ymd)" + done + +echo "Pruning up to $PRUNE_LIMIT images that were marked for deletion:" +for image_name in $(tail -$PRUNE_LIMIT $TODELETE | sort --random-sort) +do + # This can take quite some time (minutes), run in parallel disconnected from terminal + echo "TODO: Would have: $GCLOUD compute images delete $image_name &" + sleep "$[1+RANDOM/1000]s" & # Simlate background operation +done + +wait || true # Nothing to delete: No background jobs diff --git a/contrib/imgts/Dockerfile b/contrib/imgts/Dockerfile index 0746eca4c..deaadb899 100644 --- a/contrib/imgts/Dockerfile +++ b/contrib/imgts/Dockerfile @@ -7,14 +7,14 @@ RUN yum -y update && \ yum -y install google-cloud-sdk && \ yum clean all -COPY /contrib/imgts/entrypoint.sh /usr/local/bin/entrypoint.sh ENV GCPJSON="__unknown__" \ GCPNAME="__unknown__" \ GCPPROJECT="__unknown__" \ IMGNAMES="__unknown__" \ - TIMESTAMP="__unknown__" \ BUILDID="__unknown__" \ REPOREF="__unknown__" + +COPY ["/contrib/imgts/entrypoint.sh", "/contrib/imgts/lib_entrypoint.sh", "/usr/local/bin/"] RUN chmod 755 /usr/local/bin/entrypoint.sh ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/contrib/imgts/entrypoint.sh b/contrib/imgts/entrypoint.sh index 610e1f3b6..9c653eda0 100755 --- a/contrib/imgts/entrypoint.sh +++ b/contrib/imgts/entrypoint.sh @@ -2,45 +2,22 @@ set -e -RED="\e[1;36;41m" -YEL="\e[1;33;44m" -NOR="\e[0m" +source /usr/local/bin/lib_entrypoint.sh -die() { - echo -e "$2" >&2 - exit "$1" -} +req_env_var GCPJSON GCPNAME GCPPROJECT IMGNAMES BUILDID REPOREF -SENTINEL="__unknown__" # default set in dockerfile +gcloud_init -[[ "$GCPJSON" != "$SENTINEL" ]] || \ - die 1 "Must specify service account JSON in \$GCPJSON" -[[ "$GCPNAME" != "$SENTINEL" ]] || \ - die 2 "Must specify service account name in \$GCPNAME" -[[ "$GCPPROJECT" != "$SENTINEL" ]] || \ - die 4 "Must specify GCP Project ID in \$GCPPROJECT" -[[ -n "$GCPPROJECT" ]] || \ - die 5 "Must specify non-empty GCP Project ID in \$GCPPROJECT" -[[ "$IMGNAMES" != "$SENTINEL" ]] || \ - die 6 "Must specify space separated list of GCE image names in \$IMGNAMES" -[[ "$BUILDID" != "$SENTINEL" ]] || \ - die 7 "Must specify the number of current build in \$BUILDID" -[[ "$REPOREF" != "$SENTINEL" ]] || \ - die 8 "Must specify a PR number or Branch name in \$REPOREF" +ARGS=" + --update-labels=last-used=$(date +%s) + --update-labels=build-id=$BUILDID + --update-labels=repo-ref=$REPOREF + --update-labels=project=$GCPPROJECT +" -ARGS="--update-labels=last-used=$(date +%s)" -# optional -[[ -z "$BUILDID" ]] || ARGS="$ARGS --update-labels=build-id=$BUILDID" -[[ -z "$REPOREF" ]] || ARGS="$ARGS --update-labels=repo-ref=$REPOREF" -[[ -z "$GCPPROJECT" ]] || ARGS="$ARGS --update-labels=project=$GCPPROJECT" - -gcloud config set account "$GCPNAME" -gcloud config set project "$GCPPROJECT" -echo "$GCPJSON" > /tmp/gcp.json -gcloud auth activate-service-account --key-file=/tmp/gcp.json || rm /tmp/gcp.json for image in $IMGNAMES do - gcloud compute images update "$image" $ARGS & + $GCLOUD compute images update "$image" $ARGS & done -set +e # Actual update failures are only warnings -wait || die 0 "${RED}WARNING:$NOR ${YEL}Failed to update labels on one or more images:$NOR '$IMGNAMES'" + +wait || echo "Warning: No \$IMGNAMES were specified." diff --git a/contrib/imgts/lib_entrypoint.sh b/contrib/imgts/lib_entrypoint.sh new file mode 100644 index 000000000..7b76c823f --- /dev/null +++ b/contrib/imgts/lib_entrypoint.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +set -e + +RED="\e[1;36;41m" +YEL="\e[1;33;44m" +NOR="\e[0m" +SENTINEL="__unknown__" # default set in dockerfile +# Disable all input prompts +# https://cloud.google.com/sdk/docs/scripting-gcloud +GCLOUD="gcloud --quiet" + +die() { + EXIT=$1 + PFX=$2 + shift 2 + MSG="$@" + echo -e "${RED}${PFX}:${NOR} ${YEL}$MSG${NOR}" + [[ "$EXIT" -eq "0" ]] || exit "$EXIT" +} + +# Pass in a list of one or more envariable names; exit non-zero with +# helpful error message if any value is empty +req_env_var() { + for i; do + if [[ -z "${!i}" ]] + then + die 1 FATAL entrypoint.sh requires \$$i to be non-empty. + elif [[ "${!i}" == "$SENTINEL" ]] + then + die 2 FATAL entrypoint.sh requires \$$i to be explicitly set. + fi + done +} + +gcloud_init() { + set +xe + TMPF=$(mktemp -p '' .$(uuidgen)XXXX) + trap "rm -f $TMPF" EXIT + echo "$GCPJSON" > $TMPF && \ + $GCLOUD auth activate-service-account --project "$GCPPROJECT" --key-file=$TMPF || \ + die 5 FATAL auth + rm -f $TMPF +} diff --git a/docs/podman-create.1.md b/docs/podman-create.1.md index ea01a346c..89f146670 100644 --- a/docs/podman-create.1.md +++ b/docs/podman-create.1.md @@ -272,7 +272,7 @@ The following example maps uids 0-2000 in the container to the uids 30000-31999 Add additional groups to run as -**--healthcheck-command**=*"command"* | *'["command", "arg1", ...]'* +**--health-cmd**=*"command"* | *'["command", "arg1", ...]'* Set or alter a healthcheck command for a container. The command is a command to be executed inside your container that determines your container health. The command is required for other healthcheck options @@ -281,20 +281,20 @@ to be applied. A value of `none` disables existing healthchecks. Multiple options can be passed in the form of a JSON array; otherwise, the command will be interpreted as an argument to `/bin/sh -c`. -**--healthcheck-interval**=*interval* +**--health-interval**=*interval* Set an interval for the healthchecks (a value of `disable` results in no automatic timer setup) (default "30s") -**--healthcheck-retries**=*retries* +**--health-retries**=*retries* The number of retries allowed before a healthcheck is considered to be unhealthy. The default value is `3`. -**--healthcheck-start-period**=*period* +**--health-start-period**=*period* The initialization time needed for a container to bootstrap. The value can be expressed in time format like `2m3s`. The default value is `0s` -**--healthcheck-timeout**=*timeout* +**--health-timeout**=*timeout* The maximum time allowed to complete the healthcheck before an interval is considered failed. Like start-period, the value can be expressed in a time format such as `1m22s`. The default value is `30s`. diff --git a/docs/podman-run.1.md b/docs/podman-run.1.md index e3dca9300..ebf774b24 100644 --- a/docs/podman-run.1.md +++ b/docs/podman-run.1.md @@ -279,7 +279,7 @@ The example maps gids 0-2000 in the container to the gids 30000-31999 on the hos Add additional groups to run as -**--healthcheck-command**=*"command"* | *'["command", "arg1", ...]'* +**--health-cmd**=*"command"* | *'["command", "arg1", ...]'* Set or alter a healthcheck command for a container. The command is a command to be executed inside your container that determines your container health. The command is required for other healthcheck options @@ -288,20 +288,20 @@ to be applied. A value of `none` disables existing healthchecks. Multiple options can be passed in the form of a JSON array; otherwise, the command will be interpreted as an argument to `/bin/sh -c`. -**--healthcheck-interval**=*interval* +**--health-interval**=*interval* Set an interval for the healthchecks (a value of `disable` results in no automatic timer setup) (default "30s") -**--healthcheck-retries**=*retries* +**--health-retries**=*retries* The number of retries allowed before a healthcheck is considered to be unhealthy. The default value is `3`. -**--healthcheck-start-period**=*period* +**--health-start-period**=*period* The initialization time needed for a container to bootstrap. The value can be expressed in time format like `2m3s`. The default value is `0s` -**--healthcheck-timeout**=*timeout* +**--health-timeout**=*timeout* The maximum time allowed to complete the healthcheck before an interval is considered failed. Like start-period, the value can be expressed in a time format such as `1m22s`. The default value is `30s`. diff --git a/test/e2e/common_test.go b/test/e2e/common_test.go index b233a772a..abaf2cccf 100644 --- a/test/e2e/common_test.go +++ b/test/e2e/common_test.go @@ -375,7 +375,7 @@ func (p *PodmanTestIntegration) RunNginxWithHealthCheck(name string) (*PodmanSes if name != "" { podmanArgs = append(podmanArgs, "--name", name) } - podmanArgs = append(podmanArgs, "-dt", "-P", "--healthcheck-command", "curl http://localhost/", nginx) + podmanArgs = append(podmanArgs, "-dt", "-P", "--health-cmd", "curl http://localhost/", nginx) session := p.Podman(podmanArgs) session.WaitWithDefaultTimeout() return session, session.OutputToString() diff --git a/test/e2e/healthcheck_run_test.go b/test/e2e/healthcheck_run_test.go index dee86f3d9..dafc8a837 100644 --- a/test/e2e/healthcheck_run_test.go +++ b/test/e2e/healthcheck_run_test.go @@ -95,7 +95,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck should be starting", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--healthcheck-retries", "2", "--healthcheck-command", "ls /foo || exit 1", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) inspect := podmanTest.InspectContainer("hc") @@ -103,7 +103,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck failed checks in start-period should not change status", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--healthcheck-start-period", "2m", "--healthcheck-retries", "2", "--healthcheck-command", "ls /foo || exit 1", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-start-period", "2m", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -124,7 +124,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck failed checks must reach retries before unhealthy ", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--healthcheck-retries", "2", "--healthcheck-command", "ls /foo || exit 1", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -145,7 +145,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck good check results in healthy even in start-period", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--healthcheck-start-period", "2m", "--healthcheck-retries", "2", "--healthcheck-command", "ls || exit 1", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-start-period", "2m", "--health-retries", "2", "--health-cmd", "ls || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) @@ -158,7 +158,7 @@ var _ = Describe("Podman healthcheck run", func() { }) It("podman healthcheck single healthy result changes failed to healthy", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--healthcheck-retries", "2", "--healthcheck-command", "ls /foo || exit 1", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--name", "hc", "--health-retries", "2", "--health-cmd", "ls /foo || exit 1", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).To(Equal(0)) diff --git a/test/e2e/run_test.go b/test/e2e/run_test.go index 886e3e7a9..e35c84f5b 100644 --- a/test/e2e/run_test.go +++ b/test/e2e/run_test.go @@ -750,21 +750,21 @@ USER mail` }) It("podman run with bad healthcheck retries", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--healthcheck-command", "[\"foo\"]", "--healthcheck-retries", "0", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-retries", "0", ALPINE, "top"}) session.Wait() Expect(session.ExitCode()).ToNot(Equal(0)) Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-retries must be greater than 0")) }) It("podman run with bad healthcheck timeout", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--healthcheck-command", "[\"foo\"]", "--healthcheck-timeout", "0s", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-timeout", "0s", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(Equal(0)) Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-timeout must be at least 1 second")) }) It("podman run with bad healthcheck start-period", func() { - session := podmanTest.Podman([]string{"run", "-dt", "--healthcheck-command", "[\"foo\"]", "--healthcheck-start-period", "-1s", ALPINE, "top"}) + session := podmanTest.Podman([]string{"run", "-dt", "--health-cmd", "[\"foo\"]", "--health-start-period", "-1s", ALPINE, "top"}) session.WaitWithDefaultTimeout() Expect(session.ExitCode()).ToNot(Equal(0)) Expect(session.ErrorToString()).To(ContainSubstring("healthcheck-start-period must be 0 seconds or greater")) |