mirror of
https://github.com/yusing/godoxy.git
synced 2026-04-24 01:08:31 +02:00
feat(proxmox): add journalctl streaming API endpoint for LXC containers
Add new /api/v1/proxmox/journalctl/:node/:vmid/:service endpoint that streams real-time journalctl output from Proxmox LXC containers via WebSocket connection. This enables live monitoring of container services from the GoDoxy WebUI. Implementation includes: - New proxmox API handler with path parameter validation - WebSocket upgrade for streaming output - LXCCommand helper for executing commands over Proxmox VNC websocket - LXCJournalctl wrapper for convenient journalctl -u service -f invocation - Updated API documentation with proxmox integration
This commit is contained in:
65
internal/api/v1/proxmox/journalctl.go
Normal file
65
internal/api/v1/proxmox/journalctl.go
Normal file
@@ -0,0 +1,65 @@
|
||||
package proxmoxapi
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yusing/godoxy/internal/proxmox"
|
||||
"github.com/yusing/goutils/apitypes"
|
||||
"github.com/yusing/goutils/http/websocket"
|
||||
)
|
||||
|
||||
type JournalctlRequest struct {
|
||||
Node string `uri:"node" binding:"required"`
|
||||
VMID int `uri:"vmid" binding:"required"`
|
||||
Service string `uri:"service" binding:"required"`
|
||||
}
|
||||
|
||||
// @x-id "journalctl"
|
||||
// @BasePath /api/v1
|
||||
// @Summary Get journalctl output
|
||||
// @Description Get journalctl output
|
||||
// @Tags proxmox,websocket
|
||||
// @Accept json
|
||||
// @Produce application/json
|
||||
// @Param path path JournalctlRequest true "Request"
|
||||
// @Success 200 string plain "Journalctl output"
|
||||
// @Failure 400 {object} apitypes.ErrorResponse "Invalid request"
|
||||
// @Failure 403 {object} apitypes.ErrorResponse "Unauthorized"
|
||||
// @Failure 500 {object} apitypes.ErrorResponse "Internal server error"
|
||||
// @Router /api/v1/proxmox/journalctl/{node}/{vmid}/{service} [get]
|
||||
func Journalctl(c *gin.Context) {
|
||||
var request JournalctlRequest
|
||||
if err := c.ShouldBindUri(&request); err != nil {
|
||||
c.JSON(http.StatusBadRequest, apitypes.Error("invalid request", err))
|
||||
return
|
||||
}
|
||||
|
||||
node, ok := proxmox.Nodes.Get(request.Node)
|
||||
if !ok {
|
||||
c.JSON(http.StatusNotFound, apitypes.Error("node not found"))
|
||||
return
|
||||
}
|
||||
|
||||
manager, err := websocket.NewManagerWithUpgrade(c)
|
||||
if err != nil {
|
||||
c.Error(apitypes.InternalServerError(err, "failed to upgrade to websocket"))
|
||||
return
|
||||
}
|
||||
defer manager.Close()
|
||||
|
||||
reader, err := node.LXCJournalctl(c.Request.Context(), request.VMID, request.Service)
|
||||
if err != nil {
|
||||
c.Error(apitypes.InternalServerError(err, "failed to get journalctl output"))
|
||||
return
|
||||
}
|
||||
defer reader.Close()
|
||||
|
||||
writer := manager.NewWriter(websocket.TextMessage)
|
||||
_, err = io.Copy(writer, reader)
|
||||
if err != nil {
|
||||
c.Error(apitypes.InternalServerError(err, "failed to copy journalctl output"))
|
||||
return
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user