Files
rkKVM/http/route/api.go
2024-11-05 23:47:00 +01:00

193 lines
4.0 KiB
Go

package route
import (
"net/http"
"os"
"os/exec"
"path/filepath"
"rkkvm/config"
"rkkvm/hid"
"rkkvm/http/middleware"
"rkkvm/http/reqrsp"
"rkkvm/http/ws"
"rkkvm/stream"
"strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
)
func Api(e *gin.Engine) {
api := e.Group("/api").Use(middleware.CheckToken())
api.GET("/stream/mjpeg", stream.MjpegHandler)
api.GET("/ws", ws.ConnHandler)
api.POST("/stream/webrtc", stream.WebRTCPeerConnect)
api.GET("/stream/webrtc", stream.WebRTCSettings)
api.POST("/storage/image", uploadHandler)
api.GET("/storage/image", listHandler)
api.GET("/storage/image/mounted", mountedHandler)
api.POST("/storage/image/mount", mountHandler)
api.POST("/storage/image/unmount", unmountHandler)
}
func uploadHandler(c *gin.Context) {
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to get file"})
return
}
filePath := filepath.Join(config.Get().ISOPath, file.Filename)
if err := c.SaveUploadedFile(file, filePath); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save file"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "File uploaded successfully"})
}
func listHandler(c *gin.Context) {
files, err := os.ReadDir(config.Get().ISOPath)
if err != nil {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "get images failed",
})
return
}
var fileNames []string
for _, f := range files {
if !f.IsDir() {
fname := strings.ToLower(f.Name())
if strings.HasSuffix(fname, ".iso") || strings.HasSuffix(fname, ".img") {
fileNames = append(fileNames, f.Name())
}
}
}
c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{
Msg: reqrsp.MsgSuccess,
Data: reqrsp.FilesRsp{
Files: fileNames,
},
})
}
func mountHandler(c *gin.Context) {
var request struct {
Filename string `json:"file"`
}
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, reqrsp.NanoKVMRsp{
Code: -1,
Msg: "invalid arguments",
})
return
}
if request.Filename == "" {
unmountHandler(c)
return
}
imageFile := filepath.Join(config.Get().ISOPath, request.Filename)
_, err := os.Stat(imageFile)
if os.IsNotExist(err) {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "file not exists: " + request.Filename,
})
return
}
hid.GetHid().Close()
cmds := []string{
"/hid.sh detach",
"/hid.sh mount_iso " + imageFile, //+ strconv.Quote(imageFile),
"/hid.sh attach",
}
for _, cmd := range cmds {
log.Debugf("Executing: %s", cmd)
cc := exec.Command("sh", "-c", cmd)
cc.Stdout = os.Stdout
cc.Stderr = os.Stderr
if err := cc.Run(); err != nil {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "execute command failed: " + cmd,
})
return
}
}
hid.GetHid().Open()
c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{
Msg: reqrsp.MsgSuccess,
})
}
func unmountHandler(c *gin.Context) {
hid.GetHid().Close()
cmds := []string{
"/hid.sh detach",
"/hid.sh unmount_iso",
"/hid.sh attach",
}
for _, cmd := range cmds {
log.Debugf("Executing: %s", cmd)
cc := exec.Command("sh", "-c", cmd)
cc.Stdout = os.Stdout
cc.Stderr = os.Stderr
if err := cc.Run(); err != nil {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "execute command failed: " + cmd,
})
return
}
}
hid.GetHid().Open()
c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{
Msg: reqrsp.MsgSuccess,
})
}
func mountedHandler(c *gin.Context) {
cmd := exec.Command("/hid.sh", "mounted_iso")
output, err := cmd.Output()
if err != nil {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "read failed",
})
return
}
fname := strings.TrimSpace(string(output))
_, err = os.Stat(fname)
if os.IsNotExist(err) {
c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{
Code: -2,
Msg: "file not exists: " + fname,
})
return
}
c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{
Msg: reqrsp.MsgSuccess,
Data: reqrsp.FileRsp{
File: filepath.Base(fname),
},
})
}