diff --git a/.github/workflows/release-binary.yml b/.github/workflows/release-binary.yml deleted file mode 100644 index c4212cd..0000000 --- a/.github/workflows/release-binary.yml +++ /dev/null @@ -1,45 +0,0 @@ -on: - push: - # Sequence of patterns matched against refs/tags - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Upload Binary - -jobs: - build: - name: Upload Binary - runs-on: ubuntu-latest - steps: - - name: Set up Go 1.14 - uses: actions/setup-go@v1 - with: - go-version: 1.14 - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Build & Test - run: make khelm-static test check e2e-test - - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} - draft: false - prerelease: true - - - name: Upload Binary - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps - asset_path: ./build/bin/khelm-static - asset_name: khelm-linux-amd64 - asset_content_type: application/octet-stream diff --git a/.github/workflows/release-image.yml b/.github/workflows/release-image.yml deleted file mode 100644 index 0911ba7..0000000 --- a/.github/workflows/release-image.yml +++ /dev/null @@ -1,76 +0,0 @@ -# derived from https://github.com/actions/starter-workflows/blob/main/ci/docker-publish.yml -name: Release - -on: - push: - # Publish `master` as Docker `latest` image. - branches: - - master - - v2 - - v1 - - # Publish `v1.2.3` tags as releases. - tags: - - v* - -env: - IMAGE_NAME: khelm - -jobs: - # Push image to GitHub Packages. - # See also https://docs.docker.com/docker-hub/builds/ - push: - runs-on: ubuntu-latest - if: github.event_name == 'push' - - steps: - - name: Set up Go 1.14 - uses: actions/setup-go@v1 - with: - go-version: 1.14 - - - name: Check out code into the Go module directory - uses: actions/checkout@v2 - - - name: Build & Test - run: make test check e2e-test - - - name: Tag image - run: make image IMAGE=$IMAGE_NAME - - - name: Log into GitHub registry - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login docker.pkg.github.com -u ${{ github.actor }} --password-stdin - - - name: Log into DockerHub registry - run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login docker.io -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin - - - name: Push image - run: | - set -e - - IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME - DOCKERHUB_IMAGE_ID=docker.io/mgoltzsche/khelm - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - - # Strip git ref prefix from version - TAGS=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') - - # Strip "v" prefix from tag name - [[ "${{ github.ref }}" == "refs/tags/"* ]] && TAGS=$(echo $TAGS | sed -e 's/^v//') - - # Use Docker `latest` tag convention and also publish latest tag with every other tag - [ "$TAGS" == "master" ] && TAGS=latest || TAGS="latest $TAGS" - - for TAG in $TAGS; do - echo Push $IMAGE_ID:$TAG - - # Push to DockerHub - docker tag $IMAGE_NAME $DOCKERHUB_IMAGE_ID:$TAG - docker push $DOCKERHUB_IMAGE_ID:$TAG - - # Push to GitHub registry - docker tag $IMAGE_NAME $IMAGE_ID:$TAG - docker push $IMAGE_ID:$TAG - done diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..65fc6f3 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,58 @@ +name: Release + +on: + push: + # Publish `master` as Docker `latest` image. + branches: + - master + - v2 + - v1 + + # Publish `v1.2.3` tags as releases. + tags: + - v* + +jobs: + push: + runs-on: ubuntu-latest + if: github.event_name == 'push' + + steps: + - name: Set up Go + uses: actions/setup-go@v1 + with: + go-version: 1.17 + + - name: Check out code into the Go module directory + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up qemu + uses: docker/setup-qemu-action@v1 + with: + platforms: all + + - name: Extract Helm version + id: extract_helm_version + run: | + printf '::set-output name=helm_version::' && + grep helm\.sh/helm/ go.mod | sed -E -e 's!helm\.sh/helm/v3|\s+|\+.*!!g; s!^v!!' | cut -d " " -f2 | grep -E .+ + + - name: Build & Test + run: make test check image e2e-test + + - name: Log into GitHub registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + + - name: Log into DockerHub registry + run: echo "${{ secrets.DOCKERHUB_TOKEN }}" | docker login docker.io -u "${{ secrets.DOCKERHUB_USERNAME }}" --password-stdin + + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + with: + version: v0.182.1 + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + HELM_VERSION: ${{ steps.extract_helm_version.outputs.helm_version }} diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index 2a73691..ef4fb65 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -14,13 +14,20 @@ jobs: runs-on: ubuntu-latest steps: - - name: Set up Go 1.14 + - name: Set up Go uses: actions/setup-go@v1 with: - go-version: 1.14 + go-version: 1.17 - name: Check out code into the Go module directory uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up qemu + uses: docker/setup-qemu-action@v1 + with: + platforms: all - name: Build run: make khelm @@ -36,3 +43,14 @@ jobs: - name: e2e test run: make e2e-test + + - name: Extract Helm version + id: extract_helm_version + run: | + printf '::set-output name=helm_version::' && + grep helm\.sh/helm/ go.mod | sed -E -e 's!helm\.sh/helm/v3|\s+|\+.*!!g; s!^v!!' | cut -d " " -f2 | grep -E .+ + + - name: Dry-run release + run: make snapshot + env: + HELM_VERSION: ${{ steps.extract_helm_version.outputs.helm_version }} diff --git a/.gitignore b/.gitignore index 013bbec..6696418 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ /example/**/generated-manifest-without-secrets.yaml /example/kpt/linkerd/dep /example/kpt/cache-dependencies/chart/charts + +dist/ diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..3490032 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,21 @@ +linters: + enable: + - gofmt + - govet + - errcheck + - staticcheck + - unused + - gosimple + - structcheck + - varcheck + - ineffassign + - deadcode + - typecheck + - rowserrcheck + - gosec + - unconvert + +skip-dirs: + - build + - vendor + diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..51ed12c --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,90 @@ +project_name: khelm +dist: ./build/dist +before: + hooks: + - go mod tidy +builds: +- main: ./cmd/khelm + targets: + - linux_amd64 + - linux_arm64 + - darwin_amd64 + - darwin_arm64 + env: + - CGO_ENABLED=0 + ldflags: + - -s -w -extldflags '-static' -X main.khelmVersion={{.Version}} -X main.helmVersion={{.Env.HELM_VERSION}} +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: '{{ incpatch .Version }}-dev-{{.ShortCommit}}' +changelog: + sort: asc + filters: + exclude: + - '^docs(\([^)]+\))?:' + - '^test(\([^)]+\))?:' + - '^chore(\([^)]+\))?:' +dockers: +- id: khelm-amd64-image + image_templates: + - docker.io/mgoltzsche/khelm:{{.Version}}-amd64 + - ghcr.io/mgoltzsche/khelm:{{.Version}}-amd64 + use: buildx + dockerfile: Dockerfile + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--build-arg=KHELM_VERSION={{.Version}}" + - "--build-arg=HELM_VERSION={{.Env.HELM_VERSION}}" + - "--platform=linux/amd64" +- id: khelm-arm64-image + image_templates: + - docker.io/mgoltzsche/khelm:{{.Version}}-arm64v8 + - ghcr.io/mgoltzsche/khelm:{{.Version}}-arm64v8 + use: buildx + goarch: arm64 + dockerfile: Dockerfile + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--build-arg=KHELM_VERSION={{.Version}}" + - "--build-arg=HELM_VERSION={{.Env.HELM_VERSION}}" + - "--platform=linux/arm64/v8" +docker_manifests: +- id: khelm-multiarch-latest-dockerhub-image + name_template: docker.io/mgoltzsche/khelm:latest + image_templates: + - docker.io/mgoltzsche/khelm:{{.Version}}-amd64 + - docker.io/mgoltzsche/khelm:{{.Version}}-arm64v8 +- id: khelm-multiarch-latest-ghcr-image + name_template: ghcr.io/mgoltzsche/khelm:latest + image_templates: + - ghcr.io/mgoltzsche/khelm:{{.Version}}-amd64 + - ghcr.io/mgoltzsche/khelm:{{.Version}}-arm64v8 +- id: khelm-multiarch-major-dockerhub-image + name_template: docker.io/mgoltzsche/khelm:{{.Major}} + image_templates: + - docker.io/mgoltzsche/khelm:{{.Version}}-amd64 + - docker.io/mgoltzsche/khelm:{{.Version}}-arm64v8 +- id: khelm-multiarch-major-ghcr-image + name_template: ghcr.io/mgoltzsche/khelm:{{.Major}} + image_templates: + - ghcr.io/mgoltzsche/khelm:{{.Version}}-amd64 + - ghcr.io/mgoltzsche/khelm:{{.Version}}-arm64v8 +- id: khelm-multiarch-dockerhub-image + name_template: docker.io/mgoltzsche/khelm:{{.Version}} + image_templates: + - docker.io/mgoltzsche/khelm:{{.Version}}-amd64 + - docker.io/mgoltzsche/khelm:{{.Version}}-arm64v8 +- id: khelm-multiarch-ghcr-image + name_template: ghcr.io/mgoltzsche/khelm:{{.Version}} + image_templates: + - ghcr.io/mgoltzsche/khelm:{{.Version}}-amd64 + - ghcr.io/mgoltzsche/khelm:{{.Version}}-arm64v8 diff --git a/Dockerfile b/Dockerfile index 2899b42..b086463 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,12 @@ -FROM golang:1.14-alpine3.12 AS build -RUN apk add --update --no-cache git -ENV GO111MODULE=on CGO_ENABLED=0 -COPY go.mod go.sum /go/src/github.com/mgoltzsche/khelm/ -WORKDIR /go/src/github.com/mgoltzsche/khelm -RUN go mod download -COPY cmd/khelm /go/src/github.com/mgoltzsche/khelm/cmd/khelm -COPY internal /go/src/github.com/mgoltzsche/khelm/internal -COPY pkg /go/src/github.com/mgoltzsche/khelm/pkg -ARG KHELM_VERSION=dev-build -ARG HELM_VERSION=unknown-version -RUN go build -o khelm -ldflags "-X main.khelmVersion=$KHELM_VERSION -X main.helmVersion=$HELM_VERSION -s -w -extldflags '-static'" ./cmd/khelm && mv khelm /usr/local/bin/ - -FROM alpine:3.12 +FROM alpine:3.14 AS khelm +RUN apk update --no-cache RUN mkdir /helm && chown root:nobody /helm && chmod 1777 /helm ENV HELM_REPOSITORY_CONFIG=/helm/repository/repositories.yaml ENV HELM_REPOSITORY_CACHE=/helm/cache -COPY --from=build /usr/local/bin/khelm /usr/local/bin/khelmfn +COPY khelm /usr/local/bin/khelmfn ENTRYPOINT ["/usr/local/bin/khelmfn"] + +FROM khelm AS test +RUN khelmfn version + +FROM khelm diff --git a/Makefile b/Makefile index 582314f..42ed4cd 100644 --- a/Makefile +++ b/Makefile @@ -3,14 +3,15 @@ IMAGE ?= mgoltzsche/khelm:latest BUILD_DIR := $(CURDIR)/build BIN_DIR := $(BUILD_DIR)/bin KHELM := $(BIN_DIR)/khelm -KHELM_STATIC := $(BIN_DIR)/khelm-static -GOSEC := $(BIN_DIR)/go-sec -GOLINT := $(BIN_DIR)/golint +GOLANGCI_LINT = $(BIN_DIR)/golangci-lint +GORELEASER = $(BIN_DIR)/goreleaser KPT := $(BIN_DIR)/kpt KUSTOMIZE := $(BIN_DIR)/kustomize -KPT_VERSION ?= 0.39.2 -KUSTOMIZE_VERSION ?= 4.1.3 +GORELEASER_VERSION ?= v0.182.1 +GOLANGCI_LINT_VERSION ?= v1.42.1 +KPT_VERSION ?= v0.39.2 +KUSTOMIZE_VERSION ?= v4.1.3 BATS_VERSION = v1.3.0 BATS_DIR = $(BUILD_DIR)/tools/bats @@ -18,30 +19,18 @@ BATS = $(BIN_DIR)/bats REV := $(shell git rev-parse --short HEAD 2> /dev/null || echo 'unknown') VERSION ?= $(shell echo "$$(git describe --exact-match --tags $(git log -n1 --pretty='%h') 2> /dev/null || echo dev)-$(REV)" | sed 's/^v//') -HELM_VERSION := $(shell grep helm\.sh/helm/ go.mod | sed -E -e 's/helm\.sh\/helm\/v3|\s+|\+.*//g' -e 's/^v//' | cut -d " " -f2) -GO_LDFLAGS := -X main.khelmVersion=$(VERSION) -X main.helmVersion=$(HELM_VERSION) +HELM_VERSION := $(shell grep helm\.sh/helm/ go.mod | sed -E -e 's!helm\.sh/helm/v3|\s+|\+.*!!g; s!^v!!' | cut -d " " -f2 | grep -E .+) +GO_LDFLAGS := -X main.khelmVersion=$(VERSION) -X main.helmVersion=$(HELM_VERSION) -s -w -extldflags '-static' BUILDTAGS ?= +CGO_ENABLED ?= 0 +DOCKER ?= docker all: clean khelm test check -khelm: $(KHELM) +khelm: + CGO_ENABLED=$(CGO_ENABLED) go build -o $(BUILD_DIR)/bin/khelm -ldflags "$(GO_LDFLAGS)" -tags "$(BUILDTAGS)" ./cmd/khelm -khelm-static: $(KHELM_STATIC) - -$(KHELM): $(BUILD_DIR) - go build -o $(BUILD_DIR)/bin/khelm -a -ldflags "$(GO_LDFLAGS)" -tags "$(BUILDTAGS)" ./cmd/khelm - -$(KHELM_STATIC): image $(BUILD_DIR) - @echo Copying khelm binary from container - @{ \ - set -e; \ - CONTAINER=`docker create $(IMAGE)`; \ - docker cp $$CONTAINER:/usr/local/bin/khelmfn $(KHELM_STATIC); \ - [ -f $(KHELM) ] || cp $(KHELM_STATIC) $(KHELM); \ - docker rm -f $$CONTAINER >/dev/null; \ - } - -install: khelm +install: cp $(BUILD_DIR)/bin/khelm /usr/local/bin/khelm chmod +x /usr/local/bin/khelm @@ -49,8 +38,8 @@ install-kustomize-plugin: mkdir -p $${XDG_CONFIG_HOME:-$$HOME/.config}/kustomize/plugin/khelm.mgoltzsche.github.com/v1/chartrenderer cp $(BUILD_DIR)/bin/khelm $${XDG_CONFIG_HOME:-$$HOME/.config}/kustomize/plugin/khelm.mgoltzsche.github.com/v1/chartrenderer/ChartRenderer -image: - docker build --force-rm -t $(IMAGE) --build-arg KHELM_VERSION=$(VERSION) --build-arg HELM_VERSION=$(HELM_VERSION) . +image: khelm + $(DOCKER) build --force-rm -t $(IMAGE) -f ./Dockerfile $(BIN_DIR) test: $(BUILD_DIR) go test -coverprofile $(BUILD_DIR)/coverage.out -cover ./... @@ -58,21 +47,13 @@ test: $(BUILD_DIR) coverage: test go tool cover -html=$(BUILD_DIR)/coverage.out -o $(BUILD_DIR)/coverage.html -e2e-test: image khelm-static kpt kustomize | $(BATS) +e2e-test: kpt kustomize | $(BATS) @echo 'Running e2e tests (PATH=$(BUILD_DIR)/bin)' @{ \ export PATH="$(BIN_DIR):$$PATH" IMAGE=$(IMAGE); \ $(BATS) -T ./e2e; \ } -# ./e2e/kustomize-plugin-test.sh; \ -# IMAGE=$(IMAGE) ./e2e/image-cli-test.sh; \ -# ./e2e/kpt-function-test.sh; \ -# ./e2e/kpt-cache-test.sh; \ -# ./e2e/kpt-cert-manager-test.sh; \ -# ./e2e/kpt-linkerd-test.sh; \ -# } - fmt: go fmt ./... @@ -86,69 +67,34 @@ clean-all: clean rm -rf $(BUILD_DIR) find . -name charts -type d -exec rm -rf {} \; -check: gofmt vet golint gosec ## Runs all linters - -gofmt: - MSGS="$$(gofmt -s -d .)" && [ ! "$$MSGS" ] || (echo "$$MSGS" >&2; echo 'Please run `make fmt` to fix it' >&2; false) - -vet: - go vet ./... +check: $(GOLANGCI_LINT) ## Runs linters + $(GOLANGCI_LINT) run ./... -gosec: $(GOSEC) - $(GOSEC) --quiet -exclude=G302,G304,G306 ./... +snapshot: $(GORELEASER) ## Builds a snapshot release but does not publish it + HELM_VERSION="$(HELM_VERSION)" $(GORELEASER) release --snapshot --rm-dist -golint: $(GOLINT) - $(GOLINT) -set_exit_status ./... +register-qemu-binfmt: ## Enable multiarch support on the host + $(DOCKER) run --rm --privileged multiarch/qemu-user-static:5.2.0-2 --reset -p yes kpt: $(KPT) kustomize: $(KUSTOMIZE) -$(GOSEC): $(BUILD_DIR) - @echo Building gosec - @{ \ - set -e; \ - TMP_DIR=$$(mktemp -d); \ - (cd $$TMP_DIR && \ - GOPATH=$$TMP_DIR GO111MODULE=on go get github.com/securego/gosec/v2/cmd/gosec@v2.4.0); \ - cp $$TMP_DIR/bin/gosec $(GOSEC); \ - chmod -R u+w $$TMP_DIR; \ - rm -rf $$TMP_DIR; \ - } +golangci-lint: $(GOLANGCI_LINT) -$(GOLINT): $(BUILD_DIR) - @echo Building golint - @{ \ - set -e; \ - TMP_DIR=$$(mktemp -d); \ - (cd $$TMP_DIR && \ - GOPATH=$$TMP_DIR GO111MODULE=on go get golang.org/x/lint/golint); \ - cp $$TMP_DIR/bin/golint $(GOLINT); \ - chmod -R u+w $$TMP_DIR; \ - rm -rf $$TMP_DIR; \ - } +goreleaser: $(GORELEASER) -$(KPT): $(BUILD_DIR) - @echo Downloading kpt - @{ \ - set -e; \ - TMP_DIR=$$(mktemp -d); \ - curl -fsSL https://github.com/GoogleContainerTools/kpt/releases/download/v$(KPT_VERSION)/kpt_linux_amd64-$(KPT_VERSION).tar.gz | tar -xzf - -C $$TMP_DIR; \ - cp -f $$TMP_DIR/kpt $(KPT); \ - chmod -R +x $(KPT); \ - rm -rf $$TMP_DIR; \ - } +$(GOLANGCI_LINT): + $(call go-get-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)) -$(KUSTOMIZE): $(BUILD_DIR) - @echo Downloading kustomize - @{ \ - set -e; \ - TMP_DIR=$$(mktemp -d); \ - curl -fsSL https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv$(KUSTOMIZE_VERSION)/kustomize_v$(KUSTOMIZE_VERSION)_linux_amd64.tar.gz | tar -xzf - -C $$TMP_DIR; \ - cp -f $$TMP_DIR/kustomize $(KUSTOMIZE); \ - chmod -R +x $(KUSTOMIZE); \ - rm -rf $$TMP_DIR; \ - } +$(KPT): + $(call download-bin,$(KPT),"https://github.com/GoogleContainerTools/kpt/releases/download/$(KPT_VERSION)/kpt_$$(uname | tr '[:upper:]' '[:lower:]')_amd64") + +$(KUSTOMIZE): + $(call go-get-tool,$(KUSTOMIZE),sigs.k8s.io/kustomize/kustomize/v4@$(KUSTOMIZE_VERSION)) + +$(GORELEASER): + $(call go-get-tool,$(GORELEASER),github.com/goreleaser/goreleaser@$(GORELEASER_VERSION)) $(BATS): @echo Downloading bats @@ -164,3 +110,30 @@ $(BATS): $(BUILD_DIR): @mkdir -p $(BUILD_DIR)/bin + +# go-get-tool will 'go get' any package $2 and install it to $1. +PROJECT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST)))) +define go-get-tool +@[ -f $(1) ] || { \ +set -e ;\ +TMP_DIR=$$(mktemp -d) ;\ +cd $$TMP_DIR ;\ +go mod init tmp ;\ +echo "Downloading $(2)" ;\ +GOBIN=$(PROJECT_DIR)/build/bin go get $(2) ;\ +rm -rf $$TMP_DIR ;\ +} +endef + +# download-bin downloads a binary into the location given as first argument +define download-bin +@[ -f $(1) ] || { \ +set -e ;\ +mkdir -p `dirname $(1)` ;\ +TMP_FILE=$$(mktemp) ;\ +echo "Downloading $(2)" ;\ +curl -fsSLo $$TMP_FILE $(2) ;\ +chmod +x $$TMP_FILE ;\ +mv $$TMP_FILE $(1) ;\ +} +endef diff --git a/README.md b/README.md index f5b69bd..be4521f 100644 --- a/README.md +++ b/README.md @@ -225,12 +225,7 @@ Build and test the khelm binary (requires Go 1.13) as well as the container imag ```sh make clean khelm test check image e2e-test ``` -_The dynamic binary is written to `build/bin/khelm` and the static binary to `build/bin/khelm-static`_. - -Alternatively a static binary can be built using `docker`: -```sh -make khelm-static -``` +_The binary is written to `build/bin/khelm`_. Install the binary on your host at `/usr/local/bin/khelm`: ```sh diff --git a/cmd/khelm/common.go b/cmd/khelm/common.go index 44984e5..2ab02a2 100644 --- a/cmd/khelm/common.go +++ b/cmd/khelm/common.go @@ -2,7 +2,6 @@ package main import ( "context" - "io" "log" "os" "os/signal" @@ -13,18 +12,7 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -func marshal(resources []*yaml.RNode, writer io.Writer) error { - enc := yaml.NewEncoder(writer) - for _, r := range resources { - if err := enc.Encode(r.Document()); err != nil { - return err - } - } - return enc.Close() -} - func render(h *helm.Helm, req *config.ChartConfig) ([]*yaml.RNode, error) { - ctx := context.Background() ctx, cancel := context.WithCancel(context.Background()) sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) diff --git a/cmd/khelm/kustomize_plugin_test.go b/cmd/khelm/kustomize_plugin_test.go index dac8933..423ae4c 100644 --- a/cmd/khelm/kustomize_plugin_test.go +++ b/cmd/khelm/kustomize_plugin_test.go @@ -34,7 +34,7 @@ func runKustomizePlugin(t *testing.T, wd string, args ...string) (out []byte) { defer os.Unsetenv(envKustomizePluginConfigRoot) err = os.Chdir(wd) require.NoError(t, err) - defer os.Chdir(wdOrig) + defer func() { _ = os.Chdir(wdOrig) }() os.Args = append([]string{"testee"}, args...) var buf bytes.Buffer err = Execute(nil, &buf) diff --git a/e2e/kpt-function-tests.bats b/e2e/kpt-function-tests.bats index 219ad42..c8dbd2d 100755 --- a/e2e/kpt-function-tests.bats +++ b/e2e/kpt-function-tests.bats @@ -27,7 +27,7 @@ grep -Eq '^kind: CustomResourceDefinition$' ./cert-manager/static/generated-manifest.yaml || (echo 'FAIL: does not contain CustomResourceDefinition' >&2; false) } -@test "kpt fn should template linkerd example" { +@test "kpt fn should template linkerd experiment" { EXAMPLE_DIR="example" GENERATED_MANIFEST="$EXAMPLE_DIR/kpt/linkerd/manifests/static/linkerd/generated-manifest.yaml" rm -f "$GENERATED_MANIFEST" diff --git a/pkg/helm/load.go b/pkg/helm/load.go index a5f34f1..e9d7f6a 100644 --- a/pkg/helm/load.go +++ b/pkg/helm/load.go @@ -218,11 +218,6 @@ func buildLocalCharts(ctx context.Context, localCharts []localChart, cfg *config return needsReload, nil } -func dependencyFilePath(chartPath string, d *chart.Dependency) string { - name := fmt.Sprintf("%s-%s.tgz", d.Name, d.Version) - return filepath.Join(chartPath, "charts", name) -} - func buildChartDependencies(ctx context.Context, chartRequested *chart.Chart, chartPath string, cfg *config.LoaderConfig, repos repositoryConfig, settings *cli.EnvSettings, getters getter.Providers) error { man := &downloader.Manager{ Out: log.Writer(), diff --git a/pkg/helm/locate.go b/pkg/helm/locate.go index 491a50a..9b17aec 100644 --- a/pkg/helm/locate.go +++ b/pkg/helm/locate.go @@ -97,7 +97,8 @@ func locateChart(ctx context.Context, cfg *config.LoaderConfig, repos repository interrupt := ctx.Done() done := make(chan error, 1) - go func() (err error) { + go func() { + var err error defer func() { done <- err close(done) @@ -105,16 +106,13 @@ func locateChart(ctx context.Context, cfg *config.LoaderConfig, repos repository _ = os.RemoveAll(tmpDestDir) } }() - var chartFile string - chartFile, _, err = dl.DownloadTo(chartURL, cv.Version, tmpDestDir) + _, _, err = dl.DownloadTo(chartURL, cv.Version, tmpDestDir) if err != nil { - return errors.Wrapf(err, "failed to download chart %q with version %q", cfg.Chart, cv.Version) + err = errors.Wrapf(err, "failed to download chart %q with version %q", cfg.Chart, cv.Version) + return } - chartFile, err = filepath.Abs(chartFile) - if err != nil { - return errors.WithStack(err) - } - return os.Rename(tmpDestDir, destDir) + err = os.Rename(tmpDestDir, destDir) + err = errors.WithStack(err) }() select { case err = <-done: diff --git a/pkg/helm/render.go b/pkg/helm/render.go index 8112ec6..af835c1 100644 --- a/pkg/helm/render.go +++ b/pkg/helm/render.go @@ -129,17 +129,6 @@ func renderChart(chartRequested *chart.Chart, req *config.ChartConfig, getters g return transformed, nil } -// checkIfInstallable validates if a chart can be installed -// -// Application chart type is only installable -func checkIfInstallable(ch *chart.Chart) error { - switch ch.Metadata.Type { - case "", "application": - return nil - } - return errors.Errorf("cannot install chart %q since it is of type %q", ch.Name(), ch.Metadata.Type) -} - func parseKubeVersion(version string) (kv chartutil.KubeVersion, err error) { v, err := semver.NewVersion(version) if err != nil { diff --git a/pkg/helm/render_test.go b/pkg/helm/render_test.go index aad23fa..a35e11a 100644 --- a/pkg/helm/render_test.go +++ b/pkg/helm/render_test.go @@ -177,7 +177,7 @@ func TestRenderRebuildsLocalDependencies(t *testing.T) { require.NoError(t, err) defer os.RemoveAll(tplDir) data := []byte("apiVersion: fancyapi/v1\nkind: FancyKind\nmetadata:\n name: sth\nchangedField: changed-value") - err = ioutil.WriteFile(tplFile, data, 0644) + err = ioutil.WriteFile(tplFile, data, 0600) require.NoError(t, err) // Render again and verify that the dependency is rebuilt @@ -264,7 +264,7 @@ func TestRenderRepositoryCredentials(t *testing.T) { require.NoError(t, err) err = os.Mkdir(filepath.Join(tmpHelmHome, "repository"), 0755) require.NoError(t, err) - err = ioutil.WriteFile(filepath.Join(tmpHelmHome, "repository", "repositories.yaml"), b, 0644) + err = ioutil.WriteFile(filepath.Join(tmpHelmHome, "repository", "repositories.yaml"), b, 0600) // #nosec require.NoError(t, err) for _, c := range []struct { @@ -318,7 +318,7 @@ func (f *fakePrivateChartServerHandler) ServeHTTP(writer http.ResponseWriter, re return } writer.WriteHeader(200) - writer.Write(b) + _, _ = writer.Write(b) return case chartFilePath: writer.WriteHeader(200) @@ -357,7 +357,10 @@ func render(t *testing.T, req config.ChartConfig, trustAnyRepo bool, writer io.W enc := yaml.NewEncoder(writer) enc.SetIndent(2) for _, r := range resources { - enc.Encode(r.Document()) + err = enc.Encode(r.Document()) + if err != nil { + return err + } } return enc.Close() } diff --git a/pkg/helm/repositories.go b/pkg/helm/repositories.go index b689460..a511ff9 100644 --- a/pkg/helm/repositories.go +++ b/pkg/helm/repositories.go @@ -101,7 +101,7 @@ func newRepositories(settings *cli.EnvSettings, getters getter.Providers) (r *re cacheDir: settings.RepositoryCache, indexFiles: map[string]*repo.IndexFile{}, } - if !filepath.IsAbs(string(settings.RepositoryConfig)) { + if !filepath.IsAbs(settings.RepositoryConfig) { return nil, errors.Errorf("path to repositories.yaml must be absolute but was %q", settings.RepositoryConfig) } r.repos, err = repo.LoadFile(settings.RepositoryConfig) @@ -353,8 +353,8 @@ func newTempRepositories(r *repositories) (*tempRepositories, error) { return nil, errors.WithStack(err) } _ = tmpFile.Close() - err = r.repos.WriteFile(tmpFile.Name(), 640) - return &tempRepositories{r, tmpFile.Name()}, nil + err = r.repos.WriteFile(tmpFile.Name(), 0640) + return &tempRepositories{r, tmpFile.Name()}, err } func (f *tempRepositories) FilePath() string { @@ -381,7 +381,8 @@ func downloadIndexFile(ctx context.Context, entry *repo.Entry, cacheDir string, interrupt := ctx.Done() done := make(chan error, 1) - go func() (err error) { + go func() { + var err error defer func() { done <- err close(done) @@ -393,14 +394,17 @@ func downloadIndexFile(ctx context.Context, entry *repo.Entry, cacheDir string, tmpEntry.Name = filepath.Base(tmpIdxFileName) r, err := repo.NewChartRepository(&tmpEntry, getters) if err != nil { - return errors.WithStack(err) + err = errors.WithStack(err) + return } r.CachePath = filepath.Dir(tmpIdxFileName) tmpIdxFileName, err = r.DownloadIndexFile() if err != nil { - return errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", entry.URL) + err = errors.Wrapf(err, "looks like %q is not a valid chart repository or cannot be reached", entry.URL) + return } - return os.Rename(tmpIdxFileName, idxFile) + err = os.Rename(tmpIdxFileName, idxFile) + err = errors.WithStack(err) }() select { case err := <-done: diff --git a/pkg/helm/transform.go b/pkg/helm/transform.go index 6cd680b..26dad5b 100644 --- a/pkg/helm/transform.go +++ b/pkg/helm/transform.go @@ -11,10 +11,6 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -const ( - annotationManagedBy = "app.kubernetes.io/managed-by" -) - type manifestTransformer struct { ForceNamespace string Includes matcher.ResourceMatchers