refactor: improve error handling, validation and proper cleanup

This commit is contained in:
yusing
2026-01-25 19:18:14 +08:00
parent 9f245a62f2
commit 5c341d4745
12 changed files with 52 additions and 30 deletions

View File

@@ -23,7 +23,7 @@ type LogsQueryParams struct {
Since string `form:"from"`
Until string `form:"to"`
Levels string `form:"levels"`
Limit int `form:"limit,default=100" binding:"omitempty,min=1,max=1000"`
Limit int `form:"limit,default=100" binding:"min=1,max=1000"`
} // @name LogsQueryParams
// @x-id "logs"

View File

@@ -3,4 +3,4 @@ package proxmoxapi
type ActionRequest struct {
Node string `uri:"node" binding:"required"`
VMID int `uri:"vmid" binding:"required"`
}
} // @name ProxmoxVMActionRequest

View File

@@ -11,18 +11,18 @@ import (
)
type JournalctlRequest struct {
Node string `uri:"node" binding:"required"`
VMID *int `uri:"vmid"` // optional - if not provided, streams node journalctl
Service string `uri:"service"`
Limit int `query:"limit" binding:"omitempty,min=1,max=1000"`
}
Node string `uri:"node" binding:"required"` // Node name
VMID *int `uri:"vmid"` // Container VMID (optional - if not provided, streams node journalctl)
Service string `uri:"service"` // Service name (e.g., 'pveproxy' for node, 'container@.service' format for LXC)
Limit int `query:"limit" default:"100" binding:"min=1,max=1000"` // Limit output lines (1-1000)
} // @name ProxmoxJournalctlRequest
// @x-id "journalctl"
// @BasePath /api/v1
// @Summary Get journalctl output
// @Description Get journalctl output for node or LXC container. If vmid is not provided, streams node journalctl.
// @Tags proxmox,websocket
// @Accept json
// @Accept json
// @Produce application/json
// @Param node path string true "Node name"
// @Param vmid path int false "Container VMID (optional - if not provided, streams node journalctl)"
@@ -42,6 +42,10 @@ func Journalctl(c *gin.Context) {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
if err := c.ShouldBindQuery(&request); err != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
return
}
node, ok := proxmox.Nodes.Get(request.Node)
if !ok {
@@ -49,14 +53,10 @@ func Journalctl(c *gin.Context) {
return
}
manager, err := websocket.NewManagerWithUpgrade(c)
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to upgrade to websocket"))
return
}
defer manager.Close()
c.Status(http.StatusContinue)
var reader io.ReadCloser
var err error
if request.VMID == nil {
reader, err = node.NodeJournalctl(c.Request.Context(), request.Service, request.Limit)
} else {
@@ -68,6 +68,13 @@ func Journalctl(c *gin.Context) {
}
defer reader.Close()
manager, err := websocket.NewManagerWithUpgrade(c)
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to upgrade to websocket"))
return
}
defer manager.Close()
writer := manager.NewWriter(websocket.TextMessage)
_, err = io.Copy(writer, reader)
if err != nil {

View File

@@ -37,5 +37,5 @@ func Route(c *gin.Context) {
c.JSON(http.StatusOK, route)
return
}
c.JSON(http.StatusNotFound, nil)
c.JSON(http.StatusNotFound, apitypes.Error("route not found"))
}