Initial commit

This commit is contained in:
Łukasz Moskała 2024-07-07 18:51:49 +02:00
commit 799ea9a90a
12 changed files with 1332 additions and 0 deletions

87
cmd/cp2guest/cp2guest.go Normal file
View file

@ -0,0 +1,87 @@
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)
}
}

77
cmd/guestrun/guestrun.go Normal file
View file

@ -0,0 +1,77 @@
package main
import (
"encoding/base64"
"flag"
"fmt"
"git.mlody.eu/lmoskala/libguestd/pkg/libguestd"
"github.com/digitalocean/go-libvirt"
"log"
"net/url"
)
func main() {
libvirtUri := flag.String("libvirt", "qemu:///system", "libvirt connection URI")
domainName := flag.String("domain", "", "domain (instance) name")
Cmd := flag.String("cmd", "", "Command (will be run as /bin/sh -c ...)")
flag.Parse()
if *domainName == "" {
log.Fatalf("Domain name must be specified")
}
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
}
pid, err := libguestd.GuestExecStart(l, domain, agentInfo, "/bin/sh", []string{"-c", *Cmd}, []string{}, []byte{})
if err != nil {
log.Printf("Error(GuestExecStart): %s", err)
continue
}
log.Printf("PID: %d", pid)
res, err := libguestd.GuestWaitForCommand(l, domain, agentInfo, pid)
if err != nil {
log.Printf("Error(GuestWaitForCommand): %s", err)
}
log.Printf("Exit status: %d", res.ExitCode)
log.Printf("Stdout follows:")
dec, _ := base64.StdEncoding.DecodeString(res.OutDataB64)
fmt.Println(string(dec))
if res.OutTruncated {
log.Printf("[Output was truncated]")
}
log.Printf("Stderr follows:")
dec, _ = base64.StdEncoding.DecodeString(res.ErrDataB64)
fmt.Println(string(dec))
if res.ErrTruncated {
log.Printf("[Output was truncated]")
}
}
if err = l.Disconnect(); err != nil {
log.Fatalf("failed to disconnect: %v", err)
}
}

View file

@ -0,0 +1,172 @@
package main
import (
"flag"
"fmt"
"git.mlody.eu/lmoskala/libguestd/pkg/libguestd"
"github.com/digitalocean/go-libvirt"
"log"
"net/url"
"time"
)
func main() {
libvirtUri := flag.String("libvirt", "qemu:///system", "libvirt connection URI")
domainName := flag.String("domain", "", "domain name")
GetOSInfo := flag.Bool("osinfo", false, "Gather OS info")
GetNICInfo := flag.Bool("nicinfo", false, "Gather NIC info")
GetFSInfo := flag.Bool("fsinfo", false, "Gather Filesystem info")
ListKeys := flag.Bool("listkeys", false, "List ssh keys (specify username)")
GetTimeDelta := flag.Bool("timedelta", false, "Display time delta between this host and guest")
GetHostName := flag.Bool("hostname", false, "Display host name")
GetAgentInfo := flag.Bool("agentinfo", false, "Display agent info")
GetDiskInfo := flag.Bool("diskinfo", false, "Display disk info")
GetDiskStats := flag.Bool("diskstats", false, "Display disk I/O stats")
Username := flag.String("username", "", "username to edit (use with password or ssh keys)")
Password := flag.String("password", "", "password to set (specify username)")
AddKey := flag.String("sshkey-add", "", "SSH key to add (in authorized_keys format), specify username")
RemoveKey := flag.String("sshkey-remove", "", "SSH key to remove (in authorized_keys format), specify username")
flag.Parse()
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
}
if *GetAgentInfo {
agentInfo.Dump()
}
if *GetOSInfo {
osInfo, err := libguestd.GuestGetOsInfo(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetOsInfo): %s", err)
} else {
osInfo.Dump()
}
}
if *GetNICInfo {
interfaces, err := libguestd.GuestGetNetworkInterfaces(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetNetworkInterfaces): %s", err)
} else {
for _, iface := range interfaces {
iface.Dump()
}
}
}
if *GetFSInfo {
fs, err := libguestd.GuestGetFilesystemInfo(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetFilesystemInfo): %s", err)
} else {
for _, fs := range fs {
fs.Dump()
}
}
}
if *GetDiskInfo {
disk, err := libguestd.GuestGetDisks(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetDisks): %s", err)
} else {
for _, disk := range disk {
disk.Dump()
}
}
}
if *GetDiskStats {
diskstats, err := libguestd.GuestGetDiskstats(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetDiskstats): %s", err)
} else {
for _, disk := range diskstats {
disk.Dump()
}
}
}
if *Username != "" && *Password != "" {
err = libguestd.GuestChangeUserPassword(l, domain, agentInfo, *Username, *Password)
if err != nil {
log.Printf("Error(GuestChangeUserPassword): %s", err)
} else {
log.Printf("Password set")
}
}
if *Username != "" && *AddKey != "" {
err = libguestd.GuestAddSshKeys(l, domain, agentInfo, *Username, []string{*AddKey}, false)
if err != nil {
log.Printf("Error(GuestAddSshKeys): %s", err)
} else {
log.Printf("SSH key added")
}
}
if *Username != "" && *RemoveKey != "" {
err = libguestd.GuestRemoveSshKeys(l, domain, agentInfo, *Username, []string{*RemoveKey})
if err != nil {
log.Printf("Error(GuestRemoveSshKeys): %s", err)
} else {
log.Printf("SSH key removed")
}
}
if *Username != "" && *ListKeys {
keys, err := libguestd.GuestGetSshKeys(l, domain, agentInfo, *Username)
if err != nil {
log.Printf("Error(GuestGetSshKeys): %s", err)
}
fmt.Printf("Keys for %s:\n", *Username)
for _, key := range keys {
fmt.Printf("\t%s\n", key)
}
}
if *GetHostName {
hostname, err := libguestd.GuestGetHostName(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetHostName): %s", err)
} else {
fmt.Printf("Hostname: %s\n", hostname)
}
}
if *GetTimeDelta {
guestTime, err := libguestd.GuestGetTime(l, domain, agentInfo)
if err != nil {
log.Printf("Error(GuestGetTime): %s", err)
} else {
d := time.Since(time.Unix(0, guestTime))
fmt.Printf("Time diff: %f seconds\n", d.Seconds())
}
}
}
if err = l.Disconnect(); err != nil {
log.Fatalf("failed to disconnect: %v", err)
}
}