From 58c915bf21d332e54166c4eeac1dfad016f78408 Mon Sep 17 00:00:00 2001 From: Karl Isenberg Date: Thu, 2 Nov 2023 17:01:51 -0700 Subject: [PATCH] Skip helm/kustomize install when version matches (#994) Move install out to bash scripts for safer execution, linting, trap function cleanup, and conditional install with verion checking. --- Makefile | 71 ++++++++++++++++++++++++------------ Makefile.build | 14 +++---- Makefile.e2e | 4 +- Makefile.oss.prow | 33 ++--------------- Makefile.reconcilermanager | 4 +- scripts/install-helm.sh | 67 ++++++++++++++++++++++++++++++++++ scripts/install-kustomize.sh | 65 +++++++++++++++++++++++++++++++++ 7 files changed, 192 insertions(+), 66 deletions(-) create mode 100755 scripts/install-helm.sh create mode 100755 scripts/install-kustomize.sh diff --git a/Makefile b/Makefile index 8885d0bb5d..67153e6c51 100644 --- a/Makefile +++ b/Makefile @@ -49,14 +49,24 @@ DOCKER_CLI_IMAGE := gcr.io/cloud-builders/docker:20.10.14 # Directory containing installed go binaries. BIN_DIR := $(GO_DIR)/bin + KUSTOMIZE_VERSION := v5.1.1-gke.2 +KUSTOMIZE := $(BIN_DIR)/kustomize +KUSTOMIZE_STAGING_DIR := $(OUTPUT_DIR)/third_party/kustomize + HELM_VERSION := v3.13.1-gke.2 +HELM := $(BIN_DIR)/helm +HELM_STAGING_DIR := $(OUTPUT_DIR)/third_party/helm + # Keep KIND_VERSION in sync with the version defined in go.mod # When upgrading, update the node image versions at e2e/nomostest/clusters/kind.go KIND_VERSION := v0.20.0 +KIND := $(BIN_DIR)/kind + # crane cli version used for publishing OCI images # used by tests or local make targets CRANE_VERSION := v0.16.1 +CRANE := $(BIN_DIR)/crane # Directory used for staging Docker contexts. STAGING_DIR := $(OUTPUT_DIR)/staging @@ -262,7 +272,7 @@ build-status: @./scripts/build-status.sh .PHONY: test-unit -test-unit: buildenv-dirs install-kustomize +test-unit: buildenv-dirs "$(KUSTOMIZE)" @echo "+++ Running unit tests in a docker container" @./scripts/test-unit.sh $(NOMOS_GO_PKG) @@ -329,46 +339,59 @@ lint-license: buildenv-dirs "$(GOBIN)/addlicense": go install github.com/google/addlicense@v1.0.0 +"$(KUSTOMIZE)": buildenv-dirs + @KUSTOMIZE_VERSION="$(KUSTOMIZE_VERSION)" \ + INSTALL_DIR="$(BIN_DIR)" \ + TMPDIR="/tmp" \ + OUTPUT_DIR="$(OUTPUT_DIR)" \ + STAGING_DIR="$(KUSTOMIZE_STAGING_DIR)" \ + ./scripts/install-kustomize.sh + +.PHONY: install-kustomize +# install kustomize (user-friendly target alias) +install-kustomize: "$(KUSTOMIZE)" + .PHONY: clean-kustomize clean-kustomize: @rm -rf $(KUSTOMIZE_STAGING_DIR) - @rm -rf $(BIN_DIR)/kustomize + @rm -rf $(KUSTOMIZE) -KUSTOMIZE_URL := gs://config-management-release/config-sync/kustomize/tag/$(KUSTOMIZE_VERSION)/kustomize-$(KUSTOMIZE_VERSION)-linux-amd64.tar.gz -KUSTOMIZE_STAGING_DIR := $(OUTPUT_DIR)/third_party/kustomize -KUSTOMIZE_TARBALL := /tmp/kustomize-$(KUSTOMIZE_VERSION)-linux-amd64.tar.gz - -"$(BIN_DIR)/kustomize": clean-kustomize buildenv-dirs - @gsutil cp $(KUSTOMIZE_URL).sha256 $(KUSTOMIZE_TARBALL).sha256 - @gsutil cp $(KUSTOMIZE_URL) $(KUSTOMIZE_TARBALL) - @echo "$$(cat $(KUSTOMIZE_TARBALL).sha256) $(KUSTOMIZE_TARBALL)" | sha256sum -c - @mkdir -p $(KUSTOMIZE_STAGING_DIR) - @tar -zxvf $(KUSTOMIZE_TARBALL) -C $(KUSTOMIZE_STAGING_DIR) - @cp $(KUSTOMIZE_STAGING_DIR)/kustomize $(BIN_DIR)/kustomize - @rm $(KUSTOMIZE_TARBALL) - @rm $(KUSTOMIZE_TARBALL).sha256 +"$(HELM)": buildenv-dirs + @HELM_VERSION="$(HELM_VERSION)" \ + INSTALL_DIR="$(BIN_DIR)" \ + TMPDIR="/tmp" \ + OUTPUT_DIR="$(OUTPUT_DIR)" \ + STAGING_DIR="$(HELM_STAGING_DIR)" \ + ./scripts/install-helm.sh -.PHONY: install-kustomize -install-kustomize: "$(BIN_DIR)/kustomize" +.PHONY: install-helm +# install helm (user-friendly target alias) +install-helm: "$(HELM)" + +.PHONY: clean-helm +clean-helm: + @rm -rf $(HELM_STAGING_DIR) + @rm -rf $(HELM) "$(GOBIN)/kind": go install sigs.k8s.io/kind@$(KIND_VERSION) -"$(BIN_DIR)/kind": "$(GOBIN)/kind" buildenv-dirs - cp $(GOBIN)/kind $(BIN_DIR)/kind +"$(KIND)": "$(GOBIN)/kind" buildenv-dirs + cp $(GOBIN)/kind $(KIND) .PHONY: install-kind -install-kind: "$(BIN_DIR)/kind" +# install kind (user-friendly target alias) +install-kind: "$(KIND)" "$(GOBIN)/crane": go install github.com/google/go-containerregistry/cmd/crane@$(CRANE_VERSION) -"$(BIN_DIR)/crane": "$(GOBIN)/crane" buildenv-dirs - cp $(GOBIN)/crane $(BIN_DIR)/crane +"$(CRANE)": "$(GOBIN)/crane" buildenv-dirs + cp $(GOBIN)/crane $(CRANE) .PHONY: install-crane -# install crane binary to publish OCI images -install-crane: "$(BIN_DIR)/crane" +# install crane (user-friendly target alias) +install-crane: "$(CRANE)" .PHONY: license-headers license-headers: "$(GOBIN)/addlicense" diff --git a/Makefile.build b/Makefile.build index d16c302411..bd50aea52b 100644 --- a/Makefile.build +++ b/Makefile.build @@ -1,8 +1,6 @@ # Included by Makefile. # Rules related to building nomos and docker images. -HELM := $(BIN_DIR)/helm - ################################### # Build environment ################################### @@ -61,7 +59,7 @@ build-junit-report-cli: pull-buildenv buildenv-dirs BUILD_IMAGE_TARGETS := $(patsubst %,__build-image-%,$(IMAGES)) .PHONY: $(BUILD_IMAGE_TARGETS) -$(BUILD_IMAGE_TARGETS): install-helm install-kustomize +$(BUILD_IMAGE_TARGETS): "$(HELM)" "$(KUSTOMIZE)" @echo "+++ Building the $(subst __build-image-,,$@) image: $(call gen_image_tag,$(subst __build-image-,,$@))" @docker buildx build $(DOCKER_BUILD_QUIET) \ --target $(subst __build-image-,,$@) \ @@ -139,11 +137,11 @@ build-manifests: build-manifests-operator build-manifests-oss # Build Config Sync manifests for OSS installations .PHONY: build-manifests-oss -build-manifests-oss: "$(GOBIN)/addlicense" "$(BIN_DIR)/kustomize" $(OUTPUT_DIR) +build-manifests-oss: "$(GOBIN)/addlicense" "$(KUSTOMIZE)" $(OUTPUT_DIR) @ echo "+++ Generating manifests in $(OSS_MANIFEST_STAGING_DIR)" @ echo " Using tags: $(REGISTRY)/*:$(IMAGE_TAG)" @ rm -f $(OSS_MANIFEST_STAGING_DIR)/* - @ "$(BIN_DIR)/kustomize" build --load-restrictor=LoadRestrictionsNone manifests/oss \ + @ "$(KUSTOMIZE)" build --load-restrictor=LoadRestrictionsNone manifests/oss \ | sed \ -e "s|RECONCILER_IMAGE_NAME|$(call gen_image_tag,$(RECONCILER_IMAGE))|g" \ -e "s|OCI_SYNC_IMAGE_NAME|$(call gen_image_tag,$(OCI_SYNC_IMAGE))|g" \ @@ -164,11 +162,11 @@ build-manifests-oss: "$(GOBIN)/addlicense" "$(BIN_DIR)/kustomize" $(OUTPUT_DIR) # Build Config Sync manifests for ACM operator .PHONY: build-manifests-operator -build-manifests-operator: "$(GOBIN)/addlicense" "$(BIN_DIR)/kustomize" $(OUTPUT_DIR) +build-manifests-operator: "$(GOBIN)/addlicense" "$(KUSTOMIZE)" $(OUTPUT_DIR) @ echo "+++ Generating manifests in $(NOMOS_MANIFEST_STAGING_DIR)" @ echo " Using tags: $(REGISTRY)/*:$(IMAGE_TAG)" @ rm -f $(NOMOS_MANIFEST_STAGING_DIR)/* - @ "$(BIN_DIR)/kustomize" build --load-restrictor=LoadRestrictionsNone manifests/operator \ + @ "$(KUSTOMIZE)" build --load-restrictor=LoadRestrictionsNone manifests/operator \ | sed \ -e "s|RECONCILER_IMAGE_NAME|$(call gen_image_tag,$(RECONCILER_IMAGE))|g" \ -e "s|OCI_SYNC_IMAGE_NAME|$(call gen_image_tag,$(OCI_SYNC_IMAGE))|g" \ @@ -192,7 +190,7 @@ config-sync-manifest-no-push: $(OUTPUT_DIR) build-images build-manifests config-sync-manifest: config-sync-manifest-no-push push-images .PHONY: docker-registry -docker-registry: install-kind +docker-registry: "$(KIND)" @KIND_VERSION=$(KIND_VERSION) bash scripts/docker-registry.sh # config-sync-manifest-local builds config sync for local testing in kind. diff --git a/Makefile.e2e b/Makefile.e2e index 224b10958c..5f5af3ddea 100644 --- a/Makefile.e2e +++ b/Makefile.e2e @@ -40,7 +40,7 @@ test-e2e: config-sync-manifest-local __install-nomos-local test-e2e-nobuild # Run the Go e2e tests without building images/manifests. # Useful for modifying test code and rerunning tests without rebuilding images. .PHONY: test-e2e-go-nobuild -test-e2e-nobuild: install-kustomize install-helm install-crane +test-e2e-nobuild: "$(KUSTOMIZE)" "$(HELM)" "$(CRANE)" ./scripts/e2e.sh $(E2E_ARGS) # Run the Go e2e tests on GKE without building images/manifests. @@ -62,7 +62,7 @@ test-e2e-gke: config-sync-manifest test-e2e-gke-nobuild KIND_IMAGE := "kind-image" .PHONY: build-kind-e2e -build-kind-e2e: install-kind install-kustomize install-helm install-crane +build-kind-e2e: "$(KIND)" "$(KUSTOMIZE)" "$(HELM)" "$(CRANE)" @echo "+++ Building $(KIND_IMAGE)" docker buildx build . \ --target kind-e2e \ diff --git a/Makefile.oss.prow b/Makefile.oss.prow index 15b54eaf82..afd141db9e 100644 --- a/Makefile.oss.prow +++ b/Makefile.oss.prow @@ -37,33 +37,6 @@ build-gke-e2e: push-gke-e2e: @docker push $(GKE_E2E_IMAGE) -################################### -# Helpers -################################### - -.PHONY: clean-helm -# remove any existing helm directory/binary. The install-helm target was previously -# creating a directory at this path rather than the binary/file. -clean-helm: - @rm -rf $(HELM_STAGING_DIR) - @rm -rf $(HELM) - -HELM_URL := gs://config-management-release/config-sync/helm/tag/$(HELM_VERSION)/helm-$(HELM_VERSION)-linux-amd64.tar.gz -HELM_STAGING_DIR := $(OUTPUT_DIR)/third_party/helm -HELM_TARBALL := /tmp/helm-$(HELM_VERSION)-linux-amd64.tar.gz - -.PHONY: install-helm -# install helm binary to publish the image -install-helm: clean-helm buildenv-dirs - @gsutil cp $(HELM_URL).sha256 $(HELM_TARBALL).sha256 - @gsutil cp $(HELM_URL) $(HELM_TARBALL) - @echo "$$(cat $(HELM_TARBALL).sha256) $(HELM_TARBALL)" | sha256sum -c - @mkdir -p $(HELM_STAGING_DIR) - @tar -zxvf $(HELM_TARBALL) -C $(HELM_STAGING_DIR) - @cp $(HELM_STAGING_DIR)/helm $(HELM) - @rm $(HELM_TARBALL) - @rm $(HELM_TARBALL).sha256 - ################################### # Prow environment provisioning ################################### @@ -82,7 +55,7 @@ BOOKINFO_REPO_PUBLIC_AR_IMAGE := $(LOCATION)-docker.pkg.dev/$(TEST_INFRA_PROJECT # This target is run as a singleton against the ci-artifacts project, since # these require for the registries to be public. .PHONY: push-test-oci-images-public -push-test-oci-images-public: install-crane +push-test-oci-images-public: "$(CRANE)" @gcloud $(GCLOUD_QUIET) auth configure-docker $(LOCATION)-docker.pkg.dev,gcr.io cd $(KUSTOMIZE_COMPONENTS_DIR) && crane append -f <(tar -f - -c .) -t $(KUSTOMIZE_COMPONENTS_PUBLIC_GCR_IMAGE) cd $(KUSTOMIZE_COMPONENTS_DIR) && crane append -f <(tar -f - -c .) -t $(KUSTOMIZE_COMPONENTS_PUBLIC_AR_IMAGE) @@ -96,7 +69,7 @@ KUSTOMIZE_COMPONENTS_PRIVATE_GCR_IMAGE := gcr.io/$(GCP_PROJECT)/config-sync-test .PHONY: push-test-oci-images-private # push-test-oci-images-private pushes the test images to the Artifact Registry and Container Registry repositories. -push-test-oci-images-private: install-crane +push-test-oci-images-private: "$(CRANE)" @gcloud $(GCLOUD_QUIET) auth configure-docker $(LOCATION)-docker.pkg.dev,gcr.io cd $(KUSTOMIZE_COMPONENTS_DIR) && crane append -f <(tar -f - -c .) -t $(KUSTOMIZE_COMPONENTS_PRIVATE_GCR_IMAGE) cd $(KUSTOMIZE_COMPONENTS_DIR) && crane append -f <(tar -f - -c .) -t $(KUSTOMIZE_COMPONENTS_PRIVATE_AR_IMAGE) @@ -120,5 +93,5 @@ set-up-workload-identity-test: ./scripts/set-up-workload-identity-configs.sh .PHONY: push-test-helm-charts-to-ar -push-test-helm-charts-to-ar: install-helm +push-test-helm-charts-to-ar: "$(HELM)" GCP_PROJECT=$(GCP_PROJECT) ./scripts/push-test-helm-charts-to-ar.sh \ No newline at end of file diff --git a/Makefile.reconcilermanager b/Makefile.reconcilermanager index 460ada92f4..7c477d281a 100644 --- a/Makefile.reconcilermanager +++ b/Makefile.reconcilermanager @@ -13,14 +13,14 @@ generate: install-controller-gen .PHONY: configsync-crds # Generate configsync CRDs and then patch them with kustomize -configsync-crds: install-controller-gen "$(BIN_DIR)/kustomize" "$(GOBIN)/addlicense" +configsync-crds: install-controller-gen "$(KUSTOMIZE)" "$(GOBIN)/addlicense" $(CONTROLLER_GEN) crd \ paths="./pkg/api/configsync/v1alpha1" \ paths="./pkg/api/configsync/v1beta1" \ output:artifacts:config=./manifests \ && mv ./manifests/configsync.gke.io_reposyncs.yaml ./manifests/patch/reposync-crd.yaml \ && mv ./manifests/configsync.gke.io_rootsyncs.yaml ./manifests/patch/rootsync-crd.yaml \ - && "$(BIN_DIR)/kustomize" build ./manifests/patch -o ./manifests \ + && "$(KUSTOMIZE)" build ./manifests/patch -o ./manifests \ && mv ./manifests/*customresourcedefinition_rootsyncs* ./manifests/rootsync-crd.yaml \ && mv ./manifests/*customresourcedefinition_reposyncs* ./manifests/reposync-crd.yaml \ && rm ./manifests/patch/reposync-crd.yaml \ diff --git a/scripts/install-helm.sh b/scripts/install-helm.sh new file mode 100755 index 0000000000..5200752536 --- /dev/null +++ b/scripts/install-helm.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${REPO_ROOT}" + +# Required environment variables +HELM_VERSION=${HELM_VERSION} +INSTALL_DIR=${INSTALL_DIR} + +# Optional environment variables +TMPDIR=${TMPDIR:-/tmp} +OUTPUT_DIR=${OUTPUT_DIR:-${REPO_ROOT}/.output} +STAGING_DIR=${STAGING_DIR:-${OUTPUT_DIR}/third_party/helm} + +function helm_version_installed() { + local version + version=$("${INSTALL_DIR}/helm" version --short) + echo "${version%+*}" # remove commit suffix +} + +# Check installed version +if [[ -f "${INSTALL_DIR}/helm" ]] && [[ -x "${INSTALL_DIR}/helm" ]]; then + if [[ "$(helm_version_installed)" == "${HELM_VERSION}" ]]; then + echo "helm version: ${HELM_VERSION} (already installed)" + exit 0 + fi +fi + +HELM_TARBALL_URL=gs://config-management-release/config-sync/helm/tag/${HELM_VERSION}/helm-${HELM_VERSION}-linux-amd64.tar.gz +HELM_CHECKSUM_URL=${HELM_TARBALL_URL}.sha256 +HELM_TARBALL=${TMPDIR}/helm-${HELM_VERSION}-linux-amd64.tar.gz +HELM_CHECKSUM=${HELM_TARBALL}.sha256 + +function cleanup() { + rm -f "${HELM_TARBALL}" + rm -f "${HELM_CHECKSUM}" +} +trap cleanup EXIT + +echo "Downloading helm ${HELM_VERSION}" +gsutil cp "${HELM_TARBALL_URL}" "${HELM_TARBALL}" +gsutil cp "${HELM_CHECKSUM_URL}" "${HELM_CHECKSUM}" + +echo "Verifying helm checksum" +echo "$(cat "${HELM_CHECKSUM}") ${HELM_TARBALL}" | sha256sum -c + +echo "Installing helm" +mkdir -p "${STAGING_DIR}" +tar -zxvf "${HELM_TARBALL}" -C "${STAGING_DIR}" +cp "${STAGING_DIR}/helm" "${INSTALL_DIR}/helm" + +echo "helm version: $(helm_version_installed)" diff --git a/scripts/install-kustomize.sh b/scripts/install-kustomize.sh new file mode 100755 index 0000000000..be606a2393 --- /dev/null +++ b/scripts/install-kustomize.sh @@ -0,0 +1,65 @@ +#!/bin/bash +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" +cd "${REPO_ROOT}" + +# Required environment variables +KUSTOMIZE_VERSION=${KUSTOMIZE_VERSION} +INSTALL_DIR=${INSTALL_DIR} + +# Optional environment variables +TMPDIR=${TMPDIR:-/tmp} +OUTPUT_DIR=${OUTPUT_DIR:-${REPO_ROOT}/.output} +STAGING_DIR=${STAGING_DIR:-${OUTPUT_DIR}/third_party/kustomize} + +function helm_version_installed() { + "${INSTALL_DIR}/kustomize" version +} + +# Check installed version +if [[ -f "${INSTALL_DIR}/kustomize" ]] && [[ -x "${INSTALL_DIR}/kustomize" ]]; then + if [[ "$(helm_version_installed)" == "${KUSTOMIZE_VERSION}" ]]; then + echo "kustomize version: ${KUSTOMIZE_VERSION} (already installed)" + exit 0 + fi +fi + +KUSTOMIZE_TARBALL_URL=gs://config-management-release/config-sync/kustomize/tag/${KUSTOMIZE_VERSION}/kustomize-${KUSTOMIZE_VERSION}-linux-amd64.tar.gz +KUSTOMIZE_CHECKSUM_URL=${KUSTOMIZE_TARBALL_URL}.sha256 +KUSTOMIZE_TARBALL=${TMPDIR}/kustomize-${KUSTOMIZE_VERSION}-linux-amd64.tar.gz +KUSTOMIZE_CHECKSUM=${KUSTOMIZE_TARBALL}.sha256 + +function cleanup() { + rm -f "${KUSTOMIZE_TARBALL}" + rm -f "${KUSTOMIZE_CHECKSUM}" +} +trap cleanup EXIT + +echo "Downloading kustomize ${KUSTOMIZE_VERSION}" +gsutil cp "${KUSTOMIZE_TARBALL_URL}" "${KUSTOMIZE_TARBALL}" +gsutil cp "${KUSTOMIZE_CHECKSUM_URL}" "${KUSTOMIZE_CHECKSUM}" + +echo "Verifying kustomize checksum" +echo "$(cat "${KUSTOMIZE_CHECKSUM}") ${KUSTOMIZE_TARBALL}" | sha256sum -c + +echo "Installing kustomize" +mkdir -p "${STAGING_DIR}" +tar -zxvf "${KUSTOMIZE_TARBALL}" -C "${STAGING_DIR}" +cp "${STAGING_DIR}/kustomize" "${INSTALL_DIR}/kustomize" + +echo "kustomize version: $("${INSTALL_DIR}/kustomize" version)"