mirror of
https://github.com/yusing/godoxy.git
synced 2026-02-19 08:57:42 +01:00
This is a large-scale refactoring across the codebase that replaces the custom `gperr.Error` type with Go's standard `error` interface. The changes include: - Replacing `gperr.Error` return types with `error` in function signatures - Using `errors.New()` and `fmt.Errorf()` instead of `gperr.New()` and `gperr.Errorf()` - Using `%w` format verb for error wrapping instead of `.With()` method - Replacing `gperr.Subject()` calls with `gperr.PrependSubject()` - Converting error logging from `gperr.Log*()` functions to zerolog's `.Err().Msg()` pattern - Update NewLogger to handle multiline error message - Updating `goutils` submodule to latest commit This refactoring aligns with Go idioms and removes the dependency on custom error handling abstractions in favor of standard library patterns.
83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package dockerapi
|
|
|
|
import (
|
|
"context"
|
|
"sort"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
dockerSystem "github.com/moby/moby/api/types/system"
|
|
"github.com/moby/moby/client"
|
|
gperr "github.com/yusing/goutils/errs"
|
|
strutils "github.com/yusing/goutils/strings"
|
|
|
|
_ "github.com/yusing/goutils/apitypes"
|
|
)
|
|
|
|
type containerStats struct {
|
|
Total int `json:"total"`
|
|
Running int `json:"running"`
|
|
Paused int `json:"paused"`
|
|
Stopped int `json:"stopped"`
|
|
} // @name ContainerStats
|
|
|
|
type dockerInfo struct {
|
|
Name string `json:"name"`
|
|
ServerVersion string `json:"version"`
|
|
Containers containerStats `json:"containers"`
|
|
Images int `json:"images"`
|
|
NCPU int `json:"n_cpu"`
|
|
MemTotal string `json:"memory"`
|
|
} // @name ServerInfo
|
|
|
|
func toDockerInfo(info dockerSystem.Info) dockerInfo {
|
|
return dockerInfo{
|
|
Name: info.Name,
|
|
ServerVersion: info.ServerVersion,
|
|
Containers: containerStats{
|
|
Total: info.ContainersRunning,
|
|
Running: info.ContainersRunning,
|
|
Paused: info.ContainersPaused,
|
|
Stopped: info.ContainersStopped,
|
|
},
|
|
Images: info.Images,
|
|
NCPU: info.NCPU,
|
|
MemTotal: strutils.FormatByteSize(info.MemTotal),
|
|
}
|
|
}
|
|
|
|
// @x-id "info"
|
|
// @BasePath /api/v1
|
|
// @Summary Get docker info
|
|
// @Description Get docker info
|
|
// @Tags docker
|
|
// @Produce json
|
|
// @Success 200 {object} dockerInfo
|
|
// @Failure 403 {object} apitypes.ErrorResponse
|
|
// @Failure 500 {object} apitypes.ErrorResponse
|
|
// @Router /docker/info [get]
|
|
func Info(c *gin.Context) {
|
|
serveHTTP[dockerInfo](c, GetDockerInfo)
|
|
}
|
|
|
|
func GetDockerInfo(ctx context.Context, dockerClients DockerClients) ([]dockerInfo, error) {
|
|
errs := gperr.NewBuilder("failed to get docker info")
|
|
dockerInfos := make([]dockerInfo, len(dockerClients))
|
|
|
|
i := 0
|
|
for name, dockerClient := range dockerClients {
|
|
info, err := dockerClient.Info(ctx, client.InfoOptions{})
|
|
if err != nil {
|
|
errs.AddSubject(err, name)
|
|
continue
|
|
}
|
|
info.Info.Name = name
|
|
dockerInfos[i] = toDockerInfo(info.Info)
|
|
i++
|
|
}
|
|
|
|
sort.Slice(dockerInfos, func(i, j int) bool {
|
|
return dockerInfos[i].Name < dockerInfos[j].Name
|
|
})
|
|
return dockerInfos, errs.Error()
|
|
}
|