diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0f04682 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file +# Ignore build and test binaries. +bin/ +testbin/ diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..36272df --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,38 @@ +--- +name: Bug +about: Create a bug report to help us improve +title: "[Bug] " +labels: bug +assignees: mmontes11 + +--- + + + +**Describe the bug** + + +**Expected behaviour** + + +**Steps to reproduce the bug** + + +**Additional context** + + +**Environment details**: +- Kubernetes version: +- mariadb-operator version: +- agent version: diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..a466b23 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,25 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature]" +labels: feature +assignees: mmontes11 + +--- + +**Is your feature request related to a problem? Please describe.** + + +**Describe the solution you'd like** + + +**Describe alternatives you've considered** + + +**Additional context** + + +**Environment details**: +- Kubernetes version: +- mariadb-operator version: +- agent version: \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2154eaf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,85 @@ +name: CI + +on: + push: + branches: + - main + pull_request: {} + +env: + GOLANGCI_VERSION: "v1.52.2" + +jobs: + detect-noop: + runs-on: ubuntu-latest + outputs: + noop: ${{ steps.noop.outputs.should_skip }} + steps: + - name: Detect no-op changes + id: noop + uses: fkirc/skip-duplicate-actions@v5.3.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + paths_ignore: '["**.md"]' + concurrent_skipping: false + + lint: + name: Lint + runs-on: ubuntu-latest + needs: detect-noop + if: ${{ needs.detect-noop.outputs.noop != 'true' }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version-file: "go.mod" + cache: true + + - name: GolangCI Lint + uses: golangci/golangci-lint-action@v3 + with: + version: ${{ env.GOLANGCI_VERSION }} + + build: + name: Build + runs-on: ubuntu-latest + needs: detect-noop + if: ${{ needs.detect-noop.outputs.noop != 'true' }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version-file: "go.mod" + cache: true + + - name: Build + run: make build + + - name: Build Docker + run: make docker-build + env: + PLATFORM: linux/amd64 + + test: + name: Test + runs-on: ubuntu-latest + needs: detect-noop + if: ${{ needs.detect-noop.outputs.noop != 'true' }} + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Setup Go + uses: actions/setup-go@v3 + with: + go-version-file: "go.mod" + cache: true + + - name: Test + run: make test \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..d4164b4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,77 @@ +name: Release + +on: + push: + tags: + - "v*" + +env: + GORELEASER_VERSION: "v1.18.2" + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Fetch tags + run: git fetch --force --tags + + - name: Setup QEMU + uses: docker/setup-qemu-action@v2 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v2 + id: buildx + + - name: Login to container Registry + uses: docker/login-action@v2 + with: + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + registry: ghcr.io + + - name: Prepare + id: prep + run: | + VERSION=sha-${GITHUB_SHA::8} + if [[ $GITHUB_REF == refs/tags/* ]]; then + VERSION=${GITHUB_REF/refs\/tags\//} + fi + echo ::set-output name=BUILD_DATE::$(date -u +'%Y-%m-%dT%H:%M:%SZ') + echo ::set-output name=VERSION::${VERSION} + + - name: Publish multi-arch Docker image + uses: docker/build-push-action@v2 + with: + push: true + builder: ${{ steps.buildx.outputs.name }} + context: . + file: ./Dockerfile + platforms: linux/arm64,linux/amd64 + tags: | + ghcr.io/${{ github.repository_owner }}/agent:${{ steps.prep.outputs.VERSION }} + ghcr.io/${{ github.repository_owner }}/agent:latest + labels: | + org.opencontainers.image.title=${{ github.event.repository.name }} + org.opencontainers.image.description=${{ github.event.repository.description }} + org.opencontainers.image.source=${{ github.event.repository.html_url }} + org.opencontainers.image.url=${{ github.event.repository.html_url }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.version=${{ steps.prep.outputs.VERSION }} + org.opencontainers.image.created=${{ steps.prep.outputs.BUILD_DATE }} + + - name: Set GORELEASER_PREVIOUS_TAG + run: echo "GORELEASER_PREVIOUS_TAG=$(git tag -l "v*" --sort=-version:refname | head -n 2 | tail -n 1)" >> $GITHUB_ENV + + - name: GoReleaser + uses: goreleaser/goreleaser-action@v4 + with: + version: ${{ env.GORELEASER_VERSION }} + args: release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 3b735ec..4f36dcd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,3 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# # Binaries for programs and plugins *.exe *.exe~ @@ -13,9 +10,16 @@ # Output of the go coverage tool, specifically when used with LiteIDE *.out +*.html # Dependency directories (remove the comment below to include it) -# vendor/ +vendor/ -# Go workspace file -go.work +# Binaries +bin/ + +# Packaged Helm charts +*.tgz + +# Directory to keep MariaDB files used for development +mariadb/ \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 0000000..0755e2d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,31 @@ +linters-settings: + gocyclo: + min-complexity: 20 + lll: + line-length: 140 + misspell: + locale: US + +linters: + disable-all: true + enable: + - unused + - errcheck + - gocyclo + - gofmt + - goimports + - gosimple + - govet + - ineffassign + - lll + - misspell + - nestif + - staticcheck + - typecheck + - unused + - bodyclose + - noctx + +run: + timeout: 5m + go: "1.20" diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..e4aa044 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,14 @@ +changelog: + use: github-native +builds: + - id: agent + main: main.go + binary: "agent_{{ .Version }}_{{ .Arch }}" + env: + - CGO_ENABLED=0 + goos: + - linux + - darwin + goarch: + - amd64 + - arm64 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e6885dd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "main.go" + } + ] +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..abf1438 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM golang:1.20.4-alpine3.18 AS builder + +ARG TARGETOS +ARG TARGETARCH +ENV CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} + +WORKDIR /app + +COPY go.mod go.sum /app/ +RUN go mod download + +COPY . /app +RUN go build -o agent main.go + +FROM gcr.io/distroless/static AS app + +WORKDIR / +COPY --from=builder /app/agent /bin/agent +USER 65532:65532 + +ENTRYPOINT ["/bin/agent"] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..479ebc3 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +# 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 +else +GOBIN=$(shell go env GOBIN) +endif + +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + +.PHONY: all +all: help + +##@ General + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +include make/deploy.mk +include make/dev.mk +include make/tooling.mk \ No newline at end of file diff --git a/cmd/agent/root.go b/cmd/agent/root.go new file mode 100644 index 0000000..05c32b8 --- /dev/null +++ b/cmd/agent/root.go @@ -0,0 +1,130 @@ +package agent + +import ( + "context" + "log" + "os" + "time" + + "github.com/mariadb-operator/agent/pkg/filemanager" + "github.com/mariadb-operator/agent/pkg/handler" + "github.com/mariadb-operator/agent/pkg/handler/bootstrap" + "github.com/mariadb-operator/agent/pkg/handler/recovery" + "github.com/mariadb-operator/agent/pkg/logger" + "github.com/mariadb-operator/agent/pkg/mariadbd" + "github.com/mariadb-operator/agent/pkg/router" + "github.com/mariadb-operator/agent/pkg/server" + "github.com/spf13/cobra" +) + +var ( + addr string + configDir string + stateDir string + + compressLevel int + rateLimitRequests int + rateLimitDuration time.Duration + + logLevel string + logTimeEncoder string + logDev bool + + bootstrapMariadbdReloadRetries int + bootstrapMariadbdReloadRetryWait time.Duration + + recoveryMariadbdReloadRetries int + recoveryMariadbdReloadRetryWait time.Duration + recoveryRetries int + recoveryRetryWait time.Duration +) + +var rootCmd = &cobra.Command{ + Use: "agent", + Short: "Agent", + Long: `🤖 Sidecar agent for MariaDB that co-operates with mariadb-operator`, + Args: cobra.NoArgs, + Run: func(cmd *cobra.Command, args []string) { + logger, err := logger.NewLogger( + logger.WithLogLevel(logLevel), + logger.WithTimeEncoder(logTimeEncoder), + logger.WithDevelopment(logDev), + ) + if err != nil { + log.Fatalf("error creating logger: %v", err) + } + + fileManager, err := filemanager.NewFileManager(configDir, stateDir) + if err != nil { + logger.Error(err, "error creating file manager") + os.Exit(1) + } + + handlerLogger := logger.WithName("handler") + handler := handler.NewHandler(fileManager, &handlerLogger, + handler.WithBootstrapOptions( + bootstrap.WithMariadbdReload(&mariadbd.ReloadOptions{ + Retries: bootstrapMariadbdReloadRetries, + WaitRetry: bootstrapMariadbdReloadRetryWait, + }), + ), + handler.WithRecoveryOptions( + recovery.WithMariadbdReload(&mariadbd.ReloadOptions{ + Retries: recoveryMariadbdReloadRetries, + WaitRetry: recoveryMariadbdReloadRetryWait, + }), + recovery.WithRecovery(&recovery.RecoveryOptions{ + Retries: recoveryRetries, + WaitRetry: recoveryRetryWait, + }), + ), + ) + + router := router.NewRouter( + handler, + router.WithCompressLevel(compressLevel), + router.WithRateLimit(rateLimitRequests, rateLimitDuration), + ) + + serverLogger := logger.WithName("server") + server := server.NewServer(addr, router, &serverLogger) + if err := server.Start(context.Background()); err != nil { + logger.Error(err, "error starting server") + os.Exit(1) + } + }, +} + +func Execute() { + cobra.CheckErr(rootCmd.Execute()) +} + +func init() { + rootCmd.Flags().StringVar(&addr, "addr", ":5555", "The address that the HTTP server binds to") + rootCmd.Flags().StringVar(&configDir, "config-dir", "/etc/mysql/mariadb.conf.d", "The directory that contains MariaDB configuration files") + rootCmd.Flags().StringVar(&stateDir, "state-dir", "/var/lib/mysql", "The directory that contains MariaDB state files") + + rootCmd.Flags().IntVar(&compressLevel, "compress-level", 5, "HTTP compression level") + rootCmd.Flags().IntVar(&rateLimitRequests, "rate-limit-requests", 100, "Number of requests to be used as rate limit") + rootCmd.Flags().DurationVar(&rateLimitDuration, "rate-limit-duration", 1*time.Minute, "Duration to be used as rate limit") + + rootCmd.Flags().StringVar(&logLevel, "log-level", "info", "Log level to use, one of: "+ + "debug, info, warn, error, dpanic, panic, fatal.") + rootCmd.Flags().StringVar(&logTimeEncoder, "log-time-encoder", "epoch", "Log time encoder to use, one of: "+ + "epoch, millis, nano, iso8601, rfc3339 or rfc3339nano") + rootCmd.Flags().BoolVar(&logDev, "log-dev", false, "Enable development logs.") + + rootCmd.Flags().IntVar(&bootstrapMariadbdReloadRetries, "bootstrap-mariadbd-reload-retries", 10, "Maximum number of attempts "+ + "to reload MariaDB process when bootstraping a new Galera cluster") + rootCmd.Flags().DurationVar(&bootstrapMariadbdReloadRetryWait, "bootstrap-mariadbd-reload-retry-wait", 1*time.Second, + "Time to wait between MariaDB process reload attempts when bootstrapping a new Galera cluster") + + rootCmd.Flags().IntVar(&recoveryMariadbdReloadRetries, "recovery-mariadbd-reload-retries", 3, "Maximum number of attempts "+ + "to reload MariaDB process when recovering the Galera cluster") + rootCmd.Flags().DurationVar(&recoveryMariadbdReloadRetryWait, "recovery-mariadbd-reload-retry-wait", 1*time.Second, + "Time to wait between MariaDB process reload attempts when recovering the Galera cluster") + rootCmd.Flags().IntVar(&recoveryRetries, "recovery-retries", 10, "Maximum number of attempts "+ + "to recover the Galera cluster") + rootCmd.Flags().DurationVar(&recoveryRetryWait, "recovery-retry-wait", 3*time.Second, "Time to wait between "+ + "Galera cluster recover attempts ") +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7e716af --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,28 @@ +version: "3.3" + +services: + mariadb: + container_name: mariadb + image: mariadb:10.11.3 + pid: host + command: + - bash + - -c + - /scripts/galera.sh + restart: unless-stopped + environment: + - HOSTNAME=mariadb-0 + - MYSQL_TCP_PORT=3306 + - MARIADB_ROOT_PASSWORD=mariadb + - MARIADB_DATABASE=mariadb + - MARIADB_USER=mariadb + - MARIADB_PASSWORD=mariadb + ports: + - "3306" + - "4444" + - "4567" + - "4568" + volumes: + - ./hack/galera.sh:/scripts/galera.sh + - ./mariadb/config/docker:/etc/mysql/mariadb.conf.d + - ./mariadb/state/docker:/var/lib/mysql \ No newline at end of file diff --git a/examples/1-bootstrap.cnf b/examples/1-bootstrap.cnf new file mode 100644 index 0000000..e6db0a6 --- /dev/null +++ b/examples/1-bootstrap.cnf @@ -0,0 +1,2 @@ +[galera] +wsrep_new_cluster="ON" diff --git a/examples/2-recovery.cnf b/examples/2-recovery.cnf new file mode 100644 index 0000000..d342c9c --- /dev/null +++ b/examples/2-recovery.cnf @@ -0,0 +1,3 @@ +[galera] +log_error=mariadb.err +wsrep_recover="ON" diff --git a/examples/grastate-recovery.dat b/examples/grastate-recovery.dat new file mode 100644 index 0000000..348b3b0 --- /dev/null +++ b/examples/grastate-recovery.dat @@ -0,0 +1,4 @@ +version: 2.1 +uuid: 220dcdcb-1629-11e4-add3-aec059ad3734 +seqno: -1 +safe_to_bootstrap: 0 \ No newline at end of file diff --git a/examples/grastate-safe-bootstrap.dat b/examples/grastate-safe-bootstrap.dat new file mode 100644 index 0000000..77b603e --- /dev/null +++ b/examples/grastate-safe-bootstrap.dat @@ -0,0 +1,4 @@ +version: 2.1 +uuid: 220dcdcb-1629-11e4-add3-aec059ad3734 +seqno: -1 +safe_to_bootstrap: 1 \ No newline at end of file diff --git a/examples/grastate-seqno.dat b/examples/grastate-seqno.dat new file mode 100644 index 0000000..201cae7 --- /dev/null +++ b/examples/grastate-seqno.dat @@ -0,0 +1,4 @@ +version: 2.1 +uuid: 220dcdcb-1629-11e4-add3-aec059ad3734 +seqno: 1122 +safe_to_bootstrap: 0 \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..32eae71 --- /dev/null +++ b/go.mod @@ -0,0 +1,37 @@ +module github.com/mariadb-operator/agent + +go 1.20 + +require ( + github.com/go-chi/chi/v5 v5.0.8 + github.com/go-chi/httprate v0.7.4 + github.com/go-logr/logr v1.2.4 + github.com/mitchellh/go-ps v1.0.0 + github.com/spf13/cobra v1.7.0 + go.uber.org/zap v1.24.0 + sigs.k8s.io/controller-runtime v0.15.0 + github.com/google/uuid v1.3.0 +) + +require ( + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/go-logr/zapr v1.2.4 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/text v0.9.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + k8s.io/apimachinery v0.27.2 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..13809ab --- /dev/null +++ b/go.sum @@ -0,0 +1,123 @@ +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0= +github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/httprate v0.7.4 h1:a2GIjv8he9LRf3712zxxnRdckQCm7I8y8yQhkJ84V6M= +github.com/go-chi/httprate v0.7.4/go.mod h1:6GOYBSwnpra4CQfAKXu8sQZg+nZ0M1g9QnyFvxrAB8A= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= +github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg= +k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= +k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.15.0 h1:ML+5Adt3qZnMSYxZ7gAverBLNPSMQEibtzAgp0UPojU= +sigs.k8s.io/controller-runtime v0.15.0/go.mod h1:7ngYvp1MLT+9GeZ+6lH3LOlcHkp/+tzA/fmHa4iq9kk= +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/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= diff --git a/hack/galera.sh b/hack/galera.sh new file mode 100755 index 0000000..0fd8320 --- /dev/null +++ b/hack/galera.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +set -e + +if [ -z "$HOSTNAME" ]; then + echo "HOSTNAME environment variable not set" + exit 1 +fi + +if [ -z "$ENTRYPOINT" ]; then + ENTRYPOINT="/usr/local/bin/docker-entrypoint.sh" +fi + +cat <