Generate the remaining consts. (#55)
* Generate the remaining consts. There were a number of hand-written consts in go-libvirt, including flag values for various libvirt functions. Remove these and generate them instead, so that we now have a complete set, and the naming is consistent. I used c-for-go to do this generation, but turned off any cgo usage by the generated code - we don't want or need to introduce a dependency on cgo just to get constants from C headers. All code is still generated using 'go generate ./...', which now calls a wrapper script for added robustness. This change also returns to using Go types for flags for most libvirt functions, instead of plain integers.
This commit is contained in:
parent
1a220100bd
commit
59d541f193
66
README.md
66
README.md
@ -1,14 +1,14 @@
|
|||||||
libvirt [![GoDoc](http://godoc.org/github.com/digitalocean/go-libvirt?status.svg)](http://godoc.org/github.com/digitalocean/go-libvirt) [![Build Status](https://travis-ci.org/digitalocean/go-libvirt.svg?branch=master)](https://travis-ci.org/digitalocean/go-libvirt) [![Report Card](https://goreportcard.com/badge/github.com/digitalocean/go-libvirt)](https://goreportcard.com/report/github.com/digitalocean/go-libvirt)
|
libvirt [![GoDoc](http://godoc.org/github.com/digitalocean/go-libvirt?status.svg)](http://godoc.org/github.com/digitalocean/go-libvirt) [![Build Status](https://travis-ci.org/digitalocean/go-libvirt.svg?branch=master)](https://travis-ci.org/digitalocean/go-libvirt) [![Report Card](https://goreportcard.com/badge/github.com/digitalocean/go-libvirt)](https://goreportcard.com/report/github.com/digitalocean/go-libvirt)
|
||||||
====
|
====
|
||||||
|
|
||||||
Package `libvirt` provides a pure Go interface for interacting with Libvirt.
|
Package `go-libvirt` provides a pure Go interface for interacting with libvirt.
|
||||||
|
|
||||||
Rather than using Libvirt's C bindings, this package makes use of
|
Rather than using Libvirt's C bindings, this package makes use of
|
||||||
Libvirt's RPC interface, as documented [here](https://libvirt.org/internals/rpc.html).
|
libvirt's RPC interface, as documented [here](https://libvirt.org/internals/rpc.html).
|
||||||
Connections to the libvirt server may be local, or remote. RPC packets are encoded
|
Connections to the libvirt server may be local, or remote. RPC packets are encoded
|
||||||
using the XDR standard as defined by [RFC 4506](https://tools.ietf.org/html/rfc4506.html).
|
using the XDR standard as defined by [RFC 4506](https://tools.ietf.org/html/rfc4506.html).
|
||||||
|
|
||||||
Libvirt's RPC interface is quite extensive, and changes from one version to the next, so
|
libvirt's RPC interface is quite extensive, and changes from one version to the next, so
|
||||||
this project uses a code generator to build the go bindings. The code generator should
|
this project uses a code generator to build the go bindings. The code generator should
|
||||||
be run whenever you want to build go-libvirt for a new version of libvirt. To do this,
|
be run whenever you want to build go-libvirt for a new version of libvirt. To do this,
|
||||||
you'll need to set an environment variable `LIBVIRT_SOURCE` to the directory containing
|
you'll need to set an environment variable `LIBVIRT_SOURCE` to the directory containing
|
||||||
@ -18,8 +18,64 @@ and produces go bindings for all the remote procedures defined there.
|
|||||||
|
|
||||||
[Pull requests are welcome](https://github.com/digitalocean/go-libvirt/blob/master/CONTRIBUTING.md)!
|
[Pull requests are welcome](https://github.com/digitalocean/go-libvirt/blob/master/CONTRIBUTING.md)!
|
||||||
|
|
||||||
Feel free to join us in [`#go-qemu` on freenode](https://webchat.freenode.net/)
|
How to Use This Library
|
||||||
if you'd like to discuss the project.
|
-----------------------
|
||||||
|
Once you've vendored go-libvirt into your project, you'll probably want to call
|
||||||
|
some libvirt functions. There's some example code below showing how to connect
|
||||||
|
to libvirt and make one such call, but once you get past the introduction you'll
|
||||||
|
next want to call some other libvirt functions. How do you find them?
|
||||||
|
|
||||||
|
Start with the [libvirt API reference](https://libvirt.org/html/index.html).
|
||||||
|
Let's say you want to gracefully shutdown a VM, and after reading through the
|
||||||
|
libvirt docs you determine that virDomainShutdown() is the function you want to
|
||||||
|
call to do that. Where's that function in go-libvirt? We transform the names
|
||||||
|
slightly when building the go bindings. There's no need for a global prefix like
|
||||||
|
"vir" in Go, since all our functions are inside the package namespace, so we
|
||||||
|
drop it. That means the Go function for `virDomainShutdown()` is just `DomainShutdown()`,
|
||||||
|
and sure enough, you can find the Go function `DomainShutdown()` in libvirt.gen.go,
|
||||||
|
with parameters and return values equivalent to those documented in the API
|
||||||
|
reference.
|
||||||
|
|
||||||
|
Suppose you then decide you need more control over your shutdown, so you switch
|
||||||
|
over to `virDomainShutdownFlags()`. As its name suggests, this function takes a
|
||||||
|
flag parameter which has possible values specified in an enum called
|
||||||
|
`virDomainShutdownFlagValues`. Flag types like this are a little tricky for the
|
||||||
|
code generator, because the C functions just take an integer type - only the
|
||||||
|
libvirt documentation actually ties the flags to the enum types. In most cases
|
||||||
|
though we're able to generate a wrapper function with a distinct flag type,
|
||||||
|
making it easier for Go tooling to suggest possible flag values while you're
|
||||||
|
working. Checking the documentation for this function:
|
||||||
|
|
||||||
|
`godoc github.com/digitalocean/go-libvirt DomainShutdownFlags`
|
||||||
|
|
||||||
|
returns this:
|
||||||
|
|
||||||
|
`func (l *Libvirt) DomainShutdownFlags(Dom Domain, Flags DomainShutdownFlagValues) (err error)`
|
||||||
|
|
||||||
|
If you want to see the possible flag values, `godoc` can help again:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ godoc github.com/digitalocean/go-libvirt DomainShutdownFlagValues
|
||||||
|
|
||||||
|
type DomainShutdownFlagValues int32
|
||||||
|
DomainShutdownFlagValues as declared in libvirt/libvirt-domain.h:1121
|
||||||
|
|
||||||
|
const (
|
||||||
|
DomainShutdownDefault DomainShutdownFlagValues = iota
|
||||||
|
DomainShutdownAcpiPowerBtn DomainShutdownFlagValues = 1
|
||||||
|
DomainShutdownGuestAgent DomainShutdownFlagValues = 2
|
||||||
|
DomainShutdownInitctl DomainShutdownFlagValues = 4
|
||||||
|
DomainShutdownSignal DomainShutdownFlagValues = 8
|
||||||
|
DomainShutdownParavirt DomainShutdownFlagValues = 16
|
||||||
|
)
|
||||||
|
DomainShutdownFlagValues enumeration from libvirt/libvirt-domain.h:1121
|
||||||
|
```
|
||||||
|
|
||||||
|
One other suggestion: most of the code in go-libvirt is now generated, but a few
|
||||||
|
hand-written routines still exist in libvirt.go, and wrap calls to the generated
|
||||||
|
code with slightly different parameters or return values. We suggest avoiding
|
||||||
|
these hand-written routines and calling the generated routines in libvirt.gen.go
|
||||||
|
instead. Over time these handwritten routines will be removed from go-libvirt.
|
||||||
|
|
||||||
Warning
|
Warning
|
||||||
-------
|
-------
|
||||||
|
1995
const.gen.go
Normal file
1995
const.gen.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@ package lvgen
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/ast"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -23,6 +24,8 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
"unicode"
|
"unicode"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/loader"
|
||||||
)
|
)
|
||||||
|
|
||||||
// If you're making changes to the generator, or troubleshooting the generated
|
// If you're making changes to the generator, or troubleshooting the generated
|
||||||
@ -375,6 +378,8 @@ func fixAbbrevs(s string) string {
|
|||||||
// defined in the protocol file. If one or both of these structs is not defined
|
// defined in the protocol file. If one or both of these structs is not defined
|
||||||
// then either the args or return values are empty.
|
// then either the args or return values are empty.
|
||||||
func procLink() {
|
func procLink() {
|
||||||
|
flagTypes := mapFlagTypes()
|
||||||
|
|
||||||
for ix, proc := range Gen.Procs {
|
for ix, proc := range Gen.Procs {
|
||||||
argsName := proc.Name + "Args"
|
argsName := proc.Name + "Args"
|
||||||
retName := proc.Name + "Ret"
|
retName := proc.Name + "Ret"
|
||||||
@ -383,6 +388,7 @@ func procLink() {
|
|||||||
if hasArgs {
|
if hasArgs {
|
||||||
argsStruct := Gen.Structs[argsIx]
|
argsStruct := Gen.Structs[argsIx]
|
||||||
Gen.Procs[ix].ArgsStruct = argsStruct.Name
|
Gen.Procs[ix].ArgsStruct = argsStruct.Name
|
||||||
|
changeFlagType(proc.Name, &argsStruct, flagTypes)
|
||||||
Gen.Procs[ix].Args = argsStruct.Members
|
Gen.Procs[ix].Args = argsStruct.Members
|
||||||
}
|
}
|
||||||
if hasRet {
|
if hasRet {
|
||||||
@ -393,6 +399,138 @@ func procLink() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mapFlagTypes builds a map of the C types which appear to correspond to the
|
||||||
|
// various flags fields in libvirt calls. Determining whether a type actually
|
||||||
|
// corresponds to a set of flags is done by pattern matching the type name;
|
||||||
|
// libvirt isn't completely consistent about the names of flag types, but they
|
||||||
|
// all seem to have one of three suffixes, so that's what we look for here.
|
||||||
|
//
|
||||||
|
// This code uses the loader package to load the constants file generated by
|
||||||
|
// c-for-go, which runs against libvirt's C sources. This file is generated by
|
||||||
|
// 'go generate ./...' prior to the lvgen/ generator being run.
|
||||||
|
func mapFlagTypes() map[string]ast.Expr {
|
||||||
|
pconf := loader.Config{}
|
||||||
|
f, err := pconf.ParseFile("../../const.gen.go", nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintln("failed to read constants file: ", err))
|
||||||
|
}
|
||||||
|
pconf.CreateFromFiles("const", f)
|
||||||
|
prog, err := pconf.Load()
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintln("failed to load package: ", err))
|
||||||
|
}
|
||||||
|
cpkg := prog.Package("const")
|
||||||
|
|
||||||
|
tmap := make(map[string]ast.Expr)
|
||||||
|
ast.Inspect(cpkg.Files[0], func(n ast.Node) bool {
|
||||||
|
switch t := n.(type) {
|
||||||
|
case *ast.TypeSpec:
|
||||||
|
// There isn't a single name pattern that covers all of the flag
|
||||||
|
// types, so we'll collect all the types that map to int32 here.
|
||||||
|
if fmt.Sprintf("%s", t.Type) == "int32" {
|
||||||
|
tmap[t.Name.String()] = t.Type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
return tmap
|
||||||
|
}
|
||||||
|
|
||||||
|
// Many libvirt calls use flags whose values come from a set of definitions
|
||||||
|
// whose name we can't predict. So this map exists to do the translation for us.
|
||||||
|
// The only way to remove this fragile map would be to use the comments from the
|
||||||
|
// .c files in libvirt, which contain doxygen-style parameter comments that
|
||||||
|
// specify the valid value types for flags.
|
||||||
|
var flagMap = map[string]string{
|
||||||
|
"ConnectOpen": "ConnectFlags",
|
||||||
|
"DomainAddIothread": "DomainModificationImpact",
|
||||||
|
"DomainCoreDumpWithFormat": "DomainCoreDumpFlags",
|
||||||
|
"DomainCreateXML": "DomainCreateFlags",
|
||||||
|
"DomainCreateWithFiles": "DomainCreateFlags",
|
||||||
|
"DomainCreateXMLWithFiles": "DomainCreateFlags",
|
||||||
|
"DomainDefineXMLFlags": "DomainDefineFlags",
|
||||||
|
"DomainDelIothread": "DomainModificationImpact",
|
||||||
|
"DomainDestroyFlags": "DomainDestroyFlagsValues",
|
||||||
|
"DomainGetCPUStats": "TypedParameterFlags",
|
||||||
|
"DomainGetEmulatorPinInfo": "DomainModificationImpact",
|
||||||
|
"DomainGetInterfaceParameters": "DomainModificationImpact",
|
||||||
|
"DomainGetIothreadInfo": "DomainModificationImpact",
|
||||||
|
"DomainGetMetadata": "DomainModificationImpact",
|
||||||
|
"DomainGetPerfEvents": "DomainModificationImpact",
|
||||||
|
"DomainGetXMLDesc": "DomainXMLFlags",
|
||||||
|
"DomainManagedSaveDefineXML": "DomainSaveRestoreFlags",
|
||||||
|
"DomainManagedSaveGetXMLDesc": "DomainXMLFlags",
|
||||||
|
"DomainMemoryPeek": "DomainMemoryFlags",
|
||||||
|
"DomainMigratePerform3Params": "DomainMigrateFlags",
|
||||||
|
"DomainOpenChannel": "DomainChannelFlags",
|
||||||
|
"DomainOpenGraphicsFd": "DomainOpenGraphicsFlags",
|
||||||
|
"DomainPinEmulator": "DomainModificationImpact",
|
||||||
|
"DomainPinIothread": "DomainModificationImpact",
|
||||||
|
"DomainSetLifecycleAction": "DomainModificationImpact",
|
||||||
|
"DomainSetMemoryStatsPeriod": "DomainMemoryModFlags",
|
||||||
|
"DomainSetMetadata": "DomainModificationImpact",
|
||||||
|
"DomainSetPerfEvents": "DomainModificationImpact",
|
||||||
|
"DomainSetVcpu": "DomainModificationImpact",
|
||||||
|
"DomainShutdownFlags": "DomainShutdownFlagValues",
|
||||||
|
"DomainUndefineFlags": "DomainUndefineFlagsValues",
|
||||||
|
"StoragePoolCreateXML": "StoragePoolCreateFlags",
|
||||||
|
"StoragePoolGetXMLDesc": "StorageXMLFlags",
|
||||||
|
"StorageVolCreateXML": "StorageVolCreateFlags",
|
||||||
|
"StorageVolCreateXMLFrom": "StorageVolCreateFlags",
|
||||||
|
}
|
||||||
|
|
||||||
|
// findFlagType attempts to find a real type for the flags passed to a given
|
||||||
|
// libvirt routine.
|
||||||
|
func findFlagType(procName string, flagTypes map[string]ast.Expr) (string, bool) {
|
||||||
|
flagName, ok := flagMap[procName]
|
||||||
|
if ok {
|
||||||
|
// Verify the mapped name exists
|
||||||
|
if _, ok = flagTypes[flagName]; ok == false {
|
||||||
|
// If one of the manual flag mappings is wrong, complain but
|
||||||
|
// continue. This happens with older versions of libvirt.
|
||||||
|
fmt.Printf("manual flag type %v for %v not found, continuing", flagName, procName)
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
return flagName, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not in the manual map, so do a search using the 3 patterns libvirt uses.
|
||||||
|
tnames := [...]string{procName + "Flags", procName + "FlagValues", procName + "FlagsValues"}
|
||||||
|
for _, n := range tnames {
|
||||||
|
if _, ok := flagTypes[n]; ok == true {
|
||||||
|
return n, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
|
||||||
|
// changeFlagType looks up the go type for a libvirt call's flags field. In C
|
||||||
|
// these flags are all uint32, and you have to consult the documentation to
|
||||||
|
// determine what the valid set of flags is for a given libvirt call. For Go
|
||||||
|
// we're attempting to do better by specifying an actual type so that the
|
||||||
|
// possible values are easier to determine. This is a heuristic, however, based
|
||||||
|
// on naming patterns in the libvirt code. To do better we would need to look at
|
||||||
|
// the doxygen-style comments in the libvirt sources.
|
||||||
|
//
|
||||||
|
// Failing to find a flags type isn't a fatal error, it just means that we'll
|
||||||
|
// leave the flags with a type of uint32.
|
||||||
|
func changeFlagType(procName string, s *Structure, flagTypes map[string]ast.Expr) {
|
||||||
|
for ix, d := range s.Members {
|
||||||
|
if d.Name == "Flags" {
|
||||||
|
tname, found := findFlagType(procName, flagTypes)
|
||||||
|
|
||||||
|
if found {
|
||||||
|
s.Members[ix].Type = tname
|
||||||
|
} else {
|
||||||
|
// If you're adding procedures to to the manual map, you may
|
||||||
|
// want to uncomment this to see what flag types are not found.
|
||||||
|
// fmt.Println("flags type for", procName, "not found")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Routines called by the parser's actions.
|
// Routines called by the parser's actions.
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@ -592,7 +730,6 @@ func AddOptValue(identifier, itype string) {
|
|||||||
atype := "[]" + itype
|
atype := "[]" + itype
|
||||||
decl := NewDecl(identifier, atype)
|
decl := NewDecl(identifier, atype)
|
||||||
newType := "Opt" + decl.Name
|
newType := "Opt" + decl.Name
|
||||||
fmt.Printf("Adding mapping %v = %v\n", decl.Name, newType)
|
|
||||||
goEquivTypes[decl.Name] = newType
|
goEquivTypes[decl.Name] = newType
|
||||||
decl.Name = newType
|
decl.Name = newType
|
||||||
addDecl(decl)
|
addDecl(decl)
|
||||||
|
264
libvirt.gen.go
264
libvirt.gen.go
File diff suppressed because it is too large
Load Diff
438
libvirt.go
438
libvirt.go
@ -16,6 +16,10 @@
|
|||||||
// For more information on the protocol, see https://libvirt.org/internals/l.html
|
// For more information on the protocol, see https://libvirt.org/internals/l.html
|
||||||
package libvirt
|
package libvirt
|
||||||
|
|
||||||
|
// We'll use c-for-go to extract the consts and typedefs from the libvirt
|
||||||
|
// sources so we don't have to duplicate them here.
|
||||||
|
//go:generate scripts/gen-consts.sh
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -34,7 +38,7 @@ import (
|
|||||||
// are unsupported by either QEMU or libvirt.
|
// are unsupported by either QEMU or libvirt.
|
||||||
var ErrEventsNotSupported = errors.New("event monitor is not supported")
|
var ErrEventsNotSupported = errors.New("event monitor is not supported")
|
||||||
|
|
||||||
// Libvirt implements LibVirt's remote procedure call protocol.
|
// Libvirt implements libvirt's remote procedure call protocol.
|
||||||
type Libvirt struct {
|
type Libvirt struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
r *bufio.Reader
|
r *bufio.Reader
|
||||||
@ -72,371 +76,6 @@ type qemuError struct {
|
|||||||
} `json:"error"`
|
} `json:"error"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DomainXMLFlags specifies options for dumping a domain's XML.
|
|
||||||
type DomainXMLFlags uint32
|
|
||||||
|
|
||||||
// DomainAffectFlags specifies options for whether an operation affects the
|
|
||||||
// running VM, or the persistent VM configuration on disk. See FlagDomain...
|
|
||||||
// consts for values.
|
|
||||||
type DomainAffectFlags uint32
|
|
||||||
|
|
||||||
// Consts used for flags
|
|
||||||
|
|
||||||
// virDomainModificationImpact and virTypedParameterFlags values. These are
|
|
||||||
// combined here because they are both used to set the same flags fields in the
|
|
||||||
// libvirt API.
|
|
||||||
const (
|
|
||||||
// FlagDomainAffectCurrent means affect the current domain state
|
|
||||||
FlagDomainAffectCurrent DomainAffectFlags = 0
|
|
||||||
// FlagDomainAffectLive means affect the running domain state
|
|
||||||
FlagDomainAffectLive = 1 << (iota - 1)
|
|
||||||
// FlagDomainAffectConfig means affect the persistent domain state.
|
|
||||||
FlagDomainAffectConfig
|
|
||||||
// FlagTypedParamStringOkay tells the server that this client understands
|
|
||||||
// TypedParamStrings.
|
|
||||||
FlagTypedParamStringOkay
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DomainXMLFlagSecure dumps XML with sensitive information included.
|
|
||||||
DomainXMLFlagSecure DomainXMLFlags = 1 << iota
|
|
||||||
|
|
||||||
// DomainXMLFlagInactive dumps XML with inactive domain information.
|
|
||||||
DomainXMLFlagInactive
|
|
||||||
|
|
||||||
// DomainXMLFlagUpdateCPU dumps XML with guest CPU requirements according to the host CPU.
|
|
||||||
DomainXMLFlagUpdateCPU
|
|
||||||
|
|
||||||
// DomainXMLFlagMigratable dumps XML suitable for migration.
|
|
||||||
DomainXMLFlagMigratable
|
|
||||||
)
|
|
||||||
|
|
||||||
// scheduler parameters used as fields in TypedParam by the following functions:
|
|
||||||
// DomainGetSchedulerParameters
|
|
||||||
// DomainGetSchedulerParametersFlags
|
|
||||||
// DomainSetSchedulerParameters
|
|
||||||
// DomainSetSchedulerParametersFlags
|
|
||||||
const (
|
|
||||||
// DomainSchedulerCPUShares represents the propportional weight
|
|
||||||
// of the scheduler used on the host cpu, when using the posix
|
|
||||||
// scheduler. (ullong)
|
|
||||||
DomainSchedulerCPUShares = "cpu_shares"
|
|
||||||
|
|
||||||
// DomainSchedulerGlobalPeriod represents the enforcement period
|
|
||||||
// for a quota, in microseconds, for whole domain, when using the
|
|
||||||
// posix scheduler. (ullong)
|
|
||||||
DomainSchedulerGlobalPeriod = "global_period"
|
|
||||||
|
|
||||||
// DomainSchedulerGlobalQuota represents the maximum bandwidth to be
|
|
||||||
// used within a period for whole domain, when using the posix
|
|
||||||
// scheduler. (llong)
|
|
||||||
DomainSchedulerGlobalQuota = "global_quota"
|
|
||||||
|
|
||||||
// DomainSchedulerVCPUPeriod represents the enforcement period for a
|
|
||||||
// quota, in microseconds, for vcpus only, when using the posix
|
|
||||||
// scheduler. (ullong)
|
|
||||||
DomainSchedulerVCPUPeriod = "vcpu_period"
|
|
||||||
|
|
||||||
// DomainSchedulerVCPUQuota represents the maximum bandwidth to be
|
|
||||||
// used within a period for vcpus only, when using the posix
|
|
||||||
// scheduler. (llong)
|
|
||||||
DomainSchedulerVCPUQuota = "vcpu_quota"
|
|
||||||
|
|
||||||
// DomainSchedulerEmulatorPeriod represents the enforcement period
|
|
||||||
// for a quota in microseconds, when using the posix scheduler, for
|
|
||||||
// all emulator activity not tied to vcpus. (ullong)
|
|
||||||
DomainSchedulerEmulatorPeriod = "emulator_period"
|
|
||||||
|
|
||||||
// DomainSchedulerEmulatorQuota represents the maximum bandwidth to be
|
|
||||||
// used within a period for all emulator activity not tied to vcpus,
|
|
||||||
// when using the posix scheduler. (llong)
|
|
||||||
DomainSchedulerEmulatorQuota = "emulator_quota"
|
|
||||||
|
|
||||||
// DomainSchedulerIOThreadPeriod represents the enforcement period for
|
|
||||||
// a quota, in microseconds, for IOThreads only, when using the posix
|
|
||||||
// scheduler. (ullong)
|
|
||||||
DomainSchedulerIOThreadPeriod = "iothread_period"
|
|
||||||
|
|
||||||
// DomainSchedulerIOThreadQuota represents the maximum bandwidth to be
|
|
||||||
// used within a period for IOThreads only, when using the posix
|
|
||||||
// scheduler. (llong)
|
|
||||||
DomainSchedulerIOThreadQuota = "iothread_quota"
|
|
||||||
|
|
||||||
// DomainSchedulerWeight represents the relative weight, when using the
|
|
||||||
// credit scheduler. (uint)
|
|
||||||
DomainSchedulerWeight = "weight"
|
|
||||||
|
|
||||||
// DomainSchedulerCap represents the maximum scheduler cap, when using
|
|
||||||
// the credit scheduler. (uint)
|
|
||||||
DomainSchedulerCap = "cap"
|
|
||||||
|
|
||||||
// DomainSchedulerReservation represents the scheduler reservation
|
|
||||||
// value, when using the allocation scheduler. (llong)
|
|
||||||
DomainSchedulerReservation = "reservation"
|
|
||||||
|
|
||||||
// DomainSchedulerLimit represents the scheduler limit value, when using
|
|
||||||
// the allocation scheduler. (llong)
|
|
||||||
DomainSchedulerLimit = "limit"
|
|
||||||
|
|
||||||
// DomainSchedulerShares represents the scheduler shares value, when
|
|
||||||
// using the allocation scheduler. (int)
|
|
||||||
DomainSchedulerShares = "shares"
|
|
||||||
)
|
|
||||||
|
|
||||||
// MigrateFlags specifies options when performing a migration.
|
|
||||||
type MigrateFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// MigrateFlagLive performs a zero-downtime live migration.
|
|
||||||
MigrateFlagLive MigrateFlags = 1 << iota
|
|
||||||
|
|
||||||
// MigrateFlagPeerToPeer creates a direct source to destination control channel.
|
|
||||||
MigrateFlagPeerToPeer
|
|
||||||
|
|
||||||
// MigrateFlagTunneled tunnels migration data over the libvirtd connection.
|
|
||||||
MigrateFlagTunneled
|
|
||||||
|
|
||||||
// MigrateFlagPersistDestination will persist the VM on the destination host.
|
|
||||||
MigrateFlagPersistDestination
|
|
||||||
|
|
||||||
// MigrateFlagUndefineSource undefines the VM on the source host.
|
|
||||||
MigrateFlagUndefineSource
|
|
||||||
|
|
||||||
// MigrateFlagPaused will pause the remote side VM.
|
|
||||||
MigrateFlagPaused
|
|
||||||
|
|
||||||
// MigrateFlagNonSharedDisk migrate non-shared storage with full disk copy.
|
|
||||||
MigrateFlagNonSharedDisk
|
|
||||||
|
|
||||||
// MigrateFlagNonSharedIncremental migrate non-shared storage with incremental copy.
|
|
||||||
MigrateFlagNonSharedIncremental
|
|
||||||
|
|
||||||
// MigrateFlagChangeProtection prevents any changes to the domain configuration through the whole migration process.
|
|
||||||
MigrateFlagChangeProtection
|
|
||||||
|
|
||||||
// MigrateFlagUnsafe will force a migration even when it is considered unsafe.
|
|
||||||
MigrateFlagUnsafe
|
|
||||||
|
|
||||||
// MigrateFlagOffline is used to perform an offline migration.
|
|
||||||
MigrateFlagOffline
|
|
||||||
|
|
||||||
// MigrateFlagCompressed compresses data during migration.
|
|
||||||
MigrateFlagCompressed
|
|
||||||
|
|
||||||
// MigrateFlagAbortOnError will abort a migration on I/O errors encountered during migration.
|
|
||||||
MigrateFlagAbortOnError
|
|
||||||
|
|
||||||
// MigrateFlagAutoConverge forces convergence.
|
|
||||||
MigrateFlagAutoConverge
|
|
||||||
|
|
||||||
// MigrateFlagRDMAPinAll enables RDMA memory pinning.
|
|
||||||
MigrateFlagRDMAPinAll
|
|
||||||
)
|
|
||||||
|
|
||||||
// UndefineFlags specifies options available when undefining a domain.
|
|
||||||
type UndefineFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// UndefineFlagManagedSave removes all domain managed save data.
|
|
||||||
UndefineFlagManagedSave UndefineFlags = 1 << iota
|
|
||||||
|
|
||||||
// UndefineFlagSnapshotsMetadata removes all domain snapshot metadata.
|
|
||||||
UndefineFlagSnapshotsMetadata
|
|
||||||
|
|
||||||
// UndefineFlagNVRAM removes all domain NVRAM files.
|
|
||||||
UndefineFlagNVRAM
|
|
||||||
)
|
|
||||||
|
|
||||||
// DomainDefineXMLFlags specifies options available when defining a domain.
|
|
||||||
type DomainDefineXMLFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DefineValidate validates the XML document against schema
|
|
||||||
DefineValidate DomainDefineXMLFlags = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
// DestroyFlags specifies options available when destroying a domain.
|
|
||||||
type DestroyFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DestroyFlagDefault default behavior, forcefully terminate the domain.
|
|
||||||
DestroyFlagDefault DestroyFlags = 1 << iota
|
|
||||||
|
|
||||||
// DestroyFlagGraceful only sends a SIGTERM no SIGKILL.
|
|
||||||
DestroyFlagGraceful
|
|
||||||
)
|
|
||||||
|
|
||||||
// ShutdownFlags specifies options available when shutting down a domain.
|
|
||||||
type ShutdownFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// ShutdownAcpiPowerBtn - send ACPI event
|
|
||||||
ShutdownAcpiPowerBtn ShutdownFlags = 1 << iota
|
|
||||||
|
|
||||||
// ShutdownGuestAgent - use guest agent
|
|
||||||
ShutdownGuestAgent
|
|
||||||
|
|
||||||
// ShutdownInitctl - use initctl
|
|
||||||
ShutdownInitctl
|
|
||||||
|
|
||||||
// ShutdownSignal - use signal
|
|
||||||
ShutdownSignal
|
|
||||||
|
|
||||||
// ShutdownParavirt - use paravirt guest control
|
|
||||||
ShutdownParavirt
|
|
||||||
)
|
|
||||||
|
|
||||||
// DomainState specifies state of the domain
|
|
||||||
type DomainState uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DomainStateNoState No state
|
|
||||||
DomainStateNoState DomainState = iota
|
|
||||||
// DomainStateRunning The domain is running
|
|
||||||
DomainStateRunning
|
|
||||||
// DomainStateBlocked The domain is blocked on resource
|
|
||||||
DomainStateBlocked
|
|
||||||
// DomainStatePaused The domain is paused by user
|
|
||||||
DomainStatePaused
|
|
||||||
// DomainStateShutdown The domain is being shut down
|
|
||||||
DomainStateShutdown
|
|
||||||
// DomainStateShutoff The domain is shut off
|
|
||||||
DomainStateShutoff
|
|
||||||
// DomainStateCrashed The domain is crashed
|
|
||||||
DomainStateCrashed
|
|
||||||
// DomainStatePMSuspended The domain is suspended by guest power management
|
|
||||||
DomainStatePMSuspended
|
|
||||||
// DomainStateLast This value will increase over time as new events are added to the libvirt
|
|
||||||
// API. It reflects the last state supported by this version of the libvirt API.
|
|
||||||
DomainStateLast
|
|
||||||
)
|
|
||||||
|
|
||||||
// SecretUsageType specifies the usage for a libvirt secret.
|
|
||||||
type SecretUsageType uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// SecretUsageTypeNone specifies no usage.
|
|
||||||
SecretUsageTypeNone SecretUsageType = iota
|
|
||||||
// SecretUsageTypeVolume specifies a volume secret.
|
|
||||||
SecretUsageTypeVolume
|
|
||||||
// SecretUsageTypeCeph specifies secrets for ceph devices.
|
|
||||||
SecretUsageTypeCeph
|
|
||||||
// SecretUsageTypeISCSI specifies secrets for ISCSI devices.
|
|
||||||
SecretUsageTypeISCSI
|
|
||||||
)
|
|
||||||
|
|
||||||
// StoragePoolsFlags specifies storage pools to list.
|
|
||||||
type StoragePoolsFlags uint32
|
|
||||||
|
|
||||||
// These flags come in groups; if all bits from a group are 0,
|
|
||||||
// then that group is not used to filter results.
|
|
||||||
const (
|
|
||||||
StoragePoolsFlagInactive = 1 << iota
|
|
||||||
StoragePoolsFlagActive
|
|
||||||
|
|
||||||
StoragePoolsFlagPersistent
|
|
||||||
StoragePoolsFlagTransient
|
|
||||||
|
|
||||||
StoragePoolsFlagAutostart
|
|
||||||
StoragePoolsFlagNoAutostart
|
|
||||||
|
|
||||||
// pools by type
|
|
||||||
StoragePoolsFlagDir
|
|
||||||
StoragePoolsFlagFS
|
|
||||||
StoragePoolsFlagNETFS
|
|
||||||
StoragePoolsFlagLogical
|
|
||||||
StoragePoolsFlagDisk
|
|
||||||
StoragePoolsFlagISCSI
|
|
||||||
StoragePoolsFlagSCSI
|
|
||||||
StoragePoolsFlagMPATH
|
|
||||||
StoragePoolsFlagRBD
|
|
||||||
StoragePoolsFlagSheepdog
|
|
||||||
StoragePoolsFlagGluster
|
|
||||||
StoragePoolsFlagZFS
|
|
||||||
)
|
|
||||||
|
|
||||||
// DomainCreateFlags specify options for starting domains
|
|
||||||
type DomainCreateFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DomainCreateFlagPaused creates paused domain.
|
|
||||||
DomainCreateFlagPaused = 1 << iota
|
|
||||||
|
|
||||||
// DomainCreateFlagAutoDestroy destoy domain after libvirt connection closed.
|
|
||||||
DomainCreateFlagAutoDestroy
|
|
||||||
|
|
||||||
// DomainCreateFlagBypassCache avoid file system cache pollution.
|
|
||||||
DomainCreateFlagBypassCache
|
|
||||||
|
|
||||||
// DomainCreateFlagStartForceBoot boot, discarding any managed save
|
|
||||||
DomainCreateFlagStartForceBoot
|
|
||||||
|
|
||||||
// DomainCreateFlagStartValidate validate the XML document against schema
|
|
||||||
DomainCreateFlagStartValidate
|
|
||||||
)
|
|
||||||
|
|
||||||
// RebootFlags specifies domain reboot methods
|
|
||||||
type RebootFlags uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// RebootAcpiPowerBtn - send ACPI event
|
|
||||||
RebootAcpiPowerBtn RebootFlags = 1 << iota
|
|
||||||
|
|
||||||
// RebootGuestAgent - use guest agent
|
|
||||||
RebootGuestAgent
|
|
||||||
|
|
||||||
// RebootInitctl - use initctl
|
|
||||||
RebootInitctl
|
|
||||||
|
|
||||||
// RebootSignal - use signal
|
|
||||||
RebootSignal
|
|
||||||
|
|
||||||
// RebootParavirt - use paravirt guest control
|
|
||||||
RebootParavirt
|
|
||||||
)
|
|
||||||
|
|
||||||
// DomainMemoryStatTag specifies domain memory tags
|
|
||||||
type DomainMemoryStatTag uint32
|
|
||||||
|
|
||||||
const (
|
|
||||||
// DomainMemoryStatTagSwapIn - The total amount of data read from swap space (in kB).
|
|
||||||
DomainMemoryStatTagSwapIn DomainMemoryStatTag = iota
|
|
||||||
|
|
||||||
// DomainMemoryStatTagSwapOut - The total amount of memory written out to swap space (in kB).
|
|
||||||
DomainMemoryStatTagSwapOut
|
|
||||||
|
|
||||||
// DomainMemoryStatTagMajorFault - Page faults occur when a process makes a valid access to virtual memory
|
|
||||||
// that is not available. When servicing the page fault, if disk IO is
|
|
||||||
// required, it is considered a major fault.
|
|
||||||
// These are expressed as the number of faults that have occurred.
|
|
||||||
DomainMemoryStatTagMajorFault
|
|
||||||
|
|
||||||
// DomainMemoryStatTagMinorFault - If the page fault not require disk IO, it is a minor fault.
|
|
||||||
DomainMemoryStatTagMinorFault
|
|
||||||
|
|
||||||
// DomainMemoryStatTagUnused - The amount of memory left completely unused by the system (in kB).
|
|
||||||
DomainMemoryStatTagUnused
|
|
||||||
|
|
||||||
// DomainMemoryStatTagAvailable - The total amount of usable memory as seen by the domain (in kB).
|
|
||||||
DomainMemoryStatTagAvailable
|
|
||||||
|
|
||||||
// DomainMemoryStatTagActualBalloon - Current balloon value (in KB).
|
|
||||||
DomainMemoryStatTagActualBalloon
|
|
||||||
|
|
||||||
// DomainMemoryStatTagRss - Resident Set Size of the process running the domain (in KB).
|
|
||||||
DomainMemoryStatTagRss
|
|
||||||
|
|
||||||
// DomainMemoryStatTagUsable - How much the balloon can be inflated without pushing the guest system
|
|
||||||
// to swap, corresponds to 'Available' in /proc/meminfo
|
|
||||||
DomainMemoryStatTagUsable
|
|
||||||
|
|
||||||
// DomainMemoryStatTagLastUpdate - Timestamp of the last update of statistics, in seconds.
|
|
||||||
DomainMemoryStatTagLastUpdate
|
|
||||||
|
|
||||||
// DomainMemoryStatTagNr - The number of statistics supported by this version of the interface.
|
|
||||||
DomainMemoryStatTagNr
|
|
||||||
)
|
|
||||||
|
|
||||||
// Capabilities returns an XML document describing the host's capabilties.
|
// Capabilities returns an XML document describing the host's capabilties.
|
||||||
func (l *Libvirt) Capabilities() ([]byte, error) {
|
func (l *Libvirt) Capabilities() ([]byte, error) {
|
||||||
caps, err := l.ConnectGetCapabilities()
|
caps, err := l.ConnectGetCapabilities()
|
||||||
@ -479,7 +118,7 @@ func (l *Libvirt) Domains() ([]Domain, error) {
|
|||||||
func (l *Libvirt) DomainState(dom string) (DomainState, error) {
|
func (l *Libvirt) DomainState(dom string) (DomainState, error) {
|
||||||
d, err := l.lookup(dom)
|
d, err := l.lookup(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return DomainStateNoState, err
|
return DomainNostate, err
|
||||||
}
|
}
|
||||||
|
|
||||||
state, _, err := l.DomainGetState(d, 0)
|
state, _, err := l.DomainGetState(d, 0)
|
||||||
@ -553,7 +192,7 @@ func (l *Libvirt) Events(dom string) (<-chan DomainEvent, error) {
|
|||||||
// 'qemu+tcp://example.com/system'. The flags argument determines the
|
// 'qemu+tcp://example.com/system'. The flags argument determines the
|
||||||
// type of migration and how it will be performed. For more information
|
// type of migration and how it will be performed. For more information
|
||||||
// on available migration flags and their meaning, see MigrateFlag*.
|
// on available migration flags and their meaning, see MigrateFlag*.
|
||||||
func (l *Libvirt) Migrate(dom string, dest string, flags MigrateFlags) error {
|
func (l *Libvirt) Migrate(dom string, dest string, flags DomainMigrateFlags) error {
|
||||||
_, err := url.Parse(dest)
|
_, err := url.Parse(dest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -571,7 +210,7 @@ func (l *Libvirt) Migrate(dom string, dest string, flags MigrateFlags) error {
|
|||||||
destURI := []string{dest}
|
destURI := []string{dest}
|
||||||
remoteParams := []TypedParam{}
|
remoteParams := []TypedParam{}
|
||||||
cookieIn := []byte{}
|
cookieIn := []byte{}
|
||||||
_, err = l.DomainMigratePerform3Params(d, destURI, remoteParams, cookieIn, uint32(flags))
|
_, err = l.DomainMigratePerform3Params(d, destURI, remoteParams, cookieIn, flags)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,35 +292,35 @@ func (l *Libvirt) StoragePool(name string) (StoragePool, error) {
|
|||||||
|
|
||||||
// StoragePools returns a list of defined storage pools. Pools are filtered by
|
// StoragePools returns a list of defined storage pools. Pools are filtered by
|
||||||
// the provided flags. See StoragePools*.
|
// the provided flags. See StoragePools*.
|
||||||
func (l *Libvirt) StoragePools(flags StoragePoolsFlags) ([]StoragePool, error) {
|
func (l *Libvirt) StoragePools(flags ConnectListAllStoragePoolsFlags) ([]StoragePool, error) {
|
||||||
pools, _, err := l.ConnectListAllStoragePools(1, uint32(flags))
|
pools, _, err := l.ConnectListAllStoragePools(1, flags)
|
||||||
return pools, err
|
return pools, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undefine undefines the domain specified by dom, e.g., 'prod-lb-01'.
|
// Undefine undefines the domain specified by dom, e.g., 'prod-lb-01'.
|
||||||
// The flags argument allows additional options to be specified such as
|
// The flags argument allows additional options to be specified such as
|
||||||
// cleaning up snapshot metadata. For more information on available
|
// cleaning up snapshot metadata. For more information on available
|
||||||
// flags, see UndefineFlag*.
|
// flags, see DomainUndefine*.
|
||||||
func (l *Libvirt) Undefine(dom string, flags UndefineFlags) error {
|
func (l *Libvirt) Undefine(dom string, flags DomainUndefineFlagsValues) error {
|
||||||
d, err := l.lookup(dom)
|
d, err := l.lookup(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.DomainUndefineFlags(d, uint32(flags))
|
return l.DomainUndefineFlags(d, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy destroys the domain specified by dom, e.g., 'prod-lb-01'.
|
// Destroy destroys the domain specified by dom, e.g., 'prod-lb-01'.
|
||||||
// The flags argument allows additional options to be specified such as
|
// The flags argument allows additional options to be specified such as
|
||||||
// allowing a graceful shutdown with SIGTERM than SIGKILL.
|
// allowing a graceful shutdown with SIGTERM than SIGKILL.
|
||||||
// For more information on available flags, see DestroyFlag*.
|
// For more information on available flags, see DomainDestroy*.
|
||||||
func (l *Libvirt) Destroy(dom string, flags DestroyFlags) error {
|
func (l *Libvirt) Destroy(dom string, flags DomainDestroyFlagsValues) error {
|
||||||
d, err := l.lookup(dom)
|
d, err := l.lookup(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.DomainDestroyFlags(d, uint32(flags))
|
return l.DomainDestroyFlags(d, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// XML returns a domain's raw XML definition, akin to `virsh dumpxml <domain>`.
|
// XML returns a domain's raw XML definition, akin to `virsh dumpxml <domain>`.
|
||||||
@ -692,13 +331,13 @@ func (l *Libvirt) XML(dom string, flags DomainXMLFlags) ([]byte, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
xml, err := l.DomainGetXMLDesc(d, uint32(flags))
|
xml, err := l.DomainGetXMLDesc(d, flags)
|
||||||
return []byte(xml), err
|
return []byte(xml), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefineXML defines a domain, but does not start it.
|
// DefineXML defines a domain, but does not start it.
|
||||||
func (l *Libvirt) DefineXML(x []byte, flags DomainDefineXMLFlags) error {
|
func (l *Libvirt) DefineXML(x []byte, flags DomainDefineFlags) error {
|
||||||
_, err := l.DomainDefineXMLFlags(string(x), uint32(flags))
|
_, err := l.DomainDefineXMLFlags(string(x), flags)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,24 +363,24 @@ func (l *Libvirt) Version() (string, error) {
|
|||||||
|
|
||||||
// Shutdown shuts down a domain. Note that the guest OS may ignore the request.
|
// Shutdown shuts down a domain. Note that the guest OS may ignore the request.
|
||||||
// If flags is set to 0 then the hypervisor will choose the method of shutdown it considers best.
|
// If flags is set to 0 then the hypervisor will choose the method of shutdown it considers best.
|
||||||
func (l *Libvirt) Shutdown(dom string, flags ShutdownFlags) error {
|
func (l *Libvirt) Shutdown(dom string, flags DomainShutdownFlagValues) error {
|
||||||
d, err := l.lookup(dom)
|
d, err := l.lookup(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.DomainShutdownFlags(d, uint32(flags))
|
return l.DomainShutdownFlags(d, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reboot reboots the domain. Note that the guest OS may ignore the request.
|
// Reboot reboots the domain. Note that the guest OS may ignore the request.
|
||||||
// If flags is set to zero, then the hypervisor will choose the method of shutdown it considers best.
|
// If flags is set to zero, then the hypervisor will choose the method of shutdown it considers best.
|
||||||
func (l *Libvirt) Reboot(dom string, flags RebootFlags) error {
|
func (l *Libvirt) Reboot(dom string, flags DomainRebootFlagValues) error {
|
||||||
d, err := l.lookup(dom)
|
d, err := l.lookup(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.DomainReboot(d, uint32(flags))
|
return l.DomainReboot(d, flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset resets domain immediately without any guest OS shutdown
|
// Reset resets domain immediately without any guest OS shutdown
|
||||||
@ -764,33 +403,6 @@ type BlockLimit struct {
|
|||||||
Value uint64
|
Value uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockIOTune-able values. These tunables are different for different
|
|
||||||
// hypervisors; currently only the tunables for QEMU are defined here. These are
|
|
||||||
// not necessarily the only possible values; different libvirt versions may add
|
|
||||||
// or remove parameters from this list.
|
|
||||||
const (
|
|
||||||
QEMUBlockIOGroupName = "group_name"
|
|
||||||
QEMUBlockIOTotalBytesSec = "total_bytes_sec"
|
|
||||||
QEMUBlockIOReadBytesSec = "read_bytes_sec"
|
|
||||||
QEMUBlockIOWriteBytesSec = "write_bytes_sec"
|
|
||||||
QEMUBlockIOTotalIOPSSec = "total_iops_sec"
|
|
||||||
QEMUBlockIOReadIOPSSec = "read_iops_sec"
|
|
||||||
QEMUBlockIOWriteIOPSSec = "write_iops_sec"
|
|
||||||
QEMUBlockIOTotalBytesSecMax = "total_bytes_sec_max"
|
|
||||||
QEMUBlockIOReadBytesSecMax = "read_bytes_sec_max"
|
|
||||||
QEMUBlockIOWriteBytesSecMax = "write_bytes_sec_max"
|
|
||||||
QEMUBlockIOTotalIOPSSecMax = "total_iops_sec_max"
|
|
||||||
QEMUBlockIOReadIOPSSecMax = "read_iops_sec_max"
|
|
||||||
QEMUBlockIOWriteIOPSSecMax = "write_iops_sec_max"
|
|
||||||
QEMUBlockIOSizeIOPSSec = "size_iops_sec"
|
|
||||||
QEMUBlockIOTotalBytesSecMaxLength = "total_bytes_sec_max_length"
|
|
||||||
QEMUBlockIOReadBytesSecMaxLength = "read_bytes_sec_max_length"
|
|
||||||
QEMUBlockIOWriteBytesSecMaxLength = "write_bytes_sec_max_length"
|
|
||||||
QEMUBlockIOTotalIOPSSecMaxLength = "total_iops_sec_max_length"
|
|
||||||
QEMUBlockIOReadIOPSSecMaxLength = "read_iops_sec_max_length"
|
|
||||||
QEMUBlockIOWriteIOPSSecMaxLength = "write_iops_sec_max_length"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SetBlockIOTune changes the per-device block I/O tunables within a guest.
|
// SetBlockIOTune changes the per-device block I/O tunables within a guest.
|
||||||
// Parameters are the name of the VM, the name of the disk device to which the
|
// Parameters are the name of the VM, the name of the disk device to which the
|
||||||
// limits should be applied, and 1 or more BlockLimit structs containing the
|
// limits should be applied, and 1 or more BlockLimit structs containing the
|
||||||
@ -814,7 +426,7 @@ func (l *Libvirt) SetBlockIOTune(dom string, disk string, limits ...BlockLimit)
|
|||||||
params[ix] = TypedParam{Field: limit.Name, Value: tpval}
|
params[ix] = TypedParam{Field: limit.Name, Value: tpval}
|
||||||
}
|
}
|
||||||
|
|
||||||
return l.DomainSetBlockIOTune(d, disk, params, FlagDomainAffectLive)
|
return l.DomainSetBlockIOTune(d, disk, params, uint32(DomainAffectLive))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlockIOTune returns a slice containing the current block I/O tunables for
|
// GetBlockIOTune returns a slice containing the current block I/O tunables for
|
||||||
@ -825,7 +437,7 @@ func (l *Libvirt) GetBlockIOTune(dom string, disk string) ([]BlockLimit, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
lims, _, err := l.DomainGetBlockIOTune(d, []string{disk}, 32, FlagTypedParamStringOkay)
|
lims, _, err := l.DomainGetBlockIOTune(d, []string{disk}, 32, uint32(TypedParamStringOkay))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
59
libvirt.yml
Normal file
59
libvirt.yml
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# Configuration file for c-for-go, which go-libvirt uses to translate the const
|
||||||
|
# and type definitions from the C-language sources in the libvirt project into
|
||||||
|
# Go. This file is used by the c-for-go binary (github.com/xlab/c-for-go), which
|
||||||
|
# is called when 'go generate' is run. See libvirt.go for the command line used.
|
||||||
|
---
|
||||||
|
GENERATOR:
|
||||||
|
PackageName: libvirt
|
||||||
|
PackageLicense: |
|
||||||
|
Copyright 2017 The go-libvirt Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
Includes: []
|
||||||
|
|
||||||
|
PARSER:
|
||||||
|
# We can't use environment variables here, but we don't want to process the
|
||||||
|
# libvirt version installed in the system folders (if any). Instead we'll
|
||||||
|
# rely on our caller to link the libvirt source directory to lv_source/, and
|
||||||
|
# run on that code. This isn't ideal, but changes to c-for-go are needed to
|
||||||
|
# fix it.
|
||||||
|
IncludePaths: [./lv_source/include]
|
||||||
|
SourcesPaths:
|
||||||
|
- libvirt/libvirt.h
|
||||||
|
|
||||||
|
TRANSLATOR:
|
||||||
|
ConstRules:
|
||||||
|
defines: eval
|
||||||
|
Rules:
|
||||||
|
global:
|
||||||
|
- {action: accept, from: "^vir"}
|
||||||
|
post-global:
|
||||||
|
- {action: replace, from: "^vir"}
|
||||||
|
- {load: snakecase}
|
||||||
|
# Follow golint's capitalization conventions.
|
||||||
|
- {action: replace, from: "Api([A-Z]|$)", to: "API$1"}
|
||||||
|
- {action: replace, from: "Cpu([A-Z]|$)", to: "CPU$1"}
|
||||||
|
- {action: replace, from: "Dns([A-Z]|$)", to: "DNS$1"}
|
||||||
|
- {action: replace, from: "Eof([A-Z]|$)", to: "EOF$1"}
|
||||||
|
- {action: replace, from: "Id([A-Z]|$)", to: "ID$1"}
|
||||||
|
- {action: replace, from: "Ip([A-Z]|$)", to: "IP$1"}
|
||||||
|
- {action: replace, from: "Tls([A-Z]|$)", to: "TLS$1"}
|
||||||
|
- {action: replace, from: "Uuid([A-Z]|$)", to: "UUID$1"}
|
||||||
|
- {action: replace, from: "Uri([A-Z]|$)", to: "URI$1"}
|
||||||
|
- {action: replace, from: "Vcpu([A-Z]|$)", to: "VCPU$1"}
|
||||||
|
- {action: replace, from: "Xml([A-Z]|$)", to: "XML$1"}
|
||||||
|
const:
|
||||||
|
- {action: accept, from: "^VIR_"}
|
||||||
|
# Special case to prevent a collision with a type:
|
||||||
|
- {action: replace, from: "^VIR_DOMAIN_JOB_OPERATION", to: "VIR_DOMAIN_JOB_OPERATION_STR"}
|
||||||
|
- {transform: lower}
|
@ -156,7 +156,7 @@ func TestStoragePoolsIntegration(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pools, err := l.StoragePools(StoragePoolsFlagActive)
|
pools, err := l.StoragePools(ConnectListStoragePoolsActive)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -182,7 +182,7 @@ func TestStoragePoolsAutostartIntegration(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pools, err := l.StoragePools(StoragePoolsFlagAutostart)
|
pools, err := l.StoragePools(ConnectListStoragePoolsAutostart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,14 @@ func TestMigrate(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags MigrateFlags
|
var flags DomainMigrateFlags
|
||||||
flags = MigrateFlagLive |
|
flags = MigrateLive |
|
||||||
MigrateFlagPeerToPeer |
|
MigratePeer2peer |
|
||||||
MigrateFlagPersistDestination |
|
MigratePersistDest |
|
||||||
MigrateFlagChangeProtection |
|
MigrateChangeProtection |
|
||||||
MigrateFlagAbortOnError |
|
MigrateAbortOnError |
|
||||||
MigrateFlagAutoConverge |
|
MigrateAutoConverge |
|
||||||
MigrateFlagNonSharedDisk
|
MigrateNonSharedDisk
|
||||||
|
|
||||||
if err := l.Migrate("test", "qemu+tcp://foo/system", flags); err != nil {
|
if err := l.Migrate("test", "qemu+tcp://foo/system", flags); err != nil {
|
||||||
t.Fatalf("unexpected live migration error: %v", err)
|
t.Fatalf("unexpected live migration error: %v", err)
|
||||||
@ -66,14 +66,14 @@ func TestMigrateInvalidDest(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags MigrateFlags
|
var flags DomainMigrateFlags
|
||||||
flags = MigrateFlagLive |
|
flags = MigrateLive |
|
||||||
MigrateFlagPeerToPeer |
|
MigratePeer2peer |
|
||||||
MigrateFlagPersistDestination |
|
MigratePersistDest |
|
||||||
MigrateFlagChangeProtection |
|
MigrateChangeProtection |
|
||||||
MigrateFlagAbortOnError |
|
MigrateAbortOnError |
|
||||||
MigrateFlagAutoConverge |
|
MigrateAutoConverge |
|
||||||
MigrateFlagNonSharedDisk
|
MigrateNonSharedDisk
|
||||||
|
|
||||||
dest := ":$'"
|
dest := ":$'"
|
||||||
if err := l.Migrate("test", dest, flags); err == nil {
|
if err := l.Migrate("test", dest, flags); err == nil {
|
||||||
@ -122,7 +122,7 @@ func TestDomainState(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
wantState := DomainState(DomainStateRunning)
|
wantState := DomainState(DomainRunning)
|
||||||
gotState, err := l.DomainState("test")
|
gotState, err := l.DomainState("test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
@ -325,7 +325,7 @@ func TestStoragePools(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
pools, err := l.StoragePools(StoragePoolsFlagActive)
|
pools, err := l.StoragePools(ConnectListStoragePoolsTransient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ func TestUndefine(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags UndefineFlags
|
var flags DomainUndefineFlagsValues
|
||||||
if err := l.Undefine("test", flags); err != nil {
|
if err := l.Undefine("test", flags); err != nil {
|
||||||
t.Fatalf("unexpected undefine error: %v", err)
|
t.Fatalf("unexpected undefine error: %v", err)
|
||||||
}
|
}
|
||||||
@ -381,7 +381,7 @@ func TestDestroy(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags DestroyFlags
|
var flags DomainDestroyFlagsValues
|
||||||
if err := l.Destroy("test", flags); err != nil {
|
if err := l.Destroy("test", flags); err != nil {
|
||||||
t.Fatalf("unexpected destroy error: %v", err)
|
t.Fatalf("unexpected destroy error: %v", err)
|
||||||
}
|
}
|
||||||
@ -406,7 +406,7 @@ func TestDefineXML(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags DomainDefineXMLFlags
|
var flags DomainDefineFlags
|
||||||
var buf []byte
|
var buf []byte
|
||||||
if err := l.DefineXML(buf, flags); err != nil {
|
if err := l.DefineXML(buf, flags); err != nil {
|
||||||
t.Fatalf("unexpected define error: %v", err)
|
t.Fatalf("unexpected define error: %v", err)
|
||||||
@ -431,7 +431,7 @@ func TestShutdown(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags ShutdownFlags
|
var flags DomainShutdownFlagValues
|
||||||
if err := l.Shutdown("test", flags); err != nil {
|
if err := l.Shutdown("test", flags); err != nil {
|
||||||
t.Fatalf("unexpected shutdown error: %v", err)
|
t.Fatalf("unexpected shutdown error: %v", err)
|
||||||
}
|
}
|
||||||
@ -441,7 +441,7 @@ func TestReboot(t *testing.T) {
|
|||||||
conn := libvirttest.New()
|
conn := libvirttest.New()
|
||||||
l := New(conn)
|
l := New(conn)
|
||||||
|
|
||||||
var flags RebootFlags
|
var flags DomainRebootFlagValues
|
||||||
if err := l.Reboot("test", flags); err != nil {
|
if err := l.Reboot("test", flags); err != nil {
|
||||||
t.Fatalf("unexpected reboot error: %v", err)
|
t.Fatalf("unexpected reboot error: %v", err)
|
||||||
}
|
}
|
||||||
|
40
scripts/gen-consts.sh
Executable file
40
scripts/gen-consts.sh
Executable file
@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# This runs the first code generator used by go-libvirt: c-for-go. This script
|
||||||
|
# is run from the 'go generate ./...' command, and only needs to be run when
|
||||||
|
# changing to a different version of libvirt.
|
||||||
|
if [ -z "${LIBVIRT_SOURCE}" ]; then
|
||||||
|
echo "Set LIBVIRT_SOURCE to the root of the libvirt sources you want to use first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure c-for-go is installed
|
||||||
|
if ! which c-for-go > /dev/null; then
|
||||||
|
echo "c-for-go not found. Attempting to install it..."
|
||||||
|
if ! go get github.com/xlab/c-for-go/...; then
|
||||||
|
echo "failed to install c-for-go. Please install it manually from https://github.com/xlab/c-for-go"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make sure goyacc is installed (needed for the lvgen/ generator)
|
||||||
|
if ! which goyacc > /dev/null; then
|
||||||
|
echo "goyacc not found. Attempting to install it..."
|
||||||
|
if ! go get golang.org/x/tools/cmd/goyacc/...; then
|
||||||
|
echo "failed to install goyacc. Please install it manually from https://golang.org/x/tools/cmd/goyacc"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Temporarily symlink the libvirt sources to a subdirectory because c-for-go
|
||||||
|
# lacks a mechanism for us to pass it a search path for header files.
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
LVDIR=lv_source
|
||||||
|
ln -sF ${LIBVIRT_SOURCE} ${LVDIR}
|
||||||
|
if ! c-for-go -nostamp -nocgo -ccincl libvirt.yml; then
|
||||||
|
echo "c-for-go failed"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mv libvirt/const.go ${DIR}/../const.gen.go
|
||||||
|
rm ${LVDIR}
|
||||||
|
rm -rf libvirt/
|
@ -18,7 +18,6 @@ read -r -d '' EXPECTED <<EndOfLicense
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
EndOfLicense
|
EndOfLicense
|
||||||
|
|
||||||
# Scan each Go source file for license.
|
|
||||||
EXIT=0
|
EXIT=0
|
||||||
GOFILES=$(find . -name "*.go")
|
GOFILES=$(find . -name "*.go")
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user