From 6e5a459908ac28948b2dadc56e880679c24a441e Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 19 Jul 2023 09:46:28 +0200 Subject: [PATCH] Copy across build/helm boilerplate from gitopssets-controller (#6) * Copy across build/doc/helm boilerplate from gitopssets-controller - Auto-generate and publish a helm-chart - Auto-generate and copy api docs * Add and report version on startup * Update license and include in helm chart --- .github/workflows/ci.yaml | 41 +++++++++++++++++++++++++++++++++- Dockerfile | 6 +++-- LICENSE | 1 + Makefile | 47 ++++++++++++++++++++++++++++++++++++--- README.md | 15 +++++++++++++ cmd/main.go | 2 ++ cmd/version.go | 3 +++ docs/README.md | 42 ++++++++++++++++++++++++++++++---- 8 files changed, 147 insertions(+), 10 deletions(-) create mode 100644 LICENSE create mode 100644 cmd/version.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9d84647..276677f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -12,6 +12,7 @@ on: pull_request_target: types: - closed + workflow_dispatch: env: REGISTRY: ghcr.io @@ -28,7 +29,7 @@ jobs: - name: Setup uses: actions/setup-go@v3 with: - go-version: 1.19.x + go-version: 1.20.x cache: true - name: Test run: make test @@ -45,6 +46,10 @@ jobs: fetch-depth: 0 # for git describe ref: ${{ github.event.pull_request.head.sha || github.sha }} + - name: Get version + id: get_version + run: echo "::set-output name=VERSION::$(make version)" + - name: Log in to the Container registry uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 with: @@ -65,3 +70,37 @@ jobs: push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + build-args: VERSION=${{ steps.get_version.outputs.VERSION }} + + build-push-helm-chart: + runs-on: ubuntu-latest + needs: [build, test] + # only run on tag + if: startsWith(github.ref, 'refs/tags/v') + permissions: + contents: read # for actions/checkout to fetch code + packages: write + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 # for git describe + ref: ${{ github.event.pull_request.head.sha || github.sha }} + + - name: Install Helm + run: | + wget --no-verbose https://get.helm.sh/helm-v3.12.1-linux-amd64.tar.gz + tar -zxvf helm-v3.12.1-linux-amd64.tar.gz + mv linux-amd64/helm /usr/local/bin/helm + helm version + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and publish chart + run: | + make publish-helm-chart diff --git a/Dockerfile b/Dockerfile index f22f67c..464f9af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,8 @@ # Build the manager binary -FROM golang:1.19 as builder +FROM golang:1.20 as builder ARG TARGETOS ARG TARGETARCH +ARG VERSION WORKDIR /workspace # Copy the Go Modules manifests @@ -13,6 +14,7 @@ RUN go mod download # Copy the go source COPY cmd/main.go cmd/main.go +COPY cmd/version.go cmd/version.go COPY api/ api/ COPY internal/ internal/ @@ -21,7 +23,7 @@ COPY internal/ internal/ # was called. For example, if we call make docker-build in a local env which has the Apple Silicon M1 SO # the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. -RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager cmd/main.go +RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build -a -o manager -ldflags "-X main.Version=${VERSION}" cmd/main.go cmd/version.go # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d9dacb0 --- /dev/null +++ b/LICENSE @@ -0,0 +1 @@ +FluxShardController is under the same license and commercial agreement as Weave GitOps Enterprise, and can only be used in conjunction. diff --git a/Makefile b/Makefile index d7134b7..a2eba90 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,16 @@ +VERSION ?= $(shell git describe --tags --always) +# Strip off leading `v`: v0.12.0 -> 0.12.0 +# Seems to be idiomatic for chart versions: https://helm.sh/docs/topics/charts/#the-chart-file +CHART_VERSION := $(shell echo $(VERSION) | sed 's/^v//') + # Image URL to use all building/pushing image targets -IMG ?= controller:latest +IMG ?= ghcr.io/weaveworks/flux-shard-controller:${VERSION} # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.26.1 +CHART_REGISTRY ?= ghcr.io/weaveworks/charts + # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -62,18 +69,21 @@ test: manifests generate fmt vet envtest ## Run tests. .PHONY: build build: manifests generate fmt vet ## Build manager binary. - go build -o bin/manager cmd/main.go + go build -o bin/manager -ldflags "-X main.Version=${VERSION}" cmd/main.go cmd/version.go .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. go run ./cmd/main.go +version: + @echo $(VERSION) + # If you wish built the manager image targeting other platforms you can use the --platform flag. # (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build docker-build: test ## Build docker image with the manager. - docker build -t ${IMG} . + docker build -t ${IMG} --build-arg VERSION=${VERSION} . .PHONY: docker-push docker-push: ## Push docker image with the manager. @@ -160,3 +170,34 @@ $(CONTROLLER_GEN): $(LOCALBIN) envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. $(ENVTEST): $(LOCALBIN) test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + +HELMIFY = $(LOCALBIN)/helmify +.PHONY: helmify +helmify: + $(call go-get-tool,$(HELMIFY),github.com/arttor/helmify/cmd/helmify@v0.4.3) + +.PHONY: helm-chart +helm-chart: manifests kustomize helmify + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | $(HELMIFY) -crd-dir charts/flux-shard-controller + echo "fullnameOverride: flux-shard" >> charts/flux-shard-controller/values.yaml + cp LICENSE charts/flux-shard-controller/LICENSE + helm lint charts/flux-shard-controller + helm package charts/flux-shard-controller --app-version $(VERSION) --version $(CHART_VERSION) --destination /tmp/helm-repo + +publish-helm-chart: helm-chart + helm push /tmp/helm-repo/flux-shard-controller-${CHART_VERSION}.tgz oci://${CHART_REGISTRY} + +# 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)/bin go install $(2) ;\ +rm -rf $$TMP_DIR ;\ +} +endef \ No newline at end of file diff --git a/README.md b/README.md index 2153a99..b6b6a39 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,17 @@ # flux-shard-controller + Easily spread load across replicated kustomize, source, helm and notification controllers + +## Releasing + +Publishing a **GitHub release** will trigger a GitHub Action to build and push the docker image and helm chart to ghcr.io. + +### Create the release + +Create a [new Github release](https://github.com/weaveworks/flux-shard-controller/releases/new) + +1. Click "Choose a tag" and type in the tag that the release should create on publish (e.g. `v0.5.0`) +2. Click **Generate release notes** +3. Click **Publish release** + +After a few minutes the new packages should be available to view via the repo's [packages page](https://github.com/orgs/weaveworks/packages?repo_name=flux-shard-controller). diff --git a/cmd/main.go b/cmd/main.go index fca702f..9b5df2a 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -65,6 +65,8 @@ func main() { ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + setupLog.Info("configuring manager", "version", Version) + mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{ Scheme: scheme, MetricsBindAddress: metricsAddr, diff --git a/cmd/version.go b/cmd/version.go new file mode 100644 index 0000000..23bec87 --- /dev/null +++ b/cmd/version.go @@ -0,0 +1,3 @@ +package main + +var Version = "dev" diff --git a/docs/README.md b/docs/README.md index 9fb28d2..7d2fcb9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -24,8 +24,8 @@ Add `clusters/my-cluster/flux-system/kustomization.yaml` file to configure the m apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- gotk-components.yaml -- gotk-sync.yaml + - gotk-components.yaml + - gotk-sync.yaml patches: - target: kind: Deployment @@ -80,7 +80,41 @@ source-controller["--watch-label-selector=!sharding.fluxcd.io/key","--events-add ## Install the Shard Controller -**TODO** +The Shard controller is distributed as a Helm chart, you can install it with the follow `HelmRepository` and `HelmRelease`. + +Save the following YAML to a file and either apply it with `kubectl apply -f ` or commit it to your Git repository path that is reconciled in the cluster. + +```yaml +apiVersion: source.toolkit.fluxcd.io/v1beta2 +kind: HelmRepository +metadata: + name: weaveworks-charts + namespace: flux-system +spec: + interval: 1m + type: oci + url: oci://ghcr.io/weaveworks/charts +--- +apiVersion: helm.toolkit.fluxcd.io/v2beta1 +kind: HelmRelease +metadata: + name: flux-shard-controller + namespace: flux-system +spec: + interval: 10m + chart: + spec: + chart: flux-shard-controller + sourceRef: + kind: HelmRepository + name: weaveworks-charts + namespace: flux-system + version: 0.2.0 + install: + crds: CreateReplace + upgrade: + crds: CreateReplace +``` ## Create a non-sharded GitRepository @@ -354,4 +388,4 @@ ignore resources for `shard2`. ## Upgrading the Flux controller -Changes to the controller referenced by `sourceDeploymentRef` are reflected into the managed shard controller, for example, when Flux is updated. \ No newline at end of file +Changes to the controller referenced by `sourceDeploymentRef` are reflected into the managed shard controller, for example, when Flux is updated.