package main import ( "flag" "git.mlody.eu/lmoskala/libguestd/pkg/libguestd" "github.com/digitalocean/go-libvirt" "log" "net/url" "os" "time" ) func main() { libvirtUri := flag.String("libvirt", "qemu:///system", "libvirt connection URI") domainName := flag.String("domain", "", "domain (instance) name") Src := flag.String("src", "", "source file") Dst := flag.String("dst", "", "destination file") Reverse := flag.Bool("reverse", false, "reverse mode (guest to host)") flag.Parse() if *domainName == "" { log.Fatalf("Domain name must be specified") } if *Src == "" { log.Fatalf("Source file must be specified") } if *Dst == "" { log.Fatalf("Destination file must be specified") } var data []byte var err error if !*Reverse { data, err = os.ReadFile(*Src) if err != nil { log.Fatalf("error reading src file: %v\n", err) } } uri, _ := url.Parse(*libvirtUri) l, err := libvirt.ConnectToURI(uri) if err != nil { log.Fatalf("failed to connect: %v", err) } domains, _, err := l.ConnectListAllDomains(1, libvirt.ConnectListDomainsActive) if err != nil { log.Fatalf("failed to list all domains: %v", err) } for _, domain := range domains { if domain.Name != *domainName { continue } err = libguestd.GuestPing(l, domain) if err != nil { log.Printf("Error(GuestPing): %s", err) continue } agentInfo, err := libguestd.GuestInfo(l, domain) if err != nil { log.Printf("Error(GuestInfo): %s", err) continue } Start := time.Now() if *Reverse { data, err = libguestd.GuestFileRead(l, domain, agentInfo, *Src) } else { err = libguestd.GuestFileWrite(l, domain, agentInfo, *Dst, data) } if err != nil { log.Printf("Error(GuestFileWrite): %s", err) } else { duration := time.Since(Start) log.Printf("Copied %d bytes in %.1fs, (%.1f MiB/s)", len(data), duration.Seconds(), float64(len(data))/1024/1024/duration.Seconds()) } if *Reverse { err = os.WriteFile(*Dst, data, 0600) if err != nil { log.Printf("error writing file: %v", err) } } } if err = l.Disconnect(); err != nil { log.Fatalf("failed to disconnect: %v", err) } }