mirror of https://github.com/jetkvm/kvm.git
Compare commits
3 Commits
5159dc0b10
...
7b32a84075
Author | SHA1 | Date |
---|---|---|
|
7b32a84075 | |
|
951173ba19 | |
|
f49c405509 |
1
go.mod
1
go.mod
|
@ -20,6 +20,7 @@ require (
|
|||
github.com/pion/webrtc/v4 v4.0.0
|
||||
github.com/pojntfx/go-nbd v0.3.2
|
||||
github.com/psanford/httpreadat v0.1.0
|
||||
github.com/ulikunitz/xz v0.5.12
|
||||
github.com/vishvananda/netlink v1.3.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/net v0.30.0
|
||||
|
|
2
go.sum
2
go.sum
|
@ -138,6 +138,8 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
|||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
|
||||
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
|
||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||
|
|
21
network.go
21
network.go
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
var mDNSConn *mdns.Conn
|
||||
|
||||
var networkState struct {
|
||||
Up bool
|
||||
IPv4 string
|
||||
|
@ -91,13 +93,26 @@ func checkNetworkState() {
|
|||
}
|
||||
|
||||
if newState != networkState {
|
||||
networkState = newState
|
||||
fmt.Println("network state changed")
|
||||
//restart MDNS
|
||||
startMDNS()
|
||||
networkState = newState
|
||||
requestDisplayUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
func startMDNS() error {
|
||||
//If server was previously running, stop it
|
||||
if mDNSConn != nil {
|
||||
fmt.Printf("Stopping mDNS server\n")
|
||||
err := mDNSConn.Close()
|
||||
if err != nil {
|
||||
fmt.Printf("failed to stop mDNS server: %v\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
//Start a new server
|
||||
fmt.Printf("Starting mDNS server on jetkvm.local\n")
|
||||
addr4, err := net.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -118,10 +133,11 @@ func startMDNS() error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = mdns.Server(ipv4.NewPacketConn(l4), ipv6.NewPacketConn(l6), &mdns.Config{
|
||||
mDNSConn, err = mdns.Server(ipv4.NewPacketConn(l4), ipv6.NewPacketConn(l6), &mdns.Config{
|
||||
LocalNames: []string{"jetkvm.local"}, //TODO: make it configurable
|
||||
})
|
||||
if err != nil {
|
||||
mDNSConn = nil
|
||||
return err
|
||||
}
|
||||
//defer server.Close()
|
||||
|
@ -157,7 +173,6 @@ func init() {
|
|||
}
|
||||
}
|
||||
}()
|
||||
fmt.Println("Starting mDNS server")
|
||||
err := startMDNS()
|
||||
if err != nil {
|
||||
fmt.Println("failed to run mDNS: %v", err)
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/pion/webrtc/v4"
|
||||
"github.com/ulikunitz/xz"
|
||||
)
|
||||
|
||||
const massStorageName = "mass_storage.usb0"
|
||||
|
@ -269,16 +270,48 @@ func rpcMountWithStorage(filename string, mode VirtualMediaMode) error {
|
|||
return fmt.Errorf("failed to get file info: %w", err)
|
||||
}
|
||||
|
||||
err = setMassStorageImage(fullPath)
|
||||
// Handle XZ compressed images
|
||||
if strings.HasSuffix(filename, ".img.xz") {
|
||||
logger.Info("Mounting compressed XZ image")
|
||||
|
||||
// Create temporary file for decompressed image
|
||||
decompressedPath := filepath.Join(imagesFolder, strings.TrimSuffix(filename, ".xz")+".temp")
|
||||
defer os.Remove(decompressedPath) // Clean up temp file after mounting
|
||||
|
||||
err = decompressXZImage(fullPath, decompressedPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set mass storage image: %w", err)
|
||||
return fmt.Errorf("failed to decompress XZ image: %w", err)
|
||||
}
|
||||
|
||||
// Mount the decompressed image
|
||||
err = mountImage(decompressedPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mount decompressed image: %w", err)
|
||||
}
|
||||
|
||||
currentVirtualMediaState = &VirtualMediaState{
|
||||
Source: Storage,
|
||||
Mode: mode,
|
||||
Filename: filename,
|
||||
Size: fileInfo.Size(),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle regular images
|
||||
err = mountImage(fullPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set mass storage image: %w", err)
|
||||
}
|
||||
|
||||
currentVirtualMediaState = &VirtualMediaState{
|
||||
Source: Storage,
|
||||
Mode: mode,
|
||||
Filename: filename,
|
||||
Size: fileInfo.Size(),
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -556,3 +589,30 @@ func handleUploadHttp(c *gin.Context) {
|
|||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Upload completed"})
|
||||
}
|
||||
|
||||
// Add this helper function to handle XZ decompression
|
||||
func decompressXZImage(sourcePath, destPath string) error {
|
||||
sourceFile, err := os.Open(sourcePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open source file: %w", err)
|
||||
}
|
||||
defer sourceFile.Close()
|
||||
|
||||
reader, err := xz.NewReader(sourceFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create XZ reader: %w", err)
|
||||
}
|
||||
|
||||
destFile, err := os.Create(destPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create destination file: %w", err)
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
_, err = io.Copy(destFile, reader)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decompress file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue