saracen / go-qmp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

go-qmp

An experimental QMP client for Go.

Example

import (
    "github.com/saracen/go-qmp"
    "github.com/saracen/go-qmp/api/qsd"
)

func createBlockDevice() error {
    client, err := qmp.Dial(ctx, "unix", "qmp.sock")
    if err != nil {
        return err
    }

    // register qemu storage daemon event factory
    qsd.RegisterEvents(client)

    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    cancel()

    // create listener and filter for certain event & job id
    events := client.Listen(ctx, func(e qmp.Event) bool {
        switch v := e.Event.(type) {
        case *qsd.JobStatusChangeEvent:
            return v.Id == "my-job-id"
        }

        return false
    })

    // create blockdev
    create := qsd.BlockdevCreate{
        JobId: "my-job-id",
        Options: qsd.BlockdevCreateOptions{
        Driver: qsd.BlockdevDriverFile,
            File: &qsd.BlockdevCreateOptionsFile{
                Filename:      "/my/raw.disk",
                Size:          10 * 1024 * 1024,
                Preallocation: qmp.ToPtr(qsd.PreallocModeFalloc),
            },
        },
    }

    if err := create.Execute(ctx, client); err != nil {
        return fmt.Errorf("executing create block device: %w", err)
    }

    // watch events
    var errs []error
    for event := range events {
        statusChange, ok := event.Event.(*qsd.JobStatusChangeEvent)
        if !ok {
            continue
        }

        switch statusChange.Status {
        default:
            continue

        case qsd.JobStatusAborting:
            jobInfo, err := qsd.QueryJobs{}.Execute(ctx, client)
            if err != nil {
                errs = append(errs, fmt.Errorf("querying jobs: %w", err))
            } else {
                // find the error for the job id
                for _, info := range jobInfo {
                    if info.Id == "my-job-id" {
                        errs = append(errs, errors.New(qmp.FromPtr(info.Error)))
                        break
                    }
                }
            }

            continue

        case qsd.JobStatusConcluded:
            err := qsd.JobDismiss{Id: "my-job-id"}.Execute(ctx, .client)
            if err != nil {
                errs = append(errs, fmt.Errorf("dismissing job: %w", err))
            }
        }

        break
    }

    if err := errors.Join(errs...); err != nil {
        return fmt.Errorf("creating block device: %w", err)
    }

    return nil
}

About

License:MIT License


Languages

Language:Go 100.0%