GithubHelp home page GithubHelp logo

digitalocean / go-qemu Goto Github PK

View Code? Open in Web Editor NEW
697.0 38.0 86.0 954 KB

Go packages to interact with QEMU using the QEMU Machine Protocol (QMP). Apache 2.0 Licensed.

License: Other

Go 99.77% Shell 0.23%
golang qemu

go-qemu's Introduction

go-qemu GoDoc Build Status Report Card

go-qemu is a collection of Go packages for interacting with running QEMU instances. Apache 2.0 Licensed.

Feel free to join us in #go-qemu on libera chat if you'd like to discuss the project.

Installation

Use go get to retrieve all of the packages in go-qemu:

$ go get github.com/digitalocean/go-qemu/...

Overview

Here is a quick overview of each top-level package, and what they can be used for:

  • hypervisor: Package hypervisor provides management facilities for one or more QEMU virtual machines on a hypervisor.
    • Provides easier access for managing groups of VMs than the qemu package.
    • Provides access to individual qemu.Domain types.
  • qemu: Package qemu provides an interface for interacting with running QEMU instances.
    • Typically used for managing a single VM.
    • Good for quick experiments.
  • qmp: Package qmp enables interaction with QEMU instances via the QEMU Machine Protocol (QMP).
    • Typically not used by consumers outside of this repository.
    • Wraps code-generated types with friendlier APIs.

Details

Package qemu is used in production at DigitalOcean, alongside package libvirt. This being said, it is possible that there may still be subtle bugs which could cause the packages to act in unexpected ways.

If you encounter any problems, please look at the open issues and if your problem does not match any of the ones listed, file a new issue with as much detail as you are willing to provide.

The API is not considered stable at this time. We do not anticipate making major changes to the API, but it is possible that the API may change over time, if deemed necessary by the project maintainers. If you would like to include package qemu in a project, we highly recommend vendoring it into your project.

go-qemu's People

Contributors

adamwg avatar benlemasurier avatar bronzdoc avatar connorkuehl avatar danderson avatar jennigriesmann avatar kat-co avatar mdlayher avatar mosca1337 avatar ndedic avatar robertojrojas avatar sam-github avatar stgraber avatar tomponline avatar trapgate avatar wildarch avatar xmudrii avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

go-qemu's Issues

qmp: API codegen based on QMP schema

For my own uses, I'm in the middle of writing a go generate codegen to transform the QMP API spec (qapi-schema.json) into reasonably idiomatic Go code. Would you be interested in a contribution of this autogen and resulting API?

Depending on how idiomatic I'm able to make it (the API is pretty rough in places), we could make it a subpackage and allow the main qmp library to use either higher level types that wrap the raw ones, or the raw ones directly if the user needs to use a feature that hasn't been exposed. My aspirational goal is to make the autogenerated bindings good enough that this isn't necessary, but of course that's hard :).

Implement direct QEMU socket (no libvirt) qmp.Monitor

It's possible to speak QMP directly with QEMU when it isn't launched by libvirt. In addition, asynchronous events arrive automatically when the socket is being used for communication.

[zsh|matt@servnerr-2]:~ 1 % sudo socat - UNIX-CONNECT:/var/lib/libvirt/qemu/ubuntuvm0.monitor
{"QMP": {"version": {"qemu": {"micro": 0, "minor": 0, "major": 2}, "package": " (Debian 2.0.0+dfsg-2ubuntu1.22)"}, "capabilities": []}}
{"execute":"qmp_capabilities"}
{"return": {}}
// SIGINT sent in another terminal
{"timestamp": {"seconds": 1461880188, "microseconds": 107251}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": 1461880188, "microseconds": 107550}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "drive-ide0-1-0", "tray-open": true}}

qemu: speed up tests

[zsh|matt@nerr-2]:~/src/github.com/digitalocean/go-qemu 0 (master) ± go test ./...
ok      github.com/digitalocean/go-qemu 4.004s
ok      github.com/digitalocean/go-qemu/hypervisor      0.002s
ok      github.com/digitalocean/go-qemu/internal/shellexec      0.002s
ok      github.com/digitalocean/go-qemu/internal/virsh  0.014s
ok      github.com/digitalocean/go-qemu/qmp     0.002s

Let's do what we can to make qemu tests as fast as the other packages; or at least, sub 1-second if possible.

Add a CONTRIBUTING.md

Create a guide to contributing to this project. Explain the code quality standards that are expected in a submission, adding a person's name to AUTHORS, etc.

Reduce cyclomatic complexity of mockMonitor.Run

Gocyclo calculates cyclomatic complexities of functions in Go source code. The cyclomatic complexity of a function is calculated according to the following rules: 1 is the base complexity of a function +1 for each 'if', 'for', 'case', '&&' or '||'

go-qemu/mock_test.go
Line 53: warning: cyclomatic complexity 18 of function (mockMonitor).Run() is high (> 15) (gocyclo)

qemu: consider moving to github.com/digitalocean/go-qemu/qemu

For a long time, I didn't like the pattern I mentioned in the title.

Now, I find it pretty aggravating when repo and package names differ, because it's a surprise that you won't find out unless you explicitly check the code or docs.

Moving package qemu to a "subpackage" would also help clarify that this repository is a collection of packages for interacting with QEMU.

On the other hand, right now, it's front and center, and the first thing users see. That's arguably something we want to preserve as well.

Thoughts?

libvirtrpc: malformed error message when issuing command to powered-off domain

Test program:

package main

import (
    "log"
    "net"
    "time"

    "github.com/digitalocean/go-qemu"
    "github.com/digitalocean/go-qemu/qmp/libvirtrpc"
)

func main() {
    c, err := net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
    if err != nil {
        log.Fatalf("failed to dial libvirt: %v", err)
    }

    mon := libvirtrpc.New("ubuntuvm0", c)
    if err := mon.Connect(); err != nil {
        log.Fatalf("failed to connect monitor: %v", err)
    }

    dom, err := qemu.NewDomain(mon, "ubuntuvm0")
    if err != nil {
        log.Fatalf("failed to create domain: %v", err)
    }

    _, err = dom.Version()
    if err != nil {
        log.Fatalf("failed to retrieve version: %v", err)
    }
}

Libvirt and QEMU versions:

[zsh|matt@servnerr-2]:~ 0 % virsh version
Compiled against library: libvirt 1.2.2
Using library: libvirt 1.2.2
Using API: QEMU 1.2.2
Running hypervisor: QEMU 2.0.0

Error output:

2016/05/03 16:33:58 failed to retrieve version: 
7Requested operation is not valid: domain is

*: add example usage binaries

Add binaries which demonstrate usage of these packages, and make them easy to build and run to figure out how everything fits together.

qemu: add additional methods to the Domain type

qemu.Domain is the type which enables high-level interactions with QEMU. Adding functionality to it generally requires the following steps:

  • issue a qmp.Cmd with appropriate parameters
  • unmarshal response JSON into anonymous struct
  • process anonymous struct into useful data
  • return to caller

As an example, see the source for https://godoc.org/github.com/digitalocean/go-qemu#Domain.Version.

Over time, we will ideally be able to implement methods for each supported QMP command from this document: https://github.com/qemu/qemu/blob/master/qmp-commands.hx.

This will be a long-standing issue and additional issues should be created for each new method to be added. Contributions are very welcome!

qemu: simplify testing, remove mockMonitor in tests

mock_monitor is too complex, we need to simplify testing. Something like:

func TestBlockStats(t *testing.T) {
    dom := testDomain(t, func(t *testing.T, cmd qmp.Cmd) interface{} {
        if qmp.Cmd != "query-blockstats" // error

        return BlockStats{
            Device: "ide0-0",
        }
    })

    if err := dom.BlockStats(); err != nil {
        //
    }
}

ci: remove scripts/golint.sh, replace with built-in golint flag

golint has a flag that causes it to exit with non-zero status, rendering our CI build script for this purpose obsolete.

Replace with golint -set_exit_status ./... in CI.

This is an easy Hacktoberfest contribution, so I'll leave this unfixed for a few days. Feel free to submit a PR to fix this and work toward that t-shirt!

libvirtrpc: flappy test: TestEvents

=== RUN   TestEvents
--- FAIL: TestEvents (1.13s)
    rpc_test.go:472: expected event, received timeout
    rpc_test.go:477: expected device "drive-ide0-0-0", got %!q(<nil>)

Can be reproduced in a shell:

while true; do go test -v -run=TestEvents github.com/digitalocean/go-qemu/qmp/libvirtrpc ; done

qmp: consider deprecating LibvirtShellMonitor

It got us started on this project, but at this point, I think that the RPC monitor is stable enough to totally replace the shell monitor when using libvirt.

Thoughts @digitalocean/go-qemu ?

libvirtrpc: invalid character '\x00' after top-level value

Test program:

package main

import (
    "log"
    "net"
    "time"

    "github.com/digitalocean/go-qemu"
    "github.com/digitalocean/go-qemu/qmp/libvirtrpc"
)

func main() {
    c, err := net.DialTimeout("unix", "/var/run/libvirt/libvirt-sock", 2*time.Second)
    if err != nil {
        log.Fatalf("failed to dial libvirt: %v", err)
    }

    mon := libvirtrpc.New("ubuntuvm0", c)
    if err := mon.Connect(); err != nil {
        log.Fatalf("failed to connect monitor: %v", err)
    }

    dom, err := qemu.NewDomain(mon, "ubuntuvm0")
    if err != nil {
        log.Fatalf("failed to create domain: %v", err)
    }

    _, err = dom.Version()
    if err != nil {
        log.Fatalf("failed to retrieve version: %v", err)
    }
}

Libvirt and QEMU versions:

[zsh|matt@servnerr-2]:~ 0 % virsh version
Compiled against library: libvirt 1.2.2
Using library: libvirt 1.2.2
Using API: QEMU 1.2.2
Running hypervisor: QEMU 2.0.0

Error output:

2016/05/03 16:44:55 failed to retrieve version: invalid character '\x00' after top-level value

Start New Machine Instances

Hi,

Thanks for the great library. Btw, is there any examples of how to start a new machine? Is starting new machine is the same API with NewDomain? What about image configuration, etc?

Thank you

qmp: allow NewLibvirtMonitor to utilize multiple libvirt "drivers"

In order to avoid exposing too many options for qmp.Monitor types that interact with libvirt, we may be able to mask them all behind a new parameter in the qmp.NewLibvirtMonitor constructor.

Currently, the constructor looks like:

func NewLibvirtMonitor(uri, domain string) (*Libvirt, error)

The proposed constructor could be something like:

func NewLibvirtMonitor(driver LibvirtDriver, uri, domain string) (*Libvirt, error) {

Where driver could be one of the following:

type LibvirtDriver int

const (
    LibvirtDriverShell LibvirtDriver = iota
    LibvirtDriverRPC   LibvirtDriver
    LibvirtDriverCgo   LibvirtDriver
)

The shell driver is already implemented, and the native RPC driver is well underway. The cgo driver could be added in a future PR, and guarded with build tags to make it a no-op unless compiled with the correct tags.

Bindings fail to run on libvirtd 1.3.1 with Go 1.7

Hello,

I was testing out these binding in a environment running libvirtd 1.3.1 and QEMU 2.5.0 and observed the following behavior:

vagrant@localhost:/kvmhost$ ./main --domainName smoketestvm2

Connecting to unix:///var/run/libvirt/libvirt-sock
2016/10/31 13:50:28 failed to create domain object: xdr:DecodeUint: EOF while decoding 4 bytes - read: '[]'
vagrant@localhost:/kvmhost$ virsh list
 Id    Name                           State
----------------------------------------------------
 4     smoketestvm2                   running

Has anything changed significantly between libvirtd 1.2.{1,2} and/or QEMU versions that has broken the bindings?

Would appreciate any insight into this.

libvirtrpc: goroutine leak when hypervisor has no domains running

Virsh output:

[zsh|matt@nerr-2]:~ 0 % virsh list
 Id    Name                           State
----------------------------------------------------

[zsh|matt@nerr-2]:~ 0 % virsh version
Compiled against library: libvirt 1.2.2
Using library: libvirt 1.2.2
Using API: QEMU 1.2.2
Running hypervisor: QEMU 2.0.0

Test program: https://gist.github.com/mdlayher/30e4b344f46a5627ae923bb2fc49248d.
Program output: https://gist.github.com/mdlayher/bdcc40bd09f16ea3d4c4d8e53634cf5d

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.