From 7b028adaa9a6db85c0e59f8638c03971d9825fc2 Mon Sep 17 00:00:00 2001 From: yusing Date: Sun, 14 Sep 2025 00:12:23 +0800 Subject: [PATCH] feat(api): add GetContainer endpoint for Docker container retrieval - Implemented GetContainer function to retrieve container details by ID. - Added error handling for missing ID, container not found, and client creation failures. - Enhanced Container struct to support omitempty for state field in JSON responses. - Updated API documentation with Swagger annotations for the new endpoint. --- internal/api/v1/docker/container.go | 63 ++++++++++++++++++++++++++++ internal/api/v1/docker/containers.go | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 internal/api/v1/docker/container.go diff --git a/internal/api/v1/docker/container.go b/internal/api/v1/docker/container.go new file mode 100644 index 00000000..ffed3177 --- /dev/null +++ b/internal/api/v1/docker/container.go @@ -0,0 +1,63 @@ +package dockerapi + +import ( + "net/http" + + "github.com/gin-gonic/gin" + apitypes "github.com/yusing/go-proxy/internal/api/types" + "github.com/yusing/go-proxy/internal/docker" +) + +// @x-id "container" +// @BasePath /api/v1 +// @Summary Get container +// @Description Get container by container id +// @Tags docker +// @Produce json +// @Param id path string true "Container ID" +// @Success 200 {object} Container +// @Failure 400 {object} apitypes.ErrorResponse "ID is required" +// @Failure 403 {object} apitypes.ErrorResponse +// @Failure 404 {object} apitypes.ErrorResponse "Container not found" +// @Failure 500 {object} apitypes.ErrorResponse +// @Router /docker/container/{id} [get] +func GetContainer(c *gin.Context) { + id := c.Param("id") + if id == "" { + c.JSON(http.StatusBadRequest, apitypes.Error("id is required")) + return + } + + dockerHost, ok := docker.GetDockerHostByContainerID(id) + if !ok { + c.JSON(http.StatusNotFound, apitypes.Error("container not found")) + return + } + + client, err := docker.NewClient(dockerHost) + if err != nil { + c.Error(apitypes.InternalServerError(err, "failed to create docker client")) + return + } + + defer client.Close() + + cont, err := client.ContainerInspect(c.Request.Context(), id) + if err != nil { + c.Error(apitypes.InternalServerError(err, "failed to inspect container")) + return + } + + var state ContainerState + if cont.State != nil { + state = cont.State.Status + } + + c.JSON(http.StatusOK, &Container{ + Server: dockerHost, + Name: cont.Name, + ID: cont.ID, + Image: cont.Image, + State: state, + }) +} diff --git a/internal/api/v1/docker/containers.go b/internal/api/v1/docker/containers.go index 0a9c5574..e533a649 100644 --- a/internal/api/v1/docker/containers.go +++ b/internal/api/v1/docker/containers.go @@ -16,7 +16,7 @@ type Container struct { Name string `json:"name"` ID string `json:"id"` Image string `json:"image"` - State ContainerState `json:"state"` + State ContainerState `json:"state,omitempty" extensions:"x-nullable"` } // @name ContainerResponse // @x-id "containers"