From 1c1eef0fe86b494eb13e9e328ce2a3afedfb2606 Mon Sep 17 00:00:00 2001 From: Brady Pratt Date: Tue, 28 Mar 2023 05:43:45 -0500 Subject: [PATCH 1/2] Boilerplate: Update to 764036b2bf3138ef860fa07d8e0cc017c8cfca43 Conventions: - openshift/golang-osd-operator: Update - openshift/golang-osd-operator-osde2e: Subscribe --- https://github.com/openshift/boilerplate/compare/f2283ca508e2f9af2e1f1d08e86051aefdad0386...764036b2bf3138ef860fa07d8e0cc017c8cfca43 commit: b2e3e1b90c2e5a60020cba909d2112b76021f201 author: Diego Santamaria Swap sed command delimiter I believe this will explode because $TEST_IMAGE contains /s. I would use some other delimiter for that sed command -- one that can't appear in a URI -- e.g.: Co-authored-by: Eric Fried <2uasimojo@users.noreply.github.com> Remove project.mk commit: 7adb0b88cea0e8527b4d32ddeb9c5425e83aa7a3 author: Diego Santamaria Swap sed command delimiter I believe this will explode because $TEST_IMAGE contains /s. I would use some other delimiter for that sed command -- one that can't appear in a URI -- e.g.: Co-authored-by: Eric Fried <2uasimojo@users.noreply.github.com> commit: 19ae2a423b085b1ae0b650374570da1784a8daa3 author: Diego Santamaria Add acceptance Test convention commit: f9e6c350556d9d5845babbb46686639a01945d03 author: Diego Santamaria Initial Commit for PD boiletPlate commit: 479ec3635d761fb91a59a884ef6bc29be8a15470 author: Christoph Blecker Revert yq/python version bump commit: 999bf51ca03b8add6de2f6cb83971c5c5a95bb93 author: Christoph Blecker Remove tag-check exemption for config/Dockerfile commit: f77a7379f0bef64b0eab6163f91e87bdd67f8b34 author: Christoph Blecker Bump base image to v3.0.3 commit: 56d013c17a42b259a88e987ed6798d0fdc2f2c2a author: Christoph Blecker Hard code default branch commit: fc2e7a8d1eb5dda50f086e0f16059957352defba author: Christoph Blecker Remove prescriptive URL from config/Dockerfile commit: 82d19adadc2857c2359a8890631c081ac2824bda author: Christoph Blecker Rev boilerplate image to v3.0.3 commit: 46c46423d7f2df00731fbdcf3573773becd7c9e7 author: Christoph Blecker Don't check tag-check or config/Dockerfile when checking for a tag commit: ecfd17b4fed6a4aea80d5bdc551de7350a4d6fd8 author: Christoph Blecker Add skopeo to boilerplate image commit: de1f8d8aa7af04115fa2da8751c2d6a1f4227ddb author: Christoph Blecker Don't fail validate on changes to build/Dockerfile* commit: 4b929d2cb15df8fd9100797f39d67cdfa5dea0ab author: Christoph Blecker Always pull fresh images in our build pipeline commit: 89eaae4e4f08b7c1c4d4c168a64a1f6e2d6424e2 author: Christoph Blecker Write olm-registry dockerfile so that it can be updated by dependabot commit: 31dea5e0c0d561897eec99b72041b31a95e92e19 author: Ritu Mundhe Adding necessary "Test" prefix to e2e test runner function commit: 33deebe8c9f86d86aa773c9546d1545d06d0397c author: Ritu Mundhe whitespace cleanup commit: 09b943656d3d41ed617178935e3807c1e2922e3e author: Ritu Mundhe moved test files to osde2e base dir. Other minor fixes. (#270) * moved test files to osde2e base dir. Other minor fixes. * removed ginkgo.Recover() per https://github.com/openshift/boilerplate/issues/269 commit: 08d5b433772ca42a7b541e6b31a0a0050d6b1d59 author: Dustin Row Scope GO vars per make target instead of global commit: 6f0542f471fbf37ced9e909a2e5bb29e7c1ac47e author: Ritu Mundhe renamed packagename without underscore commit: c1321df3f70091c8492dd4ce2cca4ba2ca49baaf author: Ritu Mundhe removing default target from osde2e convention commit: 7ceb63b0dcc24fdb829f652b943b414c5ffdc335 author: Dustin Row Rename osde2e convention commit: 566848f4eb17890aac7401536167e81e7642f037 author: Ritu Mundhe reverted dynamic var eval commit: 483a87cd016b84879adac3997d2af5806041bc26 author: Ritu Mundhe renamed variable conflicting with other convention dirs commit: b181cee588fa3373172fefbb5da1e7d5c2585f54 author: Ritu Mundhe added note about exclusive use by operators. commit: ff36e6cb4fb3f33cf26d34d38a4283de8cbd0b25 author: Ritu Mundhe convention renamed to focus on operators --- .ci-operator.yaml | 2 +- .github/dependabot.yml | 2 + boilerplate/_data/backing-image-tag | 2 +- boilerplate/_data/last-boilerplate-commit | 2 +- boilerplate/_lib/freeze-check | 4 +- boilerplate/generated-includes.mk | 2 + .../golang-osd-operator-osde2e/README.md | 40 ++++++++++ .../e2e-harness-generate.sh | 80 +++++++++++++++++++ .../e2e-image-build-push.sh | 53 ++++++++++++ .../golang-osd-operator-osde2e/project.mk | 10 +++ .../golang-osd-operator-osde2e/standard.mk | 79 ++++++++++++++++++ .../Dockerfile.olm-registry | 21 +++++ .../csv-generate/catalog-build.sh | 28 +------ .../csv-generate/csv-generate.sh | 6 +- .../golang-osd-operator/dependabot.yml | 2 + .../openshift/golang-osd-operator/update | 32 +++++--- boilerplate/update.cfg | 1 + build/Dockerfile | 2 +- build/Dockerfile.olm-registry | 21 +++++ 19 files changed, 346 insertions(+), 43 deletions(-) create mode 100644 boilerplate/openshift/golang-osd-operator-osde2e/README.md create mode 100755 boilerplate/openshift/golang-osd-operator-osde2e/e2e-harness-generate.sh create mode 100755 boilerplate/openshift/golang-osd-operator-osde2e/e2e-image-build-push.sh create mode 100644 boilerplate/openshift/golang-osd-operator-osde2e/project.mk create mode 100644 boilerplate/openshift/golang-osd-operator-osde2e/standard.mk create mode 100644 boilerplate/openshift/golang-osd-operator/Dockerfile.olm-registry create mode 100644 build/Dockerfile.olm-registry diff --git a/.ci-operator.yaml b/.ci-operator.yaml index a65cf6c1..83f6066c 100644 --- a/.ci-operator.yaml +++ b/.ci-operator.yaml @@ -1,4 +1,4 @@ build_root_image: name: boilerplate namespace: openshift - tag: image-v3.0.2 + tag: image-v3.0.3 diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 92e7d171..d4f250ce 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,3 +10,5 @@ updates: ignore: - dependency-name: "app-sre/boilerplate" # don't upgrade boilerplate via these means + - dependency-name: "openshift/origin-operator-registry" + # don't upgrade origin-operator-registry via these means diff --git a/boilerplate/_data/backing-image-tag b/boilerplate/_data/backing-image-tag index e82f404b..8b5f6fb5 100644 --- a/boilerplate/_data/backing-image-tag +++ b/boilerplate/_data/backing-image-tag @@ -1 +1 @@ -image-v3.0.2 +image-v3.0.3 diff --git a/boilerplate/_data/last-boilerplate-commit b/boilerplate/_data/last-boilerplate-commit index e718902f..e1650ef2 100644 --- a/boilerplate/_data/last-boilerplate-commit +++ b/boilerplate/_data/last-boilerplate-commit @@ -1 +1 @@ -f2283ca508e2f9af2e1f1d08e86051aefdad0386 +764036b2bf3138ef860fa07d8e0cc017c8cfca43 diff --git a/boilerplate/_lib/freeze-check b/boilerplate/_lib/freeze-check index 88c91bbd..7fb18ec3 100755 --- a/boilerplate/_lib/freeze-check +++ b/boilerplate/_lib/freeze-check @@ -70,9 +70,9 @@ cd $REPO_ROOT BOILERPLATE_GIT_CLONE="git clone $TMPD" boilerplate/update # Okay, if anything has changed, that's bad. -if [[ $(git status --porcelain | wc -l) -ne 0 ]]; then +if [[ $(git status --porcelain -- ':!build/Dockerfile*' | wc -l) -ne 0 ]]; then echo "Your boilerplate is dirty!" >&2 - git status --porcelain + git status --porcelain -- ':!build/Dockerfile*' exit 1 fi diff --git a/boilerplate/generated-includes.mk b/boilerplate/generated-includes.mk index 78b982f6..4e424c94 100644 --- a/boilerplate/generated-includes.mk +++ b/boilerplate/generated-includes.mk @@ -5,3 +5,5 @@ include boilerplate/_lib/boilerplate.mk include boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.mk include boilerplate/openshift/golang-osd-operator/project.mk include boilerplate/openshift/golang-osd-operator/standard.mk +include boilerplate/openshift/golang-osd-operator-osde2e/project.mk +include boilerplate/openshift/golang-osd-operator-osde2e/standard.mk diff --git a/boilerplate/openshift/golang-osd-operator-osde2e/README.md b/boilerplate/openshift/golang-osd-operator-osde2e/README.md new file mode 100644 index 00000000..498b2f53 --- /dev/null +++ b/boilerplate/openshift/golang-osd-operator-osde2e/README.md @@ -0,0 +1,40 @@ +# Conventions for Ginkgo based e2e tests + +- [Conventions for Ginkgo based e2e tests](#conventions-for-ginkgo-based-e2e-tests) + - [Consuming](#consuming) + - [`make` targets and functions.](#make-targets-and-functions) + - [E2E Test Harness](#e2e-test-harness) + - [Local Testing](#e2e-harness-local-testing) + +## Consuming +Currently, this convention is only intended for OSD operators. To adopt this convention, your `boilerplate/update.cfg` should include: + +``` +openshift/golang-osd-operator-osde2e +``` + +## `make` targets and functions. + +**Note:** Your repository's main `Makefile` needs to be edited to include the +"nexus makefile include": + +``` +include boilerplate/generated-includes.mk +``` + +One of the primary purposes of these `make` targets is to allow you to +standardize your prow and app-sre pipeline configurations using the +following: + +### E2e Test Harness + +| `make` target | Purpose | +|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `e2e-harness-generate` | Generate scaffolding for an end to end test harness. The `osde2e/` directory is created where the tests and test runner reside. The harness has access to cloud client and addon passthrough secrets within the test job cluster. Add your operator related ginkgo e2e tests under the `osde2e/_tests.go` file. See [this README](https://github.com/openshift/osde2e-example-test-harness/blob/main/README.md#locally-running-this-example) for more details on test harness. | +| `e2e-harness-build`| Compiles ginkgo tests under osde2e/tests and creates the binary to be used by docker image used by osde2e. | +| `e2e-image-build-push` | Builds osde2e test harness image and pushes to operator's quay repo. Image name is defaulted to -test-harness. Quay repository must be created beforehand. | + +#### E2E Harness Local Testing + +Please follow [this README](https://github.com/openshift/osde2e-example-test-harness/blob/main/README.md#locally-running-this-example) to test your e2e harness with Osde2e locally + diff --git a/boilerplate/openshift/golang-osd-operator-osde2e/e2e-harness-generate.sh b/boilerplate/openshift/golang-osd-operator-osde2e/e2e-harness-generate.sh new file mode 100755 index 00000000..8bd83c09 --- /dev/null +++ b/boilerplate/openshift/golang-osd-operator-osde2e/e2e-harness-generate.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +set -e + +cmd=${0##*/} + +usage() { + cat < $HARNESS_DIR/Dockerfile + +echo "package osde2etests + +import \"github.com/onsi/ginkgo/v2\" + +var _ = ginkgo.Describe(\"$OPERATOR_NAME\", func() { + // Add your tests +}) +" > ${HARNESS_DIR}/${OPERATOR_HYPHEN_NAME}_tests.go + +echo "// THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT. +//go:build integration +// +build integration + +package osde2etests + +import ( + \"path/filepath\" + \"testing\" + . \"github.com/onsi/ginkgo/v2\" + . \"github.com/onsi/gomega\" +) + +const ( + testResultsDirectory = \"/test-run-results\" + jUnitOutputFilename = \"junit-example-addon.xml\" +) + +// Test entrypoint. osde2e runs this as a test suite on test pod. +func Test$REPLACE_FUNC(t *testing.T) { + RegisterFailHandler(Fail) + + suiteConfig, reporterConfig := GinkgoConfiguration() + reporterConfig.JUnitReport = filepath.Join(testResultsDirectory, jUnitOutputFilename) + RunSpecs(t, \"$REPLACE_SPECNAME\", suiteConfig, reporterConfig) + +} +" > ${HARNESS_DIR}/${OPERATOR_HYPHEN_NAME}_runner_test.go diff --git a/boilerplate/openshift/golang-osd-operator-osde2e/e2e-image-build-push.sh b/boilerplate/openshift/golang-osd-operator-osde2e/e2e-image-build-push.sh new file mode 100755 index 00000000..b0872792 --- /dev/null +++ b/boilerplate/openshift/golang-osd-operator-osde2e/e2e-image-build-push.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash + +set -ev + +usage() { + cat < Podman uses --authfile=PATH *after* the `login` subcommand; but +# also accepts REGISTRY_AUTH_FILE from the env. See +# https://www.mankier.com/1/podman-login#Options---authfile=path +export REGISTRY_AUTH_FILE = ${CONTAINER_ENGINE_CONFIG_DIR}/config.json +# If this configuration file doesn't exist, podman will error out. So +# we'll create it if it doesn't exist. +ifeq (,$(wildcard $(REGISTRY_AUTH_FILE))) +$(shell mkdir -p $(CONTAINER_ENGINE_CONFIG_DIR)) +$(shell echo '{}' > $(REGISTRY_AUTH_FILE)) +endif +# ==> Docker uses --config=PATH *before* (any) subcommand; so we'll glue +# that to the CONTAINER_ENGINE variable itself. (NOTE: I tried half a +# dozen other ways to do this. This was the least ugly one that actually +# works.) +ifndef CONTAINER_ENGINE +CONTAINER_ENGINE=$(shell command -v podman 2>/dev/null || echo docker --config=$(CONTAINER_ENGINE_CONFIG_DIR)) +endif + +REGISTRY_USER ?= +REGISTRY_TOKEN ?= + +# TODO: Figure out how to discover this dynamically +OSDE2E_CONVENTION_DIR := boilerplate/openshift/golang-osd-operator-osde2e + +# TODO: figure out how to container-engine-login only once across multiple `make` calls +.PHONY: container-build-push-one +container-build-push-one: container-engine-login + @(if [[ -z "${IMAGE_URI}" ]]; then echo "Must specify IMAGE_URI"; exit 1; fi) + @(if [[ -z "${DOCKERFILE_PATH}" ]]; then echo "Must specify DOCKERFILE_PATH"; exit 1; fi) + ${CONTAINER_ENGINE} build --pull -f $(DOCKERFILE_PATH) -t $(IMAGE_URI) . + ${CONTAINER_ENGINE} push ${IMAGE_URI} + +# log into quay.io +.PHONY: container-engine-login +container-engine-login: + @test "${REGISTRY_USER}" != "" && test "${REGISTRY_TOKEN}" != "" || (echo "REGISTRY_USER and REGISTRY_TOKEN must be defined" && exit 1) + mkdir -p ${CONTAINER_ENGINE_CONFIG_DIR} + @${CONTAINER_ENGINE} login -u="${REGISTRY_USER}" -p="${REGISTRY_TOKEN}" quay.io + +###################### +# Targets used by osde2e test harness +###################### + +# create e2e scaffolding +.PHONY: e2e-harness-generate +e2e-harness-generate: + ${OSDE2E_CONVENTION_DIR}/e2e-harness-generate.sh $(OPERATOR_NAME) $(OSDE2E_CONVENTION_DIR) + +# create binary +.PHONY: e2e-harness-build +e2e-harness-build: GOFLAGS_MOD=-mod=mod +e2e-harness-build: GOENV=GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 GOFLAGS="${GOFLAGS_MOD}" +e2e-harness-build: + go mod tidy + ${GOENV} go test ./osde2e -v -c --tags=integration -o harness.test + +# TODO: Push to a known image tag and commit id +# push harness image +.PHONY: e2e-image-build-push +e2e-image-build-push: + ${OSDE2E_CONVENTION_DIR}/e2e-image-build-push.sh "./osde2e/Dockerfile $(IMAGE_REGISTRY)/$(IMAGE_REPOSITORY)/$(HARNESS_IMAGE_NAME):latest" diff --git a/boilerplate/openshift/golang-osd-operator/Dockerfile.olm-registry b/boilerplate/openshift/golang-osd-operator/Dockerfile.olm-registry new file mode 100644 index 00000000..11ce943a --- /dev/null +++ b/boilerplate/openshift/golang-osd-operator/Dockerfile.olm-registry @@ -0,0 +1,21 @@ +FROM quay.io/openshift/origin-operator-registry:4.12 AS builder +ARG SAAS_OPERATOR_DIR +COPY ${SAAS_OPERATOR_DIR} manifests +RUN initializer --permissive + +FROM registry.access.redhat.com/ubi8/ubi-micro:latest + +COPY --from=builder /bin/registry-server /bin/registry-server +COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe +COPY --from=builder /bin/initializer /bin/initializer + +WORKDIR /registry +RUN chgrp -R 0 /registry && chmod -R g+rwx /registry + +USER 1001 + +COPY --from=builder /registry /registry + +EXPOSE 50051 + +CMD ["registry-server", "-t", "/tmp/terminate.log"] diff --git a/boilerplate/openshift/golang-osd-operator/csv-generate/catalog-build.sh b/boilerplate/openshift/golang-osd-operator/csv-generate/catalog-build.sh index 8b5f1d52..904ef767 100755 --- a/boilerplate/openshift/golang-osd-operator/csv-generate/catalog-build.sh +++ b/boilerplate/openshift/golang-osd-operator/csv-generate/catalog-build.sh @@ -36,7 +36,7 @@ check_mandatory_params operator_channel operator_name # Parameters for the Dockerfile SAAS_OPERATOR_DIR="saas-${operator_name}-bundle" BUNDLE_DIR="${SAAS_OPERATOR_DIR}/${operator_name}" -DOCKERFILE_REGISTRY="Dockerfile.olm-registry" +DOCKERFILE_REGISTRY="build/Dockerfile.olm-registry" # Checking SAAS_OPERATOR_DIR exist if [ ! -d "${SAAS_OPERATOR_DIR}/.git" ] ; then @@ -61,31 +61,7 @@ channels: currentCSV: ${operator_name}.v${OPERATOR_NEW_VERSION} EOF -# Build registry -cat < $DOCKERFILE_REGISTRY -FROM quay.io/openshift/origin-operator-registry:4.10.0 AS builder -COPY $SAAS_OPERATOR_DIR manifests -RUN initializer --permissive - -FROM registry.access.redhat.com/ubi8/ubi-micro:8.6-484 - -COPY --from=builder /bin/registry-server /bin/registry-server -COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe -COPY --from=builder /bin/initializer /bin/initializer - -WORKDIR /registry -RUN chgrp -R 0 /registry && chmod -R g+rwx /registry - -USER 1001 - -COPY --from=builder /registry /registry - -EXPOSE 50051 - -CMD ["registry-server", "-t", "/tmp/terminate.log"] -EOF - -${CONTAINER_ENGINE} build --pull -f $DOCKERFILE_REGISTRY --tag "${registry_image}:${operator_channel}-latest" . +${CONTAINER_ENGINE} build --pull -f "${DOCKERFILE_REGISTRY}" --build-arg "SAAS_OPERATOR_DIR=${SAAS_OPERATOR_DIR}" --tag "${registry_image}:${operator_channel}-latest" . if [ $? -ne 0 ] ; then echo "docker build failed, exiting..." diff --git a/boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.sh b/boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.sh index 5e7a7104..c6563ebf 100755 --- a/boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.sh +++ b/boilerplate/openshift/golang-osd-operator/csv-generate/csv-generate.sh @@ -48,7 +48,9 @@ fi if [[ -z "$CONTAINER_ENGINE" ]]; then YQ_CMD="yq" else - YQ_CMD="$CONTAINER_ENGINE run --rm -i quay.io/app-sre/yq:3.4.1 yq" + yq_image="quay.io/app-sre/yq:3.4.1" + $CONTAINER_ENGINE pull $yq_image + YQ_CMD="$CONTAINER_ENGINE run --rm -i $yq_image yq" fi # Get the image URI as repo URL + image digest @@ -175,5 +177,5 @@ else else CE_OPTS="-v `pwd`:`pwd`" fi - $CONTAINER_ENGINE run --rm ${CE_OPTS} -u `id -u`:0 -w `pwd` registry.access.redhat.com/ubi8/python-36:1-134 /bin/bash -c "python -m pip install oyaml; python ./boilerplate/openshift/golang-osd-operator/csv-generate/common-generate-operator-bundle.py -o ${operator_name} -d ${OUTPUT_DIR} ${PREV_VERSION_OPTS} -i ${REPO_DIGEST} -V ${operator_version}" + $CONTAINER_ENGINE run --pull=always --rm ${CE_OPTS} -u `id -u`:0 -w `pwd` registry.access.redhat.com/ubi8/python-36 /bin/bash -c "python -m pip install --disable-pip-version-check oyaml; python ./boilerplate/openshift/golang-osd-operator/csv-generate/common-generate-operator-bundle.py -o ${operator_name} -d ${OUTPUT_DIR} ${PREV_VERSION_OPTS} -i ${REPO_DIGEST} -V ${operator_version}" fi diff --git a/boilerplate/openshift/golang-osd-operator/dependabot.yml b/boilerplate/openshift/golang-osd-operator/dependabot.yml index 92e7d171..d4f250ce 100644 --- a/boilerplate/openshift/golang-osd-operator/dependabot.yml +++ b/boilerplate/openshift/golang-osd-operator/dependabot.yml @@ -10,3 +10,5 @@ updates: ignore: - dependency-name: "app-sre/boilerplate" # don't upgrade boilerplate via these means + - dependency-name: "openshift/origin-operator-registry" + # don't upgrade origin-operator-registry via these means diff --git a/boilerplate/openshift/golang-osd-operator/update b/boilerplate/openshift/golang-osd-operator/update index 3126a3e3..da8ce615 100755 --- a/boilerplate/openshift/golang-osd-operator/update +++ b/boilerplate/openshift/golang-osd-operator/update @@ -23,16 +23,30 @@ mkdir -p $REPO_ROOT/.github echo "Copying dependabot.yml to .github/dependabot.yml" cp ${HERE}/dependabot.yml ${REPO_ROOT}/.github/dependabot.yml +# Add olm-registry Dockerfile +mkdir -p $REPO_ROOT/build +echo "Copying Dockerfile.olm-registry to build/Dockerfile.olm-registry" +cp ${HERE}/Dockerfile.olm-registry ${REPO_ROOT}/build/Dockerfile.olm-registry +# if the gitignore file exists, remove the olm-registry line +if [[ -f ${REPO_ROOT}/.gitignore ]]; then + ${SED?} -i "/Dockerfile.olm-registry/d" ${REPO_ROOT}/.gitignore +fi + # Update Dockerfile builder image -DOCKERFILE=build/Dockerfile -echo "Overwriting $DOCKERFILE's initial FROM with $IMAGE_PULL_PATH" -${SED?} -i "1s,.*,FROM $IMAGE_PULL_PATH AS builder," $DOCKERFILE - -# Update any UBI images using latest tags to use a versioned tag that is compatible with dependabot -for ubi_latest in $(grep -oE 'registry.access.redhat.com/ubi[7-9]/ubi.*?:latest' ${DOCKERFILE}); do - replacement_image=$(skopeo inspect --override-os linux --override-arch amd64 docker://${ubi_latest} --format "{{.Name}}:{{.Labels.version}}-{{.Labels.release}}" | ${SED?} 's,\.[0-9]\+$,,') - echo "Overwriting ${DOCKERFILE}'s ${ubi_latest} image to ${replacement_image}" - ${SED?} -i "s,${ubi_latest},${replacement_image}," ${DOCKERFILE} +DOCKERFILES=$(ls -1 $REPO_ROOT/build/Dockerfile*) +for file in $DOCKERFILES; do + # only update boilerplate base on the main file + if [[ $file == *"Dockerfile" ]]; then + echo "Overwriting $file's initial FROM with $IMAGE_PULL_PATH" + ${SED?} -i "1s,.*,FROM $IMAGE_PULL_PATH AS builder," $file + fi + + # Update any UBI images using latest tags to use a versioned tag that is compatible with dependabot + for ubi_latest in $(grep -oE 'registry.access.redhat.com/ubi[7-9]/ubi.*?:latest' ${file}); do + replacement_image=$(skopeo inspect --override-os linux --override-arch amd64 docker://${ubi_latest} --format "{{.Name}}:{{.Labels.version}}-{{.Labels.release}}" | ${SED?} 's,\.[0-9]\+$,,') + echo "Overwriting ${file}'s ${ubi_latest} image to ${replacement_image}" + ${SED?} -i "s,${ubi_latest},${replacement_image}," ${file} + done done # Add ci-operator configuration diff --git a/boilerplate/update.cfg b/boilerplate/update.cfg index 7e194b21..30f4bcee 100644 --- a/boilerplate/update.cfg +++ b/boilerplate/update.cfg @@ -1,2 +1,3 @@ # Use standards for Go-based OSD operators openshift/golang-osd-operator +openshift/golang-osd-operator-osde2e diff --git a/build/Dockerfile b/build/Dockerfile index 3eaffa64..7117ae98 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/app-sre/boilerplate:image-v3.0.2 AS builder +FROM quay.io/app-sre/boilerplate:image-v3.0.3 AS builder RUN mkdir -p /workdir COPY . /workdir diff --git a/build/Dockerfile.olm-registry b/build/Dockerfile.olm-registry new file mode 100644 index 00000000..e9a54a6e --- /dev/null +++ b/build/Dockerfile.olm-registry @@ -0,0 +1,21 @@ +FROM quay.io/openshift/origin-operator-registry:4.12 AS builder +ARG SAAS_OPERATOR_DIR +COPY ${SAAS_OPERATOR_DIR} manifests +RUN initializer --permissive + +FROM registry.access.redhat.com/ubi8/ubi-micro:8.7-6 + +COPY --from=builder /bin/registry-server /bin/registry-server +COPY --from=builder /bin/grpc_health_probe /bin/grpc_health_probe +COPY --from=builder /bin/initializer /bin/initializer + +WORKDIR /registry +RUN chgrp -R 0 /registry && chmod -R g+rwx /registry + +USER 1001 + +COPY --from=builder /registry /registry + +EXPOSE 50051 + +CMD ["registry-server", "-t", "/tmp/terminate.log"] From 59a983c7174a6de55a18eab64fa8928a6bbc7929 Mon Sep 17 00:00:00 2001 From: Brady Pratt Date: Tue, 28 Mar 2023 10:39:06 -0500 Subject: [PATCH 2/2] osde2e: migrate tests move the tests from the centralized osde2e repo Signed-off-by: Brady Pratt --- go.mod | 6 +- go.sum | 16 ++- osde2e/Dockerfile | 13 ++ ...loyment_validation_operator_runner_test.go | 28 ++++ .../deployment_validation_operator_tests.go | 131 ++++++++++++++++++ 5 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 osde2e/Dockerfile create mode 100644 osde2e/deployment_validation_operator_runner_test.go create mode 100644 osde2e/deployment_validation_operator_tests.go diff --git a/go.mod b/go.mod index cc641b76..613e2a6b 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,8 @@ require ( k8s.io/api v0.26.3 k8s.io/apimachinery v0.26.3 k8s.io/client-go v0.26.3 - sigs.k8s.io/controller-runtime v0.14.0 + sigs.k8s.io/controller-runtime v0.14.5 + sigs.k8s.io/e2e-framework v0.2.0 ) require ( @@ -79,6 +80,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect + github.com/moby/spdystream v0.2.0 // indirect github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -138,3 +140,5 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +replace github.com/openshift/api => github.com/openshift/api v0.0.0-20230327113148-36ce464529eb diff --git a/go.sum b/go.sum index b227b183..f509ba82 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,7 @@ github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/O github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -109,6 +110,7 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -237,6 +239,7 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA= github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -303,6 +306,8 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI= github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA= github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= @@ -329,8 +334,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/openshift/api v3.9.0+incompatible h1:fJ/KsefYuZAjmrr3+5U9yZIZbTOpVkDDLDLFresAeYs= -github.com/openshift/api v3.9.0+incompatible/go.mod h1:dh9o4Fs58gpFXGSYfnVxGR9PnV53I8TW84pQaJDdGiY= +github.com/openshift/api v0.0.0-20230327113148-36ce464529eb h1:nJp2JVf8FsNUbdZ1QjLgmWCdvqRaLNE8dYb5WFQJ3jA= +github.com/openshift/api v0.0.0-20230327113148-36ce464529eb/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= @@ -405,6 +410,7 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/vladimirvivien/gexe v0.2.0 h1:nbdAQ6vbZ+ZNsolCgSVb9Fno60kzSuvtzVh6Ytqi/xY= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -848,8 +854,10 @@ oras.land/oras-go v1.2.2/go.mod h1:Apa81sKoZPpP7CDciE006tSZ0x3Q3+dOoBcMZ/aNxvw= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/controller-runtime v0.14.0 h1:ju2xsov5Ara6FoQuddg+az+rAxsUsTYn2IYyEKCTyDc= -sigs.k8s.io/controller-runtime v0.14.0/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU= +sigs.k8s.io/controller-runtime v0.14.5 h1:6xaWFqzT5KuAQ9ufgUaj1G/+C4Y1GRkhrxl+BJ9i+5s= +sigs.k8s.io/controller-runtime v0.14.5/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/e2e-framework v0.2.0 h1:gD6AWWAHFcHibI69E9TgkNFhh0mVwWtRCHy2RU057jQ= +sigs.k8s.io/e2e-framework v0.2.0/go.mod h1:E6JXj/V4PIlb95jsn2WrNKG+Shb45xaaI7C0+BH4PL8= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= diff --git a/osde2e/Dockerfile b/osde2e/Dockerfile new file mode 100644 index 00000000..0be6c71c --- /dev/null +++ b/osde2e/Dockerfile @@ -0,0 +1,13 @@ + +# THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT. +FROM registry.ci.openshift.org/openshift/release:golang-1.18 AS builder + +ENV PKG=/go/src/github.com/openshift/deployment-validation-operator/ +WORKDIR ${PKG} +COPY . . + +FROM registry.access.redhat.com/ubi8/ubi-minimal:latest + +COPY ./harness.test harness.test + +ENTRYPOINT [ "/harness.test" ] diff --git a/osde2e/deployment_validation_operator_runner_test.go b/osde2e/deployment_validation_operator_runner_test.go new file mode 100644 index 00000000..804a496c --- /dev/null +++ b/osde2e/deployment_validation_operator_runner_test.go @@ -0,0 +1,28 @@ +// THIS FILE IS GENERATED BY BOILERPLATE. DO NOT EDIT. +//go:build integration +// +build integration + +package osde2etests + +import ( + "path/filepath" + "testing" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +const ( + testResultsDirectory = "/test-run-results" + jUnitOutputFilename = "junit-example-addon.xml" +) + +// Test entrypoint. osde2e runs this as a test suite on test pod. +func TestDeploymentValidationOperator(t *testing.T) { + RegisterFailHandler(Fail) + + suiteConfig, reporterConfig := GinkgoConfiguration() + reporterConfig.JUnitReport = filepath.Join(testResultsDirectory, jUnitOutputFilename) + RunSpecs(t, "Deployment Validation Operator", suiteConfig, reporterConfig) + +} + diff --git a/osde2e/deployment_validation_operator_tests.go b/osde2e/deployment_validation_operator_tests.go new file mode 100644 index 00000000..9442f6ea --- /dev/null +++ b/osde2e/deployment_validation_operator_tests.go @@ -0,0 +1,131 @@ +package osde2etests + +import ( + "context" + "fmt" + "time" + + "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" //nolint:golint + appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apimachinerylabels "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes" + "sigs.k8s.io/controller-runtime/pkg/client/config" + "sigs.k8s.io/e2e-framework/klient/k8s/resources" + "sigs.k8s.io/e2e-framework/klient/wait" + "sigs.k8s.io/e2e-framework/klient/wait/conditions" +) + +var _ = ginkgo.Describe("DVO", ginkgo.Ordered, func() { + const ( + namespaceName = "openshift-deployment-validation-operator" + deploymentName = "deployment-validation-operator" + ) + + var k8s *resources.Resources + + ginkgo.BeforeAll(func() { + // setup the k8s client + cfg, err := config.GetConfig() + Expect(err).Should(BeNil(), "failed to get kubeconfig") + k8s, err = resources.New(cfg) + Expect(err).Should(BeNil(), "resources.New error") + }) + + ginkgo.It("exists and is running", func(ctx context.Context) { + const serviceName = "deployment-validation-operator-metrics" + clusterRoles := []string{ + "deployment-validation-operator-og-admin", + "deployment-validation-operator-og-edit", + "deployment-validation-operator-og-view", + } + + err := k8s.Get(ctx, namespaceName, namespaceName, &v1.Namespace{}) + Expect(err).Should(BeNil(), "unable to get namespace %s", namespaceName) + + err = k8s.Get(ctx, serviceName, namespaceName, &v1.Service{}) + Expect(err).Should(BeNil(), "unable to get service %s", serviceName) + + for _, clusterRoleName := range clusterRoles { + err = k8s.Get(ctx, clusterRoleName, "", &rbacv1.ClusterRole{}) + Expect(err).Should(BeNil(), "unable to get clusterrole %s", clusterRoleName) + } + + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{Name: deploymentName, Namespace: namespaceName}, + } + deploymentAvailable := conditions.New(k8s). + DeploymentConditionMatch(deployment, appsv1.DeploymentAvailable, v1.ConditionTrue) + err = wait.For(deploymentAvailable, wait.WithTimeout(10*time.Second)) + Expect(err).Should(BeNil(), "deployment %s never became available", deploymentName) + }) + + ginkgo.Context("validates", func() { + var namespace *v1.Namespace + + ginkgo.BeforeEach(func(ctx context.Context) { + namespace = &v1.Namespace{ObjectMeta: metav1.ObjectMeta{GenerateName: "osde2e-dvo-"}} + err := k8s.Create(ctx, namespace) + Expect(err).Should(BeNil(), "unable to create test namespace %s", namespace.GetName()) + + labels := map[string]string{"app": "test"} + deployment := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{GenerateName: "osde2e-", Namespace: namespace.GetName()}, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{MatchLabels: labels}, + Template: v1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Labels: labels}, + Spec: v1.PodSpec{ + Containers: []v1.Container{ + {Name: "pause", Image: "registry.k8s.io/pause:latest"}, + }, + }, + }, + }, + } + err = k8s.Create(ctx, deployment) + Expect(err).Should(BeNil(), "unable to create deployment %s", deployment.GetName()) + deploymentAvailable := conditions.New(k8s). + DeploymentConditionMatch(deployment, appsv1.DeploymentAvailable, v1.ConditionTrue) + err = wait.For(deploymentAvailable) + Expect(err).Should(BeNil(), "deployment %s never became available", deployment.GetName()) + + ginkgo.DeferCleanup(k8s.Delete, namespace) + }) + + ginkgo.It("new deployments", func(ctx context.Context) { + //nolint:lll + validationMsg := fmt.Sprintf("\"msg\":\"Set memory requests and limits for your container based on its requirements. Refer to https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits for details.\",\"request.namespace\":%q", namespace.GetName()) + + // Wait for the deployment logs to contain the validation message + Eventually(ctx, func(ctx context.Context) (string, error) { + pods := &v1.PodList{} + lbls := apimachinerylabels.FormatLabels(map[string]string{"app": deploymentName}) + err := k8s.List(ctx, pods, resources.WithLabelSelector(lbls)) + if err != nil { + return "", err + } + if len(pods.Items) < 1 { + return "", fmt.Errorf("unable to find pod for deployment %s", deploymentName) + } + clientset, err := kubernetes.NewForConfig(k8s.GetConfig()) + if err != nil { + return "", err + } + req := clientset.CoreV1().Pods(namespaceName). + GetLogs(pods.Items[0].GetName(), &v1.PodLogOptions{}) + logs, err := req.DoRaw(ctx) + if err != nil { + return "", err + } + return string(logs), nil + }). + WithPolling(30 * time.Second). + WithTimeout(10 * time.Minute). + Should(ContainSubstring(validationMsg)) + }) + }) +})