GoDoxy/internal/api/v1/dockerapi/utils.go
2025-02-20 18:03:54 +08:00

104 lines
2.8 KiB
Go

package dockerapi
import (
"encoding/json"
"net/http"
config "github.com/yusing/go-proxy/internal/config/types"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/gperr"
)
// getDockerClients returns a map of docker clients for the current config.
//
// Returns a map of docker clients by server name and an error if any.
//
// Even if there are errors, the map of docker clients might not be empty.
func getDockerClients() (map[string]*docker.SharedClient, gperr.Error) {
cfg := config.GetInstance()
dockerHosts := cfg.Value().Providers.Docker
dockerClients := make(map[string]*docker.SharedClient)
connErrs := gperr.NewBuilder("failed to connect to docker")
for name, host := range dockerHosts {
dockerClient, err := docker.ConnectClient(host)
if err != nil {
connErrs.Add(err)
continue
}
dockerClients[name] = dockerClient
}
for _, agent := range cfg.ListAgents() {
dockerClient, err := docker.ConnectClient(agent.FakeDockerHost())
if err != nil {
connErrs.Add(err)
continue
}
dockerClients[agent.Name()] = dockerClient
}
return dockerClients, connErrs.Error()
}
// getDockerClientsWithErrHandling returns a map of docker clients for the current config.
//
// Returns a map of docker clients by server name and a boolean indicating if http handler should stop/
func getDockerClientsWithErrHandling(w http.ResponseWriter) (map[string]*docker.SharedClient, bool) {
dockerClients, err := getDockerClients()
if err != nil {
gperr.LogError("failed to get docker clients", err)
if len(dockerClients) == 0 {
http.Error(w, "no docker hosts connected successfully", http.StatusInternalServerError)
return nil, false
}
}
return dockerClients, true
}
func getDockerClient(w http.ResponseWriter, server string) (*docker.SharedClient, bool, error) {
cfg := config.GetInstance()
var host string
for name, h := range cfg.Value().Providers.Docker {
if name == server {
host = h
break
}
}
for _, agent := range cfg.ListAgents() {
if agent.Name() == server {
host = agent.FakeDockerHost()
break
}
}
if host == "" {
return nil, false, nil
}
dockerClient, err := docker.ConnectClient(host)
if err != nil {
return nil, false, err
}
return dockerClient, true, nil
}
// closeAllClients closes all docker clients after a delay.
//
// This is used to ensure that all docker clients are closed after the http handler returns.
func closeAllClients(dockerClients map[string]*docker.SharedClient) {
for _, dockerClient := range dockerClients {
dockerClient.Close()
}
}
func handleResult[T any](w http.ResponseWriter, errs error, result []T) {
if errs != nil {
gperr.LogError("docker errors", errs)
if len(result) == 0 {
http.Error(w, "docker errors", http.StatusInternalServerError)
return
}
}
json.NewEncoder(w).Encode(result)
}