diff --git a/internal/api/v1/docker/restart.go b/internal/api/v1/docker/restart.go new file mode 100644 index 00000000..5bed245a --- /dev/null +++ b/internal/api/v1/docker/restart.go @@ -0,0 +1,52 @@ +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 "restart" +// @BasePath /api/v1 +// @Summary Restart container +// @Description Restart container by container id +// @Tags docker +// @Produce json +// @Param request body StopRequest true "Request" +// @Success 200 {object} apitypes.SuccessResponse +// @Failure 400 {object} apitypes.ErrorResponse "Invalid request" +// @Failure 403 {object} apitypes.ErrorResponse +// @Failure 404 {object} apitypes.ErrorResponse "Container not found" +// @Failure 500 {object} apitypes.ErrorResponse +// @Router /docker/restart [post] +func Restart(c *gin.Context) { + var req StopRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err)) + return + } + + dockerHost, ok := docker.GetDockerHostByContainerID(req.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() + + err = client.ContainerRestart(c.Request.Context(), req.ID, req.StopOptions) + if err != nil { + c.Error(apitypes.InternalServerError(err, "failed to restart container")) + return + } + + c.JSON(http.StatusOK, apitypes.Success("container restarted")) +} diff --git a/internal/api/v1/docker/start.go b/internal/api/v1/docker/start.go new file mode 100644 index 00000000..f1d6349a --- /dev/null +++ b/internal/api/v1/docker/start.go @@ -0,0 +1,58 @@ +package dockerapi + +import ( + "net/http" + + "github.com/docker/docker/api/types/container" + "github.com/gin-gonic/gin" + apitypes "github.com/yusing/go-proxy/internal/api/types" + "github.com/yusing/go-proxy/internal/docker" +) + +type StartRequest struct { + ID string `json:"id" binding:"required"` + container.StartOptions +} + +// @x-id "start" +// @BasePath /api/v1 +// @Summary Start container +// @Description Start container by container id +// @Tags docker +// @Produce json +// @Param request body StartRequest true "Request" +// @Success 200 {object} apitypes.SuccessResponse +// @Failure 400 {object} apitypes.ErrorResponse "Invalid request" +// @Failure 403 {object} apitypes.ErrorResponse +// @Failure 404 {object} apitypes.ErrorResponse "Container not found" +// @Failure 500 {object} apitypes.ErrorResponse +// @Router /docker/start [post] +func Start(c *gin.Context) { + var req StartRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err)) + return + } + + dockerHost, ok := docker.GetDockerHostByContainerID(req.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() + + err = client.ContainerStart(c.Request.Context(), req.ID, req.StartOptions) + if err != nil { + c.Error(apitypes.InternalServerError(err, "failed to start container")) + return + } + + c.JSON(http.StatusOK, apitypes.Success("container started")) +} diff --git a/internal/api/v1/docker/stop.go b/internal/api/v1/docker/stop.go new file mode 100644 index 00000000..506f17d0 --- /dev/null +++ b/internal/api/v1/docker/stop.go @@ -0,0 +1,58 @@ +package dockerapi + +import ( + "net/http" + + "github.com/docker/docker/api/types/container" + "github.com/gin-gonic/gin" + apitypes "github.com/yusing/go-proxy/internal/api/types" + "github.com/yusing/go-proxy/internal/docker" +) + +type StopRequest struct { + ID string `json:"id" binding:"required"` + container.StopOptions +} + +// @x-id "stop" +// @BasePath /api/v1 +// @Summary Stop container +// @Description Stop container by container id +// @Tags docker +// @Produce json +// @Param request body StopRequest true "Request" +// @Success 200 {object} apitypes.SuccessResponse +// @Failure 400 {object} apitypes.ErrorResponse "Invalid request" +// @Failure 403 {object} apitypes.ErrorResponse +// @Failure 404 {object} apitypes.ErrorResponse "Container not found" +// @Failure 500 {object} apitypes.ErrorResponse +// @Router /docker/stop [post] +func Stop(c *gin.Context) { + var req StopRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err)) + return + } + + dockerHost, ok := docker.GetDockerHostByContainerID(req.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() + + err = client.ContainerStop(c.Request.Context(), req.ID, req.StopOptions) + if err != nil { + c.Error(apitypes.InternalServerError(err, "failed to stop container")) + return + } + + c.JSON(http.StatusOK, apitypes.Success("container stopped")) +}