Files
BatchuKVM/server/service/vm/virtual-device.go

135 lines
2.5 KiB
Go

package vm
import (
"errors"
"os"
"os/exec"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"NanoKVM-Server/proto"
"NanoKVM-Server/service/hid"
)
const (
virtualNetwork = "/boot/usb.rndis0"
virtualDisk = "/boot/usb.disk0"
)
var (
mountNetworkCommands = []string{
"touch /boot/usb.rndis0",
"/etc/init.d/S03usbdev stop",
"/etc/init.d/S03usbdev start",
}
unmountNetworkCommands = []string{
"/etc/init.d/S03usbdev stop",
"rm -rf /sys/kernel/config/usb_gadget/g0/configs/c.1/rndis.usb0",
"rm /boot/usb.rndis0",
"/etc/init.d/S03usbdev start",
}
mountDiskCommands = []string{
"touch /boot/usb.disk0",
"/etc/init.d/S03usbdev stop",
"/etc/init.d/S03usbdev start",
}
unmountDiskCommands = []string{
"/etc/init.d/S03usbdev stop",
"rm -rf /sys/kernel/config/usb_gadget/g0/configs/c.1/mass_storage.disk0",
"rm /boot/usb.disk0",
"/etc/init.d/S03usbdev start",
}
)
func (s *Service) GetVirtualDevice(c *gin.Context) {
var rsp proto.Response
network, _ := isDeviceExist(virtualNetwork)
disk, _ := isDeviceExist(virtualDisk)
rsp.OkRspWithData(c, &proto.GetVirtualDeviceRsp{
Network: network,
Disk: disk,
})
log.Debugf("get virtual device success")
}
func (s *Service) UpdateVirtualDevice(c *gin.Context) {
var req proto.UpdateVirtualDeviceReq
var rsp proto.Response
if err := proto.ParseFormRequest(c, &req); err != nil {
rsp.ErrRsp(c, -1, "invalid argument")
return
}
var device string
var commands []string
switch req.Device {
case "network":
device = virtualNetwork
exist, _ := isDeviceExist(device)
if !exist {
commands = mountNetworkCommands
} else {
commands = unmountNetworkCommands
}
case "disk":
device = virtualDisk
exist, _ := isDeviceExist(device)
if !exist {
commands = mountDiskCommands
} else {
commands = unmountDiskCommands
}
default:
rsp.ErrRsp(c, -2, "invalid arguments")
return
}
h := hid.GetHid()
h.Lock()
h.CloseNoLock()
defer func() {
h.OpenNoLock()
h.Unlock()
}()
for _, command := range commands {
err := exec.Command("sh", "-c", command).Run()
if err != nil {
rsp.ErrRsp(c, -3, "operation failed")
return
}
}
on, _ := isDeviceExist(device)
rsp.OkRspWithData(c, &proto.UpdateVirtualDeviceRsp{
On: on,
})
log.Debugf("update virtual device %s success", req.Device)
}
func isDeviceExist(device string) (bool, error) {
_, err := os.Stat(device)
if err == nil {
return true, nil
}
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
log.Errorf("check file %s err: %s", device, err)
return false, err
}