From ff4c930a238208e102161940f0e42eb90ceb77bf Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Wed, 14 Jan 2026 19:12:06 +0300 Subject: [PATCH 01/11] fix Signed-off-by: Pavel Okhlopkov --- Dockerfile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 0d0717ca2..a0eab6128 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM --platform=${TARGETPLATFORM:-linux/amd64} flant/jq:b6be13d5-musl as libjq # Go builder. -FROM --platform=${TARGETPLATFORM:-linux/amd64} golang:1.23-alpine AS builder +FROM --platform=${TARGETPLATFORM:-linux/amd64} golang:1.25.5-alpine3.23 AS builder ARG appVersion=latest @@ -33,19 +33,20 @@ RUN GOOS=linux \ go build -o post-renderer ./cmd/post-renderer # Final image -FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.21 +FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.23 ARG TARGETPLATFORM # kubectl url has no variant (v7) # helm url has dashes and no variant (v7) RUN apk --no-cache add ca-certificates bash sed tini && \ kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ echo "Download kubectl for ${kubectlArch}" && \ - wget https://storage.googleapis.com/kubernetes-release/release/v1.25.5/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ + wget https://storage.googleapis.com/kubernetes-release/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ chmod +x /bin/kubectl && \ helmArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\//-/g;s/-v7//') && \ - wget https://get.helm.sh/helm-v3.10.3-${helmArch}.tar.gz -O /helm.tgz && \ + wget https://get.helm.sh/helm-v3.15.4-${helmArch}.tar.gz -O /helm.tgz && \ tar -z -x -C /bin -f /helm.tgz --strip-components=1 ${helmArch}/helm && \ rm -f /helm.tgz + COPY --from=libjq /bin/jq /usr/bin COPY --from=builder /app/addon-operator / COPY --from=builder /app/post-renderer / From 4c6b5d9c23228c7bfd1d8bdfda9c3618fd5ba1c4 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Wed, 14 Jan 2026 19:14:11 +0300 Subject: [PATCH 02/11] bump shell Signed-off-by: Pavel Okhlopkov --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index a0eab6128..f4d7f2897 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ ADD . /app # Clone shell-operator to get frameworks RUN git clone https://github.com/flant/shell-operator shell-operator-clone && \ cd shell-operator-clone && \ - git checkout v1.7.2 + git checkout v1.13.1 RUN shellOpVer=$(go list -m all | grep shell-operator | cut -d' ' -f 2-) \ GOOS=linux \ @@ -46,7 +46,7 @@ RUN apk --no-cache add ca-certificates bash sed tini && \ wget https://get.helm.sh/helm-v3.15.4-${helmArch}.tar.gz -O /helm.tgz && \ tar -z -x -C /bin -f /helm.tgz --strip-components=1 ${helmArch}/helm && \ rm -f /helm.tgz - + COPY --from=libjq /bin/jq /usr/bin COPY --from=builder /app/addon-operator / COPY --from=builder /app/post-renderer / From ac18ab0b1c6ad13ebffa2eb8161729a69cd8c842 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Wed, 14 Jan 2026 19:21:19 +0300 Subject: [PATCH 03/11] fix kubectl Signed-off-by: Pavel Okhlopkov --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f4d7f2897..8edbf5dd3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -40,7 +40,7 @@ ARG TARGETPLATFORM RUN apk --no-cache add ca-certificates bash sed tini && \ kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ echo "Download kubectl for ${kubectlArch}" && \ - wget https://storage.googleapis.com/kubernetes-release/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ + wget https://dl.k8s.io/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ chmod +x /bin/kubectl && \ helmArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\//-/g;s/-v7//') && \ wget https://get.helm.sh/helm-v3.15.4-${helmArch}.tar.gz -O /helm.tgz && \ From cd48ef026914d27a5d8e0ff9f2ff420caacf714e Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Wed, 14 Jan 2026 19:23:19 +0300 Subject: [PATCH 04/11] fix Signed-off-by: Pavel Okhlopkov --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8edbf5dd3..ff4b18646 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,7 +37,7 @@ FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.23 ARG TARGETPLATFORM # kubectl url has no variant (v7) # helm url has dashes and no variant (v7) -RUN apk --no-cache add ca-certificates bash sed tini && \ +RUN apk --no-cache add ca-certificates bash sed tini wget && \ kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ echo "Download kubectl for ${kubectlArch}" && \ wget https://dl.k8s.io/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ From dfcde37dd84cc394b8b5bdaed9dd3e304c944be5 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Wed, 14 Jan 2026 19:24:42 +0300 Subject: [PATCH 05/11] remove wget Signed-off-by: Pavel Okhlopkov --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ff4b18646..8edbf5dd3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,7 +37,7 @@ FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.23 ARG TARGETPLATFORM # kubectl url has no variant (v7) # helm url has dashes and no variant (v7) -RUN apk --no-cache add ca-certificates bash sed tini wget && \ +RUN apk --no-cache add ca-certificates bash sed tini && \ kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ echo "Download kubectl for ${kubectlArch}" && \ wget https://dl.k8s.io/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ From d77bc4ca5043205e75d31d88320ee18c6044d1b3 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 10:37:23 +0300 Subject: [PATCH 06/11] bump Signed-off-by: Pavel Okhlopkov --- .github/workflows/build.yaml | 11 ++-- .github/workflows/lint.yaml | 30 ++++------- .github/workflows/tests.yaml | 11 ++-- .gitignore | 2 + Makefile | 102 ++++++++++++++++++++++++++++++++--- 5 files changed, 114 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index baf5f32dc..80529b3cd 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -3,21 +3,18 @@ name: Build on: pull_request: types: [opened, synchronize] - jobs: build_binary: name: Build addon-operator binary runs-on: ubuntu-latest steps: - - name: Set up Go 1.25 + - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.25.5' id: go - - name: Check out addon-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4 @@ -27,15 +24,13 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Build binary - run: | + run: |- export GOOS=linux - go build ./cmd/addon-operator \ No newline at end of file + go build ./cmd/addon-operator diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index e0b155ebf..2611e9657 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,46 +1,38 @@ # every push to a branch: -# - Run Go linters. -# - Check grammar with codespell. +# - run linter name: Lint on: pull_request: types: [opened, synchronize] - jobs: - go_linters: - name: Run Go linters + run_linter: + name: Run linter runs-on: ubuntu-latest steps: - - name: Set up Go 1.25 + - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.25.5' - id: go - - - name: Check out addon-operator code + go-version: "1.25.5" + - name: Check out shell-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache - uses: actions/cache@v4 + uses: actions/cache@v4.2.3 with: path: | ~/go/pkg/mod key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Run golangci-lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b . v2.7.2 - ./golangci-lint run - + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b . v2.8.0 + ./golangci-lint run ./... codespell: name: Run codespell runs-on: ubuntu-latest @@ -48,11 +40,9 @@ jobs: - uses: actions/setup-python@v5 with: python-version: 3.8 - - name: Check out addon-operator code uses: actions/checkout@v4 - - name: Run codespell run: | pip install codespell==v1.17.1 - codespell --skip=".git,go.mod,go.sum,*.log,*.gif,*.png" -L witht,eventtypes,uint,uptodate,afterall + codespell --skip=".git,go.mod,go.sum,*.log,*.gif,*.png,*.md" -L witht,eventtypes,uint,uptodate,afterall,keypair diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index c737616fa..8c9ce8942 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -4,21 +4,18 @@ name: Unit tests on: pull_request: types: [opened, synchronize] - jobs: run_unit_tests: name: Run unit tests runs-on: ubuntu-latest steps: - - name: Set up Go 1.25 + - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.25.5' id: go - - name: Check out addon-operator code uses: actions/checkout@v4 - - name: Restore Go modules id: go-modules-cache uses: actions/cache@v4 @@ -28,17 +25,15 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- - - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | go mod download echo -n "Go modules unpacked size is: " && du -sh $HOME/go/pkg/mod - - name: Run unit tests - run: | + run: |- export GOOS=linux go test \ --race \ - ./cmd/... ./pkg/... \ No newline at end of file + ./cmd/... ./pkg/... diff --git a/.gitignore b/.gitignore index db7a0dbdf..d7b28d580 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ *.so *.dylib +bin/ + # Graph images *.gv *gv.svg diff --git a/Makefile b/Makefile index a822a469a..d1bf5c0f0 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,73 @@ + +.PHONY: go-module-version +go-module-version: go-check git-check + @echo "go get $(shell $(GO) list ./cmd/addon-operator)@$(shell $(GIT) rev-parse HEAD)" + +.PHONY: lint +lint: golangci-lint ## Run linter. + @$(GOLANGCI_LINT) run --fix + +.PHONY: test +test: go-check + @$(GO) test --race --cover ./... + +## Run all generate-* jobs in bulk. +.PHONY: generate +generate: update-k8s-version update-workflows-go-version update-workflows-golangci-lint-version update-workflows-ginkgo-version + + +##@ Dependencies + +WHOAMI ?= $(shell whoami) + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries GO=$(shell which go) GIT=$(shell which git) +GOLANGCI_LINT = $(LOCALBIN)/golangci-lint +YQ = $(LOCALBIN)/yq + +## TODO: remap in yaml file (version.yaml or smthng) +## Tool Versions +# GO_BUILDER_VERSION must be without 'v' prefix +GO_BUILDER_VERSION = 1.25.5 +GOLANGCI_LINT_VERSION = v2.8.0 +YQ_VERSION ?= v4.50.1 + + +.PHONY: update-k8s-version +update-k8s-version: go-check + @kubernetesVer=$(shell $(GO) list -m k8s.io/api | cut -d' ' -f 2); \ + kubectlVer=$$(echo $$kubernetesVer | sed 's/v0/v1/'); \ + echo "Updating kubectl version in Dockerfile to match k8s.io/api version: $$kubectlVer"; \ + sed -i "s/ARG kubectlVersion=.*/ARG kubectlVersion=$$kubectlVer/" Dockerfile; \ + echo "kubectl version in Dockerfile updated to: $$kubectlVer" + +.PHONY: update-workflows-go-version +update-workflows-go-version: yq + for file in $$(find .github/workflows -name "*.yaml"); do \ + if grep -q "actions/setup-go" $$file; then \ + $(YQ) -i '(.jobs[]?.steps[]? | select(.uses | test("actions/setup-go")) | .with."go-version") = "$(GO_BUILDER_VERSION)"' $$file; \ + fi; \ + done + echo "Updated go-version in workflow files to $(GO_BUILDER_VERSION)" + +.PHONY: update-workflows-golangci-lint-version +update-workflows-golangci-lint-version: yq + $(YQ) -i '(.jobs.run_linter.steps[] | select(.name == "Run golangci-lint") | .run) |= sub("v\\d+\\.\\d+\\.\\d+", "$(GOLANGCI_LINT_VERSION)")' .github/workflows/lint.yaml + echo "Updated golangci-lint version in lint.yaml to $(GOLANGCI_LINT_VERSION)" + +.PHONY: update-workflows-ginkgo-version +update-workflows-ginkgo-version: yq + @ginkgoVer=$(shell $(GO) list -m github.com/onsi/ginkgo/v2 | cut -d' ' -f 2); \ + $(YQ) -i '(.jobs.integration_tests.steps[] | select(.name == "Install ginkgo") | .run) |= sub("@latest", "@$$ginkgoVer")' .github/workflows/tests-labeled.yaml; \ + echo "Updated ginkgo version in tests-labeled.yaml to $$ginkgoVer" + +## Installed tools check .PHONY: go-check go-check: @@ -9,13 +77,35 @@ go-check: git-check: $(call error-if-empty,$(GIT),git) -.PHONY: go-module-version -go-module-version: go-check git-check - @echo "go get $(shell $(GO) list ./cmd/addon-operator)@$(shell $(GIT) rev-parse HEAD)" +## Tool installations + +.PHONY: golangci-lint +golangci-lint: $(GOLANGCI_LINT) ## Download golangci-lint locally if necessary. +$(GOLANGCI_LINT): $(LOCALBIN) + $(call go-install-tool,$(GOLANGCI_LINT),github.com/golangci/golangci-lint/v2/cmd/golangci-lint,$(GOLANGCI_LINT_VERSION)) + +.PHONY: yq +yq: $(YQ) ## Download yq locally if necessary. +$(YQ): $(LOCALBIN) + $(call go-install-tool,$(YQ),github.com/mikefarah/yq/v4,$(YQ_VERSION)) + + +# go-install-tool will 'go install' any package with custom target and name of binary, if it doesn't exist +# $1 - target path with name of binary +# $2 - package url which can be installed +# $3 - specific version of package +define go-install-tool +@[ -f "$(1)-$(3)" ] || { \ +set -e; \ +package=$(2)@$(3) ;\ +echo "Downloading $${package}" ;\ +rm -f $(1) || true ;\ +GOBIN=$(LOCALBIN) GOTOOLCHAIN=$(GO_TOOLCHAIN_AUTOINSTALL_VERSION) go install $${package} ;\ +mv $(1) $(1)-$(3) ;\ +} ;\ +ln -sf $(1)-$(3) $(1) +endef -.PHONY: test -test: go-check - @$(GO) test --race --cover ./... define error-if-empty @if [[ -z $(1) ]]; then echo "$(2) not installed"; false; fi From eaabb92c2ef37e17cc30c554995c06c5e83bdb5e Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 10:44:04 +0300 Subject: [PATCH 07/11] bump Signed-off-by: Pavel Okhlopkov --- .github/workflows/build.yaml | 5 +++++ Dockerfile | 8 +++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 80529b3cd..d776fdce5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -24,6 +24,11 @@ jobs: key: ${{ runner.os }}-gomod-${{ hashFiles('go.mod', 'go.sum') }} restore-keys: | ${{ runner.os }}-gomod- + - name: Check generated code is up to date + run: | + make generate + + git diff --exit-code || (echo 'Regenerated code does not match source, please run "make generate"' && exit 1) - name: Download Go modules if: steps.go-modules-cache.outputs.cache-hit != 'true' run: | diff --git a/Dockerfile b/Dockerfile index 8edbf5dd3..dcd52d940 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,12 +35,14 @@ RUN GOOS=linux \ # Final image FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.23 ARG TARGETPLATFORM -# kubectl url has no variant (v7) +ARG kubectlVersion=v1.32.10 + + # kubectl url has no variant (v7) # helm url has dashes and no variant (v7) RUN apk --no-cache add ca-certificates bash sed tini && \ kubectlArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\/v7//') && \ - echo "Download kubectl for ${kubectlArch}" && \ - wget https://dl.k8s.io/release/v1.32.10/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ + echo "Download kubectl version ${kubectlVersion} for ${kubectlArch}" && \ + wget https://dl.k8s.io/release/${kubectlVersion}/bin/${kubectlArch}/kubectl -O /bin/kubectl && \ chmod +x /bin/kubectl && \ helmArch=$(echo ${TARGETPLATFORM:-linux/amd64} | sed 's/\//-/g;s/-v7//') && \ wget https://get.helm.sh/helm-v3.15.4-${helmArch}.tar.gz -O /helm.tgz && \ From 7d8d6265c18f03bd132ae144b36545844cb7a391 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 11:01:48 +0300 Subject: [PATCH 08/11] lint Signed-off-by: Pavel Okhlopkov --- pkg/addon-operator/operator.go | 4 +++- pkg/kube_config_manager/kube_config_manager.go | 4 +++- pkg/module_manager/models/hooks/kind/batch_hook.go | 6 ++++-- pkg/module_manager/models/modules/basic.go | 7 +++++-- pkg/module_manager/models/modules/global.go | 5 ++++- pkg/module_manager/module_manager.go | 8 +++++--- pkg/task/hook_metadata.go | 4 +++- pkg/task/tasks/converge-modules/task.go | 4 ++-- pkg/utils/module_list.go | 2 +- pkg/utils/values_patch.go | 6 +++--- 10 files changed, 33 insertions(+), 17 deletions(-) diff --git a/pkg/addon-operator/operator.go b/pkg/addon-operator/operator.go index c0a74bd24..0ea78b3af 100644 --- a/pkg/addon-operator/operator.go +++ b/pkg/addon-operator/operator.go @@ -473,11 +473,13 @@ func (op *AddonOperator) BootstrapMainQueue(tqs *queue.TaskQueueSet) { func (op *AddonOperator) CreateBootstrapTasks(logLabels map[string]string) []sh_task.Task { const eventDescription = "Operator-Startup" - tasks := make([]sh_task.Task, 0) queuedAt := time.Now() // 'OnStartup' global hooks. onStartupHooks := op.ModuleManager.GetGlobalHooksInOrder(htypes.OnStartup) + + tasks := make([]sh_task.Task, 0, len(onStartupHooks)) + for _, hookName := range onStartupHooks { hookLogLabels := utils.MergeLabels(logLabels, map[string]string{ pkg.LogKeyHook: hookName, diff --git a/pkg/kube_config_manager/kube_config_manager.go b/pkg/kube_config_manager/kube_config_manager.go index 449c0ea02..0b8baa9a2 100644 --- a/pkg/kube_config_manager/kube_config_manager.go +++ b/pkg/kube_config_manager/kube_config_manager.go @@ -259,8 +259,10 @@ func (kcm *KubeConfigManager) handleConfigEvent(obj config.Event) { } func (kcm *KubeConfigManager) handleDeleteEvent(moduleName string, cfg *config.ModuleKubeConfig) { - var modulesChanged []string + modulesChanged := make([]string, 0, 1) + var modulesStateChanged []string + moduleMaintenanceChanged := make(map[string]utils.Maintenance) kcm.logger.Info("module section deleted", slog.String("name", moduleName)) diff --git a/pkg/module_manager/models/hooks/kind/batch_hook.go b/pkg/module_manager/models/hooks/kind/batch_hook.go index aff57e04c..b4b9ff13f 100644 --- a/pkg/module_manager/models/hooks/kind/batch_hook.go +++ b/pkg/module_manager/models/hooks/kind/batch_hook.go @@ -216,8 +216,10 @@ func (h *BatchHook) getConfig() (*BatchHookConfig, error) { func GetBatchHookConfig(moduleName, hookPath string) (*BatchHookConfig, error) { args := []string{"hook", "config"} - envs := make([]string, 0) - envs = append(envs, os.Environ()...) + environ := os.Environ() + + envs := make([]string, 0, len(environ)) + envs = append(envs, environ...) cmd := executor.NewExecutor( "", diff --git a/pkg/module_manager/models/modules/basic.go b/pkg/module_manager/models/modules/basic.go index 776c02aa7..682a15fa7 100644 --- a/pkg/module_manager/models/modules/basic.go +++ b/pkg/module_manager/models/modules/basic.go @@ -813,8 +813,11 @@ func (bm *BasicModule) RunEnabledScript(ctx context.Context, tmpDir string, prec slog.String("path", enabledScriptPath), slog.Any("modules", precedingEnabledModules)) - envs := make([]string, 0) - envs = append(envs, os.Environ()...) + environ := os.Environ() + + envs := make([]string, 0, len(environ)) + envs = append(envs, environ...) + envs = append(envs, fmt.Sprintf("CONFIG_VALUES_PATH=%s", configValuesPath)) envs = append(envs, fmt.Sprintf("VALUES_PATH=%s", valuesPath)) envs = append(envs, fmt.Sprintf("MODULE_ENABLED_RESULT=%s", enabledResultFilePath)) diff --git a/pkg/module_manager/models/modules/global.go b/pkg/module_manager/models/modules/global.go index b72a48567..e1e7dfbb4 100644 --- a/pkg/module_manager/models/modules/global.go +++ b/pkg/module_manager/models/modules/global.go @@ -146,12 +146,15 @@ func (gm *GlobalModule) RunHookByName(ctx context.Context, hookName string, bind if binding == types.BeforeAll || binding == types.AfterAll { snapshots := globalHook.GetHookController().KubernetesSnapshots() - newBindingContext := make([]bindingcontext.BindingContext, 0) + + newBindingContext := make([]bindingcontext.BindingContext, 0, len(bindingContext)) + for _, bc := range bindingContext { bc.Snapshots = snapshots bc.Metadata.IncludeAllSnapshots = true newBindingContext = append(newBindingContext, bc) } + bindingContext = newBindingContext } diff --git a/pkg/module_manager/module_manager.go b/pkg/module_manager/module_manager.go index 58f14e044..88a222952 100644 --- a/pkg/module_manager/module_manager.go +++ b/pkg/module_manager/module_manager.go @@ -974,7 +974,7 @@ func (mm *ModuleManager) HandleScheduleEvent( } func (mm *ModuleManager) CreateTasksByBinding(binding BindingType, createTasksFunc func(gh *hooks.GlobalHook, m *modules.BasicModule, mh *hooks.ModuleHook) []sh_task.Task) []sh_task.Task { - var allTasks []sh_task.Task + var allTasks []sh_task.Task //nolint: prealloc // Process global hooks allTasks = append(allTasks, mm.createTasksFromGlobalHooks(binding, createTasksFunc)...) @@ -987,9 +987,11 @@ func (mm *ModuleManager) CreateTasksByBinding(binding BindingType, createTasksFu // createTasksFromGlobalHooks processes all global hooks for a given binding type func (mm *ModuleManager) createTasksFromGlobalHooks(binding BindingType, createTasksFunc func(gh *hooks.GlobalHook, m *modules.BasicModule, mh *hooks.ModuleHook) []sh_task.Task) []sh_task.Task { - var tasks []sh_task.Task + hooks := mm.GetGlobalHooksInOrder(binding) + + tasks := make([]sh_task.Task, 0, len(hooks)) - for _, hookName := range mm.GetGlobalHooksInOrder(binding) { + for _, hookName := range hooks { gh := mm.GetGlobalHook(hookName) if newTasks := createTasksFunc(gh, nil, nil); len(newTasks) > 0 { tasks = append(tasks, newTasks...) diff --git a/pkg/task/hook_metadata.go b/pkg/task/hook_metadata.go index b2acf5dcb..1c10f65f7 100644 --- a/pkg/task/hook_metadata.go +++ b/pkg/task/hook_metadata.go @@ -125,11 +125,13 @@ func HookMetadataAccessor(t task.Task) HookMetadata { func (hm HookMetadata) GetDescription() string { bindingsMap := make(map[string]struct{}) - bindings := make([]string, 0) for _, bc := range hm.BindingContext { bindingsMap[bc.Binding] = struct{}{} } + + bindings := make([]string, 0, len(bindingsMap)) + for bindingName := range bindingsMap { bindings = append(bindings, bindingName) } diff --git a/pkg/task/tasks/converge-modules/task.go b/pkg/task/tasks/converge-modules/task.go index 7f6480fc9..2feeabb3c 100644 --- a/pkg/task/tasks/converge-modules/task.go +++ b/pkg/task/tasks/converge-modules/task.go @@ -252,12 +252,12 @@ func (s *Task) Handle(ctx context.Context) queue.TaskResult { // CreateBeforeAllTasks returns tasks to run BeforeAll global hooks. func (s *Task) CreateBeforeAllTasks(logLabels map[string]string, eventDescription string) []sh_task.Task { - tasks := make([]sh_task.Task, 0) queuedAt := time.Now() // Get 'beforeAll' global hooks. beforeAllHooks := s.moduleManager.GetGlobalHooksInOrder(hookTypes.BeforeAll) + tasks := make([]sh_task.Task, 0, len(beforeAllHooks)) for _, hookName := range beforeAllHooks { hookLogLabels := utils.MergeLabels(logLabels, map[string]string{ pkg.LogKeyHook: hookName, @@ -296,12 +296,12 @@ func (s *Task) CreateBeforeAllTasks(logLabels map[string]string, eventDescriptio // CreateAfterAllTasks returns tasks to run AfterAll global hooks. func (s *Task) CreateAfterAllTasks(logLabels map[string]string, eventDescription string) ([]sh_task.Task, error) { - tasks := make([]sh_task.Task, 0) queuedAt := time.Now() // Get 'afterAll' global hooks. afterAllHooks := s.moduleManager.GetGlobalHooksInOrder(hookTypes.AfterAll) + tasks := make([]sh_task.Task, 0, len(afterAllHooks)) for i, hookName := range afterAllHooks { hookLogLabels := utils.MergeLabels(logLabels, map[string]string{ pkg.LogKeyHook: hookName, diff --git a/pkg/utils/module_list.go b/pkg/utils/module_list.go index f940495fd..af9781c23 100644 --- a/pkg/utils/module_list.go +++ b/pkg/utils/module_list.go @@ -25,7 +25,7 @@ func SortReverseByReference(in []string, ref []string) []string { // SortReverse creates a copy of 'in' array and sort it in a reverse order. func SortReverse(in []string) []string { - res := make([]string, 0) + res := make([]string, 0, len(in)) res = append(res, in...) sort.Sort(sort.Reverse(sort.StringSlice(res))) diff --git a/pkg/utils/values_patch.go b/pkg/utils/values_patch.go index 47e2c8e11..2027fc005 100644 --- a/pkg/utils/values_patch.go +++ b/pkg/utils/values_patch.go @@ -188,7 +188,7 @@ func AppendValuesPatch(valuesPatches []ValuesPatch, newValuesPatch ValuesPatch) } func CompactValuesPatches(valuesPatches []ValuesPatch, newValuesPatch ValuesPatch) []ValuesPatch { - operations := []*sdkutils.ValuesPatchOperation{} + operations := make([]*sdkutils.ValuesPatchOperation, 0, len(valuesPatches)) for _, patch := range valuesPatches { operations = append(operations, patch.Operations...) @@ -248,13 +248,13 @@ func CompactPatches(existedOperations []*sdkutils.ValuesPatchOperation, newOpera } // Sort paths for proper 'add' sequence - paths := []string{} + paths := make([]string, 0, len(patchesTree)) for path := range patchesTree { paths = append(paths, path) } sort.Strings(paths) - newOps := []*sdkutils.ValuesPatchOperation{} + newOps := make([]*sdkutils.ValuesPatchOperation, 0, len(paths)) for _, path := range paths { newOps = append(newOps, patchesTree[path]...) } From fe013f5db05d4f033905d7d6d7a9975f96d52699 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 12:23:02 +0300 Subject: [PATCH 09/11] bump Signed-off-by: Pavel Okhlopkov --- .github/workflows/publish-dev.yaml | 34 ++++++++++++++++++------------ 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/.github/workflows/publish-dev.yaml b/.github/workflows/publish-dev.yaml index 6b0b33329..2ef550488 100644 --- a/.github/workflows/publish-dev.yaml +++ b/.github/workflows/publish-dev.yaml @@ -124,18 +124,26 @@ jobs: run: | # Image for one arhitecture has digest in config field. # Image with multiple manifests has digest in each manifest. - manifests=$(docker buildx imagetools inspect "${FINAL_IMAGE_NAME}" --raw) + manifests=$(docker buildx imagetools inspect "${GHCR_IO_IMAGE_NAME}" --raw) if grep manifests <<<"${manifests}" 2>&1 >/dev/null ; then - jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" + jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" \ + | while read digest platform ; do + image=${GHCR_IO_IMAGE_NAME}@${digest} + if [[ ${BUILDX_PLATFORMS} != *"${platform}"* ]] ; then + echo "=====================================" + echo "Ignore image for non-runnable platform ${platform}" + echo " ${image}" + echo "=====================================" + continue + fi + echo "=====================================" + echo "Inspect image for platform ${platform}" + echo " ${image}" + echo "=====================================" + docker run --rm --platform ${platform} --entrypoint sh ${image} -c \ + 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator' + done else - echo $(echo -n "${manifests}" | openssl dgst -sha256 | sed s/^.stdin.*\ //) ' linux/amd64' - fi \ - | while read digest platform ; do - image=$FINAL_IMAGE_NAME@${digest} - echo "=====================================" - echo "Inspect image for platform ${platform}" - echo " ${image}" - echo "=====================================" - docker run --rm --platform ${platform} --entrypoint sh ${image} -c \ - 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /addon-operator; file /bin/helm' - done + echo Not a multi-arhitecture image. + #echo $(echo -n "${manifests}" | openssl dgst -sha256) ' linux/amd64' + fi From 01f518d0a38f99aa57185e5569b813bb65c2b777 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 17:40:51 +0300 Subject: [PATCH 10/11] bump Signed-off-by: Pavel Okhlopkov --- .github/workflows/publish-dev.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-dev.yaml b/.github/workflows/publish-dev.yaml index 2ef550488..04853e790 100644 --- a/.github/workflows/publish-dev.yaml +++ b/.github/workflows/publish-dev.yaml @@ -141,7 +141,7 @@ jobs: echo " ${image}" echo "=====================================" docker run --rm --platform ${platform} --entrypoint sh ${image} -c \ - 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /shell-operator' + 'apk add file > /dev/null; file /bin/kubectl; file /bin/busybox; file /addon-operator' done else echo Not a multi-arhitecture image. From 23fdcfe96a91abdf7911870938760b5274a85677 Mon Sep 17 00:00:00 2001 From: Pavel Okhlopkov Date: Thu, 15 Jan 2026 17:43:48 +0300 Subject: [PATCH 11/11] bump Signed-off-by: Pavel Okhlopkov --- .github/workflows/publish-dev.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-dev.yaml b/.github/workflows/publish-dev.yaml index 04853e790..cee5a05d6 100644 --- a/.github/workflows/publish-dev.yaml +++ b/.github/workflows/publish-dev.yaml @@ -124,11 +124,11 @@ jobs: run: | # Image for one arhitecture has digest in config field. # Image with multiple manifests has digest in each manifest. - manifests=$(docker buildx imagetools inspect "${GHCR_IO_IMAGE_NAME}" --raw) + manifests=$(docker buildx imagetools inspect "${FINAL_IMAGE_NAME}" --raw) if grep manifests <<<"${manifests}" 2>&1 >/dev/null ; then jq -r '.manifests[]? | .digest + " " + .platform.os + "/" + .platform.architecture' <<<"${manifests}" \ | while read digest platform ; do - image=${GHCR_IO_IMAGE_NAME}@${digest} + image=${FINAL_IMAGE_NAME}@${digest} if [[ ${BUILDX_PLATFORMS} != *"${platform}"* ]] ; then echo "=====================================" echo "Ignore image for non-runnable platform ${platform}"