From 0906fab7e8021b67eef051275de51ee7bd3ea5a1 Mon Sep 17 00:00:00 2001 From: Emruz Hossain Date: Mon, 7 Feb 2022 15:05:28 +0600 Subject: [PATCH] Add stash-crd-installer image to install CRDs on helm pre-install hook (#145) Signed-off-by: Emruz Hossain --- .github/workflows/ci.yml | 15 +++- .github/workflows/release.yml | 51 ++++++++++++ .github/workflows/update-crds.yaml | 2 +- Makefile | 33 +++++++- cmd/stash-crd-installer/main.go | 120 +++++++++++++++++++++++++++++ go.mod | 1 + hack/gencrd/main.go | 8 +- openapi/swagger.json | 36 ++++----- vendor/modules.txt | 1 + 9 files changed, 241 insertions(+), 26 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 cmd/stash-crd-installer/main.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe5350f27..5b241302c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go 1.17 - uses: actions/setup-go@v1 + uses: actions/setup-go@v2 with: go-version: 1.17 id: go @@ -29,6 +29,19 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v1 + - name: Login Docker + env: + DOCKER_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + USERNAME: 1gtm + run: | + docker login --username ${USERNAME} --password ${DOCKER_TOKEN} + + - name: Push Docker Image + env: + REGISTRY: appscodeci + run: | + make push + - name: Run checks run: | sudo apt-get -qq update || true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..a93d3a7b9 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,51 @@ +name: Release + +on: + push: + tags: + - "*.*" + +jobs: + build: + name: Build + runs-on: ubuntu-latest + steps: + - name: Check out code into the Go module directory + uses: actions/checkout@v1 + + - name: Set up Go 1.17 + uses: actions/setup-go@v2 + with: + go-version: 1.17 + id: go + + - name: Print version info + id: semver + run: | + make version + + - name: Set up QEMU + id: qemu + uses: docker/setup-qemu-action@v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Publish to GitHub Container Registry + env: + REGISTRY: ghcr.io/stashed + DOCKER_TOKEN: ${{ secrets.LGTM_GITHUB_TOKEN }} + USERNAME: 1gtm + APPSCODE_ENV: prod + run: | + docker login ghcr.io --username ${USERNAME} --password ${DOCKER_TOKEN} + make release + + - name: Publish to Docker Registry + env: + DOCKER_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }} + USERNAME: 1gtm + APPSCODE_ENV: prod + run: | + docker login --username ${USERNAME} --password ${DOCKER_TOKEN} + make release diff --git a/.github/workflows/update-crds.yaml b/.github/workflows/update-crds.yaml index 583bc6405..94509cd9d 100644 --- a/.github/workflows/update-crds.yaml +++ b/.github/workflows/update-crds.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Go 1.17 - uses: actions/setup-go@v1 + uses: actions/setup-go@v2 with: go-version: 1.17 id: go diff --git a/Makefile b/Makefile index 490ae6822..e7182f29a 100644 --- a/Makefile +++ b/Makefile @@ -19,6 +19,9 @@ GO_PKG := stash.appscode.dev REPO := $(notdir $(shell pwd)) BIN := apimachinery +# Where to push the docker image. +REGISTRY ?= stashed + # Produce CRDs that work back to Kubernetes 1.11 (no version conversion) CRD_OPTIONS ?= "crd:generateEmbeddedObjectMeta=true" CODE_GENERATOR_IMAGE ?= appscode/gengo:release-1.21 @@ -50,7 +53,7 @@ RESTIC_VER := 0.12.1 ### These variables should not need tweaking. ### -SRC_PKGS := apis client crds pkg # directories which hold app source (not vendored) +SRC_PKGS := apis client cmd crds pkg # directories which hold app source (not vendored) SRC_DIRS := $(SRC_PKGS) hack/gencrd DOCKER_PLATFORMS := linux/amd64 linux/arm linux/arm64 @@ -271,7 +274,7 @@ bin/.container-$(DOTFILE_IMAGE)-TEST: -e 's|{ARG_FROM}|$(BUILD_IMAGE)|g' \ -e 's|{RESTIC_VER}|$(RESTIC_VER)|g' \ $(DOCKERFILE_TEST) > bin/.dockerfile-TEST-$(OS)_$(ARCH) - @DOCKER_CLI_EXPERIMENTAL=enabled docker buildx build --platform $(OS)/$(ARCH) --load --pull -t $(TEST_IMAGE) -f bin/.dockerfile-TEST-$(OS)_$(ARCH) . + @docker buildx build --platform $(OS)/$(ARCH) --load --pull -t $(TEST_IMAGE) -f bin/.dockerfile-TEST-$(OS)_$(ARCH) . @docker images -q $(TEST_IMAGE) > $@ @echo @@ -371,3 +374,29 @@ ci: verify check-license lint build unit-tests #cover .PHONY: clean clean: rm -rf .go bin + +.PHONY: push +push: push-crd-installer + +KO := $(shell go env GOPATH)/bin/ko +.PHONY: push-crd-installer +push-crd-installer: $(BUILD_DIRS) install-ko ## Build and push CRD installer image + @echo "Pushing CRD installer image....." + KO_DOCKER_REPO=$(REGISTRY) $(KO) publish ./cmd/stash-crd-installer --tags $(VERSION),latest --base-import-paths --platform=all + +.PHONY: install-ko +install-ko: + @echo "Installing: github.com/google/ko" + go install github.com/google/ko@latest + +.PHONY: release +release: ## Release final production docker image and push into the DockerHub. + @if [ "$$APPSCODE_ENV" != "prod" ]; then \ + echo "'release' only works in PROD env."; \ + exit 1; \ + fi + @if [ "$(version_strategy)" != "tag" ]; then \ + echo "apply tag to release binaries and/or docker images."; \ + exit 1; \ + fi + @$(MAKE) push --no-print-directory diff --git a/cmd/stash-crd-installer/main.go b/cmd/stash-crd-installer/main.go new file mode 100644 index 000000000..5babd7ee5 --- /dev/null +++ b/cmd/stash-crd-installer/main.go @@ -0,0 +1,120 @@ +/* +Copyright AppsCode Inc. and Contributors + +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. +*/ + +package main + +import ( + "flag" + "os" + + stashv1alpha1 "stash.appscode.dev/apimachinery/apis/stash/v1alpha1" + stashv1beta1 "stash.appscode.dev/apimachinery/apis/stash/v1beta1" + + crd_cs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/klog/v2" + "kmodules.xyz/client-go/apiextensions" + appcatalog "kmodules.xyz/custom-resources/apis/appcatalog/v1alpha1" + metrics "kmodules.xyz/custom-resources/apis/metrics/v1alpha1" +) + +var ( + masterURL string + kubeConfig string + enableEnterpriseFeatures bool +) + +func init() { + flag.StringVar(&kubeConfig, "kubeconfig", kubeConfig, "Path to a kube config file. Only required if out-of-cluster.") + flag.StringVar(&masterURL, "master", masterURL, "The address of the Kubernetes API server. Overrides any value in kube config file. Only required if out-of-cluster.") + flag.BoolVar(&enableEnterpriseFeatures, "enterprise", false, "Specify whether enterprise features enabled or not.") +} + +func main() { + flag.Parse() + + cfg, err := clientcmd.BuildConfigFromFlags(masterURL, kubeConfig) + if err != nil { + klog.Errorf("Error building kubeconfig: %s", err.Error()) + os.Exit(1) + } + + crdClient, err := crd_cs.NewForConfig(cfg) + if err != nil { + klog.Errorf("Error building CRD client: %s", err.Error()) + os.Exit(1) + } + + if err := registerCRDs(crdClient); err != nil { + klog.Errorf("Error building CRD client: %s", err.Error()) + os.Exit(1) + } + klog.Infoln("Successfully installed all CRDs.") +} + +func registerCRDs(crdClient crd_cs.Interface) error { + var resources []*apiextensions.CustomResourceDefinition + + resources = append(resources, getStashCRDs()...) + resources = append(resources, getAppCatalogCRDs()...) + + if enableEnterpriseFeatures { + resources = append(resources, getMetricCRDs()...) + } + return apiextensions.RegisterCRDs(crdClient, resources) +} + +func getStashCRDs() []*apiextensions.CustomResourceDefinition { + // community features CRDs + var stashCRDs []*apiextensions.CustomResourceDefinition + + stashCRDs = append(stashCRDs, + // v1alpha1 resources + stashv1alpha1.Repository{}.CustomResourceDefinition(), + + // v1beta1 resources + stashv1beta1.BackupConfiguration{}.CustomResourceDefinition(), + stashv1beta1.BackupSession{}.CustomResourceDefinition(), + stashv1beta1.RestoreSession{}.CustomResourceDefinition(), + stashv1beta1.Function{}.CustomResourceDefinition(), + stashv1beta1.Task{}.CustomResourceDefinition(), + ) + + // enterprise features CRDs + if enableEnterpriseFeatures { + stashCRDs = append(stashCRDs, + // v1beta1 resources + stashv1beta1.BackupBatch{}.CustomResourceDefinition(), + stashv1beta1.BackupBlueprint{}.CustomResourceDefinition(), + stashv1beta1.RestoreBatch{}.CustomResourceDefinition(), + ) + } + return stashCRDs +} + +func getAppCatalogCRDs() []*apiextensions.CustomResourceDefinition { + return []*apiextensions.CustomResourceDefinition{ + // v1alpha1 resources + appcatalog.AppBinding{}.CustomResourceDefinition(), + } +} + +func getMetricCRDs() []*apiextensions.CustomResourceDefinition { + return []*apiextensions.CustomResourceDefinition{ + // v1alpha1 resources + metrics.MetricsConfiguration{}.CustomResourceDefinition(), + } +} diff --git a/go.mod b/go.mod index 438d2ac3c..1f0d414c8 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( gomodules.xyz/pointer v0.1.0 gomodules.xyz/runtime v0.2.0 k8s.io/api v0.21.1 + k8s.io/apiextensions-apiserver v0.21.1 k8s.io/apimachinery v0.21.1 k8s.io/client-go v0.21.1 k8s.io/klog/v2 v2.8.0 diff --git a/hack/gencrd/main.go b/hack/gencrd/main.go index 07b5924b7..28aa8984a 100644 --- a/hack/gencrd/main.go +++ b/hack/gencrd/main.go @@ -73,12 +73,12 @@ func generateSwaggerJson() { // v1beta1 resources {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralBackupConfiguration, stashv1beta1.ResourceKindBackupConfiguration, true}, - {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourceKindBackupSession, stashv1beta1.ResourceKindBackupSession, true}, - {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourceKindBackupBatch, stashv1beta1.ResourceKindBackupBatch, false}, - {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourceKindBackupBlueprint, stashv1beta1.ResourceKindBackupBlueprint, false}, + {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralBackupSession, stashv1beta1.ResourceKindBackupSession, true}, + {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralBackupBatch, stashv1beta1.ResourceKindBackupBatch, false}, + {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralBackupBlueprint, stashv1beta1.ResourceKindBackupBlueprint, false}, {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralRestoreSession, stashv1beta1.ResourceKindRestoreSession, true}, {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralRestoreBatch, stashv1beta1.ResourceKindRestoreBatch, true}, - {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourceKindFunction, stashv1beta1.ResourceKindFunction, false}, + {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralFunction, stashv1beta1.ResourceKindFunction, false}, {stashv1beta1.SchemeGroupVersion, stashv1beta1.ResourcePluralTask, stashv1beta1.ResourceKindTask, false}, }, //nolint:govet diff --git a/openapi/swagger.json b/openapi/swagger.json index bd9135ceb..8efcfab1e 100644 --- a/openapi/swagger.json +++ b/openapi/swagger.json @@ -1574,7 +1574,7 @@ } } }, - "/apis/stash.appscode.com/v1beta1/backupbatch": { + "/apis/stash.appscode.com/v1beta1/backupbatches": { "get": { "description": "list or watch objects of kind BackupBatch", "consumes": [ @@ -1870,7 +1870,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/backupbatch/{name}": { + "/apis/stash.appscode.com/v1beta1/backupbatches/{name}": { "get": { "description": "read the specified BackupBatch", "consumes": [ @@ -2124,7 +2124,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/backupblueprint": { + "/apis/stash.appscode.com/v1beta1/backupblueprints": { "get": { "description": "list or watch objects of kind BackupBlueprint", "consumes": [ @@ -2420,7 +2420,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/backupblueprint/{name}": { + "/apis/stash.appscode.com/v1beta1/backupblueprints/{name}": { "get": { "description": "read the specified BackupBlueprint", "consumes": [ @@ -2782,7 +2782,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/backupsession": { + "/apis/stash.appscode.com/v1beta1/backupsessions": { "get": { "description": "list or watch objects of kind BackupSession", "consumes": [ @@ -2890,7 +2890,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/function": { + "/apis/stash.appscode.com/v1beta1/functions": { "get": { "description": "list or watch objects of kind Function", "consumes": [ @@ -3186,7 +3186,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/function/{name}": { + "/apis/stash.appscode.com/v1beta1/functions/{name}": { "get": { "description": "read the specified Function", "consumes": [ @@ -4006,7 +4006,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/namespaces/{namespace}/backupsession": { + "/apis/stash.appscode.com/v1beta1/namespaces/{namespace}/backupsessions": { "get": { "description": "list or watch objects of kind BackupSession", "consumes": [ @@ -4310,7 +4310,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/namespaces/{namespace}/backupsession/{name}": { + "/apis/stash.appscode.com/v1beta1/namespaces/{namespace}/backupsessions/{name}": { "get": { "description": "read the specified BackupSession", "consumes": [ @@ -6470,7 +6470,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/backupbatch": { + "/apis/stash.appscode.com/v1beta1/watch/backupbatches": { "get": { "description": "watch individual changes to a list of BackupBatch. deprecated: use the 'watch' parameter with a list operation instead.", "consumes": [ @@ -6578,7 +6578,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/backupbatch/{name}": { + "/apis/stash.appscode.com/v1beta1/watch/backupbatches/{name}": { "get": { "description": "watch changes to an object of kind BackupBatch. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", "consumes": [ @@ -6694,7 +6694,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/backupblueprint": { + "/apis/stash.appscode.com/v1beta1/watch/backupblueprints": { "get": { "description": "watch individual changes to a list of BackupBlueprint. deprecated: use the 'watch' parameter with a list operation instead.", "consumes": [ @@ -6802,7 +6802,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/backupblueprint/{name}": { + "/apis/stash.appscode.com/v1beta1/watch/backupblueprints/{name}": { "get": { "description": "watch changes to an object of kind BackupBlueprint. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", "consumes": [ @@ -7026,7 +7026,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/backupsession": { + "/apis/stash.appscode.com/v1beta1/watch/backupsessions": { "get": { "description": "watch individual changes to a list of BackupSession. deprecated: use the 'watch' parameter with a list operation instead.", "consumes": [ @@ -7134,7 +7134,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/function": { + "/apis/stash.appscode.com/v1beta1/watch/functions": { "get": { "description": "watch individual changes to a list of Function. deprecated: use the 'watch' parameter with a list operation instead.", "consumes": [ @@ -7242,7 +7242,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/function/{name}": { + "/apis/stash.appscode.com/v1beta1/watch/functions/{name}": { "get": { "description": "watch changes to an object of kind Function. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", "consumes": [ @@ -7598,7 +7598,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/namespaces/{namespace}/backupsession": { + "/apis/stash.appscode.com/v1beta1/watch/namespaces/{namespace}/backupsessions": { "get": { "description": "watch individual changes to a list of BackupSession. deprecated: use the 'watch' parameter with a list operation instead.", "consumes": [ @@ -7714,7 +7714,7 @@ } ] }, - "/apis/stash.appscode.com/v1beta1/watch/namespaces/{namespace}/backupsession/{name}": { + "/apis/stash.appscode.com/v1beta1/watch/namespaces/{namespace}/backupsessions/{name}": { "get": { "description": "watch changes to an object of kind BackupSession. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.", "consumes": [ diff --git a/vendor/modules.txt b/vendor/modules.txt index a6bf8778c..3713fe274 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -353,6 +353,7 @@ k8s.io/api/storage/v1 k8s.io/api/storage/v1alpha1 k8s.io/api/storage/v1beta1 # k8s.io/apiextensions-apiserver v0.21.1 +## explicit k8s.io/apiextensions-apiserver/pkg/apis/apiextensions k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/install k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1