Skip to content

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.

Terminal window
go get go.pilab.hu/cloud/virtpb
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)
}
}
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),
)
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
}
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)
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 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",
})
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)
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)
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)
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)
}
}

See the examples directory for complete examples.