Go SDK
The PiVirt Go SDK provides idiomatic, high-performance Go clients and ConnectRPC / gRPC bindings for orchestrating virtual machines, storage pools, networks, and clusters.
Installation
Section titled “Installation”go get go.pilab.hu/cloud/virtpbQuick Start
Section titled “Quick Start”package main
import ( "context" "fmt" "log"
"go.pilab.hu/cloud/virtpb/pilab/agent/v1" "google.golang.org/grpc" "google.golang.org/grpc/credentials")
func main() { // Connect to agent creds, err := credentials.NewClientTLSFromFile("ca.crt", "") if err != nil { log.Fatal(err) }
conn, err := grpc.Dial("agent.pilab.hu:8443", grpc.WithTransportCredentials(creds), ) if err != nil { log.Fatal(err) } defer conn.Close()
// Create VM client client := vm.NewVMServiceClient(conn)
// List VMs ctx := context.Background() stream, err := client.ListVMs(ctx, &vm.ListVMsRequest{ Namespace: "production", }) if err != nil { log.Fatal(err) }
for { vm, err := stream.Recv() if err != nil { break } fmt.Printf("VM: %s (Status: %s)\n", vm.Name, vm.Status) }}Authentication
Section titled “Authentication”import ( "google.golang.org/grpc/credentials")
creds, err := credentials.NewClientTLSFromFile("ca.crt", "")if err != nil { log.Fatal(err)}
conn, err := grpc.Dial("agent.pilab.hu:8443", grpc.WithTransportCredentials(creds),)Bearer Token
Section titled “Bearer Token”import ( "google.golang.org/grpc" "google.golang.org/grpc/metadata")
conn, err := grpc.Dial("agent.pilab.hu:8443", grpc.WithPerRPCCredentials(&tokenAuth{ token: "your-jwt-token", }),)
type tokenAuth struct { token string}
func (t *tokenAuth) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { return map[string]string{ "authorization": "Bearer " + t.token, }, nil}
func (t *tokenAuth) RequireTransportSecurity() bool { return true}VM Operations
Section titled “VM Operations”Create VM
Section titled “Create VM”import ( "go.pilab.hu/cloud/virtpb/pilab/agent/v1")
client := vm.NewVMServiceClient(conn)
req := &vm.CreateVMRequest{ Spec: &vm.VMSpec{ Name: "web-01", Vcpus: 2, MemoryBytes: 4294967296, Disks: []*vm.Disk{ { Name: "root", Pool: "default", SizeBytes: 21474836480, Format: vm.VolumeFormat_VOLUME_FORMAT_QCOW2, Bus: "virtio", }, }, Nics: []*vm.NetworkInterface{ { Name: "eth0", Bridge: "virbr0", Model: "virtio", }, }, }, Namespace: "production",}
createdVM, err := client.CreateVM(ctx, req)if err != nil { log.Fatal(err)}
fmt.Printf("Created VM: %s\n", createdVM.Id)Get VM
Section titled “Get VM”req := &vm.GetVMRequest{ Id: "vm-abc123", Namespace: "production",}
vm, err := client.GetVM(ctx, req)if err != nil { log.Fatal(err)}
fmt.Printf("VM: %s, Status: %s\n", vm.Name, vm.Status)Start/Stop VM
Section titled “Start/Stop VM”// Start VM_, err := client.StartVM(ctx, &vm.StartVMRequest{ Id: "vm-abc123", Namespace: "production",})
// Stop VM_, err := client.StopVM(ctx, &vm.StopVMRequest{ Id: "vm-abc123", Namespace: "production",})Migrate VM
Section titled “Migrate VM”req := &vm.MigrateVMRequest{ Id: "vm-abc123", Namespace: "production", TargetNode: "node-02", Options: &vm.MigrationOptions{ Live: true, BandwidthLimitMbps: 1000, DowntimeLimitMs: 500, Compress: true, },}
operation, err := client.MigrateVM(ctx, req)if err != nil { log.Fatal(err)}
fmt.Printf("Migration started: %s\n", operation.Id)Storage Operations
Section titled “Storage Operations”Create Volume
Section titled “Create Volume”import ( "go.pilab.hu/cloud/virtpb/pilab/agent/v1")
client := storage.NewStorageServiceClient(conn)
req := &storage.CreateVolumeRequest{ Name: "data-01", Pool: "default", SizeBytes: 107374182400, Format: storage.VolumeFormat_VOLUME_FORMAT_QCOW2,}
volume, err := client.CreateVolume(ctx, req)if err != nil { log.Fatal(err)}
fmt.Printf("Created volume: %s\n", volume.Id)Create Snapshot
Section titled “Create Snapshot”req := &storage.CreateSnapshotRequest{ VolumeId: "vol-abc123", Name: "backup-01",}
snapshot, err := client.CreateSnapshot(ctx, req)if err != nil { log.Fatal(err)}
fmt.Printf("Created snapshot: %s\n", snapshot.Id)Error Handling
Section titled “Error Handling”import ( "google.golang.org/grpc/status" "google.golang.org/grpc/codes")
vm, err := client.GetVM(ctx, req)if err != nil { st, ok := status.FromError(err) if !ok { log.Fatal(err) }
switch st.Code() { case codes.NotFound: fmt.Println("VM not found") case codes.PermissionDenied: fmt.Println("Permission denied") case codes.Unavailable: fmt.Println("Service unavailable") default: log.Fatal(err) }}Examples
Section titled “Examples”See the examples directory for complete examples.