Skip to content
Switch branches/tags
Go to file

Latest commit

This reverts commit 90777c7.

Adding the go.mod file had unexpected consequences for consumers of the
libvirt-go bindings, because in 1.16 it is not strongly enforced that
libraries using modules are following semver versioning.

The libvirt-go binding has always followed libvirt native API versions
1:1 and thus uses calver, not semver.  All libvirt native API versions
are backwards compatible indefinitely, and the Go bindings aim to keep
the same promise. With this in mind, it would be wrong to re-interpret
the current libvirt-go version tags as being semver, as that will
appear like an ABI break once a year when libvirt changes major version.

As a result of adding the go.mod file, consumers are unable to upgrade
to libvirt-go > 7.0.0, because Go will refuse to use v7.1.0+incompatible

  go.mod:8:2: require version "v7.2.0" invalid: should be v0 or v1, not v7

Effectively with modern Go, a program can only consume dependancies
using calver if those deps do not provide a go.mod

Changing libvirt-go to use semver would require choosing one of the
various undesirable options

 1. Delete all existing tags and go back to a v1.<libvirt version>
    scheme. Trashing history is undesirable in general, and hard
    because Go module proxy server caches tags in a append-only,
    so will remember existing tags even if the repo deletes them.

 2. Rename the repo, and do (1), to get around the Go module proxy

 3. Pick a new major version (eg v10) and use v10.<libvirt version>
    here after. Move all files under the v10/ directory and have
    all consumers update to the new import path. This is declaring
    that the new version is incompatible with all previous versions
    which is not actually true. This needlessly creates an interop
    problem until all consumers have updated.

The simplest way out of the problem in the short term at least, is
to simply stop providing go.mod for libvirt-go, at which point the
non-semver tags can be used by consumers as has been the case

There's a risk that future Go releases might get even more strict
and eventually break non-semver usage even in the case without
go.mod, but at that time we'll be no worse off then now. So it is
worth just backtracking from use of go.mod for now.

To deal with the problem 90777c7
describes, we set GO111MODULE=auto to allow non-modular builds
outside of a GOPATH hierarchy.

Signed-off-by: Daniel P. Berrangé <>

Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status API Documentation

Go bindings for libvirt.

Make sure to have libvirt-dev package (or the development files otherwise somewhere in your include path)

Version Support

The libvirt go package provides API coverage for libvirt versions from 1.2.0 onwards, through conditional compilation of newer APIs.

By default the binding will support APIs in, and Coverage for the latter two libraries can be dropped from the build using build tags 'without_qemu' or 'without_lxc' respectively.

Development status

The Go API is considered to be production ready and aims to be kept stable across future versions. Note, however, that the following changes may apply to future versions:

  • Existing structs can be augmented with new fields, but no existing fields will be changed / removed. New fields are needed when libvirt defines new typed parameters for various methods
  • Any method with an 'flags uint32' parameter will have its parameter type changed to a specific typedef, if & when the libvirt API defines constants for the flags. To avoid breakage, always pass a literal '0' to any 'flags uint32' parameter, since this will auto-cast to any future typedef that is introduced.



The libvirt project aims to add support for new APIs to libvirt-go as soon as they are added to the main libvirt C library. If you are submitting changes to the libvirt C library API, please submit a libvirt-go change at the same time. Bug fixes and other improvements to the libvirt-go library are welcome at any time.

For more information, see the CONTRIBUTING file.


The core API unit tests are all written to use the built-in test driver (test:///default), so they have no interaction with the host OS environment.

Coverage of libvirt C library APIs / constants is verified using automated tests. These can be run by passing the 'api' build tag. eg go test -tags api

For areas where the test driver lacks functionality, it is possible to use the QEMU or LXC drivers to exercise code. Such tests must be part of the 'integration_test.go' file though, which is only run when passing the 'integration' build tag. eg go test -tags integration

In order to run the unit tests, libvirtd should be configured to allow your user account read-write access with no passwords. This can be easily done using polkit config files

# cat > /etc/polkit-1/localauthority/50-local.d/50-libvirt.pkla  <<EOF
[Passwordless libvirt access]

(Replace 'berrange' with your UNIX user name).

Two of the integration tests also requires that libvirtd is listening for TCP connections on localhost, with sasl auth This can be setup by editing /etc/libvirt/libvirtd.conf to set


and then start libvirtd with the --listen flag (this can be set in /etc/sysconfig/libvirtd to make it persistent).

sasl authentication must be configured to use either digest-md5 or scram-sha-1, and the needed sasl modules must be installed on the system.

Then create a sasl user

$ saslpasswd2 -a libvirt user

and enter "pass" as the password.

Alternatively a Vagrantfile, requiring use of virtualbox, is included to run the integration tests:

  • cd ./vagrant
  • vagrant up to provision the virtual machine
  • vagrant ssh to login to the virtual machine

Once inside, sudo su - and go test -tags integration libvirt.