From 1719158c5180df4e4bdf1c5559b3076a9d8526b7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:06:43 +0000 Subject: [PATCH 1/3] Initial plan From e46db458063bf4d8753d26c385414241fee75f10 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:12:54 +0000 Subject: [PATCH 2/3] Add health check endpoint for MinIO Sidekick Co-authored-by: DavidTrachy <7200403+DavidTrachy@users.noreply.github.com> --- .gitignore | 4 ++++ go/src/ltfs-vof/main.go | 25 +++++++++++++++++++++ health_check_test.go | 49 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 health_check_test.go diff --git a/.gitignore b/.gitignore index 4e0b108..983b029 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,7 @@ __pycache__/ .idea .ipynb_checkpoints */.ipynb_checkpoints/* +go.mod +go.sum +go/src/ltfs-vof/go.mod +go/src/ltfs-vof/go.sum diff --git a/go/src/ltfs-vof/main.go b/go/src/ltfs-vof/main.go index 60ca310..7e57e62 100644 --- a/go/src/ltfs-vof/main.go +++ b/go/src/ltfs-vof/main.go @@ -8,6 +8,7 @@ import ( "io/ioutil" . "ltfs-vof/tapehardware" . "ltfs-vof/utils" + "net/http" "strings" ) @@ -47,8 +48,12 @@ func main() { simPacks := flag.Bool("simpacks", false, "Put Pack List Into Database") var simBuckets stringSlice flag.Var(&simBuckets, "simbucket", "simbucket may be repeated to create multiple simulation buckets") + healthPort := flag.String("healthport", "8080", "Port for health check endpoint") flag.Parse() + // Start health check server in background + go startHealthCheckServer(*healthPort) + // create the customer logger logger := NewLogger(*logFile, *clean) @@ -165,3 +170,23 @@ func (s *stringSlice) Set(value string) error { func (s *stringSlice) Slice() []string { return []string(*s) } + +// startHealthCheckServer starts an HTTP server for health checks +// This is used by MinIO Sidekick for load balancer health monitoring +func startHealthCheckServer(port string) { + http.HandleFunc("/health", healthCheckHandler) + http.HandleFunc("/healthz", healthCheckHandler) + http.HandleFunc("/", healthCheckHandler) + + addr := ":" + port + fmt.Printf("Starting health check server on %s\n", addr) + if err := http.ListenAndServe(addr, nil); err != nil { + fmt.Printf("Health check server error: %v\n", err) + } +} + +// healthCheckHandler responds with 200 OK for health checks +func healthCheckHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("OK")) +} diff --git a/health_check_test.go b/health_check_test.go new file mode 100644 index 0000000..49fae5a --- /dev/null +++ b/health_check_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "net/http" + "net/http/httptest" + "testing" +) + +// healthCheckHandler responds with 200 OK for health checks +func healthCheckHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("OK")) +} + +func TestHealthCheckHandler(t *testing.T) { + tests := []struct { + name string + path string + expectedStatus int + expectedBody string + }{ + {"Health endpoint", "/health", http.StatusOK, "OK"}, + {"Healthz endpoint", "/healthz", http.StatusOK, "OK"}, + {"Root endpoint", "/", http.StatusOK, "OK"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, err := http.NewRequest("GET", tt.path, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + handler := http.HandlerFunc(healthCheckHandler) + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != tt.expectedStatus { + t.Errorf("handler returned wrong status code: got %v want %v", + status, tt.expectedStatus) + } + + if rr.Body.String() != tt.expectedBody { + t.Errorf("handler returned unexpected body: got %v want %v", + rr.Body.String(), tt.expectedBody) + } + }) + } +} From 8bcfc923745a16c243e8652e2cec36466357c701 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:14:48 +0000 Subject: [PATCH 3/3] Address code review feedback - fix error handling and remove duplicate test Co-authored-by: DavidTrachy <7200403+DavidTrachy@users.noreply.github.com> --- go/src/ltfs-vof/main.go | 2 +- health_check_test.go | 49 ----------------------------------------- 2 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 health_check_test.go diff --git a/go/src/ltfs-vof/main.go b/go/src/ltfs-vof/main.go index 7e57e62..672a1a2 100644 --- a/go/src/ltfs-vof/main.go +++ b/go/src/ltfs-vof/main.go @@ -188,5 +188,5 @@ func startHealthCheckServer(port string) { // healthCheckHandler responds with 200 OK for health checks func healthCheckHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - w.Write([]byte("OK")) + _, _ = w.Write([]byte("OK")) } diff --git a/health_check_test.go b/health_check_test.go deleted file mode 100644 index 49fae5a..0000000 --- a/health_check_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "net/http" - "net/http/httptest" - "testing" -) - -// healthCheckHandler responds with 200 OK for health checks -func healthCheckHandler(w http.ResponseWriter, r *http.Request) { - w.WriteHeader(http.StatusOK) - w.Write([]byte("OK")) -} - -func TestHealthCheckHandler(t *testing.T) { - tests := []struct { - name string - path string - expectedStatus int - expectedBody string - }{ - {"Health endpoint", "/health", http.StatusOK, "OK"}, - {"Healthz endpoint", "/healthz", http.StatusOK, "OK"}, - {"Root endpoint", "/", http.StatusOK, "OK"}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - req, err := http.NewRequest("GET", tt.path, nil) - if err != nil { - t.Fatal(err) - } - - rr := httptest.NewRecorder() - handler := http.HandlerFunc(healthCheckHandler) - handler.ServeHTTP(rr, req) - - if status := rr.Code; status != tt.expectedStatus { - t.Errorf("handler returned wrong status code: got %v want %v", - status, tt.expectedStatus) - } - - if rr.Body.String() != tt.expectedBody { - t.Errorf("handler returned unexpected body: got %v want %v", - rr.Body.String(), tt.expectedBody) - } - }) - } -}