package route import ( "net/http" "os" "os/exec" "path/filepath" "rkkvm/config" "rkkvm/http/hw/hid" "rkkvm/http/hw/stream" "rkkvm/http/middleware" "rkkvm/http/reqrsp" "rkkvm/http/ws" "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("/stream/audio", stream.AudioHandler) 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 } 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{ config.RootFS + "/hid.sh detach", config.RootFS + "/hid.sh mount_iso " + imageFile, //+ strconv.Quote(imageFile), config.RootFS + "/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, }) os.Exit(0) } func unmountHandler(c *gin.Context) { if output, err := exec.Command(config.RootFS + "/hid.sh unmount_iso").Output(); err != nil { c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{ Code: -2, Msg: "execute command failed: " + string(output), }) } c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{ Msg: reqrsp.MsgSuccess, }) } func mountedHandler(c *gin.Context) { cmd := exec.Command(config.RootFS+"/hid.sh", "mounted_iso") output, err := cmd.Output() if err != nil { c.JSON(http.StatusInternalServerError, reqrsp.NanoKVMRsp{ Code: -2, Msg: "read failed", }) return } c.JSON(http.StatusOK, reqrsp.NanoKVMRsp{ Msg: reqrsp.MsgSuccess, Data: reqrsp.FileRsp{ File: string(output), }, }) }