diff --git a/.drone/drone.yml b/.drone/drone.yml
deleted file mode 100644
index d0de3d7..0000000
--- a/.drone/drone.yml
+++ /dev/null
@@ -1,152 +0,0 @@
-kind: pipeline
-type: exec
-name: linux-amd64
-
-platform:
-  arch: amd64
-  os: linux
-
-steps:
-- name: test
-  commands:
-  - mkdir -p $HOMEPATH/.docker; echo $IMAGE_PULL_SECRETS > $HOMEPATH/.docker/config.json
-  - make bootstrap test test-cover
-  environment:
-    VERSION: ${DRONE_TAG:-latest}-linux-amd64
-    DEV_REGISTRY:
-      from_secret: dev_registry
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-    IMAGE_PULL_SECRETS:
-      from_secret: container_pull_secrets
-  when:
-    event:
-    - push
-    - tag
-    - pull_request
-
-- name: codecov
-  commands:
-    - curl -s https://codecov.io/bash | bash
-  environment:
-    CODECOV_TOKEN:
-      from_secret: codecov_token
-  when:
-    status:
-    - success
-
-- name: publish
-  commands:
-  - echo $CONTAINER_PASSWORD | docker login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1
-  - make docker-build docker-immutable-push
-  environment:
-    VERSION: ${DRONE_TAG:-latest}-linux-amd64
-    DEV_REGISTRY:
-      from_secret: dev_registry
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-    CONTAINER_USERNAME:
-      from_secret: container_username
-    CONTAINER_PASSWORD:
-      from_secret: container_password
-  when:
-    event:
-    - push
-    - tag
-
----
-kind: pipeline
-type: exec
-name: linux-arm64
-
-platform:
-  arch: arm64
-  os: linux
-
-steps:
-- name: publish
-  commands:
-  - echo $CONTAINER_PASSWORD | docker login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1
-  - make docker-build docker-immutable-push
-  environment:
-    VERSION: ${DRONE_TAG:-latest}-linux-arm64
-    DEV_REGISTRY:
-      from_secret: dev_registry
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-    CONTAINER_USERNAME:
-      from_secret: container_username
-    CONTAINER_PASSWORD:
-      from_secret: container_password
-  when:
-    event:
-    - push
-    - tag
-
----
-kind: pipeline
-type: docker
-name: manifest
-image_pull_secrets:
-- container_pull_secrets
-
-steps:
-
-- name: generate manifest
-  image: registry.drycc.cc/drycc/python-dev
-  pull: always
-  commands:
-  - sed -i "s/registry.drycc.cc/$${DRYCC_REGISTRY}/g" .drone/manifest.tmpl
-  environment:
-    DEV_REGISTRY:
-      from_secret: dev_registry
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-
-- name: publish
-  image: plugins/manifest
-  settings:
-    spec: .drone/manifest.tmpl
-    username:
-      from_secret: container_username
-    password:
-      from_secret: container_password
-  environment:
-    DEV_REGISTRY:
-      from_secret: dev_registry
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-
-trigger:
-  event:
-  - push
-  - tag
-
-depends_on:
-- linux-amd64
-- linux-arm64
-
----
-kind: pipeline
-type: exec
-name: chart
-
-steps:
-- name: generate chart
-  commands:
-  - IMAGE_TAG=$([ ! -z $DRONE_TAG ] && echo \"${DRONE_TAG:1}\" || echo \"canary\")
-  - sed -i "s/imageTag:\ \"canary\"/imageTag:\ $IMAGE_TAG/g" charts/builder/values.yaml
-  - helm package -u charts/builder --version $([ -z $DRONE_TAG ] && echo 1.0.0 || echo ${DRONE_TAG#v})
-  - echo $CONTAINER_PASSWORD | helm registry login $DRYCC_REGISTRY -u $CONTAINER_USERNAME --password-stdin
-  - helm push builder-$([ -z $DRONE_TAG ] && echo 1.0.0 || echo ${DRONE_TAG#v}).tgz oci://$DRYCC_REGISTRY/$([ -z $DRONE_TAG ] && echo charts-testing || echo charts)
-  environment:
-    DRYCC_REGISTRY:
-      from_secret: drycc_registry
-    CONTAINER_USERNAME:
-      from_secret: container_username
-    CONTAINER_PASSWORD:
-      from_secret: container_password
-  when:
-    event:
-    - push
-    - tag
diff --git a/.drone/manifest.tmpl b/.drone/manifest.tmpl
deleted file mode 100644
index f483aa6..0000000
--- a/.drone/manifest.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-image: registry.drycc.cc/drycc/builder:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}canary{{/if}}
-{{#if build.tags}}
-tags:
-{{#each build.tags}}
-  - {{this}}
-{{/each}}
-{{/if}}
-manifests:
-  -
-    image: registry.drycc.cc/drycc/builder:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-amd64
-    platform:
-      architecture: amd64
-      os: linux
-  -
-    image: registry.drycc.cc/drycc/builder:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-arm64
-    platform:
-      architecture: arm64
-      os: linux
diff --git a/.woodpecker/build-linux.yml b/.woodpecker/build-linux.yml
new file mode 100644
index 0000000..22eba83
--- /dev/null
+++ b/.woodpecker/build-linux.yml
@@ -0,0 +1,35 @@
+matrix:
+  platform:
+    - linux/amd64
+    - linux/arm64
+
+labels:
+  type: exec
+  platform: ${platform}
+
+steps:
+- name: publish-linux
+  image: bash
+  commands:
+  - export VERSION=$([ -z $CI_COMMIT_TAG ] && echo latest || echo $CI_COMMIT_TAG)-$(sed 's#/#-#g' <<< $CI_SYSTEM_PLATFORM)
+  - echo $CONTAINER_PASSWORD | podman login $DRYCC_REGISTRY --username $CONTAINER_USERNAME --password-stdin > /dev/null 2>&1
+  - make podman-build podman-immutable-push
+  environment:
+    CODENAME:
+      from_secret: codename
+    DEV_REGISTRY:
+      from_secret: dev_registry
+    DRYCC_REGISTRY:
+      from_secret: drycc_registry
+    CONTAINER_USERNAME:
+      from_secret: container_username
+    CONTAINER_PASSWORD:
+      from_secret: container_password
+  when:
+    event:
+    - push
+    - tag
+    - cron
+
+depends_on:
+- test-linux
diff --git a/.woodpecker/chart.yaml b/.woodpecker/chart.yaml
new file mode 100644
index 0000000..97fc599
--- /dev/null
+++ b/.woodpecker/chart.yaml
@@ -0,0 +1,34 @@
+labels:
+  type: exec
+  platform: linux/amd64
+
+steps:
+- name: generate-chart
+  image: bash
+  commands:
+  - export VERSION=$(sed 's#v##' <<< $CI_COMMIT_TAG)
+  - export IMAGE_TAG=$([ ! -z $CI_COMMIT_TAG ] && echo \"$VERSION\" || echo \"canary\")
+  - export APP_VERSION=$([ -z $CI_COMMIT_TAG ] && echo $CI_COMMIT_SHA || echo $VERSION)
+  - export CHART_VERSION=$([ -z $CI_COMMIT_TAG ] && echo 1.0.0 || echo $VERSION)
+  - sed -i "s/imageTag:\ \"canary\"/imageTag:\ $IMAGE_TAG/g" charts/$${CI_REPO_NAME}/values.yaml
+  - helm package -u charts/$${CI_REPO_NAME} --version $CHART_VERSION --app-version $APP_VERSION
+  - echo $CONTAINER_PASSWORD | helm registry login $DRYCC_REGISTRY -u $CONTAINER_USERNAME --password-stdin
+  - helm push $${CI_REPO_NAME}-$CHART_VERSION.tgz oci://$DRYCC_REGISTRY/$([ -z $CI_COMMIT_TAG ] && echo charts-testing || echo charts)
+  environment:
+    DEV_REGISTRY:
+      from_secret: dev_registry
+    DRYCC_REGISTRY:
+      from_secret: drycc_registry
+    CONTAINER_USERNAME:
+      from_secret: container_username
+    CONTAINER_PASSWORD:
+      from_secret: container_password
+  when:
+    event:
+    - push
+    - tag
+    - cron
+
+depends_on:
+- manifest
+
diff --git a/.woodpecker/manifest.tmpl b/.woodpecker/manifest.tmpl
new file mode 100644
index 0000000..8739535
--- /dev/null
+++ b/.woodpecker/manifest.tmpl
@@ -0,0 +1,18 @@
+image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}canary{{/if}}
+{{#if build.tags}}
+tags:
+{{#each build.tags}}
+  - {{this}}
+{{/each}}
+{{/if}}
+manifests:
+  -
+    image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-amd64
+    platform:
+      architecture: amd64
+      os: linux
+  -
+    image: registry.drycc.cc/drycc/{{project}}:{{#if build.tag}}{{build.tag}}-{{else}}latest-{{/if}}linux-arm64
+    platform:
+      architecture: arm64
+      os: linux
diff --git a/.woodpecker/manifest.yml b/.woodpecker/manifest.yml
new file mode 100644
index 0000000..19fc70c
--- /dev/null
+++ b/.woodpecker/manifest.yml
@@ -0,0 +1,43 @@
+labels:
+  type: exec
+  platform: linux/amd64
+
+steps:
+- name: generate-manifest
+  image: bash
+  commands:
+  - sed -i "s/{{project}}/$${CI_REPO_NAME}/g" .woodpecker/manifest.tmpl
+  - sed -i "s/registry.drycc.cc/$${DRYCC_REGISTRY}/g" .woodpecker/manifest.tmpl
+  environment:
+    DRYCC_REGISTRY:
+      from_secret: drycc_registry
+  when:
+    event:
+    - tag
+    - push
+    - cron
+
+- name: publish-manifest
+  image: bash
+  commands:
+  - podman run --rm
+    -e PLUGIN_SPEC=.woodpecker/manifest.tmpl
+    -e PLUGIN_USERNAME=$CONTAINER_USERNAME
+    -e PLUGIN_PASSWORD=$CONTAINER_PASSWORD
+    -e DRONE_TAG=$CI_COMMIT_TAG
+    -v $(pwd):$(pwd)
+    -w $(pwd)
+    docker.io/plugins/manifest
+  environment:
+    CONTAINER_USERNAME:
+      from_secret: container_username
+    CONTAINER_PASSWORD:
+      from_secret: container_password
+  when:
+    event:
+    - tag
+    - push
+    - cron
+
+depends_on:
+- build-linux
diff --git a/.woodpecker/test-linux.yml b/.woodpecker/test-linux.yml
new file mode 100644
index 0000000..f635d8c
--- /dev/null
+++ b/.woodpecker/test-linux.yml
@@ -0,0 +1,26 @@
+matrix:
+  platform:
+  - linux/amd64
+  - linux/arm64
+
+labels:
+  type: exec
+  platform: ${platform}
+
+steps:
+- name: test-linux
+  image: bash
+  commands:
+  - make bootstrap test test-cover
+  environment:
+    CODENAME:
+      from_secret: codename
+    DEV_REGISTRY:
+      from_secret: dev_registry
+    CODECOV_TOKEN:
+      from_secret: codecov_token
+  when:
+    event:
+    - push
+    - tag
+    - cron
diff --git a/Dockerfile b/Dockerfile
index 7b18e69..b6688cc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,38 +1,39 @@
-FROM registry.drycc.cc/drycc/go-dev:latest AS build
 ARG LDFLAGS
+ARG CODENAME
+
+FROM registry.drycc.cc/drycc/go-dev:latest AS build
 ADD . /workspace
 RUN export GO111MODULE=on \
   && cd /workspace \
   && CGO_ENABLED=0 init-stack go build -ldflags "${LDFLAGS}" -o /usr/local/bin/boot boot.go
 
+FROM registry.drycc.cc/drycc/base:${CODENAME}
 
-FROM registry.drycc.cc/drycc/base:bullseye
-
-ENV DRYCC_UID=1001 \
+ARG DRYCC_UID=1001 \
   DRYCC_GID=1001 \
   DRYCC_HOME_DIR=/workspace \
-  MC_VERSION="2022.08.28.20.08.11" \
-  JQ_VERSION="1.6"
+  RCLONE_VERSION="1.71.1" \
+  JQ_VERSION="1.7.1"
 
 RUN groupadd drycc --gid ${DRYCC_GID} \
   && useradd drycc -u ${DRYCC_UID} -g ${DRYCC_GID} -s /bin/bash -m -d ${DRYCC_HOME_DIR}
 
 COPY rootfs/bin /bin/
 COPY rootfs/etc/ssh /etc/ssh/
-COPY rootfs/docker-entrypoint.sh /docker-entrypoint.sh
+COPY rootfs/container-entrypoint.sh /container-entrypoint.sh
 COPY --from=build /usr/local/bin/boot /usr/bin/boot
 
 RUN install-packages git openssh-server coreutils xz-utils tar \
-  && install-stack mc $MC_VERSION \
+  && install-stack rclone $RCLONE_VERSION \
   && install-stack jq $JQ_VERSION \
   && mkdir -p /var/run/sshd \
   && rm -rf /etc/ssh/ssh_host* \
-  && chmod +x /bin/create_bucket /docker-entrypoint.sh
+  && chmod +x /bin/create_bucket /container-entrypoint.sh
 
 USER ${DRYCC_UID}
 WORKDIR ${DRYCC_HOME_DIR}
 
-ENTRYPOINT ["init-stack", "/docker-entrypoint.sh"]
+ENTRYPOINT ["init-stack", "/container-entrypoint.sh"]
 CMD ["/usr/bin/boot", "server"]
 
 EXPOSE 2223
diff --git a/Makefile b/Makefile
index 62a9d1d..9c1e0cc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,31 +1,30 @@
 SHORT_NAME ?= builder
+DRYCC_REGISTRY ?= ${DEV_REGISTRY}
 
 include versioning.mk
 
-# dockerized development environment variables
+# container development environment variables
 REPO_PATH := github.com/drycc/${SHORT_NAME}
 DEV_ENV_IMAGE := ${DEV_REGISTRY}/drycc/go-dev
-DEV_ENV_WORK_DIR := /opt/drycc/go/src/${REPO_PATH}
-DEV_ENV_PREFIX := docker run --rm -v ${CURDIR}:${DEV_ENV_WORK_DIR} -w ${DEV_ENV_WORK_DIR}
+DEV_ENV_WORK_DIR := /root/go/src/${REPO_PATH}
+DEV_ENV_PREFIX := podman run --rm -v ${CURDIR}:${DEV_ENV_WORK_DIR} -w ${DEV_ENV_WORK_DIR} -e CODECOV_TOKEN=${CODECOV_TOKEN} --entrypoint testdata/bin/fake-k8s
 DEV_ENV_CMD := ${DEV_ENV_PREFIX} ${DEV_ENV_IMAGE}
 PLATFORM ?= linux/amd64,linux/arm64
 
-# SemVer with build information is defined in the SemVer 2 spec, but Docker
+# SemVer with build information is defined in the SemVer 2 spec, but podman
 # doesn't allow +, so we use -.
 BINARY_DEST_DIR := rootfs/usr/bin
 # Common flags passed into Go's linker.
 LDFLAGS := "-s -w -X main.version=${VERSION}"
-# Docker Root FS
+# Container Root FS
 BINDIR := ./rootfs
 
-DRYCC_REGISTRY ?= ${DEV_REGISTRY}
-
 bootstrap:
 	${DEV_ENV_CMD} go mod vendor
 
-# This illustrates a two-stage Docker build. docker-compile runs inside of
-# the Docker environment. Other alternatives are cross-compiling, doing
-# the build as a `docker build`.
+# This illustrates a two-stage Podman build. podman-compile runs inside of
+# the container environment. Other alternatives are cross-compiling, doing
+# the build as a `podman build`.
 build-binary:
 	CGO_ENABLED=0 go build -ldflags ${LDFLAGS} -o ${BINARY_DEST_DIR}/boot boot.go
 
@@ -38,17 +37,14 @@ test-style:
 	${DEV_ENV_CMD} lint
 
 test-unit:
-	${DEV_ENV_CMD} sh -c 'go test --race ./...'
+	${DEV_ENV_CMD} go test --race ./...
 
 test-cover:
 	${DEV_ENV_CMD} test-cover.sh
 
-docker-build:
-	docker build ${DOCKER_BUILD_FLAGS} -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} .
-	docker tag ${IMAGE} ${MUTABLE_IMAGE}
-
-docker-buildx:
-	docker buildx build --platform ${PLATFORM} -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} . --push
+podman-build:
+	podman build -t ${IMAGE} --build-arg LDFLAGS=${LDFLAGS} --build-arg CODENAME=${CODENAME} .
+	podman tag ${IMAGE} ${MUTABLE_IMAGE}
 
 check-kubectl:
 	@if [ -z $$(which kubectl) ]; then \
@@ -56,7 +52,7 @@ check-kubectl:
 		exit 2; \
 	fi
 
-deploy: check-kubectl docker-build docker-push
+deploy: check-kubectl podman-build podman-push
 	kubectl --namespace=drycc patch deployment drycc-$(SHORT_NAME) --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"$(IMAGE)"}]'
 
-.PHONY: bootstrap depup build docker-build test test-style test-unit test-cover deploy
+.PHONY: bootstrap depup build podman-build test test-style test-unit test-cover deploy
diff --git a/README.md b/README.md
index 347b836..d1e821f 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
-
 # Drycc Builder v2
 
-[![Build Status](https://drone.drycc.cc/api/badges/drycc/builder/status.svg)](https://drone.drycc.cc/drycc/builder)
+[![Build Status](https://woodpecker.drycc.cc/api/badges/drycc/builder/status.svg)](https://woodpecker.drycc.cc/drycc/builder)
 [![codecov](https://codecov.io/gh/drycc/builder/branch/main/graph/badge.svg)](https://codecov.io/gh/drycc/builder)
 [![Go Report Card](https://goreportcard.com/badge/github.com/drycc/builder)](https://goreportcard.com/report/github.com/drycc/builder)
 [![codebeat badge](https://codebeat.co/badges/0507e5d5-163b-4280-84ea-83bd2e0c8e41)](https://codebeat.co/projects/github-com-drycc-builder-main)
@@ -44,24 +43,16 @@ The Drycc project welcomes contributions from all developers. The high level pro
 	* If your PR fixes any [issues][issues], make sure you write `Fixes #1234` in your PR description (where `#1234` is the number of the issue you're closing)
 * The Drycc core contributors will review your code. After each of them sign off on your code, they'll label your PR with `LGTM1` and `LGTM2` (respectively). Once that happens, a contributor will merge it
 
-## Docker Based Development Environment
+## Container Based Development Environment
 
-The preferred environment for development uses [the `go-dev` Docker image](https://github.com/drycc/docker-go-dev). The tools described in this section are used to build, test, package and release each version of Drycc.
+The preferred environment for development uses [the `go-dev` Container image](https://github.com/drycc/go-dev). The tools described in this section are used to build, test, package and release each version of Drycc.
 
-To use it yourself, you must have [make](https://www.gnu.org/software/make/) installed and Docker installed and running on your local development machine.
+To use it yourself, you must have [make](https://www.gnu.org/software/make/) installed and Container installed and running on your local development machine.
 
-If you don't have Docker installed, please go to https://www.docker.com/ to install it.
+If you don't have Podman installed, please go to https://podman.io/ to install it.
 
 After you have those dependencies, grab Go dependencies with `make bootstrap`, build your code with `make build` and execute unit tests with `make test`.
 
-## Native Go Development Environment
-
-You can also use the standard `go` toolchain to build and test if you prefer. To do so, you'll need [glide](https://github.com/Masterminds/glide) 0.9 or above and [Go 1.6](http://golang.org) or above installed.
-
-After you have those dependencies, you can build and unit-test your code with `go build` and `go test $(glide nv)`, respectively.
-
-Note that you will not be able to build or push Docker images using this method of development.
-
 # Testing
 
 The Drycc project requires that as much code as possible is unit tested, but the core contributors also recognize that some code must be tested at a higher level (functional or integration tests, for example).
diff --git a/boot.go b/boot.go
index dd777a8..a379d63 100644
--- a/boot.go
+++ b/boot.go
@@ -1,6 +1,8 @@
+// Package main provides the entry point for the Drycc builder service.
 package main
 
 import (
+	"context"
 	"fmt"
 	"log"
 	"os"
@@ -19,7 +21,7 @@ import (
 	"github.com/drycc/builder/pkg/sys"
 	pkglog "github.com/drycc/pkg/log"
 	"github.com/kelseyhightower/envconfig"
-	"github.com/urfave/cli/v2"
+	"github.com/urfave/cli/v3"
 )
 
 const (
@@ -38,14 +40,14 @@ func main() {
 		log.Printf("Running in debug mode")
 	}
 
-	app := cli.NewApp()
+	app := &cli.Command{}
 
 	app.Commands = []*cli.Command{
 		{
 			Name:    "server",
 			Aliases: []string{"srv"},
 			Usage:   "Run the git server",
-			Action: func(c *cli.Context) error {
+			Action: func(ctx context.Context, cmd *cli.Command) error {
 				cnf := new(sshd.Config)
 				if err := envconfig.Process(serverConfAppName, cnf); err != nil {
 					return fmt.Errorf("getting config for %s [%s]", serverConfAppName, err)
@@ -60,8 +62,7 @@ func main() {
 					return fmt.Errorf("error getting storage parameters (%s)", err)
 				}
 				var storageDriver storagedriver.StorageDriver
-				storageDriver, err = factory.Create("s3", storageParams)
-
+				storageDriver, err = factory.Create(context.Background(), "s3", storageParams)
 				if err != nil {
 					return fmt.Errorf("error creating storage driver (%s)", err)
 				}
@@ -105,26 +106,24 @@ func main() {
 			Name:    "git-receive",
 			Aliases: []string{"gr"},
 			Usage:   "Run the git-receive hook",
-			Action: func(c *cli.Context) error {
+			Action: func(ctx context.Context, cmd *cli.Command) error {
 				cnf := new(gitreceive.Config)
 				if err := envconfig.Process(gitReceiveConfAppName, cnf); err != nil {
 					return fmt.Errorf("error getting config for %s [%s]", gitReceiveConfAppName, err)
 				}
 				cnf.CheckDurations()
-				fs := sys.RealFS()
 				env := sys.RealEnv()
 				storageParams, err := conf.GetStorageParams(env)
 				if err != nil {
 					return fmt.Errorf("error getting storage parameters (%s)", err)
 				}
 				var storageDriver storagedriver.StorageDriver
-				storageDriver, err = factory.Create("s3", storageParams)
-
+				storageDriver, err = factory.Create(context.Background(), "s3", storageParams)
 				if err != nil {
 					return fmt.Errorf("error creating storage driver (%s)", err)
 				}
 
-				if err := gitreceive.Run(cnf, fs, env, storageDriver); err != nil {
+				if err := gitreceive.Run(cnf, env, storageDriver); err != nil {
 					return fmt.Errorf("error running git receive hook [%s]", err)
 				}
 				return nil
@@ -132,7 +131,7 @@ func main() {
 		},
 	}
 
-	if err := app.Run(os.Args); err != nil {
+	if err := app.Run(context.Background(), os.Args); err != nil {
 		log.Fatal(err)
 	}
 }
diff --git a/charts/builder/Chart.yaml b/charts/builder/Chart.yaml
index 6315ec6..b68cfcb 100644
--- a/charts/builder/Chart.yaml
+++ b/charts/builder/Chart.yaml
@@ -1,10 +1,11 @@
 name: builder
 apiVersion: v2
+appVersion: 1.0.0
 home: https://github.com/drycc/builder
 dependencies:
   - name: common
     repository: oci://registry.drycc.cc/charts
-    version: ~1.1.1
+    version: ~1.1.2
 description: Git server and application builder for Drycc Workflow.
 maintainers:
   - name: Drycc Team
diff --git a/charts/builder/templates/_helpers.tpl b/charts/builder/templates/_helpers.tpl
index b592b1d..914c773 100644
--- a/charts/builder/templates/_helpers.tpl
+++ b/charts/builder/templates/_helpers.tpl
@@ -20,31 +20,39 @@ env:
   valueFrom:
     fieldRef:
       fieldPath: metadata.namespace
-- name: DRYCC_BUILDER_KEY
+- name: "DRYCC_CONTROLLER_URL"
+  value: http://drycc-controller-api
+{{- if (.Values.storageEndpoint) }}
+- name: "DRYCC_STORAGE_BUCKET"
   valueFrom:
     secretKeyRef:
-      name: builder-key-auth
-      key: builder-key
-- name: "DRYCC_STORAGE_LOOKUP"
+      name: builder-secret
+      key: storage-bucket
+- name: "DRYCC_STORAGE_ENDPOINT"
   valueFrom:
     secretKeyRef:
-      name: storage-creds
-      key: lookup
-- name: "DRYCC_STORAGE_HEALTH"
+      name: builder-secret
+      key: storage-endpoint
+- name: "DRYCC_STORAGE_ACCESSKEY"
   valueFrom:
     secretKeyRef:
-      name: storage-creds
-      key: health
-- name: "DRYCC_STORAGE_BUCKET"
+      name: builder-secret
+      key: storage-accesskey
+- name: "DRYCC_STORAGE_SECRETKEY"
   valueFrom:
     secretKeyRef:
-      name: storage-creds
-      key: builder-bucket
-- name: "DRYCC_STORAGE_ENDPOINT"
+      name: builder-secret
+      key: storage-secretkey
+- name: "DRYCC_STORAGE_PATH_STYLE"
   valueFrom:
     secretKeyRef:
-      name: storage-creds
-      key: endpoint
+      name: builder-secret
+      key: storage-path-style
+{{- else if .Values.storage.enabled  }}
+- name: "DRYCC_STORAGE_BUCKET"
+  value: "builder"
+- name: "DRYCC_STORAGE_ENDPOINT"
+  value: http://drycc-storage:9000
 - name: "DRYCC_STORAGE_ACCESSKEY"
   valueFrom:
     secretKeyRef:
@@ -55,24 +63,37 @@ env:
     secretKeyRef:
       name: storage-creds
       key: secretkey
+- name: "DRYCC_STORAGE_PATH_STYLE"
+  value: "true"
+{{- end }}
 - name: "DRYCC_REGISTRY_LOCATION"
-  value: "{{ .Values.global.registryLocation }}"
+  value: {{ ternary "on-cluster" "off-cluster" .Values.registry.enabled }}
+{{- if (.Values.registryHost) }}
 - name: "DRYCC_REGISTRY_HOST"
   valueFrom:
     secretKeyRef:
-      name: registry-secret
-      key: host
-{{- if eq .Values.global.registryLocation "on-cluster" }}
-# NOTE(bacongobbler): use drycc/registry_proxy to work around Docker --insecure-registry requirements
-- name: "DRYCC_REGISTRY_PROXY_HOST"
-  value: {{ print "127.0.0.1"  ":" .Values.global.registryProxyPort }}
-{{- else }}
+      name: builder-secret
+      key: registry-host
+- name: "DRYCC_REGISTRY_USERNAME"
+  valueFrom:
+    secretKeyRef:
+      name: builder-secret
+      key: registry-username
+- name: "DRYCC_REGISTRY_PASSWORD"
+  valueFrom:
+    secretKeyRef:
+      name: builder-secret
+      key: registry-password
 - name: "DRYCC_REGISTRY_ORGANIZATION"
   valueFrom:
     secretKeyRef:
-      name: registry-secret
-      key: organization
-{{- end }}
+      name: builder-secret
+      key: registry-organization
+{{- else if .Values.registry.enabled  }}
+- name: "DRYCC_REGISTRY_HOST"
+  value: drycc-registry:5000
+- name: "DRYCC_REGISTRY_PROXY_HOST"
+  value: {{ print "127.0.0.1"  ":" .Values.registry.proxy.port }}
 - name: "DRYCC_REGISTRY_USERNAME"
   valueFrom:
     secretKeyRef:
@@ -83,22 +104,9 @@ env:
     secretKeyRef:
       name: registry-secret
       key: password
+{{- end }}
 {{- if (.Values.builderPodNodeSelector) }}
 - name: BUILDER_POD_NODE_SELECTOR
   value: {{.Values.builderPodNodeSelector}}
 {{- end }}
 {{- end }}
-
-{{/* Generate builder deployment limits */}}
-{{- define "builder.limits" -}}
-{{- if or (.Values.limitsCpu) (.Values.limitsMemory) }}
-resources:
-  limits:
-    {{- if (.Values.limitsCpu) }}
-    cpu: {{.Values.limitsCpu}}
-    {{- end }}
-    {{- if (.Values.limitsMemory) }}
-    memory: {{.Values.limitsMemory}}
-    {{- end }}
-{{- end }}
-{{- end }}
diff --git a/charts/builder/templates/builder-clusterrole.yaml b/charts/builder/templates/builder-clusterrole.yaml
index 5a27706..8c9d9a4 100644
--- a/charts/builder/templates/builder-clusterrole.yaml
+++ b/charts/builder/templates/builder-clusterrole.yaml
@@ -1,8 +1,7 @@
-{{- if (.Values.global.rbac) -}}
 kind: ClusterRole
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
-  name: drycc:drycc-builder
+  name: {{ printf "%s:drycc-builder" .Release.Namespace | quote }}
   labels:
     app: drycc-builder
     heritage: drycc
@@ -13,4 +12,3 @@ rules:
 - apiGroups: [""]
   resources: ["secrets"]
   verbs: ["list","get"]
-{{- end -}}
diff --git a/charts/builder/templates/builder-clusterrolebinding.yaml b/charts/builder/templates/builder-clusterrolebinding.yaml
index 0d31cba..fdd34cb 100644
--- a/charts/builder/templates/builder-clusterrolebinding.yaml
+++ b/charts/builder/templates/builder-clusterrolebinding.yaml
@@ -1,17 +1,15 @@
-{{- if (.Values.global.rbac) -}}
 kind: ClusterRoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
-  name: drycc:drycc-builder
+  name: {{ printf "%s:drycc-builder" .Release.Namespace | quote }}
   labels:
     app: drycc-builder
     heritage: drycc
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
-  name: drycc:drycc-builder
+  name: {{ printf "%s:drycc-builder" .Release.Namespace | quote }}
 subjects:
 - kind: ServiceAccount
   name: drycc-builder
   namespace: {{ .Release.Namespace }}
-{{- end -}}
diff --git a/charts/builder/templates/builder-controller-secret-key-auth.yaml b/charts/builder/templates/builder-controller-secret-key-auth.yaml
deleted file mode 100644
index 0147cea..0000000
--- a/charts/builder/templates/builder-controller-secret-key-auth.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-apiVersion: v1
-kind: Secret
-metadata:
-  name: builder-key-auth
-  labels:
-    heritage: drycc
-  annotations:
-    "helm.sh/hook": pre-install
-type: Opaque
-data:
-  builder-key: {{ randAlphaNum 64 | b64enc }}
diff --git a/charts/builder/templates/builder-deployment.yaml b/charts/builder/templates/builder-deployment.yaml
index 277c369..0d6ed8e 100644
--- a/charts/builder/templates/builder-deployment.yaml
+++ b/charts/builder/templates/builder-deployment.yaml
@@ -18,12 +18,12 @@ spec:
       app: drycc-builder
   template:
     metadata:
-      labels:
+      labels: {{- include "common.labels.standard" . | nindent 8 }}
         app: drycc-builder
     spec:
       affinity:
-        podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset.type "key" .Values.podAffinityPreset.key "values" .Values.podAffinityPreset.values ) | nindent 10 }}
-        podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset.type "key" .Values.podAntiAffinityPreset.key "values" .Values.podAntiAffinityPreset.values ) | nindent 10 }}
+        podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset.type "component" "" "extraMatchLabels" .Values.podAffinityPreset.extraMatchLabels "topologyKey" "" "context" $) | nindent 10 }}
+        podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset.type "component" "" "extraMatchLabels" .Values.podAntiAffinityPreset.extraMatchLabels "topologyKey" "" "context" $) | nindent 10 }}
         nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values ) | nindent 10 }}
       serviceAccount: drycc-builder
       initContainers:
@@ -33,22 +33,28 @@ spec:
         args:
           - netcat
           - -v
-          - -g
-          - $(DRYCC_STORAGE_HEALTH)
-          - -a
-          - $(DRYCC_CONTROLLER_API_SERVICE_HOST):$(DRYCC_CONTROLLER_API_SERVICE_PORT)
+          - -u
+          - $(DRYCC_STORAGE_ENDPOINT),$(DRYCC_CONTROLLER_URL)
         {{- include "builder.envs" . | indent 8 }}
       containers:
       - name: drycc-builder
         image: {{.Values.imageRegistry}}/{{.Values.imageOrg}}/builder:{{.Values.imageTag}}
         imagePullPolicy: {{.Values.imagePullPolicy}}
+        {{- if .Values.diagnosticMode.enabled }}
+        command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 10 }}
+        args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 10 }}
+        {{- end }}
         ports:
           - containerPort: 2223
             name: ssh
           - containerPort: 8092
             name: healthsrv
         {{- include "builder.envs" . | indent 8 }}
-        {{- include "builder.limits" . | indent 8 }}
+        {{- with index .Values "resources" }}
+        resources:
+          {{- toYaml . | nindent 10 }}
+        {{- end }}
+        {{- if not .Values.diagnosticMode.enabled }}
         livenessProbe:
           httpGet:
             path: /healthz
@@ -61,23 +67,24 @@ spec:
             port: 8092
           initialDelaySeconds: 30
           timeoutSeconds: 1
+        {{- end }}
         volumeMounts:
-            - name: builder-key-auth
-              mountPath: /var/run/secrets/api/auth
-              readOnly: true
-            - name: builder-ssh-private-keys
-              mountPath: /var/run/secrets/drycc/builder/ssh
-              readOnly: true
-            - name: imagebuilder-config
-              mountPath: /etc/imagebuilder
-              readOnly: true
+          - name: controller-creds
+            mountPath: /var/run/secrets/drycc/controller
+            readOnly: true
+          - name: imagebuilder-config
+            mountPath: /etc/imagebuilder
+            readOnly: true
+          - name: builder-ssh-private-keys
+            mountPath: /var/run/secrets/drycc/builder/ssh
+            readOnly: true
       volumes:
-        - name: builder-key-auth
+        - name: controller-creds
           secret:
-            secretName: builder-key-auth
-        - name: builder-ssh-private-keys
-          secret:
-            secretName: builder-ssh-private-keys
+            secretName: controller-creds
         - name: imagebuilder-config
           configMap:
             name: imagebuilder-config
+        - name: builder-ssh-private-keys
+          secret:
+            secretName: builder-ssh-private-keys
diff --git a/charts/builder/templates/builder-role.yaml b/charts/builder/templates/builder-role.yaml
index 41d2cbe..8247089 100644
--- a/charts/builder/templates/builder-role.yaml
+++ b/charts/builder/templates/builder-role.yaml
@@ -1,4 +1,3 @@
-{{- if (.Values.global.rbac) -}}
 kind: Role
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
@@ -19,4 +18,3 @@ rules:
 - apiGroups: ["batch"]
   resources: ["jobs"]
   verbs: ["create"]
-{{- end -}}
diff --git a/charts/builder/templates/builder-rolebinding.yaml b/charts/builder/templates/builder-rolebinding.yaml
index 5a6912a..3af7125 100644
--- a/charts/builder/templates/builder-rolebinding.yaml
+++ b/charts/builder/templates/builder-rolebinding.yaml
@@ -1,4 +1,3 @@
-{{- if (.Values.global.rbac) -}}
 kind: RoleBinding
 apiVersion: rbac.authorization.k8s.io/v1
 metadata:
@@ -13,4 +12,3 @@ roleRef:
 subjects:
 - kind: ServiceAccount
   name: drycc-builder
-{{- end -}}
diff --git a/charts/builder/templates/builder-secret-ssh-private-keys.yaml b/charts/builder/templates/builder-secret-ssh-private-keys.yaml
index 7ffa3c6..7045376 100644
--- a/charts/builder/templates/builder-secret-ssh-private-keys.yaml
+++ b/charts/builder/templates/builder-secret-ssh-private-keys.yaml
@@ -4,8 +4,6 @@ metadata:
   name: builder-ssh-private-keys
   labels:
     heritage: drycc
-  annotations:
-    "helm.sh/hook": pre-install
 type: Opaque
 data:
   ssh-host-rsa-key: "{{genPrivateKey "rsa" | b64enc}}"
diff --git a/charts/builder/templates/builder-secret.yaml b/charts/builder/templates/builder-secret.yaml
new file mode 100644
index 0000000..501beb1
--- /dev/null
+++ b/charts/builder/templates/builder-secret.yaml
@@ -0,0 +1,21 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: builder-secret
+  labels:
+    heritage: drycc
+type: Opaque
+data:
+  {{- if (.Values.registryHost) }}
+  registry-host: {{ .Values.registryHost | b64enc }}
+  registry-username: {{ .Values.registryUsername | b64enc }}
+  registry-password: {{ .Values.registryPassword | b64enc }}
+  registry-organization: {{ .Values.registryOrganization | b64enc }}
+  {{- end }}
+  {{- if (.Values.storageEndpoint) }}
+  storage-bucket: {{ .Values.storageBucket | b64enc }}
+  storage-endpoint: {{ .Values.storageEndpoint | b64enc }}
+  storage-accesskey: {{ .Values.storageAccesskey | b64enc }}
+  storage-secretkey: {{ .Values.storageSecretkey | b64enc }}
+  storage-path-style: {{ .Values.storagePathStyle | b64enc }}
+  {{- end }}
diff --git a/charts/builder/templates/builder-service.yaml b/charts/builder/templates/builder-service.yaml
index bf8c5b4..dc7e54b 100644
--- a/charts/builder/templates/builder-service.yaml
+++ b/charts/builder/templates/builder-service.yaml
@@ -13,9 +13,6 @@ spec:
     - name: ssh
       port: 2222
       targetPort: 2223
-      {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }}
-      nodePort: {{ .Values.service.nodePort }}
-      {{- end }}
   selector:
     app: drycc-builder
   type: {{ .Values.service.type }}
diff --git a/charts/builder/values.yaml b/charts/builder/values.yaml
index a94df12..f62ea33 100644
--- a/charts/builder/values.yaml
+++ b/charts/builder/values.yaml
@@ -5,15 +5,34 @@ imageRegistry: "registry.drycc.cc"
 
 replicas: 1
 
+## Enable diagnostic mode
+##
+diagnosticMode:
+  ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden)
+  ##
+  enabled: false
+  ## @param diagnosticMode.command Command to override all containers
+  ##
+  command:
+    - sleep
+  ## @param diagnosticMode.args Args to override all containers
+  ##
+  args:
+    - infinity
+
 service:
   # Provide any additional service annotations
   annotations: {}
   # Service type default to LoadBalancer
   type: ClusterIP
-  # If service.type is not set to NodePort, the following statement will be ignored.
-  nodePort: ""
-# limitsCpu: "100m"
-# limitsMemory: "50Mi"
+
+resources: {}
+  # limits:
+  #   cpu: 200m
+  #   memory: 50Mi
+  # requests:
+  #   cpu: 100m
+  #   memory: 30Mi
 
 nodeAffinityPreset:
   key: "drycc.cc/node"
@@ -22,16 +41,14 @@ nodeAffinityPreset:
   - "true"
 
 podAffinityPreset:
-  key: "security"
   type: ""
-  values:
-  - "drycc-security"
+  extraMatchLabels:
+    security: "drycc-security"
 
 podAntiAffinityPreset:
-  key: "app"
   type: "soft"
-  values:
-  - "drycc-builder"
+  extraMatchLabels:
+    app: "drycc-builder"
 
 # builderPodNodeSelector: "drycc.cc/node:true"
 
@@ -39,6 +56,24 @@ podAntiAffinityPreset:
 # see: https://kubernetes.io/docs/concepts/workloads/controllers/job/#ttl-mechanism-for-finished-jobs
 ttlSecondsAfterFinished: 21600
 
-global:
-  # Role-Based Access Control for Kubernetes >= 1.5
-  rbac: false
+# The following parameters will no longer use the built-in storage component.
+storageBucket: "registry"
+storageEndpoint: ""
+storageAccesskey: ""
+storageSecretkey: ""
+storagePathStyle: "true"
+
+# The following parameters will no longer use the built-in registry component.
+registryHost: ""
+registryUsername: ""
+registryPassword: ""
+registryOrganization: ""
+
+storage:
+  enabled: true
+
+# host port for the registry proxy in the daemonset
+registry:
+  enabled: true
+  proxy:
+    port: 5555
diff --git a/go.mod b/go.mod
index 628db66..f79bb12 100644
--- a/go.mod
+++ b/go.mod
@@ -1,76 +1,110 @@
 module github.com/drycc/builder
 
-go 1.19
+go 1.26
 
 require (
-	github.com/aws/aws-sdk-go v1.44.87
-	github.com/distribution/distribution/v3 v3.0.0-20220822034424-3413bf8e14fd
-	github.com/drycc/controller-sdk-go v0.0.0-20220830032209-a334918d2242
-	github.com/drycc/pkg v0.0.0-20220830031116-26c11ff8667c
+	github.com/aws/aws-sdk-go-v2 v1.36.3
+	github.com/aws/aws-sdk-go-v2/config v1.29.14
+	github.com/aws/aws-sdk-go-v2/credentials v1.17.67
+	github.com/aws/aws-sdk-go-v2/service/ecr v1.44.1
+	github.com/distribution/distribution/v3 v3.1.0
+	github.com/drycc/controller-sdk-go v0.0.0-20260416093543-28d3a22ab999
+	github.com/drycc/pkg v0.0.0-20250917064731-345368da3dbf
+	github.com/google/uuid v1.6.0
 	github.com/kelseyhightower/envconfig v1.4.0
-	github.com/pborman/uuid v1.2.1
-	github.com/stretchr/testify v1.8.0
-	github.com/urfave/cli/v2 v2.11.2
-	golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
+	github.com/stretchr/testify v1.11.1
+	github.com/urfave/cli/v3 v3.3.3
+	golang.org/x/crypto v0.50.0
 	gopkg.in/yaml.v3 v3.0.1
-	k8s.io/api v0.25.0
-	k8s.io/apimachinery v0.25.0
-	k8s.io/client-go v0.25.0
+	k8s.io/api v0.35.4
+	k8s.io/apimachinery v0.35.4
+	k8s.io/client-go v0.35.4
 )
 
 require (
-	github.com/PuerkitoBio/purell v1.1.1 // indirect
-	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
+	github.com/aws/aws-sdk-go v1.55.5 // indirect
+	github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 // indirect
+	github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 // indirect
+	github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 // indirect
+	github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 // indirect
+	github.com/aws/smithy-go v1.22.2 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/cespare/xxhash/v2 v2.1.2 // indirect
-	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
-	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/cenkalti/backoff/v5 v5.0.3 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/docker/go-metrics v0.0.1 // indirect
-	github.com/emicklei/go-restful/v3 v3.8.0 // indirect
-	github.com/go-logr/logr v1.2.3 // indirect
-	github.com/go-openapi/jsonpointer v0.19.5 // indirect
-	github.com/go-openapi/jsonreference v0.19.5 // indirect
-	github.com/go-openapi/swag v0.19.14 // indirect
-	github.com/gogo/protobuf v1.3.2 // indirect
-	github.com/golang/protobuf v1.5.2 // indirect
-	github.com/google/gnostic v0.5.7-v3refs // indirect
-	github.com/google/go-cmp v0.5.6 // indirect
-	github.com/google/gofuzz v1.1.0 // indirect
-	github.com/google/uuid v1.1.2 // indirect
-	github.com/gorilla/mux v1.8.0 // indirect
-	github.com/goware/urlx v0.3.2 // indirect
+	github.com/emicklei/go-restful/v3 v3.12.2 // indirect
+	github.com/fxamacker/cbor/v2 v2.9.0 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
+	github.com/go-logr/stdr v1.2.2 // indirect
+	github.com/go-openapi/jsonpointer v0.21.1 // indirect
+	github.com/go-openapi/jsonreference v0.21.0 // indirect
+	github.com/go-openapi/swag v0.23.1 // indirect
+	github.com/google/gnostic-models v0.7.0 // indirect
+	github.com/google/go-cmp v0.7.0 // indirect
+	github.com/gorilla/mux v1.8.1 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/mailru/easyjson v0.7.6 // indirect
-	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
+	github.com/mailru/easyjson v0.9.0 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
-	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
 	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.12.1 // indirect
-	github.com/prometheus/client_model v0.2.0 // indirect
-	github.com/prometheus/common v0.32.1 // indirect
-	github.com/prometheus/procfs v0.7.3 // indirect
-	github.com/russross/blackfriday/v2 v2.1.0 // indirect
-	github.com/sirupsen/logrus v1.8.1 // indirect
-	github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
-	golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
-	golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
-	golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
-	golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
-	golang.org/x/text v0.3.7 // indirect
-	golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect
-	google.golang.org/appengine v1.6.7 // indirect
-	google.golang.org/protobuf v1.28.0 // indirect
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+	github.com/prometheus/client_golang v1.23.2 // indirect
+	github.com/prometheus/client_model v0.6.2 // indirect
+	github.com/prometheus/common v0.67.5 // indirect
+	github.com/prometheus/otlptranslator v1.0.0 // indirect
+	github.com/prometheus/procfs v0.20.1 // indirect
+	github.com/sirupsen/logrus v1.9.4 // indirect
+	github.com/x448/float16 v0.8.4 // indirect
+	go.opentelemetry.io/auto/sdk v1.2.1 // indirect
+	go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 // indirect
+	go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 // indirect
+	go.opentelemetry.io/otel v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/prometheus v0.64.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 // indirect
+	go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 // indirect
+	go.opentelemetry.io/otel/log v0.19.0 // indirect
+	go.opentelemetry.io/otel/metric v1.43.0 // indirect
+	go.opentelemetry.io/otel/sdk v1.43.0 // indirect
+	go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect
+	go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
+	go.opentelemetry.io/otel/trace v1.43.0 // indirect
+	go.opentelemetry.io/proto/otlp v1.10.0 // indirect
+	go.yaml.in/yaml/v2 v2.4.3 // indirect
+	go.yaml.in/yaml/v3 v3.0.4 // indirect
+	golang.org/x/net v0.52.0 // indirect
+	golang.org/x/oauth2 v0.35.0 // indirect
+	golang.org/x/sys v0.43.0 // indirect
+	golang.org/x/term v0.42.0 // indirect
+	golang.org/x/text v0.36.0 // indirect
+	golang.org/x/time v0.14.0 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect
+	google.golang.org/grpc v1.80.0 // indirect
+	google.golang.org/protobuf v1.36.11 // indirect
+	gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
-	k8s.io/klog/v2 v2.70.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
-	k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
-	sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
-	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
-	sigs.k8s.io/yaml v1.2.0 // indirect
+	k8s.io/klog/v2 v2.130.1 // indirect
+	k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
+	k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
+	sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
+	sigs.k8s.io/randfill v1.0.0 // indirect
+	sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
+	sigs.k8s.io/yaml v1.6.0 // indirect
 )
-
-replace github.com/docker/distribution v2.7.1+incompatible => github.com/distribution/distribution v2.7.1+incompatible
diff --git a/go.sum b/go.sum
index c72b09f..955bad4 100644
--- a/go.sum
+++ b/go.sum
@@ -1,617 +1,306 @@
-cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
-cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
-cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
-cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
-cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
-cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
-cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
-cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
-cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
-cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
-cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
-cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
-cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
-cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
-cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
-cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
-cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
-cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
-cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
-cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
-cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
-cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
-cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
-cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
-cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
-cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
-cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
-cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
-cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
-cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
-cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
-dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
-github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
-github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
+github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/aws/aws-sdk-go v1.44.87 h1:u/1sm8MNUSQHt8MGLEQHAj4r3lns3w0B1IXelPKbpn4=
-github.com/aws/aws-sdk-go v1.44.87/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU=
+github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU=
+github.com/aws/aws-sdk-go-v2 v1.36.3 h1:mJoei2CxPutQVxaATCzDUjcZEjVRdpsiiXi2o38yqWM=
+github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg=
+github.com/aws/aws-sdk-go-v2/config v1.29.14 h1:f+eEi/2cKCg9pqKBoAIwRGzVb70MRKqWX4dg1BDcSJM=
+github.com/aws/aws-sdk-go-v2/config v1.29.14/go.mod h1:wVPHWcIFv3WO89w0rE10gzf17ZYy+UVS1Geq8Iei34g=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.67 h1:9KxtdcIA/5xPNQyZRgUSpYOE6j9Bc4+D7nZua0KGYOM=
+github.com/aws/aws-sdk-go-v2/credentials v1.17.67/go.mod h1:p3C44m+cfnbv763s52gCqrjaqyPikj9Sg47kUVaNZQQ=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30 h1:x793wxmUWVDhshP8WW2mlnXuFrO4cOd3HLBroh1paFw=
+github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.30/go.mod h1:Jpne2tDnYiFascUEs2AWHJL9Yp7A5ZVy3TNyxaAjD6M=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34 h1:ZK5jHhnrioRkUNOc+hOgQKlUL5JeC3S6JgLxtQ+Rm0Q=
+github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34 h1:SZwFm17ZUNNg5Np0ioo/gq8Mn6u9w19Mri8DnJ15Jf0=
+github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 h1:bIqFDwgGXXN1Kpp99pDOdKMTTb5d2KyU5X/BZxjOkRo=
+github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3/go.mod h1:H5O/EsxDWyU+LP/V8i5sm8cxoZgc2fdNR9bxlOFrQTo=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.44.1 h1:tvGdftJBAi5sos34vphJ2EAbelTOyHMojnMlcTGi0Xw=
+github.com/aws/aws-sdk-go-v2/service/ecr v1.44.1/go.mod h1:iQ1skgw1XRK+6Lgkb0I9ODatAP72WoTILh0zXQ5DtbU=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
+github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15 h1:dM9/92u2F1JbDaGooxTq18wmmFzbJRfXfVfy96/1CXM=
+github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY=
+github.com/aws/aws-sdk-go-v2/service/sso v1.25.3 h1:1Gw+9ajCV1jogloEv1RRnvfRFia2cL6c9cuKV2Ps+G8=
+github.com/aws/aws-sdk-go-v2/service/sso v1.25.3/go.mod h1:qs4a9T5EMLl/Cajiw2TcbNt2UNo/Hqlyp+GiuG4CFDI=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1 h1:hXmVKytPfTy5axZ+fYbR5d0cFmC3JvwLm5kM83luako=
+github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.1/go.mod h1:MlYRNmYu/fGPoxBQVvBYr9nyr948aY/WLUvwBMBJubs=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.19 h1:1XuUZ8mYJw9B6lzAkXhqHlJd/XvaX32evhproijJEZY=
+github.com/aws/aws-sdk-go-v2/service/sts v1.33.19/go.mod h1:cQnB8CUnxbMU82JvlqjKR2HBOm3fe9pWorWBza6MBJ4=
+github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
+github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
-github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
-github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
-github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
-github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
-github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
-github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
+github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
+github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/distribution/distribution/v3 v3.0.0-20220822034424-3413bf8e14fd h1:jtncyJ6leoRxSuB7y1EkkES0nKuG0kM7arfABcZW9r0=
-github.com/distribution/distribution/v3 v3.0.0-20220822034424-3413bf8e14fd/go.mod h1:28YO/VJk9/64+sTGNuYaBjWxrXTPrj0C0XmgTIOjxX4=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
+github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/distribution/distribution/v3 v3.1.0 h1:u1v788HreKTLGdNY6s7px8Exgrs9mZ9UrCDjSrpCM8g=
+github.com/distribution/distribution/v3 v3.1.0/go.mod h1:73BuF5/ziMHNVt7nnL1roYpH4Eg/FgUlKZm3WryIx/o=
 github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
 github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/drycc/controller-sdk-go v0.0.0-20220830032209-a334918d2242 h1:UduAyToNW6QxHwDd7DrJNpjO0yl0vfFvSZxXl9O7A8M=
-github.com/drycc/controller-sdk-go v0.0.0-20220830032209-a334918d2242/go.mod h1:mTPPOfS1LzvsGpLuNpgz4wt9CGloCF12MtTYjQa5i8o=
-github.com/drycc/pkg v0.0.0-20220830031116-26c11ff8667c h1:M4veAIz8VfKEMpyegbNMvAv7McrXqW4QwAoC813lG0w=
-github.com/drycc/pkg v0.0.0-20220830031116-26c11ff8667c/go.mod h1:W2lIi2Micx/4vPIlfzIsQ7RDZXxNmKGpGcfiWkw8Qls=
-github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
-github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
-github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
-github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
-github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
-github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
+github.com/drycc/controller-sdk-go v0.0.0-20260416093543-28d3a22ab999 h1:yHGZInF3xoLRHDgIPQFnfXF8EGaPZZXaRXf0I4pxnWI=
+github.com/drycc/controller-sdk-go v0.0.0-20260416093543-28d3a22ab999/go.mod h1:eHcmYwg81ASlP55/U587xnBZnZoeZnPHXGeQ8nYWnsg=
+github.com/drycc/pkg v0.0.0-20250917064731-345368da3dbf h1:CYy3NoPhfFhkGAbEppTOQfY/HC2s0FJDcBgbtRKeweg=
+github.com/drycc/pkg v0.0.0-20250917064731-345368da3dbf/go.mod h1:BrrNrNskHKm+nJYhXfGuI114w8nupi0AMo8QZHID7CM=
+github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
+github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
+github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
+github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
-github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
-github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
-github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
-github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
-github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
-github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
-github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
+github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic=
+github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk=
+github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
+github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4=
+github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
+github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
+github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
-github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
-github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
-github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
-github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
-github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
-github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
-github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
-github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
-github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
-github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
-github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
-github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
+github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
+github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 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/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
-github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
-github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
-github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
-github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
-github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
-github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/goware/urlx v0.3.2 h1:gdoo4kBHlkqZNaf6XlQ12LGtQOmpKJrR04Rc3RnpJEo=
-github.com/goware/urlx v0.3.2/go.mod h1:h8uwbJy68o+tQXCGZNa9D73WN8n0r9OBae5bUnLcgjw=
-github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
-github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
+github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
+github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
 github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
 github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
 github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
-github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 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/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
-github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
-github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
 github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
 github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
-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/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c=
+github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-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/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
+github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
+github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 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 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-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/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
+github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
-github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
-github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
-github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
+github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
+github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
+github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
+github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
+github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
 github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
-github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
-github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
-github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
-github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
+github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
+github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
-github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
-github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
+github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
 github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
-github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
-github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
-github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
-github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
+github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
+github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
+github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos=
+github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM=
 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
 github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
-github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
-github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
-github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
-github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
+github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
-github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
-github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
-github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
+github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
+github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
+github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
+github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
+github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/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 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
-github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/urfave/cli/v2 v2.11.2 h1:FVfNg4m3vbjbBpLYxW//WjxUoHvJ9TlppXcqY9Q9ZfA=
-github.com/urfave/cli/v2 v2.11.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
-github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
-go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
-go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
-go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
+github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
+github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
+github.com/urfave/cli/v3 v3.3.3 h1:byCBaVdIXuLPIDm5CYZRVG6NvT7tv1ECqdU4YzlEa3I=
+github.com/urfave/cli/v3 v3.3.3/go.mod h1:FJSKtM/9AiiTOJL4fJ6TbMUkxBXn7GO9guZqoZtpYpo=
+github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
+github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
+go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
+go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
+go.opentelemetry.io/contrib/bridges/prometheus v0.67.0 h1:dkBzNEAIKADEaFnuESzcXvpd09vxvDZsOjx11gjUqLk=
+go.opentelemetry.io/contrib/bridges/prometheus v0.67.0/go.mod h1:Z5RIwRkZgauOIfnG5IpidvLpERjhTninpP1dTG2jTl4=
+go.opentelemetry.io/contrib/exporters/autoexport v0.67.0 h1:4fnRcNpc6YFtG3zsFw9achKn3XgmxPxuMuqIL5rE8e8=
+go.opentelemetry.io/contrib/exporters/autoexport v0.67.0/go.mod h1:qTvIHMFKoxW7HXg02gm6/Wofhq5p3Ib/A/NNt1EoBSQ=
+go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
+go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 h1:deI9UQMoGFgrg5iLPgzueqFPHevDl+28YKfSpPTI6rY=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0/go.mod h1:PFx9NgpNUKXdf7J4Q3agRxMs3Y07QhTCVipKmLsMKnU=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag=
+go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 h1:8UQVDcZxOJLtX6gxtDt3vY2WTgvZqMQRzjsqiIHQdkc=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0/go.mod h1:2lmweYCiHYpEjQ/lSJBYhj9jP1zvCvQW4BqL9dnT7FQ=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY=
+go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak=
+go.opentelemetry.io/otel/exporters/prometheus v0.64.0 h1:g0LRDXMX/G1SEZtK8zl8Chm4K6GBwRkjPKE36LxiTYs=
+go.opentelemetry.io/otel/exporters/prometheus v0.64.0/go.mod h1:UrgcjnarfdlBDP3GjDIJWe6HTprwSazNjwsI+Ru6hro=
+go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0 h1:KJVjPD3rcPb98rIs3HznyJlrfx9ge5oJvxxlGR+P/7s=
+go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.18.0/go.mod h1:K3kRa2ckmHWQaTWQdPRHc7qGXASuVuoEQXzrvlA98Ws=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 h1:TC+BewnDpeiAmcscXbGMfxkO+mwYUwE/VySwvw88PfA=
+go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0/go.mod h1:J/ZyF4vfPwsSr9xJSPyQ4LqtcTPULFR64KwTikGLe+A=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 h1:mS47AX77OtFfKG4vtp+84kuGSFZHTyxtXIN269vChY0=
+go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0/go.mod h1:PJnsC41lAGncJlPUniSwM81gc80GkgWJWr3cu2nKEtU=
+go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4=
+go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk=
+go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
+go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
+go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
+go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
+go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko=
+go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg=
+go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk=
+go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk=
+go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
+go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
+go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
+go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
+go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
+go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
+go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
+go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
+go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
+go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-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/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
-golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
-golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
-golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
-golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
-golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
-golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
-golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
-golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
-golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
-golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
-golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
-golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
-golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
-golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
-golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
+golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
+golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
+golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
-golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
-golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
-golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
-golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
+golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
+golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
+golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
+golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
-golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
+golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
+golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
-golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
-golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44=
-golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
-golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
-google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
-google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
-google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
-google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
-google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
-google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
-google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
-google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
-google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
-google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
-google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
-google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
-google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
-google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
-google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
-google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
-google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
-google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
-google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
-google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
-google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
-google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
-google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
-google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
-google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
-google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
-google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
-google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
-google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
-google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
+golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
+golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
+golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
+gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
+gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
+google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA=
+google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
+google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
+google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 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/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
+gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
 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.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.3.0/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.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
-honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.25.0 h1:H+Q4ma2U/ww0iGB78ijZx6DRByPz6/733jIuFpX70e0=
-k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk=
-k8s.io/apimachinery v0.25.0 h1:MlP0r6+3XbkUG2itd6vp3oxbtdQLQI94fD5gCS+gnoU=
-k8s.io/apimachinery v0.25.0/go.mod h1:qMx9eAk0sZQGsXGu86fab8tZdffHbwUfsvzqKn4mfB0=
-k8s.io/client-go v0.25.0 h1:CVWIaCETLMBNiTUta3d5nzRbXvY5Hy9Dpl+VvREpu5E=
-k8s.io/client-go v0.25.0/go.mod h1:lxykvypVfKilxhTklov0wz1FoaUZ8X4EwbhS6rpRfN8=
-k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
-k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ=
-k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
-k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
-k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4=
-k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
-rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
-rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
-sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/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=
-sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
-sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
+k8s.io/api v0.35.4 h1:P7nFYKl5vo9AGUp1Z+Pmd3p2tA7bX2wbFWCvDeRv988=
+k8s.io/api v0.35.4/go.mod h1:yl4lqySWOgYJJf9RERXKUwE9g2y+CkuwG+xmcOK8wXU=
+k8s.io/apimachinery v0.35.4 h1:xtdom9RG7e+yDp71uoXoJDWEE2eOiHgeO4GdBzwWpds=
+k8s.io/apimachinery v0.35.4/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
+k8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8=
+k8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY=
+k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
+k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
+k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
+k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
+k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
+k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
+sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
+sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
+sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
+sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
+sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
+sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
diff --git a/pkg/builder.go b/pkg/builder.go
index 40701c4..bfddeee 100644
--- a/pkg/builder.go
+++ b/pkg/builder.go
@@ -1,6 +1,6 @@
 // Package pkg provides common libraries for the Drycc builder.
 //
-// The Drycc builder is responsible for building buildpack and docker images for use in the Drycc
+// The Drycc builder is responsible for building buildpack and container images for use in the Drycc
 // on the Drycc PaaS platform.
 package pkg
 
diff --git a/pkg/cleaner/cleaner.go b/pkg/cleaner/cleaner.go
index 409b1ea..06eba02 100644
--- a/pkg/cleaner/cleaner.go
+++ b/pkg/cleaner/cleaner.go
@@ -5,23 +5,18 @@ package cleaner
 import (
 	"context"
 	"fmt"
-	"io/ioutil"
+	"os"
 	"path/filepath"
 	"regexp"
 	"strings"
 	"time"
 
-	//"github.com/distribution/distribution/v3/context"
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 	"github.com/drycc/builder/pkg/gitreceive"
 	"github.com/drycc/builder/pkg/k8s"
 	"github.com/drycc/builder/pkg/sys"
 	"github.com/drycc/pkg/log"
 	corev1 "k8s.io/api/core/v1"
-
-	//"k8s.io/apimachinery/pkg/labels"
-	//"k8s.io/apimachinery/pkg/fields"
-	//"k8s.io/apimachinery/pkg/apis/meta/internalversion"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -32,7 +27,7 @@ const (
 // localDirs returns all of the local directories immediately under gitHome that filter returns true for.
 // filter will receive only the names of each of the top level directories (not their fully qualified paths), and should return true if it should be included in the output
 func localDirs(gitHome string, filter func(string) bool) ([]string, error) {
-	fileInfos, err := ioutil.ReadDir(gitHome)
+	fileInfos, err := os.ReadDir(gitHome)
 	if err != nil {
 		return nil, err
 	}
@@ -89,7 +84,6 @@ func dirHasGitSuffix(dir string) bool {
 }
 
 func deleteFromStorage(app string, storageDriver storagedriver.StorageDriver) error {
-
 	// delete all files matching app
 	objs, err := storageDriver.List(context.Background(), "home")
 	if err != nil {
diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index 0ab132c..464aee9 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -1,46 +1,47 @@
+// Package conf provides configuration utilities for the builder service.
 package conf
 
 import (
 	"fmt"
-	"io/ioutil"
 	"net"
 	"net/url"
+	"os"
 	"strings"
 
 	"github.com/drycc/builder/pkg/sys"
 )
 
 const (
-	storageLookupEnvVar    = "DRYCC_STORAGE_LOOKUP"
 	storageBucketEnvVar    = "DRYCC_STORAGE_BUCKET"
 	storageEndpointEnvVar  = "DRYCC_STORAGE_ENDPOINT"
 	storageAccesskeyEnvVar = "DRYCC_STORAGE_ACCESSKEY"
 	storageSecretkeyEnvVar = "DRYCC_STORAGE_SECRETKEY"
+	storagePathStyleEnvVar = "DRYCC_STORAGE_PATH_STYLE"
 )
 
-// BuilderKeyLocation holds the path of the builder key secret.
-var BuilderKeyLocation = "/var/run/secrets/api/auth/builder-key"
+// ServiceKeyLocation holds the path of the service key secret.
+var ServiceKeyLocation = "/var/run/secrets/drycc/controller/service-key"
 
 // Parameters is map which contains storage params
-type Parameters map[string]interface{}
+type Parameters map[string]any
 
-// GetBuilderKey returns the key to be used as token to interact with drycc-controller
-func GetBuilderKey() (string, error) {
-	builderKeyBytes, err := ioutil.ReadFile(BuilderKeyLocation)
+// GetServiceKey returns the key to be used as token to interact with drycc-controller
+func GetServiceKey() (string, error) {
+	serviceKeyBytes, err := os.ReadFile(ServiceKeyLocation)
 	if err != nil {
-		return "", fmt.Errorf("couldn't get builder key from %s (%s)", BuilderKeyLocation, err)
+		return "", fmt.Errorf("couldn't get builder key from %s (%s)", ServiceKeyLocation, err)
 	}
-	builderKey := strings.Trim(string(builderKeyBytes), "\n")
-	return builderKey, nil
+	serviceKey := strings.TrimSuffix(string(serviceKeyBytes), "\n")
+	return serviceKey, nil
 }
 
 // GetStorageParams returns the credentials required for connecting to object storage
 func GetStorageParams(env sys.Env) (Parameters, error) {
-	params := make(map[string]interface{})
+	params := make(map[string]any)
 
 	mEndpoint := env.Get(storageEndpointEnvVar)
 	params["regionendpoint"] = mEndpoint
-	region := "us-east-1" //region is required in distribution
+	region := "us-east-1" // region is required in distribution
 	if endpointURL, err := url.Parse(mEndpoint); err == nil {
 		if endpointURL.Hostname() != "" && net.ParseIP(endpointURL.Hostname()) == nil {
 			region = strings.Split(endpointURL.Hostname(), ".")[0]
@@ -51,9 +52,8 @@ func GetStorageParams(env sys.Env) (Parameters, error) {
 	params["accesskey"] = env.Get(storageAccesskeyEnvVar)
 	params["secretkey"] = env.Get(storageSecretkeyEnvVar)
 	params["bucket"] = env.Get(storageBucketEnvVar)
-	if env.Get(storageLookupEnvVar) == "path" {
+	if env.Get(storagePathStyleEnvVar) == "true" {
 		params["forcepathstyle"] = "true"
 	}
-
 	return params, nil
 }
diff --git a/pkg/conf/config_test.go b/pkg/conf/config_test.go
index 2a77a3c..42460e7 100644
--- a/pkg/conf/config_test.go
+++ b/pkg/conf/config_test.go
@@ -1,7 +1,6 @@
 package conf
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
@@ -11,14 +10,13 @@ import (
 )
 
 func TestGetStorageParams(t *testing.T) {
-
 	env := sys.NewFakeEnv()
 	env.Envs = map[string]string{
-		"DRYCC_STORAGE_LOOKUP":    "path",
-		"DRYCC_STORAGE_BUCKET":    "builder",
-		"DRYCC_STORAGE_ENDPOINT":  "http://localhost:8088",
-		"DRYCC_STORAGE_ACCESSKEY": "admin",
-		"DRYCC_STORAGE_SECRETKEY": "adminpass",
+		"DRYCC_STORAGE_BUCKET":     "builder",
+		"DRYCC_STORAGE_ENDPOINT":   "http://localhost:8088",
+		"DRYCC_STORAGE_ACCESSKEY":  "admin",
+		"DRYCC_STORAGE_SECRETKEY":  "adminpass",
+		"DRYCC_STORAGE_PATH_STYLE": "true",
 	}
 	params, err := GetStorageParams(env)
 	if err != nil {
@@ -33,29 +31,29 @@ func TestGetStorageParams(t *testing.T) {
 }
 
 func TestGetControllerClient(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "tmpdir")
+	tmpDir, err := os.MkdirTemp("", "tmpdir")
 	if err != nil {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 
 	defer func() {
 		if err := os.RemoveAll(tmpDir); err != nil {
-			t.Fatalf("failed to remove builder-key from %s (%s)", tmpDir, err)
+			t.Fatalf("failed to remove service-key from %s (%s)", tmpDir, err)
 		}
 	}()
 
-	BuilderKeyLocation = filepath.Join(tmpDir, "builder-key")
+	ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := ioutil.WriteFile(BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", BuilderKeyLocation, err)
+	if err := os.WriteFile(ServiceKeyLocation, data, 0o644); err != nil {
+		t.Fatalf("error creating %s (%s)", ServiceKeyLocation, err)
 	}
 
-	key, err := GetBuilderKey()
+	key, err := GetServiceKey()
 	assert.Equal(t, err, nil)
 	assert.Equal(t, key, string(data), "data")
 }
 
-func TestGetBuilderKeyError(t *testing.T) {
-	_, err := GetBuilderKey()
+func TestGetServiceKeyError(t *testing.T) {
+	_, err := GetServiceKey()
 	assert.True(t, err != nil, "no error received when there should have been")
 }
diff --git a/pkg/controller/utils.go b/pkg/controller/utils.go
index 6450195..2edb12b 100644
--- a/pkg/controller/utils.go
+++ b/pkg/controller/utils.go
@@ -1,27 +1,25 @@
+// Package controller provides utilities for interacting with the Drycc controller.
 package controller
 
 import (
-	"fmt"
-
 	"github.com/drycc/builder/pkg/conf"
 	drycc "github.com/drycc/controller-sdk-go"
 	"github.com/drycc/pkg/log"
 )
 
 // New creates a new SDK client configured as the builder.
-func New(host, port string) (*drycc.Client, error) {
-
-	client, err := drycc.New(true, fmt.Sprintf("http://%s:%s/", host, port), "")
+func New(url string) (*drycc.Client, error) {
+	client, err := drycc.New(true, url, "")
 	if err != nil {
 		return client, err
 	}
 	client.UserAgent = "drycc-builder"
 
-	builderKey, err := conf.GetBuilderKey()
+	serviceKey, err := conf.GetServiceKey()
 	if err != nil {
 		return client, err
 	}
-	client.HooksToken = builderKey
+	client.ServiceKey = serviceKey
 
 	return client, nil
 }
diff --git a/pkg/controller/utils_test.go b/pkg/controller/utils_test.go
index 928a8f4..63c8494 100644
--- a/pkg/controller/utils_test.go
+++ b/pkg/controller/utils_test.go
@@ -2,54 +2,49 @@ package controller
 
 import (
 	"errors"
-	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"testing"
 
 	builderconf "github.com/drycc/builder/pkg/conf"
-	"github.com/stretchr/testify/assert"
-
 	drycc "github.com/drycc/controller-sdk-go"
+	"github.com/stretchr/testify/assert"
 )
 
 func TestNew(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "tmpdir")
+	tmpDir, err := os.MkdirTemp("", "tmpdir")
 	if err != nil {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 
 	defer func() {
 		if err := os.RemoveAll(tmpDir); err != nil {
-			t.Fatalf("failed to remove builder-key from %s (%s)", tmpDir, err)
+			t.Fatalf("failed to remove service-key from %s (%s)", tmpDir, err)
 		}
 	}()
 
-	builderconf.BuilderKeyLocation = filepath.Join(tmpDir, "builder-key")
+	builderconf.ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := ioutil.WriteFile(builderconf.BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", builderconf.BuilderKeyLocation, err)
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0o644); err != nil {
+		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
-	host := "127.0.0.1"
-	port := "80"
-	cli, err := New(host, port)
+	url := "http://127.0.0.1:80"
+	cli, err := New(url)
 	assert.Equal(t, err, nil)
-	assert.Equal(t, cli.ControllerURL.String(), fmt.Sprintf("http://%s:%s/", host, port), "data")
-	assert.Equal(t, cli.HooksToken, string(data), "data")
+	assert.Equal(t, cli.ControllerURL.String(), url, "data")
+	assert.Equal(t, cli.ServiceKey, string(data), "data")
 	assert.Equal(t, cli.UserAgent, "drycc-builder", "user-agent")
 
-	port = "invalid-port-number"
-	if _, err = New(host, port); err == nil {
+	url = "http://127.0.0.1:invalid-port-number"
+	if _, err = New(url); err == nil {
 		t.Errorf("expected error with invalid port number, got nil")
 	}
 }
 
 func TestNewWithInvalidBuilderKeyPath(t *testing.T) {
-	host := "127.0.0.1"
-	port := "80"
-	_, err := New(host, port)
+	url := "http://127.0.0.1:80"
+	_, err := New(url)
 	assert.True(t, err != nil, "no error received when there should have been")
 }
 
diff --git a/pkg/git/git.go b/pkg/git/git.go
index 3182c75..0224457 100644
--- a/pkg/git/git.go
+++ b/pkg/git/git.go
@@ -1,3 +1,4 @@
+// Package git provides Git repository handling functionality for the SSH server.
 package git
 
 // This file just contains the Git-specific portions of sshd.
@@ -45,8 +46,8 @@ var preReceiveHookTpl = template.Must(template.New("hooks").Parse(preReceiveHook
 func Receive(
 	repo, operation, gitHome string,
 	channel ssh.Channel,
-	fingerprint, username, conndata, receivetype string) error {
-
+	fingerprint, username, conndata, receivetype string,
+) error {
 	log.Info("receiving git repo name: %s, operation: %s, fingerprint: %s, user: %s", repo, operation, fingerprint, username)
 
 	if receivetype == "mock" {
@@ -54,16 +55,17 @@ func Receive(
 		return nil
 	}
 	repoPath := filepath.Join(gitHome, repo)
+	defer os.RemoveAll(repoPath)
 	log.Info("creating repo directory %s", repoPath)
 	if _, err := createRepo(repoPath); err != nil {
-		err = fmt.Errorf("Did not create new repo (%s)", err)
+		err = fmt.Errorf("did not create new repo (%s)", err)
 
 		return err
 	}
 
 	log.Info("writing pre-receive hook under %s", repoPath)
 	if err := createPreReceiveHook(gitHome, repoPath); err != nil {
-		err = fmt.Errorf("Did not write pre-receive hook (%s)", err)
+		err = fmt.Errorf("did not write pre-receive hook (%s)", err)
 		return err
 	}
 
@@ -93,19 +95,19 @@ func Receive(
 	cmd.Stderr = io.MultiWriter(channel.Stderr(), &errbuff)
 
 	if err := cmd.Start(); err != nil {
-		err = fmt.Errorf("Failed to start git pre-receive hook: %s (%s)", err, errbuff.Bytes())
+		err = fmt.Errorf("failed to start git pre-receive hook: %s (%s)", err, errbuff.Bytes())
 		return err
 	}
 
 	if _, err := io.Copy(inpipe, channel); err != nil {
-		err = fmt.Errorf("Failed to write git objects into the git pre-receive hook (%s)", err)
+		err = fmt.Errorf("failed to write git objects into the git pre-receive hook (%s)", err)
 		return err
 	}
 
 	fmt.Println("Waiting for git-receive to run.")
 	fmt.Println("Waiting for deploy.")
 	if err := cmd.Wait(); err != nil {
-		err = fmt.Errorf("Failed to run git pre-receive hook: %s (%s)", errbuff.Bytes(), err)
+		err = fmt.Errorf("failed to run git pre-receive hook: %s (%s)", errbuff.Bytes(), err)
 		return err
 	}
 	if errbuff.Len() > 0 {
@@ -137,7 +139,7 @@ func createRepo(repoPath string) (bool, error) {
 	} else if os.IsNotExist(err) {
 		log.Debug("Creating new directory at %s", repoPath)
 		// Create directory
-		if err := os.MkdirAll(repoPath, 0755); err != nil {
+		if err := os.MkdirAll(repoPath, 0o755); err != nil {
 			log.Err("Failed to create repository: %s", err)
 			return false, err
 		}
@@ -160,16 +162,16 @@ func createPreReceiveHook(gitHome, repoPath string) error {
 	writePath := filepath.Join(repoPath, "hooks", "pre-receive")
 	fd, err := os.Create(writePath)
 	if err != nil {
-		return fmt.Errorf("Cannot create pre-receive hook file at %s (%s)", writePath, err)
+		return fmt.Errorf("cannot create pre-receive hook file at %s (%s)", writePath, err)
 	}
 	defer fd.Close()
 
 	// parse & generate the template anew each receive for each new git home
 	if err := preReceiveHookTpl.Execute(fd, map[string]string{"GitHome": gitHome}); err != nil {
-		return fmt.Errorf("Cannot write pre-receive hook to %s (%s)", writePath, err)
+		return fmt.Errorf("cannot write pre-receive hook to %s (%s)", writePath, err)
 	}
-	if err := os.Chmod(writePath, 0755); err != nil {
-		return fmt.Errorf("Cannot change pre-receive hook script permissions (%s)", err)
+	if err := os.Chmod(writePath, 0o755); err != nil {
+		return fmt.Errorf("cannot change pre-receive hook script permissions (%s)", err)
 	}
 
 	return nil
diff --git a/pkg/git/git_test.go b/pkg/git/git_test.go
index 4b29a56..5a87f15 100644
--- a/pkg/git/git_test.go
+++ b/pkg/git/git_test.go
@@ -2,7 +2,6 @@ package git
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -16,7 +15,7 @@ func TestCreatePreReceiveHook(t *testing.T) {
 	gopath := os.Getenv("GOPATH")
 	repoPath := filepath.Join(gopath, "src", "github.com", "drycc", "builder", "testdata")
 	assert.Equal(t, createPreReceiveHook(gitHome, repoPath), nil)
-	hookBytes, err := ioutil.ReadFile(filepath.Join(repoPath, "hooks", "pre-receive"))
+	hookBytes, err := os.ReadFile(filepath.Join(repoPath, "hooks", "pre-receive"))
 	assert.Equal(t, err, nil)
 	hookStr := string(hookBytes)
 	gitHomeIdx := strings.Index(hookStr, fmt.Sprintf("GIT_HOME=%s", gitHome))
diff --git a/pkg/gitreceive/build.go b/pkg/gitreceive/build.go
index f2e383f..86b9f9a 100644
--- a/pkg/gitreceive/build.go
+++ b/pkg/gitreceive/build.go
@@ -1,24 +1,24 @@
+// Package gitreceive provides functionality for handling git receive operations.
 package gitreceive
 
 import (
 	"bytes"
-	ctx "context"
+	"context"
 	"encoding/json"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"regexp"
 	"strings"
 
-	"github.com/distribution/distribution/v3/context"
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 	"github.com/drycc/builder/pkg/controller"
 	"github.com/drycc/builder/pkg/git"
 	"github.com/drycc/builder/pkg/k8s"
 	"github.com/drycc/builder/pkg/sys"
+	drycc "github.com/drycc/controller-sdk-go"
 	dryccAPI "github.com/drycc/controller-sdk-go/api"
 	"github.com/drycc/controller-sdk-go/hooks"
 	"github.com/drycc/pkg/log"
@@ -58,13 +58,11 @@ func run(cmd *exec.Cmd) error {
 func build(
 	conf *Config,
 	storageDriver storagedriver.StorageDriver,
-	//kubeClient *client.Client,
+	// kubeClient *client.Client,
 	kubeClient *kubernetes.Clientset,
-	fs sys.FS,
 	env sys.Env,
-	builderKey,
-	rawGitSha string) error {
-
+	rawGitSha string,
+) error {
 	// Rewrite regular expression, compatible with slug type
 	storagedriver.PathRegexp = regexp.MustCompile(`^([A-Za-z0-9._:-]*(/[A-Za-z0-9._:-]+)*)+$`)
 
@@ -79,11 +77,11 @@ func build(
 	repoDir := filepath.Join(conf.GitHome, repo)
 	buildDir := filepath.Join(repoDir, "build")
 
-	if err := os.MkdirAll(buildDir, 0700); err != nil {
+	if err := os.MkdirAll(buildDir, 0o700); err != nil {
 		return fmt.Errorf("making the build directory %s (%s)", buildDir, err)
 	}
 
-	tmpDir, err := ioutil.TempDir(buildDir, "tmp")
+	tmpDir, err := os.MkdirTemp(buildDir, "tmp")
 	if err != nil {
 		return fmt.Errorf("unable to create tmpdir %s (%s)", buildDir, err)
 	}
@@ -93,7 +91,7 @@ func build(
 		}
 	}()
 
-	client, err := controller.New(conf.ControllerHost, conf.ControllerPort)
+	client, err := controller.New(conf.ControllerURL)
 	if err != nil {
 		return err
 	}
@@ -124,7 +122,7 @@ func build(
 
 	stack := getStack(tmpDir, appConf)
 
-	appTgzdata, err := ioutil.ReadFile(absAppTgz)
+	appTgzdata, err := os.ReadFile(absAppTgz)
 	if err != nil {
 		return fmt.Errorf("error while reading file %s: (%s)", appTgz, err)
 	}
@@ -183,7 +181,7 @@ func build(
 	}
 	jobsInterface := kubeClient.BatchV1().Jobs(conf.PodNamespace)
 
-	newJob, err := jobsInterface.Create(ctx.TODO(), job, metav1.CreateOptions{})
+	newJob, err := jobsInterface.Create(context.TODO(), job, metav1.CreateOptions{})
 	if err != nil {
 		return fmt.Errorf("creating builder pod (%s)", err)
 	}
@@ -193,12 +191,12 @@ func build(
 	defer close(stopCh)
 	go pw.Controller.Run(stopCh)
 
-	if err := waitForPod(pw, newJob.Namespace, newJob.Name, conf.SessionIdleInterval(), conf.BuilderPodTickDuration(), conf.BuilderPodWaitDuration()); err != nil {
+	if err := waitForPod(pw, newJob.Name, conf.SessionIdleInterval(), conf.BuilderPodTickDuration(), conf.BuilderPodWaitDuration()); err != nil {
 		return fmt.Errorf("watching events for builder pod startup (%s)", err)
 	}
 
 	options := metav1.ListOptions{
-		LabelSelector: fmt.Sprintf("heritage=%s", newJob.Name),
+		LabelSelector: fmt.Sprintf("job-name=%s", newJob.Name),
 	}
 	podList, err := kubeClient.CoreV1().Pods(newJob.Namespace).List(context.Background(), options)
 	if err != nil {
@@ -210,7 +208,7 @@ func build(
 			Follow: true,
 		}, scheme.ParameterCodec)
 
-	rc, err := req.Stream(ctx.TODO())
+	rc, err := req.Stream(context.TODO())
 	if err != nil {
 		return fmt.Errorf("attempting to stream logs (%s)", err)
 	}
@@ -231,12 +229,12 @@ func build(
 	)
 	// check the state and exit code of the build pod.
 	// if the code is not 0 return error
-	if err := waitForPodEnd(pw, newJob.Namespace, newJob.Name, conf.BuilderPodTickDuration(), conf.BuilderPodWaitDuration()); err != nil {
+	if err := waitForPodEnd(pw, newJob.Name, conf.BuilderPodTickDuration(), conf.BuilderPodWaitDuration()); err != nil {
 		return fmt.Errorf("error getting builder pod status (%s)", err)
 	}
 	log.Debug("Done")
 	log.Debug("Checking for builder pod exit code")
-	buildPod, err := kubeClient.CoreV1().Pods(newJob.Namespace).Get(ctx.TODO(), podList.Items[0].Name, metav1.GetOptions{})
+	buildPod, err := kubeClient.CoreV1().Pods(newJob.Namespace).Get(context.TODO(), podList.Items[0].Name, metav1.GetOptions{})
 	if err != nil {
 		return fmt.Errorf("error getting builder pod status (%s)", err)
 	}
@@ -249,7 +247,7 @@ func build(
 	}
 	log.Debug("Done")
 
-	procfile, err := getProcfile(tmpDir, stack)
+	procfile, err := getProcfile(tmpDir)
 	if err != nil {
 		return err
 	}
@@ -257,23 +255,25 @@ func build(
 	if err != nil {
 		return err
 	}
+	dryccfile, err := drycc.ParseDryccfile(filepath.Join(tmpDir, ".drycc"))
+	if err != nil {
+		return err
+	}
 	log.Info("Build complete.")
 
 	quit := progress("...", conf.SessionIdleInterval())
 	log.Info("Launching App...")
-	release, err := hooks.CreateBuild(client, conf.Username, conf.App(), imageName, stack["name"], gitSha.Short(), procfile, dockerfile)
+	release, err := hooks.CreateBuild(client, conf.Username, conf.App(), imageName, stack["name"], gitSha.Short(), procfile, dryccfile, dockerfile)
 	quit <- true
 	<-quit
 	if controller.CheckAPICompat(client, err) != nil {
-		return fmt.Errorf("The controller returned an error when publishing the release: %s", err)
+		return fmt.Errorf("the controller returned an error when publishing the release: %s", err)
 	}
 
 	log.Info("Done, %s:v%d deployed to Workflow\n", appName, release)
 	log.Info("Use 'drycc open' to view this application in your browser\n")
 	log.Info("To learn more, use 'drycc help' or visit https://www.drycc.cc/\n")
 
-	run(repoCmd(repoDir, "git", "gc"))
-
 	return nil
 }
 
@@ -291,7 +291,7 @@ func buildBuilderPodNodeSelector(config string) (map[string]string, error) {
 	return selector, nil
 }
 
-func prettyPrintJSON(data interface{}) (string, error) {
+func prettyPrintJSON(data any) (string, error) {
 	output := &bytes.Buffer{}
 	if err := json.NewEncoder(output).Encode(data); err != nil {
 		return "", err
@@ -303,27 +303,28 @@ func prettyPrintJSON(data interface{}) (string, error) {
 	return formatted.String(), nil
 }
 
-func getProcfile(dirName string, stack map[string]string) (dryccAPI.ProcessType, error) {
+func getProcfile(dirName string) (dryccAPI.ProcessType, error) {
 	procfile := dryccAPI.ProcessType{}
-	if _, err := os.Stat(fmt.Sprintf("%s/Procfile", dirName)); err == nil {
-		rawProcFile, err := ioutil.ReadFile(fmt.Sprintf("%s/Procfile", dirName))
+	file := fmt.Sprintf("%s/Procfile", dirName)
+	if _, err := os.Stat(file); err == nil {
+		rawProcFile, err := os.ReadFile(file)
 		if err != nil {
-			return nil, fmt.Errorf("error in reading %s/Procfile (%s)", dirName, err)
+			return nil, fmt.Errorf("error in reading %s (%s)", file, err)
 		}
 		if err := yaml.Unmarshal(rawProcFile, &procfile); err != nil {
-			return nil, fmt.Errorf("procfile %s/ProcFile is malformed (%s)", dirName, err)
+			return nil, fmt.Errorf("procfile %s is malformed (%s)", file, err)
 		}
-		return procfile, nil
 	}
-	return nil, fmt.Errorf("no Procfile can be matched in (%s)", dirName)
+	return procfile, nil
 }
 
 func getDockerfile(dirName string, stack map[string]string) (string, error) {
 	if stack["name"] == "container" {
-		if _, err := os.Stat(fmt.Sprintf("%s/Dockerfile", dirName)); err == nil {
-			rawDockerfile, err := ioutil.ReadFile(fmt.Sprintf("%s/Dockerfile", dirName))
+		file := fmt.Sprintf("%s/Dockerfile", dirName)
+		if _, err := os.Stat(file); err == nil {
+			rawDockerfile, err := os.ReadFile(file)
 			if err != nil {
-				return "", fmt.Errorf("error in reading %s/Dockerfile (%s)", dirName, err)
+				return "", fmt.Errorf("error in reading %s (%s)", file, err)
 			}
 			return string(rawDockerfile), nil
 		}
diff --git a/pkg/gitreceive/build_test.go b/pkg/gitreceive/build_test.go
index e9a05d1..450eaa2 100644
--- a/pkg/gitreceive/build_test.go
+++ b/pkg/gitreceive/build_test.go
@@ -2,14 +2,12 @@ package gitreceive
 
 import (
 	"bytes"
-	"fmt"
-	"io/ioutil"
+	"context"
 	"os"
 	"os/exec"
 	"path/filepath"
 	"testing"
 
-	//"github.com/distribution/distribution/v3/context"
 	"github.com/distribution/distribution/v3/registry/storage/driver/factory"
 	_ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
 	builderconf "github.com/drycc/builder/pkg/conf"
@@ -32,11 +30,10 @@ type podSelectorBuildCase struct {
 func TestBuild(t *testing.T) {
 	config := &Config{}
 	env := sys.NewFakeEnv()
-	fs := sys.NewFakeFS()
 	// NOTE(bacongobbler): there's a little easter egg here... ;)
 	sha := "0462cef5812ce31fe12f25596ff68dc614c708af"
 
-	tmpDir, err := ioutil.TempDir("", "tmpdir")
+	tmpDir, err := os.MkdirTemp("", "tmpdir")
 	if err != nil {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
@@ -49,44 +46,43 @@ func TestBuild(t *testing.T) {
 
 	config.GitHome = tmpDir
 
-	storageDriver, err := factory.Create("inmemory", nil)
+	storageDriver, err := factory.Create(context.Background(), "inmemory", nil)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if err := build(config, storageDriver, nil, fs, env, "foo", sha); err == nil {
+	if err := build(config, storageDriver, nil, env, sha); err == nil {
 		t.Error("expected running build() without setting config.ImagebuilderImagePullPolicy to fail")
 	}
 
 	config.ImagebuilderImagePullPolicy = "Always"
-	if err := build(config, storageDriver, nil, fs, env, "foo", sha); err == nil {
+	if err := build(config, storageDriver, nil, env, sha); err == nil {
 		t.Error("expected running build() without setting config.ImagebuilderImagePullPolicy to fail")
 	}
 
-	err = build(config, storageDriver, nil, fs, env, "foo", "abc123")
+	err = build(config, storageDriver, nil, env, "abc123")
 	expected := "git sha abc123 was invalid"
 	if err.Error() != expected {
 		t.Errorf("expected '%s', got '%v'", expected, err.Error())
 	}
 
-	if err := build(config, storageDriver, nil, fs, env, "foo", sha); err == nil {
+	if err := build(config, storageDriver, nil, env, sha); err == nil {
 		t.Error("expected running build() without valid controller client info to fail")
 	}
 
-	config.ControllerHost = "localhost"
-	config.ControllerPort = "1234"
+	config.ControllerURL = "http://localhost:1234"
 
-	if err := build(config, storageDriver, nil, fs, env, "foo", sha); err == nil {
+	if err := build(config, storageDriver, nil, env, sha); err == nil {
 		t.Error("expected running build() without a valid builder key to fail")
 	}
 
-	builderconf.BuilderKeyLocation = filepath.Join(tmpDir, "builder-key")
+	builderconf.ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := ioutil.WriteFile(builderconf.BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", builderconf.BuilderKeyLocation, err)
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0o644); err != nil {
+		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
-	if err := build(config, storageDriver, nil, fs, env, "foo", sha); err == nil {
+	if err := build(config, storageDriver, nil, env, sha); err == nil {
 		t.Error("expected running build() without a valid controller connection to fail")
 	}
 }
@@ -99,12 +95,12 @@ func TestRepoCmd(t *testing.T) {
 }
 
 func TestGetProcfileFromRepoSuccess(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "tmpdir")
+	tmpDir, err := os.MkdirTemp("", "tmpdir")
 	if err != nil {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 	data := []byte("web: example-go")
-	if err := ioutil.WriteFile(tmpDir+"/Procfile", data, 0644); err != nil {
+	if err := os.WriteFile(tmpDir+"/Procfile", data, 0o644); err != nil {
 		t.Fatalf("error creating %s/Procfile (%s)", tmpDir, err)
 	}
 	defer func() {
@@ -112,11 +108,7 @@ func TestGetProcfileFromRepoSuccess(t *testing.T) {
 			t.Fatalf("failed to remove Procfile from %s (%s)", tmpDir, err)
 		}
 	}()
-	config := api.Config{}
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "buildpack",
-	}
-	procType, err := getProcfile(tmpDir, getStack(tmpDir, config))
+	procType, err := getProcfile(tmpDir)
 	actualData := api.ProcessType{}
 	yaml.Unmarshal(data, &actualData)
 	assert.Equal(t, err, nil)
@@ -124,12 +116,12 @@ func TestGetProcfileFromRepoSuccess(t *testing.T) {
 }
 
 func TestGetProcfileFromRepoFailure(t *testing.T) {
-	tmpDir, err := ioutil.TempDir("", "tmpdir")
+	tmpDir, err := os.MkdirTemp("", "tmpdir")
 	if err != nil {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 	data := []byte("web= example-go")
-	if err := ioutil.WriteFile(tmpDir+"/Procfile", data, 0644); err != nil {
+	if err := os.WriteFile(tmpDir+"/Procfile", data, 0o644); err != nil {
 		t.Fatalf("error creating %s/Procfile (%s)", tmpDir, err)
 	}
 	defer func() {
@@ -137,38 +129,17 @@ func TestGetProcfileFromRepoFailure(t *testing.T) {
 			t.Fatalf("failed to remove Procfile from %s (%s)", tmpDir, err)
 		}
 	}()
-	config := api.Config{}
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "buildpack",
-	}
-	_, err = getProcfile(tmpDir, getStack(tmpDir, config))
+	_, err = getProcfile(tmpDir)
 
 	assert.True(t, err != nil, "no error received when there should have been")
 }
 
 func TestGetProcfileFromServerSuccess(t *testing.T) {
-	data := []byte("web: example-go")
-	tmpDir := os.TempDir()
-	config := api.Config{}
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "buildpack",
-	}
-
-	_, err := getProcfile("", getStack(tmpDir, config))
+	data := []byte("")
+	expect, _ := getProcfile("")
 	actualData := api.ProcessType{}
 	yaml.Unmarshal(data, &actualData)
-	assert.Error(t, err, fmt.Errorf("no Procfile can be matched in (%s)", ""))
-}
-
-func TestGetProcfileFromServerFailure(t *testing.T) {
-	tmpDir := os.TempDir()
-	config := api.Config{}
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "buildpack",
-	}
-	_, err := getProcfile("", getStack(tmpDir, config))
-	assert.Error(t, err, fmt.Errorf("no Procfile can be matched in (%s)", ""))
-	assert.True(t, err != nil, "no error received when there should have been")
+	assert.Equal(t, expect, actualData)
 }
 
 func TestPrettyPrintJSON(t *testing.T) {
diff --git a/pkg/gitreceive/build_type.go b/pkg/gitreceive/build_type.go
index 4231177..1c19dc3 100644
--- a/pkg/gitreceive/build_type.go
+++ b/pkg/gitreceive/build_type.go
@@ -3,7 +3,6 @@ package gitreceive
 import (
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"os"
 
 	"github.com/drycc/controller-sdk-go/api"
@@ -28,7 +27,7 @@ var Stacks []map[string]string
 
 // initStack load stack by config
 func initStack() error {
-	data, err := ioutil.ReadFile("/etc/imagebuilder/images.json")
+	data, err := os.ReadFile("/etc/imagebuilder/images.json")
 	if err == nil {
 		return json.Unmarshal(data, &Stacks)
 	}
@@ -42,13 +41,16 @@ func getStack(dirName string, config api.Config) map[string]string {
 	}
 	log.Debug("Stacks: %s", Stacks)
 	log.Debug("Config values %s", config.Values)
-	if stackInterface, ok := config.Values["DRYCC_STACK"]; ok {
-		if strStack, ok := stackInterface.(string); ok {
-			for _, stack := range Stacks {
-				if stack["name"] == strStack {
-					return stack
-				}
-			}
+	strStack := ""
+	for _, v := range config.Values {
+		if v.Group == "global" && v.Name == "DRYCC_STACK" {
+			strStack = v.Value.(string)
+		}
+	}
+
+	for _, stack := range Stacks {
+		if stack["name"] == strStack {
+			return stack
 		}
 	}
 
diff --git a/pkg/gitreceive/build_type_test.go b/pkg/gitreceive/build_type_test.go
index 515bf87..350984c 100644
--- a/pkg/gitreceive/build_type_test.go
+++ b/pkg/gitreceive/build_type_test.go
@@ -35,16 +35,28 @@ func TestGetStack(t *testing.T) {
 			t.Fatalf("failed to remove Procfile from %s (%s)", tmpDir, err)
 		}
 	}()
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "buildpack",
+	config.Values = []api.ConfigValue{
+		{
+			Group: "global",
+			ConfigVar: api.ConfigVar{
+				Name:  "DRYCC_STACK",
+				Value: "buildpack",
+			},
+		},
 	}
 	stack = getStack(tmpDir, config)
 	if stack["name"] != "buildpack" {
 		t.Fatalf("expected procfile build, got %s", stack)
 	}
 
-	config.Values = map[string]interface{}{
-		"DRYCC_STACK": "container",
+	config.Values = []api.ConfigValue{
+		{
+			Group: "global",
+			ConfigVar: api.ConfigVar{
+				Name:  "DRYCC_STACK",
+				Value: "container",
+			},
+		},
 	}
 	stack = getStack(tmpDir, config)
 	if stack["name"] != "container" {
diff --git a/pkg/gitreceive/config.go b/pkg/gitreceive/config.go
index c2f7340..8d4083d 100644
--- a/pkg/gitreceive/config.go
+++ b/pkg/gitreceive/config.go
@@ -13,10 +13,7 @@ const (
 // Config is the envconfig (http://github.com/kelseyhightower/envconfig) compatible struct for the
 // builder's git-receive hook.
 type Config struct {
-	// k8s service discovery env vars
-	ControllerHost string `envconfig:"DRYCC_CONTROLLER_API_SERVICE_HOST" required:"true"`
-	ControllerPort string `envconfig:"DRYCC_CONTROLLER_API_SERVICE_PORT" required:"true"`
-
+	ControllerURL                 string `envconfig:"DRYCC_CONTROLLER_URL" required:"true"`
 	GitHome                       string `envconfig:"GIT_HOME" required:"true"`
 	SSHConnection                 string `envconfig:"SSH_CONNECTION" required:"true"`
 	SSHOriginalCommand            string `envconfig:"SSH_ORIGINAL_COMMAND" required:"true"`
diff --git a/pkg/gitreceive/imagebuilder.go b/pkg/gitreceive/imagebuilder.go
index 115d6dc..46c19be 100644
--- a/pkg/gitreceive/imagebuilder.go
+++ b/pkg/gitreceive/imagebuilder.go
@@ -7,14 +7,12 @@ import (
 	"github.com/drycc/builder/pkg/sys"
 )
 
-var (
-	requiredEnvNames = []string{
-		"DRYCC_STORAGE_LOOKUP",
-		"DRYCC_STORAGE_BUCKET",
-		"DRYCC_STORAGE_ENDPOINT",
-		"DRYCC_REGISTRY_HOST",
-	}
-)
+var requiredEnvNames = []string{
+	"DRYCC_STORAGE_BUCKET",
+	"DRYCC_STORAGE_ENDPOINT",
+	"DRYCC_STORAGE_PATH_STYLE",
+	"DRYCC_REGISTRY_HOST",
+}
 
 func checkImagebuilderRequiredEnv(imagebuilderEnv map[string]string) error {
 	for index := range requiredEnvNames {
diff --git a/pkg/gitreceive/imagebuilder_test.go b/pkg/gitreceive/imagebuilder_test.go
index 28dcf2e..f498002 100644
--- a/pkg/gitreceive/imagebuilder_test.go
+++ b/pkg/gitreceive/imagebuilder_test.go
@@ -15,14 +15,14 @@ func TestGetImagebuilderEnvOffclusterErr(t *testing.T) {
 	}
 	env := sys.NewFakeEnv()
 	env.Envs = map[string]string{
-		"DRYCC_STORAGE_LOOKUP":    "path",
-		"DRYCC_STORAGE_BUCKET":    "builder",
-		"DRYCC_STORAGE_ENDPOINT":  "drycc-storage.drycc.svc.cluster.local",
-		"DRYCC_REGISTRY_LOCATION": "off-cluster",
+		"DRYCC_STORAGE_BUCKET":     "builder",
+		"DRYCC_STORAGE_ENDPOINT":   "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE": "true",
+		"DRYCC_REGISTRY_LOCATION":  "off-cluster",
 	}
 	_, err := getImagebuilderEnv(&image, config, env)
 	assert.Error(t, err, errors.New("the environment variable DRYCC_REGISTRY_HOST is required"))
-	env.Envs["DRYCC_REGISTRY_HOST"] = "drycc-registry.drycc.svc.cluster.local"
+	env.Envs["DRYCC_REGISTRY_HOST"] = "drycc-registry"
 	_, err = getImagebuilderEnv(&image, config, env)
 	assert.Error(t, err, errors.New("the environment variable DRYCC_REGISTRY_ORGANIZATION is required"))
 }
@@ -30,17 +30,17 @@ func TestGetImagebuilderEnvOffclusterErr(t *testing.T) {
 func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 	env := sys.NewFakeEnv()
 	env.Envs = map[string]string{
-		"DRYCC_STORAGE_LOOKUP":        "path",
 		"DRYCC_STORAGE_BUCKET":        "builder",
-		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage.drycc.svc.cluster.local",
+		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
 	}
 	expectedData := map[string]string{
-		"DRYCC_STORAGE_LOOKUP":        "path",
 		"DRYCC_STORAGE_BUCKET":        "builder",
-		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage.drycc.svc.cluster.local",
+		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
@@ -61,18 +61,18 @@ func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 func TestGetImagebuilderEnvOnclusterSuccess(t *testing.T) {
 	env := sys.NewFakeEnv()
 	env.Envs = map[string]string{
-		"DRYCC_STORAGE_LOOKUP":      "path",
 		"DRYCC_STORAGE_BUCKET":      "builder",
-		"DRYCC_STORAGE_ENDPOINT":    "drycc-storage.drycc.svc.cluster.local",
-		"DRYCC_REGISTRY_HOST":       "drycc-registry.drycc.svc.cluster.local",
+		"DRYCC_STORAGE_ENDPOINT":    "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE":  "true",
+		"DRYCC_REGISTRY_HOST":       "drycc-registry",
 		"DRYCC_REGISTRY_PROXY_HOST": "127.0.0.1:8000",
 		"DRYCC_REGISTRY_LOCATION":   "on-cluster",
 	}
 	expectedData := map[string]string{
-		"DRYCC_STORAGE_LOOKUP":        "path",
 		"DRYCC_STORAGE_BUCKET":        "builder",
-		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage.drycc.svc.cluster.local",
-		"DRYCC_REGISTRY_HOST":         "drycc-registry.drycc.svc.cluster.local",
+		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
+		"DRYCC_REGISTRY_HOST":         "drycc-registry",
 		"DRYCC_REGISTRY_LOCATION":     "on-cluster",
 		"DRYCC_REGISTRY_PROXY_HOST":   "127.0.0.1:8000",
 		"DRYCC_REGISTRY_ORGANIZATION": "python-getting-started",
diff --git a/pkg/gitreceive/k8s_util.go b/pkg/gitreceive/k8s_util.go
index 50a075a..bcab989 100644
--- a/pkg/gitreceive/k8s_util.go
+++ b/pkg/gitreceive/k8s_util.go
@@ -2,14 +2,14 @@ package gitreceive
 
 import (
 	"context"
-	"encoding/json"
 	"fmt"
 	"os"
 	"strconv"
 	"time"
 
 	"github.com/drycc/builder/pkg/k8s"
-	"github.com/pborman/uuid"
+	"github.com/drycc/controller-sdk-go/api"
+	"github.com/google/uuid"
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
 	apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -28,7 +28,7 @@ const (
 )
 
 func imagebuilderJobName(appName, shortSha string) string {
-	uid := uuid.New()[:8]
+	uid := uuid.New().String()[:8]
 	// NOTE(bacongobbler): pod names cannot exceed 63 characters in length, so we truncate
 	// the application name to stay under that limit when adding all the extra metadata to the name
 	if len(appName) > 33 {
@@ -41,7 +41,7 @@ func createBuilderJob(
 	debug bool,
 	name,
 	namespace string,
-	env map[string]interface{},
+	config []api.ConfigValue,
 	tarKey,
 	gitShortHash string,
 	imageName,
@@ -52,20 +52,7 @@ func createBuilderJob(
 	securityContext corev1.SecurityContext,
 	nodeSelector map[string]string,
 ) *batchv1.Job {
-
-	job := buildJob(debug, name, namespace, pullPolicy, securityContext, nodeSelector, env)
-
-	// inject application envvars as a special envvar which will be handled by imagebuilder to
-	// inject them as build-time variables.
-	// NOTE(bacongobbler): image-py takes buildargs as a json string in the form of
-	//
-	// {"KEY": "value"}
-	//
-	// So we need to translate the map into json.
-	if _, ok := env["DRYCC_DOCKER_BUILD_ARGS_ENABLED"]; ok {
-		imageBuildArgs, _ := json.Marshal(env)
-		addEnvToJob(job, "DOCKER_BUILD_ARGS", string(imageBuildArgs))
-	}
+	job := buildJob(debug, name, namespace, builderName, pullPolicy, securityContext, nodeSelector, config)
 	job.Spec.Template.Spec.Containers[0].Name = builderName
 	job.Spec.Template.Spec.Containers[0].Image = builderImage
 
@@ -87,12 +74,13 @@ func newInt32(i int32) *int32 {
 func buildJob(
 	debug bool,
 	name,
-	namespace string,
-	//pullPolicy api.PullPolicy,
+	namespace,
+	builderName string,
 	pullPolicy corev1.PullPolicy,
 	securityContext corev1.SecurityContext,
 	nodeSelector map[string]string,
-	env map[string]interface{}) batchv1.Job {
+	values []api.ConfigValue,
+) batchv1.Job {
 	TTLSecondsAfterFinished := newInt32(21600)
 	if os.Getenv("TTL_SECONDS_AFTER_FINISHED") != "" {
 		ttl, err := strconv.ParseInt(os.Getenv("TTL_SECONDS_AFTER_FINISHED"), 10, 32)
@@ -108,7 +96,9 @@ func buildJob(
 			Template: corev1.PodTemplateSpec{
 				ObjectMeta: metav1.ObjectMeta{
 					Labels: map[string]string{
-						"heritage": name,
+						"app":      builderName,
+						"job-name": name,
+						"heritage": "drycc",
 					},
 				},
 				Spec: corev1.PodSpec{
@@ -125,7 +115,9 @@ func buildJob(
 			Name:      name,
 			Namespace: namespace,
 			Labels: map[string]string{
-				"heritage": name,
+				"app":      builderName,
+				"job-name": name,
+				"heritage": "drycc",
 			},
 		},
 	}
@@ -151,10 +143,17 @@ func buildJob(
 	})
 
 	if len(job.Spec.Template.Spec.Containers) > 0 {
-		for k, v := range env {
+		cvs := []api.ConfigVar{}
+		// only take the value of the global group
+		for _, v := range values {
+			if v.Group == "global" {
+				cvs = append(cvs, v.ConfigVar)
+			}
+		}
+		for _, v := range cvs {
 			job.Spec.Template.Spec.Containers[0].Env = append(job.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{
-				Name:  k,
-				Value: fmt.Sprintf("%v", v),
+				Name:  v.Name,
+				Value: fmt.Sprintf("%v", v.Value),
 			})
 		}
 	}
@@ -180,7 +179,7 @@ func addEnvToJob(job batchv1.Job, key, value string) {
 }
 
 // waitForPod waits for a pod in state running, succeeded or failed
-func waitForPod(pw *k8s.PodWatcher, ns, podName string, ticker, interval, timeout time.Duration) error {
+func waitForPod(pw *k8s.PodWatcher, jobName string, ticker, interval, timeout time.Duration) error {
 	condition := func(pod *corev1.Pod) (bool, error) {
 		if pod.Status.Phase == corev1.PodRunning {
 			return true, nil
@@ -189,20 +188,20 @@ func waitForPod(pw *k8s.PodWatcher, ns, podName string, ticker, interval, timeou
 			return true, nil
 		}
 		if pod.Status.Phase == corev1.PodFailed {
-			return true, fmt.Errorf("Giving up; pod went into failed status: \n[%s]:%s", pod.Status.Reason, pod.Status.Message)
+			return true, fmt.Errorf("giving up; pod went into failed status: \n[%s]:%s", pod.Status.Reason, pod.Status.Message)
 		}
 		return false, nil
 	}
 
 	quit := progress("...", ticker)
-	err := waitForPodCondition(pw, ns, podName, condition, interval, timeout)
+	err := waitForPodCondition(pw, jobName, condition, interval, timeout)
 	quit <- true
 	<-quit
 	return err
 }
 
 // waitForPodEnd waits for a pod in state succeeded or failed
-func waitForPodEnd(pw *k8s.PodWatcher, ns, podName string, interval, timeout time.Duration) error {
+func waitForPodEnd(pw *k8s.PodWatcher, jobName string, interval, timeout time.Duration) error {
 	condition := func(pod *corev1.Pod) (bool, error) {
 		if pod.Status.Phase == corev1.PodSucceeded {
 			return true, nil
@@ -213,32 +212,35 @@ func waitForPodEnd(pw *k8s.PodWatcher, ns, podName string, interval, timeout tim
 		return false, nil
 	}
 
-	return waitForPodCondition(pw, ns, podName, condition, interval, timeout)
+	return waitForPodCondition(pw, jobName, condition, interval, timeout)
 }
 
 // waitForPodCondition waits for a pod in state defined by a condition (func)
-func waitForPodCondition(pw *k8s.PodWatcher, ns, podName string, condition func(pod *corev1.Pod) (bool, error),
-	interval, timeout time.Duration) error {
-	return wait.PollImmediate(interval, timeout, func() (bool, error) {
-		pods, err := pw.Store.List(labels.Set{"heritage": podName}.AsSelector())
+func waitForPodCondition(pw *k8s.PodWatcher, jobName string, condition func(pod *corev1.Pod) (bool, error),
+	interval, timeout time.Duration,
+) error {
+	return wait.PollUntilContextTimeout(context.Background(), interval, timeout, true, func(context.Context) (done bool, err error) {
+		selector := labels.Set{
+			"job-name": jobName,
+			"heritage": "drycc",
+		}.AsSelector()
+		pods, err := pw.Store.List(selector)
 		if err != nil || len(pods) == 0 {
 			return false, nil
 		}
-
-		done, err := condition(pods[0])
+		done, err = condition(pods[0])
 		if err != nil {
 			return false, err
 		}
 		if done {
 			return true, nil
 		}
-
 		return false, nil
 	})
 }
 
 func progress(msg string, interval time.Duration) chan bool {
-	tick := time.Tick(interval)
+	tick := time.NewTicker(interval)
 	quit := make(chan bool)
 	go func() {
 		for {
@@ -246,7 +248,7 @@ func progress(msg string, interval time.Duration) chan bool {
 			case <-quit:
 				close(quit)
 				return
-			case <-tick:
+			case <-tick.C:
 				fmt.Println(msg)
 			}
 		}
@@ -254,7 +256,7 @@ func progress(msg string, interval time.Duration) chan bool {
 	return quit
 }
 
-func createAppEnvConfigSecret(secretsClient typedcorev1.SecretInterface, secretName string, env map[string]interface{}) error {
+func createAppEnvConfigSecret(secretsClient typedcorev1.SecretInterface, secretName string, env map[string]any) error {
 	newSecret := new(corev1.Secret)
 	newSecret.Name = secretName
 	newSecret.Type = corev1.SecretTypeOpaque
diff --git a/pkg/gitreceive/k8s_util_test.go b/pkg/gitreceive/k8s_util_test.go
index 66c7ced..b4aa536 100644
--- a/pkg/gitreceive/k8s_util_test.go
+++ b/pkg/gitreceive/k8s_util_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 
 	"github.com/drycc/builder/pkg/k8s"
+	"github.com/drycc/controller-sdk-go/api"
 	"github.com/stretchr/testify/assert"
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
@@ -32,7 +33,7 @@ type imageBuildCase struct {
 	debug                       bool
 	name                        string
 	namespace                   string
-	env                         map[string]interface{}
+	env                         []api.ConfigValue
 	tarKey                      string
 	gitShortHash                string
 	imgName                     string
@@ -43,13 +44,17 @@ type imageBuildCase struct {
 }
 
 func TestBuildJob(t *testing.T) {
-	emptyEnv := make(map[string]interface{})
-
-	env := make(map[string]interface{})
-	env["KEY"] = "VALUE"
-	buildArgsEnv := make(map[string]interface{})
-	buildArgsEnv["DRYCC_DOCKER_BUILD_ARGS_ENABLED"] = "1"
-	buildArgsEnv["KEY"] = "VALUE"
+	emptyValues := []api.ConfigValue{}
+
+	values := []api.ConfigValue{
+		{
+			Group: "global",
+			ConfigVar: api.ConfigVar{
+				Name:  "KEY",
+				Value: "VALUE",
+			},
+		},
+	}
 	var job *batchv1.Job
 
 	emptyNodeSelector := make(map[string]string)
@@ -62,14 +67,13 @@ func TestBuildJob(t *testing.T) {
 	nodeSelector2["network"] = "fast"
 
 	imageBuilds := []imageBuildCase{
-		{true, "test", "default", emptyEnv, "tar", "deadbeef", "imagebuilder", "", "", corev1.PullAlways, nodeSelector1},
-		{true, "test", "default", env, "tar", "deadbeef", "", "imagebuilder", "", corev1.PullAlways, nodeSelector2},
-		{true, "test", "default", emptyEnv, "tar", "deadbeef", "img", "imagebuilder", "", corev1.PullAlways, emptyNodeSelector},
-		{true, "test", "default", env, "tar", "deadbeef", "img", "imagebuilder", "", corev1.PullAlways, emptyNodeSelector},
-		{true, "test", "default", env, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullAlways, emptyNodeSelector},
-		{true, "test", "default", env, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullIfNotPresent, emptyNodeSelector},
-		{true, "test", "default", env, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullNever, nil},
-		{true, "test", "default", buildArgsEnv, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullIfNotPresent, emptyNodeSelector},
+		{true, "test", "default", emptyValues, "tar", "deadbeef", "imagebuilder", "", "", corev1.PullAlways, nodeSelector1},
+		{true, "test", "default", values, "tar", "deadbeef", "", "imagebuilder", "", corev1.PullAlways, nodeSelector2},
+		{true, "test", "default", emptyValues, "tar", "deadbeef", "img", "imagebuilder", "", corev1.PullAlways, emptyNodeSelector},
+		{true, "test", "default", values, "tar", "deadbeef", "img", "imagebuilder", "", corev1.PullAlways, emptyNodeSelector},
+		{true, "test", "default", values, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullAlways, emptyNodeSelector},
+		{true, "test", "default", values, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullIfNotPresent, emptyNodeSelector},
+		{true, "test", "default", values, "tar", "deadbeef", "img", "imagebuilder", "customimage", corev1.PullNever, nil},
 	}
 	buildImageEnv := map[string]string{"DRYCC_REGISTRY_LOCATION": "on-cluster"}
 	for _, build := range imageBuilds {
@@ -89,20 +93,17 @@ func TestBuildJob(t *testing.T) {
 			build.builderPodNodeSelector,
 		)
 
-		if job.ObjectMeta.Name != build.name {
-			t.Errorf("expected %v but returned %v ", build.name, job.ObjectMeta.Name)
+		if job.Name != build.name {
+			t.Errorf("expected %v but returned %v ", build.name, job.Name)
 		}
-		if job.ObjectMeta.Namespace != build.namespace {
-			t.Errorf("expected %v but returned %v ", build.namespace, job.ObjectMeta.Namespace)
+		if job.Namespace != build.namespace {
+			t.Errorf("expected %v but returned %v ", build.namespace, job.Namespace)
 		}
 
 		checkForEnv(t, job, "SOURCE_VERSION", build.gitShortHash)
 		checkForEnv(t, job, "TAR_PATH", build.tarKey)
 		checkForEnv(t, job, "IMAGE_NAME", build.imgName)
 		checkForEnv(t, job, "DRYCC_REGISTRY_LOCATION", "on-cluster")
-		if _, ok := build.env["DRYCC_DOCKER_BUILD_ARGS_ENABLED"]; ok {
-			checkForEnv(t, job, "DOCKER_BUILD_ARGS", `{"DRYCC_DOCKER_BUILD_ARGS_ENABLED":"1","KEY":"VALUE"}`)
-		}
 		if build.imagebuilderImage != "" {
 			if job.Spec.Template.Spec.Containers[0].Image != build.imagebuilderImage {
 				t.Errorf("expected %v but returned %v", build.imagebuilderImage, job.Spec.Template.Spec.Containers[0].Image)
diff --git a/pkg/gitreceive/run.go b/pkg/gitreceive/run.go
index 50d71e6..7468006 100644
--- a/pkg/gitreceive/run.go
+++ b/pkg/gitreceive/run.go
@@ -7,11 +7,9 @@ import (
 	"strings"
 
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
-	builderconf "github.com/drycc/builder/pkg/conf"
+	"github.com/drycc/builder/pkg/k8s"
 	"github.com/drycc/builder/pkg/sys"
 	"github.com/drycc/pkg/log"
-
-	"github.com/drycc/builder/pkg/k8s"
 )
 
 func readLine(line string) (string, string, string, error) {
@@ -24,15 +22,9 @@ func readLine(line string) (string, string, string, error) {
 
 // Run runs the git-receive hook. This func is effectively the main for the git-receive hook,
 // although it is called from the main in boot.go.
-func Run(conf *Config, fs sys.FS, env sys.Env, storageDriver storagedriver.StorageDriver) error {
+func Run(conf *Config, env sys.Env, storageDriver storagedriver.StorageDriver) error {
 	log.Debug("Running git hook")
-
-	builderKey, err := builderconf.GetBuilderKey()
-	if err != nil {
-		return err
-	}
-
-	//kubeClient, err := client.NewInCluster()
+	// kubeClient, err := client.NewInCluster()
 	kubeClient, err := k8s.NewInCluster()
 	if err != nil {
 		return fmt.Errorf("couldn't reach the api server (%s)", err)
@@ -42,7 +34,6 @@ func Run(conf *Config, fs sys.FS, env sys.Env, storageDriver storagedriver.Stora
 	for scanner.Scan() {
 		line := scanner.Text()
 		oldRev, newRev, refName, err := readLine(line)
-
 		if err != nil {
 			return fmt.Errorf("reading STDIN (%s)", err)
 		}
@@ -51,11 +42,10 @@ func Run(conf *Config, fs sys.FS, env sys.Env, storageDriver storagedriver.Stora
 
 		// if we're processing a receive-pack on an existing repo, run a build
 		if strings.HasPrefix(conf.SSHOriginalCommand, "git-receive-pack") {
-			if err := build(conf, storageDriver, kubeClient, fs, env, builderKey, newRev); err != nil {
+			if err := build(conf, storageDriver, kubeClient, env, newRev); err != nil {
 				return err
 			}
 		}
 	}
-
 	return scanner.Err()
 }
diff --git a/pkg/gitreceive/run_test.go b/pkg/gitreceive/run_test.go
index 251169d..16af974 100644
--- a/pkg/gitreceive/run_test.go
+++ b/pkg/gitreceive/run_test.go
@@ -5,7 +5,7 @@ import (
 )
 
 func TestReadLine(t *testing.T) {
-	//readLine() expects a line with two spaces.
+	// readLine() expects a line with two spaces.
 	good := "foo bar car"
 	foo, bar, car, err := readLine(good)
 	if err != nil {
@@ -28,7 +28,7 @@ func TestReadLine(t *testing.T) {
 
 func TestRun(t *testing.T) {
 	// NOTE(bacongobbler): not much we can test at this time other than it fails based on bad setup
-	if err := Run(nil, nil, nil, nil); err == nil {
-		t.Errorf("expected error to be non-nil, got nil")
+	if err := Run(nil, nil, nil); err != nil {
+		t.Errorf("expected error to be nil, got %s", err)
 	}
 }
diff --git a/pkg/healthsrv/buckets_lister.go b/pkg/healthsrv/buckets_lister.go
index cdb60ae..433d9d0 100644
--- a/pkg/healthsrv/buckets_lister.go
+++ b/pkg/healthsrv/buckets_lister.go
@@ -1,8 +1,8 @@
+// Package healthsrv provides health check services for the builder.
 package healthsrv
 
 import (
 	"context"
-	//"github.com/distribution/distribution/v3/context"
 )
 
 // BucketLister is a *(github.com/distribution/distribution/v3/registry/storage/driver).StorageDriver compatible interface that provides just
diff --git a/pkg/healthsrv/circuit_state.go b/pkg/healthsrv/circuit_state.go
index 208425c..9d3b3b8 100644
--- a/pkg/healthsrv/circuit_state.go
+++ b/pkg/healthsrv/circuit_state.go
@@ -7,7 +7,9 @@ import (
 )
 
 // circuitState determines whether circ.State() == sshd.ClosedState, and sends the results back on
-//  the various given channels. This func is intended to be run in a goroutine and communicates
+//
+//	the various given channels. This func is intended to be run in a goroutine and communicates
+//
 // via the channels it's passed.
 //
 // If the circuit is closed, it passes an empty struct back on succCh. On failure, it sends an
diff --git a/pkg/healthsrv/healthz_handler.go b/pkg/healthsrv/healthz_handler.go
index f6e7fcb..1c4be34 100644
--- a/pkg/healthsrv/healthz_handler.go
+++ b/pkg/healthsrv/healthz_handler.go
@@ -13,7 +13,7 @@ const (
 )
 
 func healthZHandler(bLister BucketLister, serverCircuit *sshd.Circuit) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		stopCh := make(chan struct{})
 
 		numChecks := 0
diff --git a/pkg/healthsrv/healthz_handler_test.go b/pkg/healthsrv/healthz_handler_test.go
index a9d307a..ce134de 100644
--- a/pkg/healthsrv/healthz_handler_test.go
+++ b/pkg/healthsrv/healthz_handler_test.go
@@ -9,20 +9,16 @@ import (
 	"net/http/httptest"
 	"testing"
 
-	//"github.com/distribution/distribution/v3/context"
-
 	"github.com/drycc/builder/pkg/sshd"
 	drycc "github.com/drycc/controller-sdk-go"
 	"github.com/stretchr/testify/assert"
 )
 
-var (
-	errTest = errors.New("test error")
-)
+var errTest = errors.New("test error")
 
 type emptyBucketLister struct{}
 
-func (e emptyBucketLister) List(ctx context.Context, opath string) ([]string, error) {
+func (e emptyBucketLister) List(context.Context, string) ([]string, error) {
 	return nil, nil
 }
 
@@ -30,7 +26,7 @@ type errBucketLister struct {
 	err error
 }
 
-func (e errBucketLister) List(ctx context.Context, opath string) ([]string, error) {
+func (e errBucketLister) List(context.Context, string) ([]string, error) {
 	return nil, e.err
 }
 
diff --git a/pkg/healthsrv/namespace_lister.go b/pkg/healthsrv/namespace_lister.go
index 7258d2b..2491e0c 100644
--- a/pkg/healthsrv/namespace_lister.go
+++ b/pkg/healthsrv/namespace_lister.go
@@ -2,6 +2,7 @@ package healthsrv
 
 import (
 	"context"
+
 	corev1 "k8s.io/api/core/v1"
 	//"k8s.io/apimachinery/pkg/labels"
 	//"k8s.io/apimachinery/pkg/fields"
@@ -19,7 +20,7 @@ type NamespaceLister interface {
 
 type emptyNamespaceLister struct{}
 
-func (n emptyNamespaceLister) List(ctx context.Context, opts metav1.ListOptions) (*corev1.NamespaceList, error) {
+func (n emptyNamespaceLister) List(context.Context, metav1.ListOptions) (*corev1.NamespaceList, error) {
 	return &corev1.NamespaceList{}, nil
 }
 
@@ -27,7 +28,7 @@ type errNamespaceLister struct {
 	err error
 }
 
-func (e errNamespaceLister) List(ctx context.Context, opts metav1.ListOptions) (*corev1.NamespaceList, error) {
+func (e errNamespaceLister) List(context.Context, metav1.ListOptions) (*corev1.NamespaceList, error) {
 	return nil, e.err
 }
 
diff --git a/pkg/healthsrv/readiness_handler.go b/pkg/healthsrv/readiness_handler.go
index b8ad390..3765a5b 100644
--- a/pkg/healthsrv/readiness_handler.go
+++ b/pkg/healthsrv/readiness_handler.go
@@ -6,11 +6,11 @@ import (
 	"time"
 
 	drycc "github.com/drycc/controller-sdk-go"
-	"k8s.io/api/core/v1"
+	v1 "k8s.io/api/core/v1"
 )
 
 func readinessHandler(client *drycc.Client, nsLister NamespaceLister) http.Handler {
-	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+	return http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
 		stopCh := make(chan struct{})
 
 		numChecks := 0
diff --git a/pkg/healthsrv/server.go b/pkg/healthsrv/server.go
index 56cc356..3697ff4 100644
--- a/pkg/healthsrv/server.go
+++ b/pkg/healthsrv/server.go
@@ -12,7 +12,7 @@ import (
 // with the indicative error.
 func Start(cnf *sshd.Config, nsLister NamespaceLister, bLister BucketLister, sshServerCircuit *sshd.Circuit) error {
 	mux := http.NewServeMux()
-	client, err := controller.New(cnf.ControllerHost, cnf.ControllerPort)
+	client, err := controller.New(cnf.ControllerURL)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/k8s/client.go b/pkg/k8s/client.go
index 8984e00..d69ac60 100644
--- a/pkg/k8s/client.go
+++ b/pkg/k8s/client.go
@@ -1,3 +1,4 @@
+// Package k8s provides Kubernetes client utilities for the builder service.
 package k8s
 
 import (
@@ -5,6 +6,7 @@ import (
 	"k8s.io/client-go/rest"
 )
 
+// NewInCluster creates a new kubernetes clientset using the in-cluster configuration.
 func NewInCluster() (*kubernetes.Clientset, error) {
 	// creates the in-cluster config
 	config, err := rest.InClusterConfig()
diff --git a/pkg/k8s/namespace.go b/pkg/k8s/namespace.go
index ca5c53b..2d53806 100644
--- a/pkg/k8s/namespace.go
+++ b/pkg/k8s/namespace.go
@@ -2,6 +2,7 @@ package k8s
 
 import (
 	"context"
+
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
diff --git a/pkg/k8s/secrets.go b/pkg/k8s/secrets.go
index a956ed3..a24c415 100644
--- a/pkg/k8s/secrets.go
+++ b/pkg/k8s/secrets.go
@@ -4,7 +4,6 @@ import (
 	"context"
 
 	corev1 "k8s.io/api/core/v1"
-	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/watch"
@@ -17,52 +16,53 @@ import (
 // so you can unit test your code.
 type FakeSecret struct {
 	FnGet    func(string) (*corev1.Secret, error)
-	FnCreate func(*v1.Secret) (*corev1.Secret, error)
-	FnUpdate func(*v1.Secret) (*corev1.Secret, error)
+	FnCreate func(*corev1.Secret) (*corev1.Secret, error)
+	FnUpdate func(*corev1.Secret) (*corev1.Secret, error)
 }
 
 // Get is the interface definition.
-func (f *FakeSecret) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Secret, error) {
+func (f *FakeSecret) Get(_ context.Context, name string, _ metav1.GetOptions) (*corev1.Secret, error) {
 	return f.FnGet(name)
 }
 
 // Delete is the interface definition.
-func (f *FakeSecret) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
+func (f *FakeSecret) Delete(context.Context, string, metav1.DeleteOptions) error {
 	return nil
 }
 
 // Create is the interface definition.
-func (f *FakeSecret) Create(ctx context.Context, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) {
+func (f *FakeSecret) Create(_ context.Context, secret *corev1.Secret, _ metav1.CreateOptions) (*corev1.Secret, error) {
 	return f.FnCreate(secret)
 }
 
 // Update is the interface definition.
-func (f *FakeSecret) Update(ctx context.Context, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error) {
+func (f *FakeSecret) Update(_ context.Context, secret *corev1.Secret, _ metav1.UpdateOptions) (*corev1.Secret, error) {
 	return f.FnUpdate(secret)
 }
 
 // List is the interface definition.
-func (f *FakeSecret) List(ctx context.Context, opts metav1.ListOptions) (*v1.SecretList, error) {
-	return &v1.SecretList{}, nil
+func (f *FakeSecret) List(context.Context, metav1.ListOptions) (*corev1.SecretList, error) {
+	return &corev1.SecretList{}, nil
 }
 
 // Watch is the interface definition.
-func (f *FakeSecret) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) {
+func (f *FakeSecret) Watch(context.Context, metav1.ListOptions) (watch.Interface, error) {
 	return nil, nil
 }
 
 // DeleteCollection is the interface definition.
-func (f *FakeSecret) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error {
+func (f *FakeSecret) DeleteCollection(context.Context, metav1.DeleteOptions, metav1.ListOptions) error {
 	return nil
 }
 
 // Patch is the interface definition.
-func (f *FakeSecret) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (*v1.Secret, error) {
-	return &v1.Secret{}, nil
+func (f *FakeSecret) Patch(context.Context, string, types.PatchType, []byte, metav1.PatchOptions, ...string) (*corev1.Secret, error) {
+	return &corev1.Secret{}, nil
 }
 
-func (f *FakeSecret) Apply(ctx context.Context, secret *applyconfigurationscorev1.SecretApplyConfiguration, opts metav1.ApplyOptions) (result *v1.Secret, err error) {
-	return &v1.Secret{}, nil
+// Apply is the interface definition for applying a secret configuration.
+func (f *FakeSecret) Apply(context.Context, *applyconfigurationscorev1.SecretApplyConfiguration, metav1.ApplyOptions) (result *corev1.Secret, err error) {
+	return &corev1.Secret{}, nil
 }
 
 // FakeSecretsNamespacer is a mock function that can be swapped in for an
@@ -71,6 +71,8 @@ func (f *FakeSecret) Apply(ctx context.Context, secret *applyconfigurationscorev
 //	Fn func(string) typedcorev1.SecretInterface
 //}
 
+// FakeSecretsGetter is a mock function that can be swapped in for an
+// (k8s.io/kubernetes/pkg/client/unversioned).SecretsNamespacer, so you can unit test you code
 type FakeSecretsGetter struct {
 	Fn func(string) typedcorev1.SecretInterface
 }
diff --git a/pkg/k8s/watch.go b/pkg/k8s/watch.go
index fb57da6..fe2ae47 100644
--- a/pkg/k8s/watch.go
+++ b/pkg/k8s/watch.go
@@ -2,30 +2,28 @@ package k8s
 
 import (
 	"context"
-	"k8s.io/api/core/v1"
+
+	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/watch"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/tools/cache"
-	"time"
-)
-
-var (
-	resyncPeriod = 30 * time.Second
 )
 
+// StoreToPodLister is a wrapper around cache.Store that provides methods to list pods.
 type StoreToPodLister struct {
 	cache.Store
 }
 
-//PodWatcher is a struct which holds the return values of (k8s.io/kubernetes/pkg/controller/framework).NewIndexerInformer together.
+// PodWatcher is a struct which holds the return values of (k8s.io/kubernetes/pkg/controller/framework).NewIndexerInformer together.
 type PodWatcher struct {
 	Store      StoreToPodLister
 	Controller cache.Controller
 }
 
+// List returns a list of pods that match the given label selector.
 func (s *StoreToPodLister) List(selector labels.Selector) (pods []*v1.Pod, err error) {
 	// TODO: it'd be great to just call
 	// s.Pods(api.NamespaceAll).List(selector), however then we'd have to
@@ -40,31 +38,29 @@ func (s *StoreToPodLister) List(selector labels.Selector) (pods []*v1.Pod, err e
 	return pods, nil
 }
 
-//NewPodWatcher creates a new BuildPodWatcher useful to list the pods using a cache which gets updated based on the watch func.
+// NewPodWatcher creates a new BuildPodWatcher useful to list the pods using a cache which gets updated based on the watch func.
 func NewPodWatcher(c kubernetes.Clientset, ns string) *PodWatcher {
 	pw := &PodWatcher{}
 
-	pw.Store.Store, pw.Controller = cache.NewIndexerInformer(
-		&cache.ListWatch{
+	pw.Store.Store, pw.Controller = cache.NewInformerWithOptions(cache.InformerOptions{
+		ListerWatcher: &cache.ListWatch{
 			ListFunc:  podListFunc(c, ns),
 			WatchFunc: podWatchFunc(c, ns),
 		},
-		&v1.Pod{},
-		resyncPeriod,
-		cache.ResourceEventHandlerFuncs{},
-		cache.Indexers{},
-	)
+		ObjectType: &v1.Pod{},
+		Handler:    cache.ResourceEventHandlerFuncs{},
+	})
 	return pw
 }
 
 func podListFunc(c kubernetes.Clientset, ns string) func(options metav1.ListOptions) (runtime.Object, error) {
-	return func(opts metav1.ListOptions) (runtime.Object, error) {
+	return func(metav1.ListOptions) (runtime.Object, error) {
 		return c.CoreV1().Pods(ns).List(context.TODO(), metav1.ListOptions{})
 	}
 }
 
 func podWatchFunc(c kubernetes.Clientset, ns string) func(options metav1.ListOptions) (watch.Interface, error) {
-	return func(opts metav1.ListOptions) (watch.Interface, error) {
+	return func(metav1.ListOptions) (watch.Interface, error) {
 		return c.CoreV1().Pods(ns).Watch(context.TODO(), metav1.ListOptions{})
 	}
 }
diff --git a/pkg/sshd/circuit.go b/pkg/sshd/circuit.go
index 0b63372..0d7069f 100644
--- a/pkg/sshd/circuit.go
+++ b/pkg/sshd/circuit.go
@@ -17,11 +17,12 @@ const (
 
 // String is the fmt.Stringer interface implementation.
 func (c CircuitState) String() string {
-	if c == OpenState {
+	switch c {
+	case OpenState:
 		return "OPEN"
-	} else if c == ClosedState {
+	case ClosedState:
 		return "CLOSED"
-	} else {
+	default:
 		return fmt.Sprintf("Unknown (%d)", c.toUint32())
 	}
 }
diff --git a/pkg/sshd/circuit_test.go b/pkg/sshd/circuit_test.go
index 0d6a71d..43aeb6f 100644
--- a/pkg/sshd/circuit_test.go
+++ b/pkg/sshd/circuit_test.go
@@ -5,7 +5,6 @@ import (
 	"sync"
 	"sync/atomic"
 	"testing"
-	"time"
 )
 
 const (
@@ -13,7 +12,9 @@ const (
 )
 
 func init() {
-	rand.Seed(time.Now().UnixNano())
+	// rand.Seed is deprecated as of Go 1.20
+	// Programs that call Seed with a known value should use New(NewSource(seed))
+	// No need to seed for random values as of Go 1.20
 }
 
 func TestOpenCloseSerial(t *testing.T) {
@@ -41,7 +42,7 @@ func TestOpenCloseConcurrent(t *testing.T) {
 	state := uint32(0)
 	for i := 0; i < numConcurrents; i++ {
 		wg.Add(1)
-		go func(i int) {
+		go func(int) {
 			defer wg.Done()
 			r := rand.Int() % 2
 			if r == 0 {
diff --git a/pkg/sshd/config.go b/pkg/sshd/config.go
index f33acb2..8d245df 100644
--- a/pkg/sshd/config.go
+++ b/pkg/sshd/config.go
@@ -6,8 +6,7 @@ import (
 
 // Config represents the required SSH server configuration.
 type Config struct {
-	ControllerHost              string `envconfig:"DRYCC_CONTROLLER_API_SERVICE_HOST" required:"true"`
-	ControllerPort              string `envconfig:"DRYCC_CONTROLLER_API_SERVICE_PORT" required:"true"`
+	ControllerURL               string `envconfig:"DRYCC_CONTROLLER_URL" required:"true"`
 	SSHHostIP                   string `envconfig:"SSH_HOST_IP" default:"0.0.0.0" required:"true"`
 	SSHHostPort                 int    `envconfig:"SSH_HOST_PORT" default:"2223" required:"true"`
 	HealthSrvPort               int    `envconfig:"HEALTH_SERVER_PORT" default:"8092"`
@@ -22,7 +21,7 @@ func (c Config) CleanerPollSleepDuration() time.Duration {
 	return time.Duration(c.CleanerPollSleepDurationSec) * time.Second
 }
 
-//GitLockTimeout return LockTimeout in minutes
+// GitLockTimeout return LockTimeout in minutes
 func (c Config) GitLockTimeout() time.Duration {
 	return time.Duration(c.LockTimeout) * time.Minute
 }
diff --git a/pkg/sshd/lock.go b/pkg/sshd/lock.go
index ea01107..9623013 100644
--- a/pkg/sshd/lock.go
+++ b/pkg/sshd/lock.go
@@ -7,9 +7,7 @@ import (
 	"time"
 )
 
-var (
-	errAlreadyLocked = errors.New("already locked")
-)
+var errAlreadyLocked = errors.New("already locked")
 
 // RepositoryLock interface that allows the creation of a lock associated
 // with a repository name to avoid simultaneous git operations.
diff --git a/pkg/sshd/lock_test.go b/pkg/sshd/lock_test.go
index 6d10788..8a5e416 100644
--- a/pkg/sshd/lock_test.go
+++ b/pkg/sshd/lock_test.go
@@ -13,9 +13,7 @@ const (
 	callbackTimeout = 1 * time.Second
 )
 
-var (
-	errGitReceive = errors.New("git receive error")
-)
+var errGitReceive = errors.New("git receive error")
 
 func TestMultipleSameRepoLocks(t *testing.T) {
 	var wg sync.WaitGroup
@@ -45,7 +43,7 @@ func TestMultipleSameRepoLocks(t *testing.T) {
 func TestSingleLock(t *testing.T) {
 	rl := NewInMemoryRepositoryLock(0)
 	key := "fakeid"
-	callbackCh := make(chan interface{})
+	callbackCh := make(chan any)
 	go lockAndCallback(rl, key, callbackCh)
 	verifyCallbackHappens(t, callbackCh)
 }
@@ -53,7 +51,7 @@ func TestSingleLock(t *testing.T) {
 func TestSingleLockUnlock(t *testing.T) {
 	rl := NewInMemoryRepositoryLock(0)
 	key := "fakeid"
-	callbackCh := make(chan interface{})
+	callbackCh := make(chan any)
 	go lockAndCallback(rl, key, callbackCh)
 	verifyCallbackHappens(t, callbackCh)
 	err := rl.Unlock(key)
@@ -74,8 +72,8 @@ func TestInvalidUnlock(t *testing.T) {
 func TestDoubleLockUnlock(t *testing.T) {
 	rl := NewInMemoryRepositoryLock(0)
 	key := "fakeid"
-	callbackCh1stLock := make(chan interface{})
-	callbackCh2ndLock := make(chan interface{})
+	callbackCh1stLock := make(chan any)
+	callbackCh2ndLock := make(chan any)
 
 	go lockAndCallback(rl, key, callbackCh1stLock)
 	verifyCallbackHappens(t, callbackCh1stLock)
@@ -110,13 +108,13 @@ func TestWrapInLock(t *testing.T) {
 	}), nil)
 }
 
-func lockAndCallback(rl RepositoryLock, id string, callbackCh chan<- interface{}) {
+func lockAndCallback(rl RepositoryLock, id string, callbackCh chan<- any) {
 	if err := rl.Lock(id); err == nil {
 		callbackCh <- true
 	}
 }
 
-func verifyCallbackHappens(t *testing.T, callbackCh <-chan interface{}) bool {
+func verifyCallbackHappens(t *testing.T, callbackCh <-chan any) bool {
 	select {
 	case <-callbackCh:
 		return true
@@ -126,7 +124,7 @@ func verifyCallbackHappens(t *testing.T, callbackCh <-chan interface{}) bool {
 	}
 }
 
-func verifyCallbackDoesntHappens(t *testing.T, callbackCh <-chan interface{}) bool {
+func verifyCallbackDoesntHappens(t *testing.T, callbackCh <-chan any) bool {
 	select {
 	case <-callbackCh:
 		t.Fatalf("Unexpected callback.")
diff --git a/pkg/sshd/server.go b/pkg/sshd/server.go
index a7440e8..67e45cf 100644
--- a/pkg/sshd/server.go
+++ b/pkg/sshd/server.go
@@ -7,8 +7,8 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"net"
+	"os"
 	"strings"
 
 	"github.com/drycc/builder/pkg/controller"
@@ -29,14 +29,16 @@ const (
 	multiplePush string = "Another git push is ongoing"
 )
 
-var errBuildAppPerm = errors.New("user has no permission to build the app")
-var errDirPerm = errors.New("cannot change directory in file name")
-var errDirCreatePerm = errors.New("empty repo name")
+var (
+	errBuildAppPerm  = errors.New("user has no permission to build the app")
+	errDirPerm       = errors.New("cannot change directory in file name")
+	errDirCreatePerm = errors.New("empty repo name")
+)
 
 // AuthKey authenticates based on a public key.
 func AuthKey(key ssh.PublicKey, cnf *Config) (*ssh.Permissions, error) {
 	log.Info("Starting ssh authentication")
-	client, err := controller.New(cnf.ControllerHost, cnf.ControllerPort)
+	client, err := controller.New(cnf.ControllerURL)
 	if err != nil {
 		return nil, err
 	}
@@ -71,10 +73,11 @@ func AuthKey(key ssh.PublicKey, cnf *Config) (*ssh.Permissions, error) {
 // ConfigureServerSshConfig
 //
 // Returns:
-//  An *ssh.ServerConfig
+//
+//	An *ssh.ServerConfig
 func Configure(cnf *Config) (*ssh.ServerConfig, error) {
 	cfg := &ssh.ServerConfig{
-		PublicKeyCallback: func(m ssh.ConnMetadata, k ssh.PublicKey) (*ssh.Permissions, error) {
+		PublicKeyCallback: func(_ ssh.ConnMetadata, k ssh.PublicKey) (*ssh.Permissions, error) {
 			return AuthKey(k, cnf)
 		},
 	}
@@ -83,7 +86,7 @@ func Configure(cnf *Config) (*ssh.ServerConfig, error) {
 	for _, t := range hostKeyTypes {
 		path := fmt.Sprintf(pathTpl, t)
 
-		key, err := ioutil.ReadFile(path)
+		key, err := os.ReadFile(path)
 		if err != nil {
 			log.Debug("Failed to read key %s (skipping): %s", path, err)
 			return nil, err
@@ -96,7 +99,7 @@ func Configure(cnf *Config) (*ssh.ServerConfig, error) {
 		log.Debug("Parsed host key %s.", path)
 		cfg.AddHostKey(hk)
 	}
-	cfg.Config.Ciphers = []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com"}
+	cfg.Ciphers = []string{"aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com"}
 	return cfg, nil
 }
 
@@ -106,8 +109,8 @@ func Serve(
 	serverCircuit *Circuit,
 	gitHomeDir string,
 	concurrentPushLock RepositoryLock,
-	addr, receivetype string) error {
-
+	addr, receivetype string,
+) error {
 	listener, err := net.Listen("tcp", addr)
 	if err != nil {
 		return err
@@ -136,7 +139,6 @@ type server struct {
 // listen handles accepting and managing connections. However, since closer
 // is len(1), it will not block the sender.
 func (s *server) listen(l net.Listener, conf *ssh.ServerConfig) error {
-
 	log.Info("Accepting new connections.")
 	defer l.Close()
 
@@ -199,7 +201,7 @@ func sshConnection(conn net.Conn) string {
 }
 
 func sendExitStatus(status uint32, channel ssh.Channel) error {
-	exit := struct{ Status uint32 }{uint32(0)}
+	exit := struct{ Status uint32 }{uint32(status)}
 	_, err := channel.SendRequest("exit-status", false, ssh.Marshal(exit))
 	return err
 }
@@ -347,9 +349,8 @@ func cleanExec(pay []byte) string {
 // Returns the string PONG and exit status 0.
 //
 // Params:
-// 	- channel (ssh.Channel): The channel to respond on.
-// 	- request (*ssh.Request): The request.
-//
+//   - channel (ssh.Channel): The channel to respond on.
+//   - request (*ssh.Request): The request.
 func Ping(channel ssh.Channel, req *ssh.Request) error {
 	log.Info("PING")
 	if _, err := channel.Write([]byte("pong")); err != nil {
@@ -368,7 +369,7 @@ func cleanRepoName(name string) (string, error) {
 	if strings.Contains(name, "..") {
 		return "", errDirPerm
 	}
-	name = strings.Replace(name, "'", "", -1)
+	name = strings.ReplaceAll(name, "'", "")
 	return strings.TrimPrefix(strings.TrimSuffix(name, ".git"), "/"), nil
 }
 
diff --git a/pkg/sshd/server_test.go b/pkg/sshd/server_test.go
index 4dc32b6..0d88827 100644
--- a/pkg/sshd/server_test.go
+++ b/pkg/sshd/server_test.go
@@ -30,7 +30,7 @@ func TestGitPktLine(t *testing.T) {
 
 func serverConfigure() (*ssh.ServerConfig, error) {
 	cfg := &ssh.ServerConfig{
-		PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
+		PasswordCallback: func(ssh.ConnMetadata, []byte) (*ssh.Permissions, error) {
 			return mockAuthKey()
 		},
 	}
@@ -43,7 +43,7 @@ func clientConfig() *ssh.ClientConfig {
 		Auth: []ssh.AuthMethod{
 			ssh.Password("password"),
 		},
-		HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
+		HostKeyCallback: func(string, net.Addr, ssh.PublicKey) error {
 			return nil
 		},
 	}
@@ -106,7 +106,6 @@ func TestReceive(t *testing.T) {
 	if err := sess.Run("illegal command"); err == nil {
 		t.Fatalf("expected a failed run with command 'illegal command'")
 	}
-
 }
 
 // TestPushInvalidArgsLength tests trying to do a push with only the command, not the repo
@@ -245,9 +244,9 @@ func runServer(
 	c *Circuit,
 	pushLock RepositoryLock,
 	testAddr string,
-	handlerSleepDur time.Duration,
-	t *testing.T) {
-
+	_ time.Duration,
+	t *testing.T,
+) {
 	go func() {
 		if err := Serve(config, c, gitHome, pushLock, testAddr, "mock"); err != nil {
 			t.Errorf("Failed serving with %s", err)
@@ -266,8 +265,7 @@ func mockAuthKey() (*ssh.Permissions, error) {
 	return perm, nil
 }
 
-var (
-	testingHostKey = `-----BEGIN RSA PRIVATE KEY-----
+var testingHostKey = `-----BEGIN RSA PRIVATE KEY-----
 MIIEpAIBAAKCAQEA0xOK/wubqj+e4HNp+yAdK4WJnLZCvcjS2DwaxwF+E968kSeU
 27SOqiol7Y0UwLGLpB6rpIBnSqXo70xiMUSrnteKmMejddzfbGkvnyvo0dwE4nDd
 vnbz64I25xfjTldb4RtNvpk6ymr0soq0EEYssLmdnt7pIgHT71n9RNtu+RPpRe5n
@@ -295,4 +293,3 @@ v3+ZZfZMlci4pxBtXqrnoyj4uUoqZtR3ENLz53SN1i0vpT7DtC6gMnEF1UWiaoJ6
 6mGH5/bxCg9wpV7qpqR0EbFM/dhQFZmmnirOS8x+00hJvc1HFiuN/A==
 -----END RSA PRIVATE KEY-----
 `
-)
diff --git a/pkg/storage/image_repo.go b/pkg/storage/image_repo.go
index a4dd0cd..7960b56 100644
--- a/pkg/storage/image_repo.go
+++ b/pkg/storage/image_repo.go
@@ -1,15 +1,16 @@
+// Package storage provides image repository management functionality.
 package storage
 
 import (
+	"context"
+	"errors"
 	"fmt"
 
-	"github.com/aws/aws-sdk-go/aws"
-	"github.com/aws/aws-sdk-go/aws/awserr"
-	"github.com/aws/aws-sdk-go/aws/credentials"
-	"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
-	"github.com/aws/aws-sdk-go/aws/ec2metadata"
-	"github.com/aws/aws-sdk-go/aws/session"
-	"github.com/aws/aws-sdk-go/service/ecr"
+	"github.com/aws/aws-sdk-go-v2/aws"
+	"github.com/aws/aws-sdk-go-v2/config"
+	"github.com/aws/aws-sdk-go-v2/credentials"
+	"github.com/aws/aws-sdk-go-v2/service/ecr"
+	"github.com/aws/aws-sdk-go-v2/service/ecr/types"
 )
 
 // CreateImageRepo create a repository for the image on amazon's ECR(EC2 Container Repository)
@@ -32,32 +33,30 @@ func CreateImageRepo(reponame string, params map[string]string) error {
 	}
 	regionName, ok = params["region"]
 	if !ok || fmt.Sprint(regionName) == "" {
-		return fmt.Errorf("No region parameter provided")
+		return fmt.Errorf("no region parameter provided: %s", regionName)
 	}
 	region := fmt.Sprint(regionName)
-	creds := credentials.NewChainCredentials([]credentials.Provider{
-		&credentials.StaticProvider{
-			Value: credentials.Value{
-				AccessKeyID:     accessKey,
-				SecretAccessKey: secretKey,
-			},
-		},
-		&credentials.EnvProvider{},
-		&credentials.SharedCredentialsProvider{},
-		&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(session.New())},
-	})
-	awsConfig := aws.NewConfig()
-	awsConfig.WithCredentials(creds)
-	awsConfig.WithRegion(region)
-	svc := ecr.New(session.New(awsConfig))
 
+	ctx := context.Background()
+	cfg, err := config.LoadDefaultConfig(ctx,
+		config.WithRegion(region),
+		config.WithCredentialsProvider(
+			aws.NewCredentialsCache(
+				credentials.NewStaticCredentialsProvider(accessKey, secretKey, ""),
+			),
+		),
+	)
+	if err != nil {
+		return err
+	}
+
+	client := ecr.NewFromConfig(cfg)
 	repoInput := &ecr.CreateRepositoryInput{
 		RepositoryName: aws.String(reponame),
 	}
-
-	_, err := svc.CreateRepository(repoInput)
-	if err != nil {
-		if s3Err, ok := err.(awserr.Error); ok && s3Err.Code() == "RepositoryAlreadyExistsException" {
+	if _, err := client.CreateRepository(ctx, repoInput); err != nil {
+		var repoExistsErr *types.RepositoryAlreadyExistsException
+		if ok := errors.As(err, &repoExistsErr); ok {
 			return nil
 		}
 		return err
diff --git a/pkg/storage/interfaces.go b/pkg/storage/interfaces.go
index 09791e9..70b553f 100644
--- a/pkg/storage/interfaces.go
+++ b/pkg/storage/interfaces.go
@@ -2,7 +2,7 @@ package storage
 
 import (
 	"context"
-	//"github.com/distribution/distribution/v3/context"
+
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 )
 
diff --git a/pkg/storage/object.go b/pkg/storage/object.go
index be57837..12cac7e 100644
--- a/pkg/storage/object.go
+++ b/pkg/storage/object.go
@@ -1,11 +1,11 @@
 package storage
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"time"
 
-	"github.com/distribution/distribution/v3/context"
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 )
 
@@ -39,9 +39,8 @@ func WaitForObject(statter ObjectStatter, objKey string, tick, timeout time.Dura
 			return err
 		} else if exists {
 			return nil
-		} else {
-			return noExist
 		}
+		return noExist
 	}
 	if err := checker(); err == nil {
 		return nil
@@ -60,7 +59,7 @@ func WaitForObject(statter ObjectStatter, objKey string, tick, timeout time.Dura
 			if err := checker(); err == nil {
 				return nil
 			}
-			return fmt.Errorf("Object %s didn't exist after %s", objKey, timeout)
+			return fmt.Errorf("object %s didn't exist after %s", objKey, timeout)
 		}
 	}
 }
diff --git a/pkg/storage/object_test.go b/pkg/storage/object_test.go
index 71a1393..acd35ff 100644
--- a/pkg/storage/object_test.go
+++ b/pkg/storage/object_test.go
@@ -6,7 +6,6 @@ import (
 	"testing"
 	"time"
 
-	//"github.com/distribution/distribution/v3/context"
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 	"github.com/stretchr/testify/assert"
 )
diff --git a/pkg/sys/env.go b/pkg/sys/env.go
index 49165ca..568bbb9 100644
--- a/pkg/sys/env.go
+++ b/pkg/sys/env.go
@@ -1,3 +1,4 @@
+// Package sys provides system utilities for environment variable handling.
 package sys
 
 import (
@@ -52,6 +53,7 @@ func (f *FakeEnv) Get(name string) string {
 	return f.Envs[name]
 }
 
+// Environ returns a map of environment variables that match the given prefixes.
 func (f *FakeEnv) Environ(prefixs []string) map[string]string {
 	envs := make(map[string]string)
 	for key := range f.Envs {
diff --git a/pkg/sys/fs.go b/pkg/sys/fs.go
index 3d09f46..24b35fa 100644
--- a/pkg/sys/fs.go
+++ b/pkg/sys/fs.go
@@ -2,7 +2,6 @@ package sys
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 )
 
@@ -26,7 +25,7 @@ type realFS struct{}
 
 // ReadFile is the interface implementation for FS.
 func (r *realFS) ReadFile(name string) ([]byte, error) {
-	return ioutil.ReadFile(name)
+	return os.ReadFile(name)
 }
 
 // RemoveAll is the interface implementation for FS.
diff --git a/pkg/sys/fs_test.go b/pkg/sys/fs_test.go
index 5a6a35c..730a2b1 100644
--- a/pkg/sys/fs_test.go
+++ b/pkg/sys/fs_test.go
@@ -2,7 +2,6 @@ package sys
 
 import (
 	"fmt"
-	"io/ioutil"
 	"os"
 	"testing"
 )
@@ -18,7 +17,7 @@ func TestRealFS(t *testing.T) {
 		t.Error("expected to receive error when real file does not exist")
 	}
 
-	tmpfile, err := ioutil.TempFile("", testFilename)
+	tmpfile, err := os.CreateTemp("", testFilename)
 	if err != nil {
 		t.Fatal(err)
 	}
diff --git a/rootfs/README.md b/rootfs/README.md
index 42e6ceb..87d36ba 100644
--- a/rootfs/README.md
+++ b/rootfs/README.md
@@ -1,8 +1,8 @@
 # RootFS
 
 This directory stores all files that should be copied to the rootfs of a
-Docker container. The files should be stored according to the correct
-directory structure of the destination container. For example:
+container. The files should be stored according to the correct directory
+structure of the destination container. For example:
 
 ```
 rootfs/bin -> /bin
diff --git a/rootfs/bin/create_bucket b/rootfs/bin/create_bucket
index 0a58efe..addadaa 100644
--- a/rootfs/bin/create_bucket
+++ b/rootfs/bin/create_bucket
@@ -2,22 +2,18 @@
 
 set -e
 
-mc config host add storage \
-  "${DRYCC_STORAGE_ENDPOINT}" \
-  "${DRYCC_STORAGE_ACCESSKEY}" \
-  "${DRYCC_STORAGE_SECRETKEY}" \
-  --lookup "${DRYCC_STORAGE_LOOKUP}" \
-  --api s3v4
+mkdir -p ~/.config/rclone
+touch ~/.config/rclone/rclone.conf
+rclone config create storage s3 \
+  provider=Other \
+  access_key_id="${DRYCC_STORAGE_ACCESSKEY}" \
+  secret_access_key="${DRYCC_STORAGE_SECRETKEY}" \
+  endpoint="${DRYCC_STORAGE_ENDPOINT}" \
+  force_path_style="${DRYCC_STORAGE_PATH_STYLE:-true}" --no-output
 
-has_bucket(){
-    mc ls storage -json|jq -r '.key'|grep -w "${DRYCC_STORAGE_BUCKET}"
-}
-
-if  [ -z "$(has_bucket)" ] ;then
-    mc mb storage/"${DRYCC_STORAGE_BUCKET}"
-    if  [ -z "$(has_bucket)" ] ;then
-        echo "create bucket ${DRYCC_STORAGE_BUCKET} error"
-        exit 1
-    fi
+if ! rclone lsd storage: > /dev/null 2>&1; then
+  sleep 9s
+  echo "waiting for object storage to become ready..."
 fi
-echo "create bucket ${DRYCC_STORAGE_BUCKET} success"
+
+rclone mkdir "storage:${DRYCC_STORAGE_BUCKET}"
diff --git a/rootfs/docker-entrypoint.sh b/rootfs/container-entrypoint.sh
similarity index 100%
rename from rootfs/docker-entrypoint.sh
rename to rootfs/container-entrypoint.sh
diff --git a/testdata/bin/fake-k8s b/testdata/bin/fake-k8s
new file mode 100755
index 0000000..bd50573
--- /dev/null
+++ b/testdata/bin/fake-k8s
@@ -0,0 +1,33 @@
+#!/usr/bin/env bash
+#
+# This script is designed to be run inside the container
+#
+
+# fail hard and fast even on pipelines
+set -eou pipefail
+
+function fake_k8s_env() {
+    export KUBERNETES_SERVICE_HOST=10.43.0.1
+    export KUBERNETES_SERVICE_PORT=443
+    mkdir -p /var/run/secrets/kubernetes.io/serviceaccount
+    cat << EOF > "/var/run/secrets/kubernetes.io/serviceaccount/token"
+eyJhbGciOiJSUzI1NiIsImtpZCI6IlBrb1V6eGNRUWFfSEU3NG1lLWxZaUlnMUhEYnhnYWc1RXo2ZC1wOW4yMncifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzE4NzU1OTY2LCJpYXQiOjE2ODcyMTk5NjYsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkcnljYyIsInBvZCI6eyJuYW1lIjoiZHJ5Y2MtZGF0YWJhc2UtMiIsInVpZCI6IjljMDEzYjcwLTgzNmUtNDI2NC05OTMyLWM1NWY3ZTg2ODQyOSJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZHJ5Y2MtZGF0YWJhc2UiLCJ1aWQiOiI4MWVhNjM4ZC1jYjZhLTQ3YzYtYWRjMi1iODgzM2Q3NjMwNzYifSwid2FybmFmdGVyIjoxNjg3MjIzNTczfSwibmJmIjoxNjg3MjE5OTY2LCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZHJ5Y2M6ZHJ5Y2MtZGF0YWJhc2UifQ.fmSqpvSPHB9KUD1preXfp5MPE4WQrxDppFVD5EPyH_RskYRtrP8z4-ys0kaRcqf4tlsMovnBFgv9dvHWJGBxlowzXWWaaXwxEMCwwIjlLDEyTn2hazdmYINfB61xjvOq0EAUeZP3GKd_nPFqmCM21bs9mzvWQRAPCsis60o_DISbPaipxea-An1WPLysJH_saByx1qOCaAfwSROp8lUKX5db_-mpr2lAj-130UelVxa0umJ0BY0HA6jfeBLo_vRH4Y7-enKeY0Zce93zjYmZHgL7Lep3K4w0ja9uECiuIhcOyxYz-SYe1Hym4OSCuqJEP9kiyZ9B3irIDcyRCcRpKw
+EOF
+    cat << EOF > "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
+-----BEGIN CERTIFICATE-----
+MIIBdzCCAR2gAwIBAgIBADAKBggqhkjOPQQDAjAjMSEwHwYDVQQDDBhrM3Mtc2Vy
+dmVyLWNhQDE2ODU5MzE2NzcwHhcNMjMwNjA1MDIyMTE3WhcNMzMwNjAyMDIyMTE3
+WjAjMSEwHwYDVQQDDBhrM3Mtc2VydmVyLWNhQDE2ODU5MzE2NzcwWTATBgcqhkjO
+PQIBBggqhkjOPQMBBwNCAAR4ULHC4BX7Ss8BVBrrdcT7o57tc323jlLczUOxVQVo
+Q4LkoXY1EAKrjEaFu1HGo3Gr8GQ6d/ZJNzrTAWTGIo0ro0IwQDAOBgNVHQ8BAf8E
+BAMCAqQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUnPRP/O6bnrUeVknNFFUe
+Iw4ruF8wCgYIKoZIzj0EAwIDSAAwRQIgHjUAelTQCKoehiZM8c+RYyeJGKvjTB44
+W5RbH+np4T0CIQDCgnhCCPAWtS04DRR7nFog3ilH9bFoIj0g5tOTEVNfLg==
+-----END CERTIFICATE-----
+EOF
+}
+
+. init-stack
+fake_k8s_env
+
+"$@"
diff --git a/versioning.mk b/versioning.mk
index 2bfd999..8b30958 100644
--- a/versioning.mk
+++ b/versioning.mk
@@ -11,13 +11,13 @@ info:
 	@echo "Immutable tag:   ${IMAGE}"
 	@echo "Mutable tag:     ${MUTABLE_IMAGE}"
 
-.PHONY: docker-push
-docker-push: docker-immutable-push docker-mutable-push
+.PHONY: podman-push
+podman-push: podman-immutable-push podman-mutable-push
 
-.PHONY: docker-immutable-push
-docker-immutable-push:
-	docker push ${IMAGE}
+.PHONY: podman-immutable-push
+podman-immutable-push:
+	podman push ${IMAGE}
 
-.PHONY: docker-mutable-push
-docker-mutable-push:
-	docker push ${MUTABLE_IMAGE}
+.PHONY: podman-mutable-push
+podman-mutable-push:
+	podman push ${MUTABLE_IMAGE}
