From 303b79193ec28ed38f9060f2c1d40b9fce7ce265 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Wed, 25 Jun 2025 13:13:18 +0800
Subject: [PATCH 01/13] chore(builder): use service key

---
 charts/builder/templates/_helpers.tpl         |  5 ----
 .../builder-controller-secret-key-auth.yaml   |  9 ------
 .../builder/templates/builder-deployment.yaml | 28 +++++++++----------
 go.mod                                        |  2 +-
 go.sum                                        |  4 +--
 pkg/conf/config.go                            | 16 +++++------
 pkg/conf/config_test.go                       | 14 +++++-----
 pkg/controller/utils.go                       |  4 +--
 pkg/controller/utils_test.go                  | 10 +++----
 pkg/gitreceive/build_test.go                  |  6 ++--
 10 files changed, 42 insertions(+), 56 deletions(-)
 delete mode 100644 charts/builder/templates/builder-controller-secret-key-auth.yaml

diff --git a/charts/builder/templates/_helpers.tpl b/charts/builder/templates/_helpers.tpl
index 5be18ff..4dd1080 100644
--- a/charts/builder/templates/_helpers.tpl
+++ b/charts/builder/templates/_helpers.tpl
@@ -20,11 +20,6 @@ env:
   valueFrom:
     fieldRef:
       fieldPath: metadata.namespace
-- name: DRYCC_BUILDER_KEY
-  valueFrom:
-    secretKeyRef:
-      name: builder-key-auth
-      key: builder-key
 {{- if (.Values.storageEndpoint) }}
 - name: "DRYCC_STORAGE_LOOKUP"
   valueFrom:
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 cbc705a..0000000
--- a/charts/builder/templates/builder-controller-secret-key-auth.yaml
+++ /dev/null
@@ -1,9 +0,0 @@
-apiVersion: v1
-kind: Secret
-metadata:
-  name: builder-key-auth
-  labels:
-    heritage: drycc
-type: Opaque
-data:
-  builder-key: {{ include "common.secrets.lookup" (dict "secret" "builder-key-auth" "key" "builder-key" "defaultValue" (randAlphaNum 64) "context" $) }}
\ No newline at end of file
diff --git a/charts/builder/templates/builder-deployment.yaml b/charts/builder/templates/builder-deployment.yaml
index 1ca2c45..c36b789 100644
--- a/charts/builder/templates/builder-deployment.yaml
+++ b/charts/builder/templates/builder-deployment.yaml
@@ -71,22 +71,22 @@ spec:
           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/go.mod b/go.mod
index 87426b8..9710ec9 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.24
 require (
 	github.com/aws/aws-sdk-go v1.55.6
 	github.com/distribution/distribution/v3 v3.0.0
-	github.com/drycc/controller-sdk-go v0.0.0-20250326034724-1dafccaadf6b
+	github.com/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be
 	github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f
 	github.com/google/uuid v1.6.0
 	github.com/kelseyhightower/envconfig v1.4.0
diff --git a/go.sum b/go.sum
index bc8a2f3..acb0e98 100644
--- a/go.sum
+++ b/go.sum
@@ -20,8 +20,8 @@ github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN
 github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
 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/drycc/controller-sdk-go v0.0.0-20250326034724-1dafccaadf6b h1:IA4sT1t/x/JtUm6F6T7j66ETAXwikYaUuNoQMmVp5ew=
-github.com/drycc/controller-sdk-go v0.0.0-20250326034724-1dafccaadf6b/go.mod h1:m4nhGeLJvR9bWuF12XhJ1c+hvkVY27OPN48F3l+AvAI=
+github.com/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be h1:aIdgIpvYa6SuPQIV3C3UKNItMaTK3YDxP0sRlfrYSUE=
+github.com/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be/go.mod h1:MbFxGlgRQUaVlThbn3DmB06EJsf+e3/O+qgbWmdvtoE=
 github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f h1:/OV4bY2yQDu0mg3l5wdJG6d2tal1hbSX+uI5eiQBQ4o=
 github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f/go.mod h1:Ss0KonBbfmUVv4bdL+8QAhLtzuBik7DS5tJTMAhycaI=
 github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index b10f805..2298f78 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -18,20 +18,20 @@ const (
 	storageSecretkeyEnvVar = "DRYCC_STORAGE_SECRETKEY"
 )
 
-// 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{}
 
-// GetBuilderKey returns the key to be used as token to interact with drycc-controller
-func GetBuilderKey() (string, error) {
-	builderKeyBytes, err := os.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.Trim(string(serviceKeyBytes), "\n")
+	return serviceKey, nil
 }
 
 // GetStorageParams returns the credentials required for connecting to object storage
diff --git a/pkg/conf/config_test.go b/pkg/conf/config_test.go
index 84ba79e..e617e02 100644
--- a/pkg/conf/config_test.go
+++ b/pkg/conf/config_test.go
@@ -39,22 +39,22 @@ func TestGetControllerClient(t *testing.T) {
 
 	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 := os.WriteFile(BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", BuilderKeyLocation, err)
+	if err := os.WriteFile(ServiceKeyLocation, data, 0644); 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..dcec861 100644
--- a/pkg/controller/utils.go
+++ b/pkg/controller/utils.go
@@ -17,11 +17,11 @@ func New(host, port string) (*drycc.Client, error) {
 	}
 	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 96ede6b..94fdd40 100644
--- a/pkg/controller/utils_test.go
+++ b/pkg/controller/utils_test.go
@@ -21,14 +21,14 @@ func TestNew(t *testing.T) {
 
 	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 := os.WriteFile(builderconf.BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", builderconf.BuilderKeyLocation, err)
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0644); err != nil {
+		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
 	host := "127.0.0.1"
@@ -36,7 +36,7 @@ func TestNew(t *testing.T) {
 	cli, err := New(host, port)
 	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.ServiceKey, string(data), "data")
 	assert.Equal(t, cli.UserAgent, "drycc-builder", "user-agent")
 
 	port = "invalid-port-number"
diff --git a/pkg/gitreceive/build_test.go b/pkg/gitreceive/build_test.go
index 68498db..3d9a75c 100644
--- a/pkg/gitreceive/build_test.go
+++ b/pkg/gitreceive/build_test.go
@@ -77,10 +77,10 @@ func TestBuild(t *testing.T) {
 		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 := os.WriteFile(builderconf.BuilderKeyLocation, data, 0644); err != nil {
-		t.Fatalf("error creating %s (%s)", builderconf.BuilderKeyLocation, err)
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0644); err != nil {
+		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
 	if err := build(config, storageDriver, nil, env, sha); err == nil {

From bd9bc6ff49797469791b282ec04c63421266bcd8 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Fri, 11 Jul 2025 10:45:47 +0800
Subject: [PATCH 02/13] chore(builder): add --ignore-existing bucket

---
 rootfs/bin/create_bucket | 15 +--------------
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/rootfs/bin/create_bucket b/rootfs/bin/create_bucket
index e8f79fe..7c0cdc0 100644
--- a/rootfs/bin/create_bucket
+++ b/rootfs/bin/create_bucket
@@ -8,18 +8,5 @@ mc config host add storage \
   "${DRYCC_STORAGE_SECRETKEY}" \
   --lookup "${DRYCC_STORAGE_LOOKUP}" \
   --api s3v4
-
-has_bucket(){
-    mc ls storage -json|jq -r '.key'|grep -w "${DRYCC_STORAGE_BUCKET}"
-}
-
 mc ping storage -x
-
-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
-fi
-echo "create bucket ${DRYCC_STORAGE_BUCKET} success"
+mc mb --ignore-existing storage/"${DRYCC_STORAGE_BUCKET}"

From 63c1071ad64e5c41d9b10c061479f7ba570125c8 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Tue, 15 Jul 2025 22:02:51 +0800
Subject: [PATCH 03/13] chore(builder): simplify the connection controller

---
 charts/builder/templates/_helpers.tpl           |  7 ++++---
 .../builder/templates/builder-deployment.yaml   |  4 +---
 pkg/controller/utils.go                         |  6 ++----
 pkg/controller/utils_test.go                    | 17 +++++++----------
 pkg/gitreceive/build.go                         |  2 +-
 pkg/gitreceive/build_test.go                    |  3 +--
 pkg/gitreceive/config.go                        |  5 +----
 pkg/gitreceive/imagebuilder_test.go             | 16 ++++++++--------
 pkg/healthsrv/server.go                         |  2 +-
 pkg/sshd/config.go                              |  3 +--
 pkg/sshd/server.go                              |  2 +-
 11 files changed, 28 insertions(+), 39 deletions(-)

diff --git a/charts/builder/templates/_helpers.tpl b/charts/builder/templates/_helpers.tpl
index 4dd1080..a96001a 100644
--- a/charts/builder/templates/_helpers.tpl
+++ b/charts/builder/templates/_helpers.tpl
@@ -20,6 +20,8 @@ env:
   valueFrom:
     fieldRef:
       fieldPath: metadata.namespace
+- name: "DRYCC_CONTROLLER_URL"
+  value: http://drycc-controller-api
 {{- if (.Values.storageEndpoint) }}
 - name: "DRYCC_STORAGE_LOOKUP"
   valueFrom:
@@ -52,7 +54,7 @@ env:
 - name: "DRYCC_STORAGE_BUCKET"
   value: "builder"
 - name: "DRYCC_STORAGE_ENDPOINT"
-  value: {{ printf "http://drycc-storage.%s.svc.%s:9000" .Release.Namespace .Values.global.clusterDomain }}
+  value: http://drycc-storage:9000
 - name: "DRYCC_STORAGE_ACCESSKEY"
   valueFrom:
     secretKeyRef:
@@ -89,7 +91,7 @@ env:
       key: registry-organization
 {{- else if .Values.registry.enabled  }}
 - name: "DRYCC_REGISTRY_HOST"
-  value: {{ printf "drycc-registry.%s.svc.%s:5000" .Release.Namespace .Values.global.clusterDomain }}
+  value: drycc-registry:5000
 - name: "DRYCC_REGISTRY_PROXY_HOST"
   value: {{ print "127.0.0.1"  ":" .Values.registry.proxy.port }}
 - name: "DRYCC_REGISTRY_USERNAME"
@@ -103,7 +105,6 @@ env:
       name: registry-secret
       key: password
 {{- end }}
-
 {{- if (.Values.builderPodNodeSelector) }}
 - name: BUILDER_POD_NODE_SELECTOR
   value: {{.Values.builderPodNodeSelector}}
diff --git a/charts/builder/templates/builder-deployment.yaml b/charts/builder/templates/builder-deployment.yaml
index c36b789..0d6ed8e 100644
--- a/charts/builder/templates/builder-deployment.yaml
+++ b/charts/builder/templates/builder-deployment.yaml
@@ -34,9 +34,7 @@ spec:
           - netcat
           - -v
           - -u
-          - $(DRYCC_STORAGE_ENDPOINT)
-          - -a
-          - $(DRYCC_CONTROLLER_API_SERVICE_HOST):$(DRYCC_CONTROLLER_API_SERVICE_PORT)
+          - $(DRYCC_STORAGE_ENDPOINT),$(DRYCC_CONTROLLER_URL)
         {{- include "builder.envs" . | indent 8 }}
       containers:
       - name: drycc-builder
diff --git a/pkg/controller/utils.go b/pkg/controller/utils.go
index dcec861..1af5bf0 100644
--- a/pkg/controller/utils.go
+++ b/pkg/controller/utils.go
@@ -1,17 +1,15 @@
 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) {
+func New(url string) (*drycc.Client, error) {
 
-	client, err := drycc.New(true, fmt.Sprintf("http://%s:%s/", host, port), "")
+	client, err := drycc.New(true, url, "")
 	if err != nil {
 		return client, err
 	}
diff --git a/pkg/controller/utils_test.go b/pkg/controller/utils_test.go
index 94fdd40..6b288e0 100644
--- a/pkg/controller/utils_test.go
+++ b/pkg/controller/utils_test.go
@@ -2,7 +2,6 @@ package controller
 
 import (
 	"errors"
-	"fmt"
 	"os"
 	"path/filepath"
 	"testing"
@@ -31,24 +30,22 @@ func TestNew(t *testing.T) {
 		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.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/gitreceive/build.go b/pkg/gitreceive/build.go
index a943847..bca542b 100644
--- a/pkg/gitreceive/build.go
+++ b/pkg/gitreceive/build.go
@@ -90,7 +90,7 @@ func build(
 		}
 	}()
 
-	client, err := controller.New(conf.ControllerHost, conf.ControllerPort)
+	client, err := controller.New(conf.ControllerURL)
 	if err != nil {
 		return err
 	}
diff --git a/pkg/gitreceive/build_test.go b/pkg/gitreceive/build_test.go
index 3d9a75c..543a9f4 100644
--- a/pkg/gitreceive/build_test.go
+++ b/pkg/gitreceive/build_test.go
@@ -70,8 +70,7 @@ func TestBuild(t *testing.T) {
 		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, env, sha); err == nil {
 		t.Error("expected running build() without a valid builder key to fail")
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_test.go b/pkg/gitreceive/imagebuilder_test.go
index 28dcf2e..c6db989 100644
--- a/pkg/gitreceive/imagebuilder_test.go
+++ b/pkg/gitreceive/imagebuilder_test.go
@@ -17,12 +17,12 @@ func TestGetImagebuilderEnvOffclusterErr(t *testing.T) {
 	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_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"))
 }
@@ -32,7 +32,7 @@ func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 	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_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
@@ -40,7 +40,7 @@ func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 	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_REGISTRY_LOCATION":     "off-cluster",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
@@ -63,16 +63,16 @@ func TestGetImagebuilderEnvOnclusterSuccess(t *testing.T) {
 	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_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_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/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/sshd/config.go b/pkg/sshd/config.go
index 9616013..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"`
diff --git a/pkg/sshd/server.go b/pkg/sshd/server.go
index 150e51d..c66155c 100644
--- a/pkg/sshd/server.go
+++ b/pkg/sshd/server.go
@@ -36,7 +36,7 @@ var 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
 	}

From 1684d296c63628872b1f0efe74f0d4a8109fac65 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Thu, 17 Jul 2025 17:10:38 +0800
Subject: [PATCH 04/13] chore(build): remove git gc

---
 pkg/gitreceive/build.go | 2 --
 1 file changed, 2 deletions(-)

diff --git a/pkg/gitreceive/build.go b/pkg/gitreceive/build.go
index bca542b..6585a3f 100644
--- a/pkg/gitreceive/build.go
+++ b/pkg/gitreceive/build.go
@@ -273,8 +273,6 @@ func build(
 	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
 }
 

From 405090db635c286cef44942618c3a534a6759dfb Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Tue, 22 Jul 2025 10:25:19 +0800
Subject: [PATCH 05/13] chore(storage): use path style replace lookup

---
 charts/builder/templates/_helpers.tpl        | 14 +++++++-------
 charts/builder/templates/builder-secret.yaml |  2 +-
 charts/builder/values.yaml                   |  2 +-
 pkg/conf/config.go                           |  4 ++--
 pkg/conf/config_test.go                      | 10 +++++-----
 pkg/gitreceive/imagebuilder.go               |  2 +-
 pkg/gitreceive/imagebuilder_test.go          | 17 +++++++++--------
 rootfs/bin/create_bucket                     |  6 +++---
 8 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/charts/builder/templates/_helpers.tpl b/charts/builder/templates/_helpers.tpl
index a96001a..6391e76 100644
--- a/charts/builder/templates/_helpers.tpl
+++ b/charts/builder/templates/_helpers.tpl
@@ -23,11 +23,6 @@ env:
 - name: "DRYCC_CONTROLLER_URL"
   value: http://drycc-controller-api
 {{- if (.Values.storageEndpoint) }}
-- name: "DRYCC_STORAGE_LOOKUP"
-  valueFrom:
-    secretKeyRef:
-      name: builder-secret
-      key: storage-lookup
 - name: "DRYCC_STORAGE_BUCKET"
   valueFrom:
     secretKeyRef:
@@ -48,9 +43,12 @@ env:
     secretKeyRef:
       name: builder-secret
       key: storage-secretkey
+- name: "DRYCC_STORAGE_PATH_STYLE"
+  valueFrom:
+    secretKeyRef:
+      name: builder-secret
+      key: storage-path-style
 {{- else if .Values.storage.enabled  }}
-- name: "DRYCC_STORAGE_LOOKUP"
-  value: "path"
 - name: "DRYCC_STORAGE_BUCKET"
   value: "builder"
 - name: "DRYCC_STORAGE_ENDPOINT"
@@ -65,6 +63,8 @@ env:
     secretKeyRef:
       name: storage-creds
       key: secretkey
+- name: "DRYCC_STORAGE_PATH_STYLE"
+  value: "on"
 {{- end }}
 - name: "DRYCC_REGISTRY_LOCATION"
   value: {{ ternary "on-cluster" "off-cluster" .Values.registry.enabled }}
diff --git a/charts/builder/templates/builder-secret.yaml b/charts/builder/templates/builder-secret.yaml
index 4a0fbc9..501beb1 100644
--- a/charts/builder/templates/builder-secret.yaml
+++ b/charts/builder/templates/builder-secret.yaml
@@ -13,9 +13,9 @@ data:
   registry-organization: {{ .Values.registryOrganization | b64enc }}
   {{- end }}
   {{- if (.Values.storageEndpoint) }}
-  storage-lookup: {{ .Values.storageLookup | b64enc }}
   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/values.yaml b/charts/builder/values.yaml
index 12ce6bc..b24bdf7 100644
--- a/charts/builder/values.yaml
+++ b/charts/builder/values.yaml
@@ -57,11 +57,11 @@ podAntiAffinityPreset:
 ttlSecondsAfterFinished: 21600
 
 # The following parameters will no longer use the built-in storage component.
-storageLookup: "auto"
 storageBucket: "registry"
 storageEndpoint: ""
 storageAccesskey: ""
 storageSecretkey: ""
+storagePathStyle: "auto"
 
 # The following parameters will no longer use the built-in registry component.
 registryHost: ""
diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index 2298f78..aba7d93 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -11,11 +11,11 @@ import (
 )
 
 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"
 )
 
 // ServiceKeyLocation holds the path of the service key secret.
@@ -51,7 +51,7 @@ 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) == "on" {
 		params["forcepathstyle"] = "true"
 	}
 
diff --git a/pkg/conf/config_test.go b/pkg/conf/config_test.go
index e617e02..2163cf0 100644
--- a/pkg/conf/config_test.go
+++ b/pkg/conf/config_test.go
@@ -13,11 +13,11 @@ 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": "on",
 	}
 	params, err := GetStorageParams(env)
 	if err != nil {
diff --git a/pkg/gitreceive/imagebuilder.go b/pkg/gitreceive/imagebuilder.go
index 115d6dc..fa8a55c 100644
--- a/pkg/gitreceive/imagebuilder.go
+++ b/pkg/gitreceive/imagebuilder.go
@@ -9,9 +9,9 @@ import (
 
 var (
 	requiredEnvNames = []string{
-		"DRYCC_STORAGE_LOOKUP",
 		"DRYCC_STORAGE_BUCKET",
 		"DRYCC_STORAGE_ENDPOINT",
+		"DRYCC_STORAGE_PATH_STYLE",
 		"DRYCC_REGISTRY_HOST",
 	}
 )
diff --git a/pkg/gitreceive/imagebuilder_test.go b/pkg/gitreceive/imagebuilder_test.go
index c6db989..d3d8dea 100644
--- a/pkg/gitreceive/imagebuilder_test.go
+++ b/pkg/gitreceive/imagebuilder_test.go
@@ -15,10 +15,10 @@ 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_REGISTRY_LOCATION": "off-cluster",
+		"DRYCC_STORAGE_BUCKET":     "builder",
+		"DRYCC_STORAGE_ENDPOINT":   "drycc-storage",
+		"DRYCC_STORAGE_PATH_STYLE": "auto",
+		"DRYCC_REGISTRY_LOCATION":  "off-cluster",
 	}
 	_, err := getImagebuilderEnv(&image, config, env)
 	assert.Error(t, err, errors.New("the environment variable DRYCC_REGISTRY_HOST 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_STORAGE_PATH_STYLE":    "auto",
 		"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_STORAGE_PATH_STYLE":    "auto",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
@@ -61,17 +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_STORAGE_PATH_STYLE":  "auto",
 		"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_STORAGE_PATH_STYLE":    "auto",
 		"DRYCC_REGISTRY_HOST":         "drycc-registry",
 		"DRYCC_REGISTRY_LOCATION":     "on-cluster",
 		"DRYCC_REGISTRY_PROXY_HOST":   "127.0.0.1:8000",
diff --git a/rootfs/bin/create_bucket b/rootfs/bin/create_bucket
index 7c0cdc0..e650b9a 100644
--- a/rootfs/bin/create_bucket
+++ b/rootfs/bin/create_bucket
@@ -2,11 +2,11 @@
 
 set -e
 
-mc config host add storage \
+mc alias set storage \
   "${DRYCC_STORAGE_ENDPOINT}" \
   "${DRYCC_STORAGE_ACCESSKEY}" \
   "${DRYCC_STORAGE_SECRETKEY}" \
-  --lookup "${DRYCC_STORAGE_LOOKUP}" \
-  --api s3v4
+  --path "${DRYCC_STORAGE_PATH_STYLE}"
+
 mc ping storage -x
 mc mb --ignore-existing storage/"${DRYCC_STORAGE_BUCKET}"

From 8b440222ce4244001c017cf0cf33878802c80790 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Tue, 2 Sep 2025 14:05:14 +0800
Subject: [PATCH 06/13] fix(shell): check storage ready

---
 rootfs/bin/create_bucket | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/rootfs/bin/create_bucket b/rootfs/bin/create_bucket
index e650b9a..fdd42df 100644
--- a/rootfs/bin/create_bucket
+++ b/rootfs/bin/create_bucket
@@ -9,4 +9,9 @@ mc alias set storage \
   --path "${DRYCC_STORAGE_PATH_STYLE}"
 
 mc ping storage -x
+if ! mc admin info storage > /dev/null 2>&1; then
+  sleep 9s
+else
+  mc ready storage
+fi
 mc mb --ignore-existing storage/"${DRYCC_STORAGE_BUCKET}"

From 22675edc0dfddc4faf7c58439653b00277502d58 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Thu, 4 Sep 2025 08:52:47 +0800
Subject: [PATCH 07/13] fix(config): service key miss whitespace

---
 pkg/conf/config.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index aba7d93..664fe67 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -30,7 +30,7 @@ func GetServiceKey() (string, error) {
 	if err != nil {
 		return "", fmt.Errorf("couldn't get builder key from %s (%s)", ServiceKeyLocation, err)
 	}
-	serviceKey := strings.Trim(string(serviceKeyBytes), "\n")
+	serviceKey := strings.TrimSuffix(string(serviceKeyBytes), "\n")
 	return serviceKey, nil
 }
 

From bd6c0fa9007ad992ad39b4c47461abee1cd4caeb Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Fri, 12 Sep 2025 10:15:17 +0800
Subject: [PATCH 08/13] chore(go): bump go version to 1.25

---
 go.mod | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/go.mod b/go.mod
index 9710ec9..7642f03 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/drycc/builder
 
-go 1.24
+go 1.25
 
 require (
 	github.com/aws/aws-sdk-go v1.55.6

From 1bc9d8c62d121a05afb5a30ddbe88a29c0557431 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Wed, 17 Sep 2025 15:41:56 +0800
Subject: [PATCH 09/13] chore(builder): fmt go code

---
 Dockerfile                            |  2 +-
 boot.go                               |  3 +--
 go.mod                                |  4 ++--
 go.sum                                |  8 ++++----
 pkg/cleaner/cleaner.go                |  2 --
 pkg/conf/config.go                    |  3 ++-
 pkg/conf/config_test.go               |  3 +--
 pkg/controller/utils.go               |  2 +-
 pkg/controller/utils_test.go          |  5 ++---
 pkg/git/git.go                        |  9 +++++----
 pkg/gitreceive/build.go               |  9 +++++----
 pkg/gitreceive/build_test.go          |  6 +++---
 pkg/gitreceive/imagebuilder.go        | 14 ++++++--------
 pkg/gitreceive/imagebuilder_test.go   |  1 -
 pkg/gitreceive/k8s_util.go            |  7 ++++---
 pkg/gitreceive/k8s_util_test.go       |  8 ++++----
 pkg/gitreceive/run.go                 |  6 ++----
 pkg/gitreceive/run_test.go            |  2 +-
 pkg/healthsrv/buckets_lister.go       |  1 +
 pkg/healthsrv/healthz_handler_test.go |  4 +---
 pkg/healthsrv/namespace_lister.go     |  1 -
 pkg/k8s/client.go                     |  2 ++
 pkg/k8s/namespace.go                  |  1 +
 pkg/k8s/secrets.go                    | 26 ++++++++++++++------------
 pkg/k8s/watch.go                      | 19 +++++++------------
 pkg/sshd/circuit.go                   |  8 +++++---
 pkg/sshd/circuit_test.go              |  5 +++--
 pkg/sshd/lock.go                      |  4 +---
 pkg/sshd/lock_test.go                 |  4 +---
 pkg/sshd/server.go                    | 17 +++++++++--------
 pkg/sshd/server_test.go               |  9 +++------
 pkg/storage/image_repo.go             |  3 ++-
 pkg/storage/interfaces.go             |  1 +
 pkg/storage/object.go                 |  3 +--
 pkg/sys/env.go                        |  2 ++
 35 files changed, 98 insertions(+), 106 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 9cc4f0f..67c29ba 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,7 +12,7 @@ FROM registry.drycc.cc/drycc/base:${CODENAME}
 ENV DRYCC_UID=1001 \
   DRYCC_GID=1001 \
   DRYCC_HOME_DIR=/workspace \
-  MC_VERSION="2025.04.03.17.07.56" \
+  MC_VERSION="2025.08.13.08.35.41" \
   JQ_VERSION="1.7.1"
 
 RUN groupadd drycc --gid ${DRYCC_GID} \
diff --git a/boot.go b/boot.go
index f2a577b..1c4abe8 100644
--- a/boot.go
+++ b/boot.go
@@ -1,3 +1,4 @@
+// Package main provides the entry point for the Drycc builder service.
 package main
 
 import (
@@ -62,7 +63,6 @@ func main() {
 				}
 				var storageDriver storagedriver.StorageDriver
 				storageDriver, err = factory.Create(context.Background(), "s3", storageParams)
-
 				if err != nil {
 					return fmt.Errorf("error creating storage driver (%s)", err)
 				}
@@ -119,7 +119,6 @@ func main() {
 				}
 				var storageDriver storagedriver.StorageDriver
 				storageDriver, err = factory.Create(context.Background(), "s3", storageParams)
-
 				if err != nil {
 					return fmt.Errorf("error creating storage driver (%s)", err)
 				}
diff --git a/go.mod b/go.mod
index 7642f03..5efe774 100644
--- a/go.mod
+++ b/go.mod
@@ -5,8 +5,8 @@ go 1.25
 require (
 	github.com/aws/aws-sdk-go v1.55.6
 	github.com/distribution/distribution/v3 v3.0.0
-	github.com/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be
-	github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f
+	github.com/drycc/controller-sdk-go v0.0.0-20250930075415-578495a55414
+	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/stretchr/testify v1.10.0
diff --git a/go.sum b/go.sum
index acb0e98..df48b37 100644
--- a/go.sum
+++ b/go.sum
@@ -20,10 +20,10 @@ github.com/distribution/distribution/v3 v3.0.0 h1:q4R8wemdRQDClzoNNStftB2ZAfqOiN
 github.com/distribution/distribution/v3 v3.0.0/go.mod h1:tRNuFoZsUdyRVegq8xGNeds4KLjwLCRin/tTo6i1DhU=
 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/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be h1:aIdgIpvYa6SuPQIV3C3UKNItMaTK3YDxP0sRlfrYSUE=
-github.com/drycc/controller-sdk-go v0.0.0-20250625050826-8be5432737be/go.mod h1:MbFxGlgRQUaVlThbn3DmB06EJsf+e3/O+qgbWmdvtoE=
-github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f h1:/OV4bY2yQDu0mg3l5wdJG6d2tal1hbSX+uI5eiQBQ4o=
-github.com/drycc/pkg v0.0.0-20250324060552-65752139ab2f/go.mod h1:Ss0KonBbfmUVv4bdL+8QAhLtzuBik7DS5tJTMAhycaI=
+github.com/drycc/controller-sdk-go v0.0.0-20250930075415-578495a55414 h1:wiVKgwQsSEBbrQj92Lor6YknaAwPUVp1s/VmAmS3/lI=
+github.com/drycc/controller-sdk-go v0.0.0-20250930075415-578495a55414/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.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
diff --git a/pkg/cleaner/cleaner.go b/pkg/cleaner/cleaner.go
index 29e7296..06eba02 100644
--- a/pkg/cleaner/cleaner.go
+++ b/pkg/cleaner/cleaner.go
@@ -17,7 +17,6 @@ import (
 	"github.com/drycc/builder/pkg/sys"
 	"github.com/drycc/pkg/log"
 	corev1 "k8s.io/api/core/v1"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
@@ -85,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 664fe67..2608932 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -1,3 +1,4 @@
+// Package conf provides configuration utilities for the builder service.
 package conf
 
 import (
@@ -40,7 +41,7 @@ func GetStorageParams(env sys.Env) (Parameters, error) {
 
 	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]
diff --git a/pkg/conf/config_test.go b/pkg/conf/config_test.go
index 2163cf0..596fce0 100644
--- a/pkg/conf/config_test.go
+++ b/pkg/conf/config_test.go
@@ -10,7 +10,6 @@ import (
 )
 
 func TestGetStorageParams(t *testing.T) {
-
 	env := sys.NewFakeEnv()
 	env.Envs = map[string]string{
 		"DRYCC_STORAGE_BUCKET":     "builder",
@@ -45,7 +44,7 @@ func TestGetControllerClient(t *testing.T) {
 
 	ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := os.WriteFile(ServiceKeyLocation, data, 0644); err != nil {
+	if err := os.WriteFile(ServiceKeyLocation, data, 0o644); err != nil {
 		t.Fatalf("error creating %s (%s)", ServiceKeyLocation, err)
 	}
 
diff --git a/pkg/controller/utils.go b/pkg/controller/utils.go
index 1af5bf0..2edb12b 100644
--- a/pkg/controller/utils.go
+++ b/pkg/controller/utils.go
@@ -1,3 +1,4 @@
+// Package controller provides utilities for interacting with the Drycc controller.
 package controller
 
 import (
@@ -8,7 +9,6 @@ import (
 
 // New creates a new SDK client configured as the builder.
 func New(url string) (*drycc.Client, error) {
-
 	client, err := drycc.New(true, url, "")
 	if err != nil {
 		return client, err
diff --git a/pkg/controller/utils_test.go b/pkg/controller/utils_test.go
index 6b288e0..63c8494 100644
--- a/pkg/controller/utils_test.go
+++ b/pkg/controller/utils_test.go
@@ -7,9 +7,8 @@ import (
 	"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) {
@@ -26,7 +25,7 @@ func TestNew(t *testing.T) {
 
 	builderconf.ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0644); err != nil {
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0o644); err != nil {
 		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
diff --git a/pkg/git/git.go b/pkg/git/git.go
index d3eb0bb..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" {
@@ -138,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
 		}
@@ -169,7 +170,7 @@ func createPreReceiveHook(gitHome, repoPath string) error {
 	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)
 	}
-	if err := os.Chmod(writePath, 0755); err != nil {
+	if err := os.Chmod(writePath, 0o755); err != nil {
 		return fmt.Errorf("cannot change pre-receive hook script permissions (%s)", err)
 	}
 
diff --git a/pkg/gitreceive/build.go b/pkg/gitreceive/build.go
index 6585a3f..afdd547 100644
--- a/pkg/gitreceive/build.go
+++ b/pkg/gitreceive/build.go
@@ -1,3 +1,4 @@
+// Package gitreceive provides functionality for handling git receive operations.
 package gitreceive
 
 import (
@@ -57,11 +58,11 @@ func run(cmd *exec.Cmd) error {
 func build(
 	conf *Config,
 	storageDriver storagedriver.StorageDriver,
-	//kubeClient *client.Client,
+	// kubeClient *client.Client,
 	kubeClient *kubernetes.Clientset,
 	env sys.Env,
-	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._:-]+)*)+$`)
 
@@ -76,7 +77,7 @@ 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)
 	}
 
diff --git a/pkg/gitreceive/build_test.go b/pkg/gitreceive/build_test.go
index 543a9f4..450eaa2 100644
--- a/pkg/gitreceive/build_test.go
+++ b/pkg/gitreceive/build_test.go
@@ -78,7 +78,7 @@ func TestBuild(t *testing.T) {
 
 	builderconf.ServiceKeyLocation = filepath.Join(tmpDir, "service-key")
 	data := []byte("testbuilderkey")
-	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0644); err != nil {
+	if err := os.WriteFile(builderconf.ServiceKeyLocation, data, 0o644); err != nil {
 		t.Fatalf("error creating %s (%s)", builderconf.ServiceKeyLocation, err)
 	}
 
@@ -100,7 +100,7 @@ func TestGetProcfileFromRepoSuccess(t *testing.T) {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 	data := []byte("web: example-go")
-	if err := os.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() {
@@ -121,7 +121,7 @@ func TestGetProcfileFromRepoFailure(t *testing.T) {
 		t.Fatalf("error creating temp directory (%s)", err)
 	}
 	data := []byte("web= example-go")
-	if err := os.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() {
diff --git a/pkg/gitreceive/imagebuilder.go b/pkg/gitreceive/imagebuilder.go
index fa8a55c..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_BUCKET",
-		"DRYCC_STORAGE_ENDPOINT",
-		"DRYCC_STORAGE_PATH_STYLE",
-		"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 d3d8dea..336a7a6 100644
--- a/pkg/gitreceive/imagebuilder_test.go
+++ b/pkg/gitreceive/imagebuilder_test.go
@@ -69,7 +69,6 @@ func TestGetImagebuilderEnvOnclusterSuccess(t *testing.T) {
 		"DRYCC_REGISTRY_LOCATION":   "on-cluster",
 	}
 	expectedData := map[string]string{
-
 		"DRYCC_STORAGE_BUCKET":        "builder",
 		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
 		"DRYCC_STORAGE_PATH_STYLE":    "auto",
diff --git a/pkg/gitreceive/k8s_util.go b/pkg/gitreceive/k8s_util.go
index 2cf1a6e..533aef4 100644
--- a/pkg/gitreceive/k8s_util.go
+++ b/pkg/gitreceive/k8s_util.go
@@ -52,7 +52,6 @@ func createBuilderJob(
 	securityContext corev1.SecurityContext,
 	nodeSelector map[string]string,
 ) *batchv1.Job {
-
 	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
@@ -80,7 +79,8 @@ func buildJob(
 	pullPolicy corev1.PullPolicy,
 	securityContext corev1.SecurityContext,
 	nodeSelector map[string]string,
-	values []api.ConfigValue) 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)
@@ -217,7 +217,8 @@ func waitForPodEnd(pw *k8s.PodWatcher, jobName string, interval, timeout time.Du
 
 // waitForPodCondition waits for a pod in state defined by a condition (func)
 func waitForPodCondition(pw *k8s.PodWatcher, jobName string, condition func(pod *corev1.Pod) (bool, error),
-	interval, timeout time.Duration) 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,
diff --git a/pkg/gitreceive/k8s_util_test.go b/pkg/gitreceive/k8s_util_test.go
index 006b857..b4aa536 100644
--- a/pkg/gitreceive/k8s_util_test.go
+++ b/pkg/gitreceive/k8s_util_test.go
@@ -93,11 +93,11 @@ 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)
diff --git a/pkg/gitreceive/run.go b/pkg/gitreceive/run.go
index 0530b4a..7468006 100644
--- a/pkg/gitreceive/run.go
+++ b/pkg/gitreceive/run.go
@@ -7,10 +7,9 @@ import (
 	"strings"
 
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
+	"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) {
@@ -25,7 +24,7 @@ func readLine(line string) (string, string, string, error) {
 // although it is called from the main in boot.go.
 func Run(conf *Config, env sys.Env, storageDriver storagedriver.StorageDriver) error {
 	log.Debug("Running git hook")
-	//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)
@@ -35,7 +34,6 @@ func Run(conf *Config, env sys.Env, storageDriver storagedriver.StorageDriver) e
 	for scanner.Scan() {
 		line := scanner.Text()
 		oldRev, newRev, refName, err := readLine(line)
-
 		if err != nil {
 			return fmt.Errorf("reading STDIN (%s)", err)
 		}
diff --git a/pkg/gitreceive/run_test.go b/pkg/gitreceive/run_test.go
index ba17c43..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 {
diff --git a/pkg/healthsrv/buckets_lister.go b/pkg/healthsrv/buckets_lister.go
index e684257..433d9d0 100644
--- a/pkg/healthsrv/buckets_lister.go
+++ b/pkg/healthsrv/buckets_lister.go
@@ -1,3 +1,4 @@
+// Package healthsrv provides health check services for the builder.
 package healthsrv
 
 import (
diff --git a/pkg/healthsrv/healthz_handler_test.go b/pkg/healthsrv/healthz_handler_test.go
index 3f33839..ce134de 100644
--- a/pkg/healthsrv/healthz_handler_test.go
+++ b/pkg/healthsrv/healthz_handler_test.go
@@ -14,9 +14,7 @@ import (
 	"github.com/stretchr/testify/assert"
 )
 
-var (
-	errTest = errors.New("test error")
-)
+var errTest = errors.New("test error")
 
 type emptyBucketLister struct{}
 
diff --git a/pkg/healthsrv/namespace_lister.go b/pkg/healthsrv/namespace_lister.go
index 13648e6..2491e0c 100644
--- a/pkg/healthsrv/namespace_lister.go
+++ b/pkg/healthsrv/namespace_lister.go
@@ -4,7 +4,6 @@ import (
 	"context"
 
 	corev1 "k8s.io/api/core/v1"
-
 	//"k8s.io/apimachinery/pkg/labels"
 	//"k8s.io/apimachinery/pkg/fields"
 	//"k8s.io/apimachinery/pkg/apis/meta/internalversion"
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 0fa7dc3..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,12 +16,12 @@ 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(_ context.Context, name string, _ metav1.GetOptions) (*v1.Secret, error) {
+func (f *FakeSecret) Get(_ context.Context, name string, _ metav1.GetOptions) (*corev1.Secret, error) {
 	return f.FnGet(name)
 }
 
@@ -32,18 +31,18 @@ func (f *FakeSecret) Delete(context.Context, string, metav1.DeleteOptions) error
 }
 
 // Create is the interface definition.
-func (f *FakeSecret) Create(_ context.Context, secret *v1.Secret, _ 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(_ context.Context, secret *v1.Secret, _ 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(context.Context, 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.
@@ -57,12 +56,13 @@ func (f *FakeSecret) DeleteCollection(context.Context, metav1.DeleteOptions, met
 }
 
 // Patch is the interface definition.
-func (f *FakeSecret) Patch(context.Context, string, types.PatchType, []byte, metav1.PatchOptions, ...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(context.Context, *applyconfigurationscorev1.SecretApplyConfiguration, 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(context.Context, *applyconfigurationscorev1.SecretApp
 //	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 6cf56b0..fe2ae47 100644
--- a/pkg/k8s/watch.go
+++ b/pkg/k8s/watch.go
@@ -2,7 +2,6 @@ package k8s
 
 import (
 	"context"
-	"time"
 
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -13,10 +12,7 @@ import (
 	"k8s.io/client-go/tools/cache"
 )
 
-var (
-	resyncPeriod = 30 * time.Second
-)
-
+// StoreToPodLister is a wrapper around cache.Store that provides methods to list pods.
 type StoreToPodLister struct {
 	cache.Store
 }
@@ -27,6 +23,7 @@ type PodWatcher struct {
 	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
@@ -45,16 +42,14 @@ func (s *StoreToPodLister) List(selector labels.Selector) (pods []*v1.Pod, err e
 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
 }
 
diff --git a/pkg/sshd/circuit.go b/pkg/sshd/circuit.go
index c9a2d44..0d7069f 100644
--- a/pkg/sshd/circuit.go
+++ b/pkg/sshd/circuit.go
@@ -17,12 +17,14 @@ 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"
+	default:
+		return fmt.Sprintf("Unknown (%d)", c.toUint32())
 	}
-	return fmt.Sprintf("Unknown (%d)", c.toUint32())
 }
 
 func (c CircuitState) toUint32() uint32 {
diff --git a/pkg/sshd/circuit_test.go b/pkg/sshd/circuit_test.go
index be4970a..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) {
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..ba068f8 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
diff --git a/pkg/sshd/server.go b/pkg/sshd/server.go
index c66155c..67e45cf 100644
--- a/pkg/sshd/server.go
+++ b/pkg/sshd/server.go
@@ -29,9 +29,11 @@ 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) {
@@ -97,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
 }
 
@@ -107,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
@@ -137,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()
 
@@ -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 288e8ed..0d88827 100644
--- a/pkg/sshd/server_test.go
+++ b/pkg/sshd/server_test.go
@@ -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
@@ -246,8 +245,8 @@ func runServer(
 	pushLock RepositoryLock,
 	testAddr string,
 	_ time.Duration,
-	t *testing.T) {
-
+	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 47b9a93..3af3198 100644
--- a/pkg/storage/image_repo.go
+++ b/pkg/storage/image_repo.go
@@ -1,3 +1,4 @@
+// Package storage provides image repository management functionality.
 package storage
 
 import (
@@ -44,7 +45,7 @@ func CreateImageRepo(reponame string, params map[string]string) error {
 		},
 		&credentials.EnvProvider{},
 		&credentials.SharedCredentialsProvider{},
-		&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(session.New())},
+		&ec2rolecreds.EC2RoleProvider{Client: ec2metadata.New(session.Must(session.NewSession()))},
 	})
 	awsConfig := aws.NewConfig()
 	awsConfig.WithCredentials(creds)
diff --git a/pkg/storage/interfaces.go b/pkg/storage/interfaces.go
index 85626df..70b553f 100644
--- a/pkg/storage/interfaces.go
+++ b/pkg/storage/interfaces.go
@@ -2,6 +2,7 @@ package storage
 
 import (
 	"context"
+
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 )
 
diff --git a/pkg/storage/object.go b/pkg/storage/object.go
index 77987a4..12cac7e 100644
--- a/pkg/storage/object.go
+++ b/pkg/storage/object.go
@@ -1,12 +1,11 @@
 package storage
 
 import (
+	"context"
 	"errors"
 	"fmt"
 	"time"
 
-	"context"
-
 	storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
 )
 
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 {

From fa977dcdc4adcc4bf7dc3a6546e11c3118c86029 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Fri, 17 Oct 2025 15:25:48 +0800
Subject: [PATCH 10/13] chore(imagebuilder): use rclone replace mc

---
 Dockerfile                            |  6 +++---
 charts/builder/templates/_helpers.tpl |  2 +-
 charts/builder/values.yaml            |  2 +-
 pkg/conf/config_test.go               |  2 +-
 pkg/gitreceive/imagebuilder_test.go   | 10 +++++-----
 rootfs/bin/create_bucket              | 22 ++++++++++++----------
 6 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/Dockerfile b/Dockerfile
index 67c29ba..b6688cc 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,10 +9,10 @@ RUN export GO111MODULE=on \
 
 FROM registry.drycc.cc/drycc/base:${CODENAME}
 
-ENV DRYCC_UID=1001 \
+ARG DRYCC_UID=1001 \
   DRYCC_GID=1001 \
   DRYCC_HOME_DIR=/workspace \
-  MC_VERSION="2025.08.13.08.35.41" \
+  RCLONE_VERSION="1.71.1" \
   JQ_VERSION="1.7.1"
 
 RUN groupadd drycc --gid ${DRYCC_GID} \
@@ -24,7 +24,7 @@ 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* \
diff --git a/charts/builder/templates/_helpers.tpl b/charts/builder/templates/_helpers.tpl
index 6391e76..914c773 100644
--- a/charts/builder/templates/_helpers.tpl
+++ b/charts/builder/templates/_helpers.tpl
@@ -64,7 +64,7 @@ env:
       name: storage-creds
       key: secretkey
 - name: "DRYCC_STORAGE_PATH_STYLE"
-  value: "on"
+  value: "true"
 {{- end }}
 - name: "DRYCC_REGISTRY_LOCATION"
   value: {{ ternary "on-cluster" "off-cluster" .Values.registry.enabled }}
diff --git a/charts/builder/values.yaml b/charts/builder/values.yaml
index b24bdf7..f62ea33 100644
--- a/charts/builder/values.yaml
+++ b/charts/builder/values.yaml
@@ -61,7 +61,7 @@ storageBucket: "registry"
 storageEndpoint: ""
 storageAccesskey: ""
 storageSecretkey: ""
-storagePathStyle: "auto"
+storagePathStyle: "true"
 
 # The following parameters will no longer use the built-in registry component.
 registryHost: ""
diff --git a/pkg/conf/config_test.go b/pkg/conf/config_test.go
index 596fce0..42460e7 100644
--- a/pkg/conf/config_test.go
+++ b/pkg/conf/config_test.go
@@ -16,7 +16,7 @@ func TestGetStorageParams(t *testing.T) {
 		"DRYCC_STORAGE_ENDPOINT":   "http://localhost:8088",
 		"DRYCC_STORAGE_ACCESSKEY":  "admin",
 		"DRYCC_STORAGE_SECRETKEY":  "adminpass",
-		"DRYCC_STORAGE_PATH_STYLE": "on",
+		"DRYCC_STORAGE_PATH_STYLE": "true",
 	}
 	params, err := GetStorageParams(env)
 	if err != nil {
diff --git a/pkg/gitreceive/imagebuilder_test.go b/pkg/gitreceive/imagebuilder_test.go
index 336a7a6..f498002 100644
--- a/pkg/gitreceive/imagebuilder_test.go
+++ b/pkg/gitreceive/imagebuilder_test.go
@@ -17,7 +17,7 @@ func TestGetImagebuilderEnvOffclusterErr(t *testing.T) {
 	env.Envs = map[string]string{
 		"DRYCC_STORAGE_BUCKET":     "builder",
 		"DRYCC_STORAGE_ENDPOINT":   "drycc-storage",
-		"DRYCC_STORAGE_PATH_STYLE": "auto",
+		"DRYCC_STORAGE_PATH_STYLE": "true",
 		"DRYCC_REGISTRY_LOCATION":  "off-cluster",
 	}
 	_, err := getImagebuilderEnv(&image, config, env)
@@ -32,7 +32,7 @@ func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 	env.Envs = map[string]string{
 		"DRYCC_STORAGE_BUCKET":        "builder",
 		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
-		"DRYCC_STORAGE_PATH_STYLE":    "auto",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
@@ -40,7 +40,7 @@ func TestGetImagebuilderEnvOffclusterSuccess(t *testing.T) {
 	expectedData := map[string]string{
 		"DRYCC_STORAGE_BUCKET":        "builder",
 		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
-		"DRYCC_STORAGE_PATH_STYLE":    "auto",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
 		"DRYCC_REGISTRY_LOCATION":     "off-cluster",
 		"DRYCC_REGISTRY_HOST":         "quay.io",
 		"DRYCC_REGISTRY_ORGANIZATION": "kmala",
@@ -63,7 +63,7 @@ func TestGetImagebuilderEnvOnclusterSuccess(t *testing.T) {
 	env.Envs = map[string]string{
 		"DRYCC_STORAGE_BUCKET":      "builder",
 		"DRYCC_STORAGE_ENDPOINT":    "drycc-storage",
-		"DRYCC_STORAGE_PATH_STYLE":  "auto",
+		"DRYCC_STORAGE_PATH_STYLE":  "true",
 		"DRYCC_REGISTRY_HOST":       "drycc-registry",
 		"DRYCC_REGISTRY_PROXY_HOST": "127.0.0.1:8000",
 		"DRYCC_REGISTRY_LOCATION":   "on-cluster",
@@ -71,7 +71,7 @@ func TestGetImagebuilderEnvOnclusterSuccess(t *testing.T) {
 	expectedData := map[string]string{
 		"DRYCC_STORAGE_BUCKET":        "builder",
 		"DRYCC_STORAGE_ENDPOINT":      "drycc-storage",
-		"DRYCC_STORAGE_PATH_STYLE":    "auto",
+		"DRYCC_STORAGE_PATH_STYLE":    "true",
 		"DRYCC_REGISTRY_HOST":         "drycc-registry",
 		"DRYCC_REGISTRY_LOCATION":     "on-cluster",
 		"DRYCC_REGISTRY_PROXY_HOST":   "127.0.0.1:8000",
diff --git a/rootfs/bin/create_bucket b/rootfs/bin/create_bucket
index fdd42df..addadaa 100644
--- a/rootfs/bin/create_bucket
+++ b/rootfs/bin/create_bucket
@@ -2,16 +2,18 @@
 
 set -e
 
-mc alias set storage \
-  "${DRYCC_STORAGE_ENDPOINT}" \
-  "${DRYCC_STORAGE_ACCESSKEY}" \
-  "${DRYCC_STORAGE_SECRETKEY}" \
-  --path "${DRYCC_STORAGE_PATH_STYLE}"
+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
 
-mc ping storage -x
-if ! mc admin info storage > /dev/null 2>&1; then
+if ! rclone lsd storage: > /dev/null 2>&1; then
   sleep 9s
-else
-  mc ready storage
+  echo "waiting for object storage to become ready..."
 fi
-mc mb --ignore-existing storage/"${DRYCC_STORAGE_BUCKET}"
+
+rclone mkdir "storage:${DRYCC_STORAGE_BUCKET}"

From 990d47763a9d5ee7461a8be9af2e785145cfce79 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Tue, 21 Oct 2025 15:22:23 +0800
Subject: [PATCH 11/13] fix(conf): nil config error

---
 Makefile           | 2 +-
 pkg/conf/config.go | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 3721748..9c1e0cc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 SHORT_NAME ?= builder
+DRYCC_REGISTRY ?= ${DEV_REGISTRY}
 
 include versioning.mk
-DRYCC_REGISTRY ?= ${DEV_REGISTRY}
 
 # container development environment variables
 REPO_PATH := github.com/drycc/${SHORT_NAME}
diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index 2608932..c08077c 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -52,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(storagePathStyleEnvVar) == "on" {
+	if env.Get(storagePathStyleEnvVar) == "true" {
 		params["forcepathstyle"] = "true"
 	}
-
 	return params, nil
 }

From d0b654a9be3272be22e2a735d1674f885540c005 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Wed, 3 Dec 2025 21:30:07 +0800
Subject: [PATCH 12/13] chore(deps): bump golang.org/x/crypto from 0.36.0 to
 0.45.0 (#29)

Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.36.0 to 0.45.0.
- [Commits](https://github.com/golang/crypto/compare/v0.36.0...v0.45.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.45.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
 go.mod | 10 +++++-----
 go.sum | 24 ++++++++++++------------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/go.mod b/go.mod
index 5efe774..fdb9642 100644
--- a/go.mod
+++ b/go.mod
@@ -11,7 +11,7 @@ require (
 	github.com/kelseyhightower/envconfig v1.4.0
 	github.com/stretchr/testify v1.10.0
 	github.com/urfave/cli/v2 v2.27.6
-	golang.org/x/crypto v0.36.0
+	golang.org/x/crypto v0.45.0
 	gopkg.in/yaml.v3 v3.0.1
 	k8s.io/api v0.32.3
 	k8s.io/apimachinery v0.32.3
@@ -79,11 +79,11 @@ require (
 	go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect
 	go.opentelemetry.io/otel/trace v1.35.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.5.0 // indirect
-	golang.org/x/net v0.38.0 // indirect
+	golang.org/x/net v0.47.0 // indirect
 	golang.org/x/oauth2 v0.28.0 // indirect
-	golang.org/x/sys v0.31.0 // indirect
-	golang.org/x/term v0.30.0 // indirect
-	golang.org/x/text v0.23.0 // indirect
+	golang.org/x/sys v0.38.0 // indirect
+	golang.org/x/term v0.37.0 // indirect
+	golang.org/x/text v0.31.0 // indirect
 	golang.org/x/time v0.11.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
diff --git a/go.sum b/go.sum
index df48b37..58c3918 100644
--- a/go.sum
+++ b/go.sum
@@ -210,8 +210,8 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
-golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
+golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
 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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -220,8 +220,8 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
-golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
+golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
 golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
 golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -236,22 +236,22 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
-golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
-golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
+golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
+golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
-golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
+golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
 golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
 golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
-golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
+golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
+golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
 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=

From 73f514c023837f99359d9c81826dd53cdb521279 Mon Sep 17 00:00:00 2001
From: duanhongyi <duanhongyi@doopai.com>
Date: Sat, 6 Dec 2025 22:45:02 +0800
Subject: [PATCH 13/13] chore(builder): change interface{} to any

---
 pkg/conf/config.go         |  4 ++--
 pkg/gitreceive/build.go    |  2 +-
 pkg/gitreceive/k8s_util.go |  2 +-
 pkg/sshd/lock_test.go      | 14 +++++++-------
 4 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/pkg/conf/config.go b/pkg/conf/config.go
index c08077c..464aee9 100644
--- a/pkg/conf/config.go
+++ b/pkg/conf/config.go
@@ -23,7 +23,7 @@ const (
 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
 
 // GetServiceKey returns the key to be used as token to interact with drycc-controller
 func GetServiceKey() (string, error) {
@@ -37,7 +37,7 @@ func GetServiceKey() (string, error) {
 
 // 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
diff --git a/pkg/gitreceive/build.go b/pkg/gitreceive/build.go
index afdd547..86b9f9a 100644
--- a/pkg/gitreceive/build.go
+++ b/pkg/gitreceive/build.go
@@ -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
diff --git a/pkg/gitreceive/k8s_util.go b/pkg/gitreceive/k8s_util.go
index 533aef4..bcab989 100644
--- a/pkg/gitreceive/k8s_util.go
+++ b/pkg/gitreceive/k8s_util.go
@@ -256,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/sshd/lock_test.go b/pkg/sshd/lock_test.go
index ba068f8..8a5e416 100644
--- a/pkg/sshd/lock_test.go
+++ b/pkg/sshd/lock_test.go
@@ -43,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)
 }
@@ -51,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)
@@ -72,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)
@@ -108,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
@@ -124,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.")
