GithubHelp home page GithubHelp logo

digitalocean / go-qemu Goto Github PK

View Code? Open in Web Editor NEW
699.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 Issues

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.

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.

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)

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!

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 :).

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

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

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 ?

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.

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 {
        //
    }
}

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

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

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!

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

*: 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.

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.

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?

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.