diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index f030766d90d9..00a29df2877b 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -1758,6 +1758,11 @@ "ImportPath": "github.com/libopenstorage/openstorage/volume", "Rev": "6e787003b91ddba85f108b8aede075b1af0d3606" }, + { + "ImportPath": "github.com/libvirt/libvirt-go", + "Comment": "v3.4.0", + "Rev": "5ba8227244c30438609adcec6ea84dc1e688dfbd" + }, { "ImportPath": "github.com/lpabon/godbc", "Comment": "v1.0-1-g9577782", diff --git a/Makefile b/Makefile index d9879af90496..9e7d4b601365 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,8 @@ LOCALKUBEFILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' ./cmd/local MINIKUBEFILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' ./cmd/minikube/ | grep k8s.io | GOPATH=$(GOPATH) xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}' HYPERKIT_FILES := GOPATH=$(GOPATH) go list -f '{{join .Deps "\n"}}' k8s.io/minikube/cmd/drivers/hyperkit | grep k8s.io | GOPATH=$(GOPATH) xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}' +KVM_DRIVER_FILES := $(shell go list -f '{{join .Deps "\n"}}' ./cmd/drivers/kvm/ | grep k8s.io | xargs go list -f '{{ range $$file := .GoFiles }} {{$$.Dir}}/{{$$file}}{{"\n"}}{{end}}') + MINIKUBE_ENV_linux := CGO_ENABLED=1 GOARCH=amd64 GOOS=linux MINIKUBE_ENV_darwin := CGO_ENABLED=1 GOARCH=amd64 GOOS=darwin MINIKUBE_ENV_windows := CGO_ENABLED=0 GOARCH=amd64 GOOS=windows @@ -174,7 +176,7 @@ $(GOPATH)/bin/go-bindata: GOBIN=$(GOPATH)/bin go get github.com/jteeuwen/go-bindata/... .PHONY: cross -cross: out/localkube out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/docker-machine-driver-hyperkit +cross: out/localkube out/minikube-linux-amd64 out/minikube-darwin-amd64 out/minikube-windows-amd64.exe out/docker-machine-driver-hyperkit out/docker-machine-driver-kvm2 .PHONY: e2e-cross e2e-cross: e2e-linux-amd64 e2e-darwin-amd64 e2e-windows-amd64.exe @@ -286,3 +288,16 @@ $(ISO_BUILD_IMAGE): deploy/iso/minikube-iso/Dockerfile release-iso: minikube_iso checksum gsutil cp out/minikube.iso gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION).iso gsutil cp out/minikube.iso.sha256 gs://$(ISO_BUCKET)/minikube-$(ISO_VERSION).iso.sha256 + +out/docker-machine-driver-kvm2: $(KVM_DRIVER_FILES) + go build \ + -installsuffix "static" \ + -ldflags "-X k8s.io/minikube/pkg/drivers/kvm/version.VERSION=$(VERSION)" \ + -tags libvirt.1.2.2 \ + -o $(BUILD_DIR)/docker-machine-driver-kvm2 \ + k8s.io/minikube/cmd/drivers/kvm + chmod +X $@ + +.PHONY: install-kvm +install-kvm: out/docker-machine-driver-kvm2 + cp out/docker-machine-driver-kvm2 $(GOBIN)/docker-machine-driver-kvm2 diff --git a/cmd/drivers/kvm/main.go b/cmd/drivers/kvm/main.go new file mode 100644 index 000000000000..7b2f2b153038 --- /dev/null +++ b/cmd/drivers/kvm/main.go @@ -0,0 +1,28 @@ +// +build linux + +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package main + +import ( + "github.com/docker/machine/libmachine/drivers/plugin" + "k8s.io/minikube/pkg/drivers/kvm" +) + +func main() { + plugin.RegisterDriver(kvm.NewDriver("", "")) +} diff --git a/cmd/minikube/cmd/start.go b/cmd/minikube/cmd/start.go index 05bc86eaa602..d01d05db82c4 100644 --- a/cmd/minikube/cmd/start.go +++ b/cmd/minikube/cmd/start.go @@ -28,7 +28,6 @@ import ( "time" "github.com/blang/semver" - units "github.com/docker/go-units" "github.com/docker/machine/libmachine/host" "github.com/golang/glog" "github.com/spf13/cobra" @@ -93,7 +92,7 @@ func runStart(cmd *cobra.Command, args []string) { defer api.Close() diskSize := viper.GetString(humanReadableDiskSize) - diskSizeMB := calculateDiskSizeInMB(diskSize) + diskSizeMB := util.CalculateDiskSizeInMB(diskSize) if diskSizeMB < constants.MinimumDiskSizeMB { err := fmt.Errorf("Disk Size %dMB (%s) is too small, the minimum disk size is %dMB", diskSizeMB, diskSize, constants.MinimumDiskSizeMB) @@ -317,14 +316,6 @@ func validateK8sVersion(version string) { } } -func calculateDiskSizeInMB(humanReadableDiskSize string) int { - diskSize, err := units.FromHumanSize(humanReadableDiskSize) - if err != nil { - glog.Errorf("Invalid disk size: %s", err) - } - return int(diskSize / units.MB) -} - func init() { startCmd.Flags().Bool(keepContext, constants.DefaultKeepContext, "This will keep the existing kubectl context and will create a minikube context.") startCmd.Flags().Bool(createMount, false, "This will start the mount daemon and automatically mount files into minikube") diff --git a/hack/jenkins/common.sh b/hack/jenkins/common.sh index 9fca5972953a..d905a1cd02f1 100644 --- a/hack/jenkins/common.sh +++ b/hack/jenkins/common.sh @@ -79,6 +79,9 @@ sudo rm -rf $HOME/.kube || true # See the default image ./out/minikube-${OS_ARCH} start -h | grep iso +# see what driver we are using +which docker-machine-driver-${VM_DRIVER} || true + # Allow this to fail, we'll switch on the return code below. set +e ${SUDO_PREFIX}out/e2e-${OS_ARCH} -minikube-args="--vm-driver=${VM_DRIVER} --v=10 --logtostderr" -test.v -test.timeout=30m -binary=out/minikube-${OS_ARCH} diff --git a/hack/jenkins/linux_integration_tests_kvm_alt.sh b/hack/jenkins/linux_integration_tests_kvm_alt.sh index 84092780506e..e150088603bf 100644 --- a/hack/jenkins/linux_integration_tests_kvm_alt.sh +++ b/hack/jenkins/linux_integration_tests_kvm_alt.sh @@ -26,7 +26,7 @@ set -e OS_ARCH="linux-amd64" -VM_DRIVER="kvm" +VM_DRIVER="kvm2" JOB_NAME="Linux-KVM-Alt" # Download files and set permissions diff --git a/hack/jenkins/minikube_cross_build_and_upload.sh b/hack/jenkins/minikube_cross_build_and_upload.sh index 848df80388ab..4bbe3ce9b0cc 100755 --- a/hack/jenkins/minikube_cross_build_and_upload.sh +++ b/hack/jenkins/minikube_cross_build_and_upload.sh @@ -40,9 +40,10 @@ fi export GOPATH=~/go -# Cross build the binary and test binary for all platforms (Windows, Linux, OSX). +# Build the e2e test target for Darwin and Linux. We don't run tests on Windows yet. # We build these on Linux, but run the tests on different platforms. # This makes it easier to provision slaves, since they don't need to have a go toolchain.' +# Cross also builds the hyperkit and kvm2 drivers. BUILD_IN_DOCKER=y make cross e2e-cross cp -r test/integration/testdata out/ diff --git a/pkg/drivers/kvm/domain.go b/pkg/drivers/kvm/domain.go new file mode 100644 index 000000000000..06e47c001628 --- /dev/null +++ b/pkg/drivers/kvm/domain.go @@ -0,0 +1,152 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package kvm + +import ( + "bytes" + "fmt" + "text/template" + + libvirt "github.com/libvirt/libvirt-go" + "github.com/pkg/errors" +) + +const domainTmpl = ` + + {{.MachineName}} + {{.Memory}} + {{.CPU}} + + + + + + + hvm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /dev/random + + + +` + +const connectionErrorText = ` +Error connecting to libvirt socket. Have you set up libvirt correctly? + +# Install libvirt and qemu-kvm on your system, e.g. +# Debian/Ubuntu +$ sudo apt install libvirt-bin qemu-kvm +# Fedora/CentOS/RHEL +$ sudo yum install libvirt-daemon-kvm qemu-kvm + +# Add yourself to the libvirtd group (use libvirt group for rpm based distros) so you don't need to sudo +# Debian/Ubuntu (NOTE: For Ubuntu 17.04 change the group to libvirt) +$ sudo usermod -a -G libvirtd $(whoami) +# Fedora/CentOS/RHEL +$ sudo usermod -a -G libvirt $(whoami) + +# Update your current session for the group change to take effect +# Debian/Ubuntu (NOTE: For Ubuntu 17.04 change the group to libvirt) +$ newgrp libvirtd +# Fedora/CentOS/RHEL +$ newgrp libvirt + +Visit https://github.com/kubernetes/minikube/blob/master/docs/drivers.md#kvm-driver for more information. +` + +func (d *Driver) getDomain() (*libvirt.Domain, *libvirt.Connect, error) { + conn, err := getConnection() + if err != nil { + return nil, nil, errors.Wrap(err, "getting domain") + } + + dom, err := conn.LookupDomainByName(d.MachineName) + if err != nil { + return nil, nil, errors.Wrap(err, "looking up domain") + } + + return dom, conn, nil +} + +func getConnection() (*libvirt.Connect, error) { + conn, err := libvirt.NewConnect(qemusystem) + if err != nil { + return nil, errors.Wrap(err, connectionErrorText) + } + + return conn, nil +} + +func closeDomain(dom *libvirt.Domain, conn *libvirt.Connect) error { + dom.Free() + if res, _ := conn.Close(); res != 0 { + return fmt.Errorf("Error closing connection CloseConnection() == %d, expected 0", res) + } + return nil +} + +func (d *Driver) createDomain() (*libvirt.Domain, error) { + tmpl := template.Must(template.New("domain").Parse(domainTmpl)) + var domainXml bytes.Buffer + if err := tmpl.Execute(&domainXml, d); err != nil { + return nil, errors.Wrap(err, "executing domain xml") + } + + conn, err := getConnection() + if err != nil { + return nil, errors.Wrap(err, "Error getting libvirt connection") + } + defer conn.Close() + + dom, err := conn.DomainDefineXML(domainXml.String()) + if err != nil { + return nil, errors.Wrapf(err, "Error defining domain xml: %s", domainXml.String()) + } + + return dom, nil +} diff --git a/pkg/drivers/kvm/kvm.go b/pkg/drivers/kvm/kvm.go new file mode 100644 index 000000000000..7998326ae1bc --- /dev/null +++ b/pkg/drivers/kvm/kvm.go @@ -0,0 +1,382 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package kvm + +import ( + "fmt" + "os" + "path/filepath" + "time" + + "k8s.io/minikube/pkg/minikube/config" + "k8s.io/minikube/pkg/minikube/constants" + "k8s.io/minikube/pkg/util" + + "github.com/docker/machine/libmachine/drivers" + "github.com/docker/machine/libmachine/log" + "github.com/docker/machine/libmachine/mcnflag" + "github.com/docker/machine/libmachine/mcnutils" + "github.com/docker/machine/libmachine/state" + libvirt "github.com/libvirt/libvirt-go" + "github.com/pkg/errors" +) + +const ( + qemusystem = "qemu:///system" + defaultPrivateNetworkName = "minikube-net" +) + +type Driver struct { + *drivers.BaseDriver + + // How much memory, in MB, to allocate to the VM + Memory int + + // How many cpus to allocate to the VM + CPU int + + // The name of the default network + Network string + + // The name of the private network + PrivateNetwork string + + // The size of the disk to be created for the VM, in MB + DiskSize int + + // The path of the disk .img + DiskPath string + + // A file or network URI to fetch the minikube ISO + Boot2DockerURL string + + // The location of the iso to boot from + ISO string +} + +func NewDriver(hostName, storePath string) *Driver { + return &Driver{ + BaseDriver: &drivers.BaseDriver{ + MachineName: hostName, + StorePath: storePath, + }, + Boot2DockerURL: constants.DefaultIsoUrl, + CPU: constants.DefaultCPUS, + PrivateNetwork: defaultPrivateNetworkName, + DiskSize: util.CalculateDiskSizeInMB(constants.DefaultDiskSize), + Memory: constants.DefaultMemory, + Network: defaultNetworkName, + DiskPath: filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), fmt.Sprintf("%s.img", config.GetMachineName())), + ISO: filepath.Join(constants.GetMinipath(), "machines", config.GetMachineName(), "boot2docker.iso"), + } +} + +//Not implemented yet +func (d *Driver) GetCreateFlags() []mcnflag.Flag { + return nil +} + +//Not implemented yet +func (d *Driver) SetConfigFromFlags(flags drivers.DriverOptions) error { + return nil +} + +func (d *Driver) PreCommandCheck() error { + conn, err := getConnection() + if err != nil { + return errors.Wrap(err, "Error connecting to libvirt socket. Have you added yourself to the libvirtd group?") + } + libVersion, err := conn.GetLibVersion() + if err != nil { + return errors.Wrap(err, "getting libvirt version") + } + log.Debugf("Using libvirt version %d", libVersion) + + return nil +} + +func (d *Driver) GetURL() (string, error) { + if err := d.PreCommandCheck(); err != nil { + return "", errors.Wrap(err, "getting URL, precheck failed") + } + + ip, err := d.GetIP() + if err != nil { + return "", errors.Wrap(err, "getting URL, could not get IP") + } + if ip == "" { + return "", nil + } + + return fmt.Sprintf("tcp://%s:2376", ip), nil +} + +func (d *Driver) GetState() (state.State, error) { + dom, conn, err := d.getDomain() + if err != nil { + return state.None, errors.Wrap(err, "getting connection") + } + defer closeDomain(dom, conn) + + libvirtState, _, err := dom.GetState() // state, reason, error + if err != nil { + return state.None, errors.Wrap(err, "getting domain state") + } + + switch libvirtState { + case libvirt.DOMAIN_RUNNING: + return state.Running, nil + case libvirt.DOMAIN_BLOCKED, libvirt.DOMAIN_CRASHED: + return state.Error, nil + case libvirt.DOMAIN_PAUSED: + return state.Paused, nil + case libvirt.DOMAIN_SHUTDOWN, libvirt.DOMAIN_SHUTOFF: + return state.Stopped, nil + case libvirt.DOMAIN_PMSUSPENDED: + return state.Saved, nil + case libvirt.DOMAIN_NOSTATE: + return state.None, nil + default: + return state.None, nil + } +} + +func (d *Driver) GetIP() (string, error) { + s, err := d.GetState() + if err != nil { + return "", errors.Wrap(err, "machine in unknown state") + } + if s != state.Running { + return "", errors.New("host is not running.") + } + ip, err := d.lookupIP() + if err != nil { + return "", errors.Wrap(err, "getting IP") + } + + return ip, nil +} + +func (d *Driver) GetMachineName() string { + return d.MachineName +} + +func (d *Driver) GetSSHHostname() (string, error) { + return d.GetIP() +} + +func (d *Driver) GetSSHUsername() string { + return "docker" +} + +func (d *Driver) GetSSHKeyPath() string { + return d.ResolveStorePath("id_rsa") +} + +func (d *Driver) GetSSHPort() (int, error) { + if d.SSHPort == 0 { + d.SSHPort = 22 + } + + return d.SSHPort, nil +} + +func (d *Driver) DriverName() string { + return "kvm" +} + +func (d *Driver) Kill() error { + dom, conn, err := d.getDomain() + if err != nil { + return errors.Wrap(err, "getting connection") + } + defer closeDomain(dom, conn) + + return dom.Destroy() +} + +func (d *Driver) Restart() error { + dom, conn, err := d.getDomain() + if err != nil { + return errors.Wrap(err, "getting connection") + } + defer closeDomain(dom, conn) + + if err := d.Stop(); err != nil { + return errors.Wrap(err, "stopping VM:") + } + return d.Start() +} + +func (d *Driver) Start() error { + log.Info("Getting domain xml...") + dom, conn, err := d.getDomain() + if err != nil { + return errors.Wrap(err, "getting connection") + } + defer closeDomain(dom, conn) + + log.Info("Creating domain...") + if err := dom.Create(); err != nil { + return errors.Wrap(err, "Error creating VM") + } + + log.Info("Waiting to get IP...") + for i := 0; i <= 40; i++ { + ip, err := d.GetIP() + if err != nil { + return errors.Wrap(err, "getting ip during machine start") + } + if ip == "" { + log.Debugf("Waiting for machine to come up %d/%d", i, 40) + time.Sleep(3 * time.Second) + continue + } + + if ip != "" { + log.Infof("Found IP for machine: %s", ip) + d.IPAddress = ip + break + } + } + + if d.IPAddress == "" { + return errors.New("Machine didn't return an IP after 120 seconds") + } + + log.Info("Waiting for SSH to be available...") + if err := drivers.WaitForSSH(d); err != nil { + d.IPAddress = "" + return errors.Wrap(err, "SSH not available after waiting") + } + + return nil +} + +func (d *Driver) Create() error { + log.Info("Creating machine...") + + //TODO(r2d4): rewrite this, not using b2dutils + b2dutils := mcnutils.NewB2dUtils(d.StorePath) + if err := b2dutils.CopyIsoToMachineDir(d.Boot2DockerURL, d.MachineName); err != nil { + return errors.Wrap(err, "Error copying ISO to machine dir") + } + + log.Info("Creating network...") + err := d.createNetwork() + if err != nil { + return errors.Wrap(err, "creating network") + } + + log.Info("Setting up minikube home directory...") + if err := os.MkdirAll(d.ResolveStorePath("."), 0755); err != nil { + return errors.Wrap(err, "Error making store path directory") + } + + for dir := d.ResolveStorePath("."); dir != "/"; dir = filepath.Dir(dir) { + info, err := os.Stat(dir) + if err != nil { + return err + } + mode := info.Mode() + if mode&0001 != 1 { + log.Debugf("Setting executable bit set on %s", dir) + mode |= 0001 + os.Chmod(dir, mode) + } + } + + log.Info("Building disk image...") + err = d.buildDiskImage() + if err != nil { + return errors.Wrap(err, "Error creating disk") + } + + log.Info("Creating domain...") + dom, err := d.createDomain() + if err != nil { + return errors.Wrap(err, "creating domain") + } + defer dom.Free() + + log.Debug("Finished creating machine, now starting machine...") + return d.Start() +} + +func (d *Driver) Stop() error { + d.IPAddress = "" + s, err := d.GetState() + if err != nil { + return errors.Wrap(err, "getting state of VM") + } + + if s != state.Stopped { + dom, conn, err := d.getDomain() + defer closeDomain(dom, conn) + if err != nil { + return errors.Wrap(err, "getting connection") + } + + err = dom.Shutdown() + if err != nil { + return errors.Wrap(err, "stopping vm") + } + + for i := 0; i < 60; i++ { + s, err := d.GetState() + if err != nil { + return errors.Wrap(err, "Error getting state of VM") + } + if s == state.Stopped { + return nil + } + log.Info("Waiting for machine to stop %d/%d", i, 60) + time.Sleep(1 * time.Second) + } + + } + + return fmt.Errorf("Could not stop VM, current state %s", s.String()) +} + +func (d *Driver) Remove() error { + log.Debug("Removing machine...") + conn, err := getConnection() + if err != nil { + return errors.Wrap(err, "getting connection") + } + defer conn.Close() + + //Tear down network and disk if they exist + network, _ := conn.LookupNetworkByName(d.PrivateNetwork) + log.Debug("Checking if the network needs to be deleted") + if network != nil { + log.Infof("Network %s exists, removing...", d.PrivateNetwork) + network.Destroy() + network.Undefine() + } + + log.Debug("Checking if the domain needs to be deleted") + dom, err := conn.LookupDomainByName(d.MachineName) + if dom != nil { + log.Infof("Domain %s exists, removing...", d.MachineName) + dom.Destroy() + dom.Undefine() + } + + return nil +} diff --git a/pkg/drivers/kvm/network.go b/pkg/drivers/kvm/network.go new file mode 100644 index 000000000000..dc5b3e8d9e6b --- /dev/null +++ b/pkg/drivers/kvm/network.go @@ -0,0 +1,163 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package kvm + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "strings" + "text/template" + + "github.com/docker/machine/libmachine/log" + libvirt "github.com/libvirt/libvirt-go" + "github.com/pkg/errors" +) + +// Replace with hardcoded range with CIDR +// https://play.golang.org/p/m8TNTtygK0 +const networkTmpl = ` + + {{.PrivateNetwork}} + + + + + + +` + +const defaultNetworkName = "minikube-net" + +func (d *Driver) createNetwork() error { + conn, err := getConnection() + if err != nil { + return errors.Wrap(err, "getting libvirt connection") + } + defer conn.Close() + + tmpl := template.Must(template.New("network").Parse(networkTmpl)) + var networkXML bytes.Buffer + err = tmpl.Execute(&networkXML, d) + if err != nil { + return errors.Wrap(err, "executing network template") + } + + //Check if network already exists + network, err := conn.LookupNetworkByName(d.PrivateNetwork) + if err == nil { + return nil + } + + network, err = conn.NetworkDefineXML(networkXML.String()) + if err != nil { + return errors.Wrapf(err, "defining network from xml: %s", networkXML.String()) + } + err = network.SetAutostart(true) + if err != nil { + return errors.Wrap(err, "setting network to autostart") + } + + err = network.Create() + if err != nil { + return errors.Wrap(err, "creating network") + } + + return nil +} + +func (d *Driver) lookupIP() (string, error) { + conn, err := getConnection() + if err != nil { + return "", errors.Wrap(err, "getting connection and domain") + } + + defer conn.Close() + + libVersion, err := conn.GetLibVersion() + if err != nil { + return "", errors.Wrap(err, "getting libversion") + } + + // Earlier versions of libvirt use a lease file instead of a status file + if libVersion < 1002006 { + return d.lookupIPFromLeasesFile() + } + + return d.lookupIPFromStatusFile(conn) +} + +func (d *Driver) lookupIPFromStatusFile(conn *libvirt.Connect) (string, error) { + network, err := conn.LookupNetworkByName(d.PrivateNetwork) + if err != nil { + return "", errors.Wrap(err, "looking up network by name") + } + + bridge, err := network.GetBridgeName() + if err != nil { + log.Warnf("Failed to get network bridge: %s", err) + return "", err + } + statusFile := fmt.Sprintf("/var/lib/libvirt/dnsmasq/%s.status", bridge) + statuses, err := ioutil.ReadFile(statusFile) + if err != nil { + return "", errors.Wrap(err, "reading status file") + } + type StatusEntry struct { + IPAddress string `json:"ip-address"` + Hostname string `json:"hostname"` + } + + var statusEntries []StatusEntry + + // If the status file is empty, parsing will fail, ignore this error. + _ = json.Unmarshal(statuses, &statusEntries) + + ipAddress := "" + for _, status := range statusEntries { + if status.Hostname == d.MachineName { + ipAddress = status.IPAddress + } + } + + return ipAddress, nil +} + +func (d *Driver) lookupIPFromLeasesFile() (string, error) { + leasesFile := fmt.Sprintf("/var/lib/libvirt/dnsmasq/%s.leases", d.PrivateNetwork) + leases, err := ioutil.ReadFile(leasesFile) + if err != nil { + return "", errors.Wrap(err, "reading leases file") + } + ipAddress := "" + for _, lease := range strings.Split(string(leases), "\n") { + if len(lease) == 0 { + continue + } + // format for lease entry + // ExpiryTime MAC IP Hostname ExtendedMAC + entry := strings.Split(lease, " ") + if len(entry) != 5 { + return "", fmt.Errorf("Malformed leases entry: %s", entry) + } + if entry[3] == d.MachineName { + ipAddress = entry[2] + } + } + return ipAddress, nil +} diff --git a/pkg/drivers/kvm/storage.go b/pkg/drivers/kvm/storage.go new file mode 100644 index 000000000000..91b28013fc5a --- /dev/null +++ b/pkg/drivers/kvm/storage.go @@ -0,0 +1,115 @@ +/* +Copyright 2016 The Kubernetes Authors All rights reserved. + +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. +*/ + +package kvm + +import ( + "archive/tar" + "bytes" + "fmt" + "io/ioutil" + "math" + "os" + + "github.com/docker/machine/libmachine/ssh" + "github.com/pkg/errors" +) + +func createRawDiskImage(dest string, size int) error { + f, err := os.OpenFile(dest, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644) + if err != nil { + if os.IsExist(err) { + return nil + } + return errors.Wrap(err, "opening file for raw disk image") + } + f.Close() + + if err := os.Truncate(dest, int64(float64(size)*math.Pow10(6))); err != nil { + return errors.Wrap(err, "writing sparse file") + } + + return nil +} + +func (d *Driver) buildDiskImage() error { + diskPath := d.ResolveStorePath(fmt.Sprintf("%s.img", d.MachineName)) + err := createRawDiskImage(diskPath, d.DiskSize) + if err := createRawDiskImage(diskPath, d.DiskSize); err != nil { + return errors.Wrap(err, "creating raw disk image") + } + tarBuf, err := d.generateCertBundle() + if err != nil { + return errors.Wrap(err, "generating cert bundle") + } + f, err := os.OpenFile(d.DiskPath, os.O_WRONLY, 0644) + if err != nil { + return errors.Wrap(err, "opening raw disk image to write cert bundle") + } + defer f.Close() + + f.Seek(0, os.SEEK_SET) + _, err = f.Write(tarBuf.Bytes()) + if err != nil { + return errors.Wrap(err, "wrting cert bundle to disk image") + } + + return nil +} + +func (d *Driver) generateCertBundle() (*bytes.Buffer, error) { + magicString := "boot2docker, please format-me" + + if err := ssh.GenerateSSHKey(d.GetSSHKeyPath()); err != nil { + return nil, errors.Wrap(err, "generating ssh key") + } + buf := new(bytes.Buffer) + tw := tar.NewWriter(buf) + + file := &tar.Header{Name: magicString, Size: int64(len(magicString))} + if err := tw.WriteHeader(file); err != nil { + return nil, errors.Wrap(err, "writing magic string header to tar") + } + if _, err := tw.Write([]byte(magicString)); err != nil { + return nil, errors.Wrap(err, "writing magic string to tar") + } + // .ssh/key.pub => authorized_keys + file = &tar.Header{Name: ".ssh", Typeflag: tar.TypeDir, Mode: 0700} + if err := tw.WriteHeader(file); err != nil { + return nil, errors.Wrap(err, "writing .ssh header to tar") + } + pubKey, err := ioutil.ReadFile(d.publicSSHKeyPath()) + if err != nil { + return nil, errors.Wrap(err, "reading ssh pub key for tar") + } + file = &tar.Header{Name: ".ssh/authorized_keys", Size: int64(len(pubKey)), Mode: 0644} + if err := tw.WriteHeader(file); err != nil { + return nil, errors.Wrap(err, "writing header for authorized_keys to tar") + } + if _, err := tw.Write([]byte(pubKey)); err != nil { + return nil, errors.Wrap(err, "writing pub key to tar") + } + + if err := tw.Close(); err != nil { + return nil, errors.Wrap(err, "closing tar writer") + } + + return buf, nil +} + +func (d *Driver) publicSSHKeyPath() string { + return d.GetSSHKeyPath() + ".pub" +} diff --git a/pkg/minikube/cluster/cluster.go b/pkg/minikube/cluster/cluster.go index cf1ddf43b33b..843da42e36a1 100644 --- a/pkg/minikube/cluster/cluster.go +++ b/pkg/minikube/cluster/cluster.go @@ -338,7 +338,7 @@ func createHost(api libmachine.API, config MachineConfig) (*host.Host, error) { driver = createVirtualboxHost(config) case "vmwarefusion": driver = createVMwareFusionHost(config) - case "kvm": + case "kvm", "kvm2": driver = createKVMHost(config) case "xhyve": driver = createXhyveHost(config) diff --git a/pkg/minikube/constants/constants_linux.go b/pkg/minikube/constants/constants_linux.go index 7c8bb1c7c28f..30e020310510 100644 --- a/pkg/minikube/constants/constants_linux.go +++ b/pkg/minikube/constants/constants_linux.go @@ -25,6 +25,7 @@ import ( var SupportedVMDrivers = [...]string{ "virtualbox", "kvm", + "kvm2", "none", } diff --git a/pkg/util/utils.go b/pkg/util/utils.go index e6d0361518ea..644ff8384fc8 100644 --- a/pkg/util/utils.go +++ b/pkg/util/utils.go @@ -30,6 +30,8 @@ import ( "time" "github.com/blang/semver" + units "github.com/docker/go-units" + "github.com/golang/glog" "github.com/pkg/errors" "k8s.io/minikube/pkg/minikube/constants" "k8s.io/minikube/pkg/minikube/kubernetes_versions" @@ -42,6 +44,14 @@ type RetriableError struct { func (r RetriableError) Error() string { return "Temporary Error: " + r.Err.Error() } +func CalculateDiskSizeInMB(humanReadableDiskSize string) int { + diskSize, err := units.FromHumanSize(humanReadableDiskSize) + if err != nil { + glog.Errorf("Invalid disk size: %s", err) + } + return int(diskSize / units.MB) +} + // Until endlessly loops the provided function until a message is received on the done channel. // The function will wait the duration provided in sleep between function calls. Errors will be sent on provider Writer. func Until(fn func() error, w io.Writer, name string, sleep time.Duration, done <-chan struct{}) { diff --git a/vendor/github.com/libvirt/libvirt-go/.gitignore b/vendor/github.com/libvirt/libvirt-go/.gitignore new file mode 100644 index 000000000000..3624e1cfa0da --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/.gitignore @@ -0,0 +1,7 @@ +*.sublime-workspace +*.sublime-project +.vagrant +/libvirt-go.test +*~ +.#* +\#* diff --git a/vendor/github.com/libvirt/libvirt-go/.travis.yml b/vendor/github.com/libvirt/libvirt-go/.travis.yml new file mode 100644 index 000000000000..63c0c672429b --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/.travis.yml @@ -0,0 +1,38 @@ +language: go +os: linux +dist: trusty +sudo: require + +go: + - 1.5 + - 1.6 + - 1.7 + +env: + - LIBVIRT=1.2.0 EXT=gz + - LIBVIRT=1.2.10 EXT=gz + - LIBVIRT=1.2.20 EXT=gz + - LIBVIRT=2.5.0 EXT=xz + +install: + - sudo apt-get -qqy build-dep libvirt + - sudo apt-get -qqy install curl qemu-system-x86 sasl2-bin + - sudo mkdir -p /usr/src && sudo chown $(id -u) /usr/src + - curl -O -s https://libvirt.org/sources/libvirt-${LIBVIRT}.tar.${EXT} + - tar -C /usr/src -xf libvirt-${LIBVIRT}.tar.${EXT} + - pushd /usr/src/libvirt-${LIBVIRT} + - | + ./configure --prefix=/usr --localstatedir=/var --sysconfdir=/etc \ + --without-polkit \ + --without-esx --without-vbox --without-xen --without-libxl \ + --with-qemu --with-lxc + - make + - sudo make install + - popd + - sudo libvirtd -d -l -f libvirtd.conf + - sudo virtlogd -d || true + - sudo chmod a+rwx /var/run/libvirt/libvirt-sock* + - echo "pass" | sudo saslpasswd2 -p -a libvirt user + +script: + go test -timeout 1m -tags "integration" -v diff --git a/vendor/github.com/libvirt/libvirt-go/FAQ.md b/vendor/github.com/libvirt/libvirt-go/FAQ.md new file mode 100644 index 000000000000..0e731817a5fc --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/FAQ.md @@ -0,0 +1,19 @@ +#libvirt-go + +##FAQ - Frequently asked questions + +If your question is a good one, please ask it as a well-formatted patch to this +repository, and we'll merge it along with the answer. + +###Why does this fail when added to my project in travis? + +This lib requires a newish version of the libvirt-dev library to compile. These +are only available in the newer travis environment. You can add: + +``` +sudo: true +dist: trusty +install: sudo apt-get install -y libvirt-dev +``` + +to your `.travis.yaml` file to avoid these errors. diff --git a/vendor/github.com/libvirt/libvirt-go/LICENSE b/vendor/github.com/libvirt/libvirt-go/LICENSE new file mode 100644 index 000000000000..202f5fcef8d6 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2013 Alex Zorin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/vendor/github.com/libvirt/libvirt-go/README.md b/vendor/github.com/libvirt/libvirt-go/README.md new file mode 100644 index 000000000000..326d6a0604a3 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/README.md @@ -0,0 +1,136 @@ +# libvirt-go [![Build Status](https://travis-ci.org/libvirt/libvirt-go.svg?branch=master)](https://travis-ci.org/libvirt/libvirt-go) [![GoDoc](https://godoc.org/github.com/libvirt/libvirt-go?status.svg)](https://godoc.org/github.com/libvirt/libvirt-go) + +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 libvirt.so, libvirt-qemu.so +and libvirt-lxc.so. 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. + +## Documentation + +* [api documentation for the bindings](https://godoc.org/github.com/libvirt/libvirt-go) +* [api documentation for libvirt](http://libvirt.org/html/libvirt-libvirt.html) + +## Contributing + +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. The preferred submission method is to use +git send-email to submit patches to the libvir-list@redhat.com +mailing list. eg. to send a single patch + + git send-email --to libvir-list@redhat.com --subject-prefix "PATCH go" \ + --smtp-server=$HOSTNAME -1 + +Or to send all patches on the current branch, against master + + git send-email --to libvir-list@redhat.com --subject-prefix "PATCH go" \ + --smtp-server=$HOSTNAME --no-chain-reply-to --cover-letter --annotate \ + master.. + +Note the master GIT repository is at + +* http://libvirt.org/git/?p=libvirt-go.git;a=summary + +The following automatic read-only mirrors are available as a +convenience to allow contributors to "fork" the repository: + +* https://gitlab.com/libvirt/libvirt-go +* https://github.com/libvirt/libvirt-go + +While you can send pull-requests to these mirrors, they will be +re-submitted via emai to the mailing list for review before +being merged, unless they are trivial/obvious bug fixes. + +## Testing + +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 < +#include +#include "callbacks_cfuncs.h" + +extern void freeCallbackId(long); +void freeGoCallback_cgo(void* goCallbackId) { + freeCallbackId((long)goCallbackId); +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/callbacks_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/callbacks_cfuncs.h new file mode 100644 index 000000000000..689a77789b80 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/callbacks_cfuncs.h @@ -0,0 +1,32 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_CALLBACKS_CFUNCS_H__ +#define LIBVIRT_GO_CALLBACKS_CFUNCS_H__ + +void freeGoCallback_cgo(void* goCallbackId); + +#endif /* LIBVIRT_GO_CALLBACKS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/connect.go b/vendor/github.com/libvirt/libvirt-go/connect.go new file mode 100644 index 000000000000..ac6c0fe674e6 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/connect.go @@ -0,0 +1,2567 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "os" + "reflect" + "sync" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "connect_compat.h" +#include "connect_cfuncs.h" +*/ +import "C" + +func init() { + C.virInitialize() +} + +const ( + VERSION_NUMBER = uint32(C.LIBVIR_VERSION_NUMBER) +) + +type ConnectCloseReason int + +const ( + CONNECT_CLOSE_REASON_ERROR = ConnectCloseReason(C.VIR_CONNECT_CLOSE_REASON_ERROR) + CONNECT_CLOSE_REASON_EOF = ConnectCloseReason(C.VIR_CONNECT_CLOSE_REASON_EOF) + CONNECT_CLOSE_REASON_KEEPALIVE = ConnectCloseReason(C.VIR_CONNECT_CLOSE_REASON_KEEPALIVE) + CONNECT_CLOSE_REASON_CLIENT = ConnectCloseReason(C.VIR_CONNECT_CLOSE_REASON_CLIENT) +) + +type ConnectListAllDomainsFlags int + +const ( + CONNECT_LIST_DOMAINS_ACTIVE = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_ACTIVE) + CONNECT_LIST_DOMAINS_INACTIVE = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_INACTIVE) + CONNECT_LIST_DOMAINS_PERSISTENT = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_PERSISTENT) + CONNECT_LIST_DOMAINS_TRANSIENT = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_TRANSIENT) + CONNECT_LIST_DOMAINS_RUNNING = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_RUNNING) + CONNECT_LIST_DOMAINS_PAUSED = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_PAUSED) + CONNECT_LIST_DOMAINS_SHUTOFF = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_SHUTOFF) + CONNECT_LIST_DOMAINS_OTHER = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_OTHER) + CONNECT_LIST_DOMAINS_MANAGEDSAVE = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE) + CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE) + CONNECT_LIST_DOMAINS_AUTOSTART = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_AUTOSTART) + CONNECT_LIST_DOMAINS_NO_AUTOSTART = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART) + CONNECT_LIST_DOMAINS_HAS_SNAPSHOT = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT) + CONNECT_LIST_DOMAINS_NO_SNAPSHOT = ConnectListAllDomainsFlags(C.VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT) +) + +type ConnectListAllNetworksFlags int + +const ( + CONNECT_LIST_NETWORKS_INACTIVE = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_INACTIVE) + CONNECT_LIST_NETWORKS_ACTIVE = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_ACTIVE) + CONNECT_LIST_NETWORKS_PERSISTENT = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_PERSISTENT) + CONNECT_LIST_NETWORKS_TRANSIENT = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_TRANSIENT) + CONNECT_LIST_NETWORKS_AUTOSTART = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_AUTOSTART) + CONNECT_LIST_NETWORKS_NO_AUTOSTART = ConnectListAllNetworksFlags(C.VIR_CONNECT_LIST_NETWORKS_NO_AUTOSTART) +) + +type ConnectListAllStoragePoolsFlags int + +const ( + CONNECT_LIST_STORAGE_POOLS_INACTIVE = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_INACTIVE) + CONNECT_LIST_STORAGE_POOLS_ACTIVE = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_ACTIVE) + CONNECT_LIST_STORAGE_POOLS_PERSISTENT = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_PERSISTENT) + CONNECT_LIST_STORAGE_POOLS_TRANSIENT = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_TRANSIENT) + CONNECT_LIST_STORAGE_POOLS_AUTOSTART = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_AUTOSTART) + CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_NO_AUTOSTART) + CONNECT_LIST_STORAGE_POOLS_DIR = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_DIR) + CONNECT_LIST_STORAGE_POOLS_FS = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_FS) + CONNECT_LIST_STORAGE_POOLS_NETFS = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS) + CONNECT_LIST_STORAGE_POOLS_LOGICAL = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_LOGICAL) + CONNECT_LIST_STORAGE_POOLS_DISK = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_DISK) + CONNECT_LIST_STORAGE_POOLS_ISCSI = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI) + CONNECT_LIST_STORAGE_POOLS_SCSI = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_SCSI) + CONNECT_LIST_STORAGE_POOLS_MPATH = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_MPATH) + CONNECT_LIST_STORAGE_POOLS_RBD = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_RBD) + CONNECT_LIST_STORAGE_POOLS_SHEEPDOG = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_SHEEPDOG) + CONNECT_LIST_STORAGE_POOLS_GLUSTER = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER) + CONNECT_LIST_STORAGE_POOLS_ZFS = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_ZFS) + CONNECT_LIST_STORAGE_POOLS_VSTORAGE = ConnectListAllStoragePoolsFlags(C.VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE) +) + +type ConnectBaselineCPUFlags int + +const ( + CONNECT_BASELINE_CPU_EXPAND_FEATURES = ConnectBaselineCPUFlags(C.VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES) + CONNECT_BASELINE_CPU_MIGRATABLE = ConnectBaselineCPUFlags(C.VIR_CONNECT_BASELINE_CPU_MIGRATABLE) +) + +type ConnectCompareCPUFlags int + +const ( + CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE = ConnectCompareCPUFlags(C.VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE) +) + +type ConnectListAllInterfacesFlags int + +const ( + CONNECT_LIST_INTERFACES_INACTIVE = ConnectListAllInterfacesFlags(C.VIR_CONNECT_LIST_INTERFACES_INACTIVE) + CONNECT_LIST_INTERFACES_ACTIVE = ConnectListAllInterfacesFlags(C.VIR_CONNECT_LIST_INTERFACES_ACTIVE) +) + +type ConnectListAllNodeDeviceFlags int + +const ( + CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SYSTEM) + CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV) + CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV) + CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE) + CONNECT_LIST_NODE_DEVICES_CAP_NET = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET) + CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST) + CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_TARGET) + CONNECT_LIST_NODE_DEVICES_CAP_SCSI = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI) + CONNECT_LIST_NODE_DEVICES_CAP_STORAGE = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE) + CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST) + CONNECT_LIST_NODE_DEVICES_CAP_VPORTS = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_VPORTS) + CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_GENERIC) + CONNECT_LIST_NODE_DEVICES_CAP_DRM = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM) + CONNECT_LIST_NODE_DEVICES_CAP_MDEV = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV) + CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES) + CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV = ConnectListAllNodeDeviceFlags(C.VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV) +) + +type ConnectListAllSecretsFlags int + +const ( + CONNECT_LIST_SECRETS_EPHEMERAL = ConnectListAllSecretsFlags(C.VIR_CONNECT_LIST_SECRETS_EPHEMERAL) + CONNECT_LIST_SECRETS_NO_EPHEMERAL = ConnectListAllSecretsFlags(C.VIR_CONNECT_LIST_SECRETS_NO_EPHEMERAL) + CONNECT_LIST_SECRETS_PRIVATE = ConnectListAllSecretsFlags(C.VIR_CONNECT_LIST_SECRETS_PRIVATE) + CONNECT_LIST_SECRETS_NO_PRIVATE = ConnectListAllSecretsFlags(C.VIR_CONNECT_LIST_SECRETS_NO_PRIVATE) +) + +type ConnectGetAllDomainStatsFlags int + +const ( + CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE) + CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE) + CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT) + CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT) + CONNECT_GET_ALL_DOMAINS_STATS_RUNNING = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING) + CONNECT_GET_ALL_DOMAINS_STATS_PAUSED = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED) + CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF) + CONNECT_GET_ALL_DOMAINS_STATS_OTHER = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER) + CONNECT_GET_ALL_DOMAINS_STATS_BACKING = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING) + CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS = ConnectGetAllDomainStatsFlags(C.VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS) +) + +type ConnectFlags int + +const ( + CONNECT_RO = ConnectFlags(C.VIR_CONNECT_RO) + CONNECT_NO_ALIASES = ConnectFlags(C.VIR_CONNECT_NO_ALIASES) +) + +type ConnectDomainEventAgentLifecycleState int + +const ( + CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED = ConnectDomainEventAgentLifecycleState(C.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED) + CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED = ConnectDomainEventAgentLifecycleState(C.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED) +) + +type ConnectDomainEventAgentLifecycleReason int + +const ( + CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN = ConnectDomainEventAgentLifecycleReason(C.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN) + CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED = ConnectDomainEventAgentLifecycleReason(C.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED) + CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL = ConnectDomainEventAgentLifecycleReason(C.VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL) +) + +type CPUCompareResult int + +const ( + CPU_COMPARE_ERROR = CPUCompareResult(C.VIR_CPU_COMPARE_ERROR) + CPU_COMPARE_INCOMPATIBLE = CPUCompareResult(C.VIR_CPU_COMPARE_INCOMPATIBLE) + CPU_COMPARE_IDENTICAL = CPUCompareResult(C.VIR_CPU_COMPARE_IDENTICAL) + CPU_COMPARE_SUPERSET = CPUCompareResult(C.VIR_CPU_COMPARE_SUPERSET) +) + +type NodeAllocPagesFlags int + +const ( + NODE_ALLOC_PAGES_ADD = NodeAllocPagesFlags(C.VIR_NODE_ALLOC_PAGES_ADD) + NODE_ALLOC_PAGES_SET = NodeAllocPagesFlags(C.VIR_NODE_ALLOC_PAGES_SET) +) + +type NodeSuspendTarget int + +const ( + NODE_SUSPEND_TARGET_MEM = NodeSuspendTarget(C.VIR_NODE_SUSPEND_TARGET_MEM) + NODE_SUSPEND_TARGET_DISK = NodeSuspendTarget(C.VIR_NODE_SUSPEND_TARGET_DISK) + NODE_SUSPEND_TARGET_HYBRID = NodeSuspendTarget(C.VIR_NODE_SUSPEND_TARGET_HYBRID) +) + +type NodeGetCPUStatsAllCPUs int + +const ( + NODE_CPU_STATS_ALL_CPUS = NodeGetCPUStatsAllCPUs(C.VIR_NODE_CPU_STATS_ALL_CPUS) +) + +const ( + NODE_MEMORY_STATS_ALL_CELLS = int(C.VIR_NODE_MEMORY_STATS_ALL_CELLS) +) + +type ConnectCredentialType int + +const ( + CRED_USERNAME = ConnectCredentialType(C.VIR_CRED_USERNAME) + CRED_AUTHNAME = ConnectCredentialType(C.VIR_CRED_AUTHNAME) + CRED_LANGUAGE = ConnectCredentialType(C.VIR_CRED_LANGUAGE) + CRED_CNONCE = ConnectCredentialType(C.VIR_CRED_CNONCE) + CRED_PASSPHRASE = ConnectCredentialType(C.VIR_CRED_PASSPHRASE) + CRED_ECHOPROMPT = ConnectCredentialType(C.VIR_CRED_ECHOPROMPT) + CRED_NOECHOPROMPT = ConnectCredentialType(C.VIR_CRED_NOECHOPROMPT) + CRED_REALM = ConnectCredentialType(C.VIR_CRED_REALM) + CRED_EXTERNAL = ConnectCredentialType(C.VIR_CRED_EXTERNAL) +) + +type Connect struct { + ptr C.virConnectPtr +} + +type NodeInfo struct { + Model string + Memory uint64 + Cpus uint + MHz uint + Nodes uint32 + Sockets uint32 + Cores uint32 + Threads uint32 +} + +// Additional data associated to the connection. +type virConnectionData struct { + errCallbackId *int + closeCallbackId *int +} + +var connections map[C.virConnectPtr]*virConnectionData +var connectionsLock sync.RWMutex + +func init() { + connections = make(map[C.virConnectPtr]*virConnectionData) +} + +func saveConnectionData(c *Connect, d *virConnectionData) { + if c.ptr == nil { + return // Or panic? + } + connectionsLock.Lock() + defer connectionsLock.Unlock() + connections[c.ptr] = d +} + +func getConnectionData(c *Connect) *virConnectionData { + connectionsLock.RLock() + d := connections[c.ptr] + connectionsLock.RUnlock() + if d != nil { + return d + } + d = &virConnectionData{} + saveConnectionData(c, d) + return d +} + +func releaseConnectionData(c *Connect) { + if c.ptr == nil { + return + } + connectionsLock.Lock() + defer connectionsLock.Unlock() + delete(connections, c.ptr) +} + +func GetVersion() (uint32, error) { + var version C.ulong + if err := C.virGetVersion(&version, nil, nil); err < 0 { + return 0, GetLastError() + } + return uint32(version), nil +} + +func NewConnect(uri string) (*Connect, error) { + var cUri *C.char + if uri != "" { + cUri = C.CString(uri) + defer C.free(unsafe.Pointer(cUri)) + } + ptr := C.virConnectOpen(cUri) + if ptr == nil { + return nil, GetLastError() + } + return &Connect{ptr: ptr}, nil +} + +type ConnectCredential struct { + Type ConnectCredentialType + Prompt string + Challenge string + DefResult string + Result string + ResultLen int +} + +type ConnectAuthCallback func(creds []*ConnectCredential) + +type ConnectAuth struct { + CredType []ConnectCredentialType + Callback ConnectAuthCallback +} + +//export connectAuthCallback +func connectAuthCallback(ccredlist C.virConnectCredentialPtr, ncred C.uint, callbackID C.int) C.int { + cred := make([]*ConnectCredential, int(ncred)) + + for i := 0; i < int(ncred); i++ { + ccred := (C.virConnectCredentialPtr)(unsafe.Pointer((uintptr)(unsafe.Pointer(ccredlist)) + (unsafe.Sizeof(*ccredlist) * uintptr(i)))) + cred[i] = &ConnectCredential{ + Type: ConnectCredentialType(ccred._type), + Prompt: C.GoString(ccred.prompt), + Challenge: C.GoString(ccred.challenge), + DefResult: C.GoString(ccred.defresult), + ResultLen: -1, + } + } + callbackEntry := getCallbackId(int(callbackID)) + callback, ok := callbackEntry.(ConnectAuthCallback) + if !ok { + panic("Unexpected callback type") + } + + callback(cred) + + for i := 0; i < int(ncred); i++ { + ccred := (C.virConnectCredentialPtr)(unsafe.Pointer((uintptr)(unsafe.Pointer(ccredlist)) + (unsafe.Sizeof(*ccredlist) * uintptr(i)))) + if cred[i].ResultLen >= 0 { + ccred.result = C.CString(cred[i].Result) + ccred.resultlen = C.uint(cred[i].ResultLen) + } + } + + return 0 +} + +func NewConnectWithAuth(uri string, auth *ConnectAuth, flags ConnectFlags) (*Connect, error) { + var cUri *C.char + + ccredtype := make([]C.int, len(auth.CredType)) + + for i := 0; i < len(auth.CredType); i++ { + ccredtype[i] = C.int(auth.CredType[i]) + } + + if uri != "" { + cUri = C.CString(uri) + defer C.free(unsafe.Pointer(cUri)) + } + + callbackID := registerCallbackId(auth.Callback) + + ptr := C.virConnectOpenAuthWrap(cUri, &ccredtype[0], C.uint(len(auth.CredType)), C.int(callbackID), C.uint(flags)) + freeCallbackId(callbackID) + if ptr == nil { + return nil, GetLastError() + } + return &Connect{ptr: ptr}, nil +} + +func NewConnectReadOnly(uri string) (*Connect, error) { + var cUri *C.char + if uri != "" { + cUri = C.CString(uri) + defer C.free(unsafe.Pointer(cUri)) + } + ptr := C.virConnectOpenReadOnly(cUri) + if ptr == nil { + return nil, GetLastError() + } + return &Connect{ptr: ptr}, nil +} + +func (c *Connect) Close() (int, error) { + result := int(C.virConnectClose(c.ptr)) + if result == -1 { + return result, GetLastError() + } + if result == 0 { + // No more reference to this connection, release data. + releaseConnectionData(c) + c.ptr = nil + } + return result, nil +} + +func (c *Connect) Ref() error { + ret := C.virConnectRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +type CloseCallback func(conn *Connect, reason ConnectCloseReason) + +// Register a close callback for the given destination. Only one +// callback per connection is allowed. Setting a callback will remove +// the previous one. +func (c *Connect) RegisterCloseCallback(callback CloseCallback) error { + c.UnregisterCloseCallback() + goCallbackId := registerCallbackId(callback) + callbackPtr := unsafe.Pointer(C.closeCallback_cgo) + res := C.virConnectRegisterCloseCallback_cgo(c.ptr, C.virConnectCloseFunc(callbackPtr), C.long(goCallbackId)) + if res != 0 { + freeCallbackId(goCallbackId) + return GetLastError() + } + connData := getConnectionData(c) + connData.closeCallbackId = &goCallbackId + return nil +} + +func (c *Connect) UnregisterCloseCallback() error { + connData := getConnectionData(c) + if connData.closeCallbackId == nil { + return nil + } + callbackPtr := unsafe.Pointer(C.closeCallback_cgo) + res := C.virConnectUnregisterCloseCallback(c.ptr, C.virConnectCloseFunc(callbackPtr)) + if res != 0 { + return GetLastError() + } + connData.closeCallbackId = nil + return nil +} + +//export closeCallback +func closeCallback(conn C.virConnectPtr, reason ConnectCloseReason, goCallbackId int) { + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(CloseCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(&Connect{ptr: conn}, reason) +} + +func (c *Connect) GetCapabilities() (string, error) { + str := C.virConnectGetCapabilities(c.ptr) + if str == nil { + return "", GetLastError() + } + capabilities := C.GoString(str) + C.free(unsafe.Pointer(str)) + return capabilities, nil +} + +func (c *Connect) GetNodeInfo() (*NodeInfo, error) { + var cinfo C.virNodeInfo + result := C.virNodeGetInfo(c.ptr, &cinfo) + if result == -1 { + return nil, GetLastError() + } + return &NodeInfo{ + Model: C.GoString((*C.char)(unsafe.Pointer(&cinfo.model[0]))), + Memory: uint64(cinfo.memory), + Cpus: uint(cinfo.cpus), + MHz: uint(cinfo.mhz), + Nodes: uint32(cinfo.nodes), + Sockets: uint32(cinfo.sockets), + Cores: uint32(cinfo.cores), + Threads: uint32(cinfo.threads), + }, nil +} + +func (ni *NodeInfo) GetMaxCPUs() uint32 { + return ni.Nodes * ni.Sockets * ni.Cores * ni.Threads +} + +func (c *Connect) GetHostname() (string, error) { + str := C.virConnectGetHostname(c.ptr) + if str == nil { + return "", GetLastError() + } + hostname := C.GoString(str) + C.free(unsafe.Pointer(str)) + return hostname, nil +} + +func (c *Connect) GetLibVersion() (uint32, error) { + var version C.ulong + if err := C.virConnectGetLibVersion(c.ptr, &version); err < 0 { + return 0, GetLastError() + } + return uint32(version), nil +} + +func (c *Connect) GetType() (string, error) { + str := C.virConnectGetType(c.ptr) + if str == nil { + return "", GetLastError() + } + hypDriver := C.GoString(str) + return hypDriver, nil +} + +func (c *Connect) IsAlive() (bool, error) { + result := C.virConnectIsAlive(c.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (c *Connect) IsEncrypted() (bool, error) { + result := C.virConnectIsEncrypted(c.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (c *Connect) IsSecure() (bool, error) { + result := C.virConnectIsSecure(c.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (c *Connect) ListDefinedDomains() ([]string, error) { + var names [1024](*C.char) + namesPtr := unsafe.Pointer(&names) + numDomains := C.virConnectListDefinedDomains( + c.ptr, + (**C.char)(namesPtr), + 1024) + if numDomains == -1 { + return nil, GetLastError() + } + goNames := make([]string, numDomains) + for k := 0; k < int(numDomains); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListDomains() ([]uint32, error) { + var cDomainsIds [512](uint32) + cDomainsPointer := unsafe.Pointer(&cDomainsIds) + numDomains := C.virConnectListDomains(c.ptr, (*C.int)(cDomainsPointer), 512) + if numDomains == -1 { + return nil, GetLastError() + } + + return cDomainsIds[:numDomains], nil +} + +func (c *Connect) ListInterfaces() ([]string, error) { + const maxIfaces = 1024 + var names [maxIfaces](*C.char) + namesPtr := unsafe.Pointer(&names) + numIfaces := C.virConnectListInterfaces( + c.ptr, + (**C.char)(namesPtr), + maxIfaces) + if numIfaces == -1 { + return nil, GetLastError() + } + goNames := make([]string, numIfaces) + for k := 0; k < int(numIfaces); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListNetworks() ([]string, error) { + const maxNets = 1024 + var names [maxNets](*C.char) + namesPtr := unsafe.Pointer(&names) + numNetworks := C.virConnectListNetworks( + c.ptr, + (**C.char)(namesPtr), + maxNets) + if numNetworks == -1 { + return nil, GetLastError() + } + goNames := make([]string, numNetworks) + for k := 0; k < int(numNetworks); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListNWFilters() ([]string, error) { + const maxFilters = 1024 + var names [maxFilters](*C.char) + namesPtr := unsafe.Pointer(&names) + numNWFilters := C.virConnectListNWFilters( + c.ptr, + (**C.char)(namesPtr), + maxFilters) + if numNWFilters == -1 { + return nil, GetLastError() + } + goNames := make([]string, numNWFilters) + for k := 0; k < int(numNWFilters); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListStoragePools() ([]string, error) { + const maxPools = 1024 + var names [maxPools](*C.char) + namesPtr := unsafe.Pointer(&names) + numStoragePools := C.virConnectListStoragePools( + c.ptr, + (**C.char)(namesPtr), + maxPools) + if numStoragePools == -1 { + return nil, GetLastError() + } + goNames := make([]string, numStoragePools) + for k := 0; k < int(numStoragePools); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListSecrets() ([]string, error) { + const maxSecrets = 1024 + var uuids [maxSecrets](*C.char) + uuidsPtr := unsafe.Pointer(&uuids) + numSecrets := C.virConnectListSecrets( + c.ptr, + (**C.char)(uuidsPtr), + maxSecrets) + if numSecrets == -1 { + return nil, GetLastError() + } + goUuids := make([]string, numSecrets) + for k := 0; k < int(numSecrets); k++ { + goUuids[k] = C.GoString(uuids[k]) + C.free(unsafe.Pointer(uuids[k])) + } + return goUuids, nil +} + +func (c *Connect) ListDevices(cap string, flags uint32) ([]string, error) { + ccap := C.CString(cap) + defer C.free(unsafe.Pointer(ccap)) + const maxNodeDevices = 1024 + var uuids [maxNodeDevices](*C.char) + uuidsPtr := unsafe.Pointer(&uuids) + numNodeDevices := C.virNodeListDevices( + c.ptr, ccap, + (**C.char)(uuidsPtr), + maxNodeDevices, C.uint(flags)) + if numNodeDevices == -1 { + return nil, GetLastError() + } + goUuids := make([]string, numNodeDevices) + for k := 0; k < int(numNodeDevices); k++ { + goUuids[k] = C.GoString(uuids[k]) + C.free(unsafe.Pointer(uuids[k])) + } + return goUuids, nil +} + +func (c *Connect) LookupDomainById(id uint32) (*Domain, error) { + ptr := C.virDomainLookupByID(c.ptr, C.int(id)) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) LookupDomainByName(id string) (*Domain, error) { + cName := C.CString(id) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virDomainLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) LookupDomainByUUIDString(uuid string) (*Domain, error) { + cUuid := C.CString(uuid) + defer C.free(unsafe.Pointer(cUuid)) + ptr := C.virDomainLookupByUUIDString(c.ptr, cUuid) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) LookupDomainByUUID(uuid []byte) (*Domain, error) { + if len(uuid) != C.VIR_UUID_BUFLEN { + return nil, fmt.Errorf("UUID must be exactly %d bytes in size", + int(C.VIR_UUID_BUFLEN)) + } + cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) + for i := 0; i < C.VIR_UUID_BUFLEN; i++ { + cUuid[i] = C.uchar(uuid[i]) + } + ptr := C.virDomainLookupByUUID(c.ptr, &cUuid[0]) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) DomainCreateXML(xmlConfig string, flags DomainCreateFlags) (*Domain, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virDomainCreateXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) DomainCreateXMLWithFiles(xmlConfig string, files []os.File, flags DomainCreateFlags) (*Domain, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + cfiles := make([]C.int, len(files)) + for i := 0; i < len(files); i++ { + cfiles[i] = C.int(files[i].Fd()) + } + ptr := C.virDomainCreateXMLWithFiles(c.ptr, cXml, C.uint(len(files)), (&cfiles[0]), C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) DomainDefineXML(xmlConfig string) (*Domain, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virDomainDefineXML(c.ptr, cXml) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) DomainDefineXMLFlags(xmlConfig string, flags DomainDefineFlags) (*Domain, error) { + if C.LIBVIR_VERSION_NUMBER < 1002012 { + return nil, GetNotImplementedError("virDomainDefineXMLFlags") + } + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virDomainDefineXMLFlagsCompat(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +func (c *Connect) ListDefinedInterfaces() ([]string, error) { + const maxIfaces = 1024 + var names [maxIfaces](*C.char) + namesPtr := unsafe.Pointer(&names) + numIfaces := C.virConnectListDefinedInterfaces( + c.ptr, + (**C.char)(namesPtr), + maxIfaces) + if numIfaces == -1 { + return nil, GetLastError() + } + goNames := make([]string, numIfaces) + for k := 0; k < int(numIfaces); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListDefinedNetworks() ([]string, error) { + const maxNets = 1024 + var names [maxNets](*C.char) + namesPtr := unsafe.Pointer(&names) + numNetworks := C.virConnectListDefinedNetworks( + c.ptr, + (**C.char)(namesPtr), + maxNets) + if numNetworks == -1 { + return nil, GetLastError() + } + goNames := make([]string, numNetworks) + for k := 0; k < int(numNetworks); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) ListDefinedStoragePools() ([]string, error) { + const maxPools = 1024 + var names [maxPools](*C.char) + namesPtr := unsafe.Pointer(&names) + numStoragePools := C.virConnectListDefinedStoragePools( + c.ptr, + (**C.char)(namesPtr), + maxPools) + if numStoragePools == -1 { + return nil, GetLastError() + } + goNames := make([]string, numStoragePools) + for k := 0; k < int(numStoragePools); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (c *Connect) NumOfDefinedDomains() (int, error) { + result := int(C.virConnectNumOfDefinedDomains(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfDefinedInterfaces() (int, error) { + result := int(C.virConnectNumOfDefinedInterfaces(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfDefinedNetworks() (int, error) { + result := int(C.virConnectNumOfDefinedNetworks(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfDefinedStoragePools() (int, error) { + result := int(C.virConnectNumOfDefinedStoragePools(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfDomains() (int, error) { + result := int(C.virConnectNumOfDomains(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfStoragePools() (int, error) { + result := int(C.virConnectNumOfStoragePools(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfInterfaces() (int, error) { + result := int(C.virConnectNumOfInterfaces(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfNetworks() (int, error) { + result := int(C.virConnectNumOfNetworks(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfNWFilters() (int, error) { + result := int(C.virConnectNumOfNWFilters(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfSecrets() (int, error) { + result := int(C.virConnectNumOfSecrets(c.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NumOfDevices(cap string, flags uint32) (int, error) { + ccap := C.CString(cap) + defer C.free(unsafe.Pointer(ccap)) + result := int(C.virNodeNumOfDevices(c.ptr, ccap, C.uint(flags))) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) NetworkDefineXML(xmlConfig string) (*Network, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virNetworkDefineXML(c.ptr, cXml) + if ptr == nil { + return nil, GetLastError() + } + return &Network{ptr: ptr}, nil +} + +func (c *Connect) NetworkCreateXML(xmlConfig string) (*Network, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virNetworkCreateXML(c.ptr, cXml) + if ptr == nil { + return nil, GetLastError() + } + return &Network{ptr: ptr}, nil +} + +func (c *Connect) LookupNetworkByName(name string) (*Network, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virNetworkLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &Network{ptr: ptr}, nil +} + +func (c *Connect) LookupNetworkByUUIDString(uuid string) (*Network, error) { + cUuid := C.CString(uuid) + defer C.free(unsafe.Pointer(cUuid)) + ptr := C.virNetworkLookupByUUIDString(c.ptr, cUuid) + if ptr == nil { + return nil, GetLastError() + } + return &Network{ptr: ptr}, nil +} + +func (c *Connect) LookupNetworkByUUID(uuid []byte) (*Network, error) { + if len(uuid) != C.VIR_UUID_BUFLEN { + return nil, fmt.Errorf("UUID must be exactly %d bytes in size", + int(C.VIR_UUID_BUFLEN)) + } + cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) + for i := 0; i < C.VIR_UUID_BUFLEN; i++ { + cUuid[i] = C.uchar(uuid[i]) + } + ptr := C.virNetworkLookupByUUID(c.ptr, &cUuid[0]) + if ptr == nil { + return nil, GetLastError() + } + return &Network{ptr: ptr}, nil +} + +func (c *Connect) SetKeepAlive(interval int, count uint) error { + res := int(C.virConnectSetKeepAlive(c.ptr, C.int(interval), C.uint(count))) + switch res { + case 0: + return nil + default: + return GetLastError() + } +} + +func (c *Connect) GetSysinfo(flags uint32) (string, error) { + cStr := C.virConnectGetSysinfo(c.ptr, C.uint(flags)) + if cStr == nil { + return "", GetLastError() + } + info := C.GoString(cStr) + C.free(unsafe.Pointer(cStr)) + return info, nil +} + +func (c *Connect) GetURI() (string, error) { + cStr := C.virConnectGetURI(c.ptr) + if cStr == nil { + return "", GetLastError() + } + uri := C.GoString(cStr) + C.free(unsafe.Pointer(cStr)) + return uri, nil +} + +func (c *Connect) GetMaxVcpus(typeAttr string) (int, error) { + var cTypeAttr *C.char + if typeAttr != "" { + cTypeAttr = C.CString(typeAttr) + defer C.free(unsafe.Pointer(cTypeAttr)) + } + result := int(C.virConnectGetMaxVcpus(c.ptr, cTypeAttr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (c *Connect) InterfaceDefineXML(xmlConfig string, flags uint32) (*Interface, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virInterfaceDefineXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Interface{ptr: ptr}, nil +} + +func (c *Connect) LookupInterfaceByName(name string) (*Interface, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virInterfaceLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &Interface{ptr: ptr}, nil +} + +func (c *Connect) LookupInterfaceByMACString(mac string) (*Interface, error) { + cName := C.CString(mac) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virInterfaceLookupByMACString(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &Interface{ptr: ptr}, nil +} + +func (c *Connect) StoragePoolDefineXML(xmlConfig string, flags uint32) (*StoragePool, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virStoragePoolDefineXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: ptr}, nil +} + +func (c *Connect) StoragePoolCreateXML(xmlConfig string, flags StoragePoolCreateFlags) (*StoragePool, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virStoragePoolCreateXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: ptr}, nil +} + +func (c *Connect) LookupStoragePoolByName(name string) (*StoragePool, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virStoragePoolLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: ptr}, nil +} + +func (c *Connect) LookupStoragePoolByUUIDString(uuid string) (*StoragePool, error) { + cUuid := C.CString(uuid) + defer C.free(unsafe.Pointer(cUuid)) + ptr := C.virStoragePoolLookupByUUIDString(c.ptr, cUuid) + if ptr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: ptr}, nil +} + +func (c *Connect) LookupStoragePoolByUUID(uuid []byte) (*StoragePool, error) { + if len(uuid) != C.VIR_UUID_BUFLEN { + return nil, fmt.Errorf("UUID must be exactly %d bytes in size", + int(C.VIR_UUID_BUFLEN)) + } + cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) + for i := 0; i < C.VIR_UUID_BUFLEN; i++ { + cUuid[i] = C.uchar(uuid[i]) + } + ptr := C.virStoragePoolLookupByUUID(c.ptr, &cUuid[0]) + if ptr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: ptr}, nil +} + +func (c *Connect) NWFilterDefineXML(xmlConfig string) (*NWFilter, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virNWFilterDefineXML(c.ptr, cXml) + if ptr == nil { + return nil, GetLastError() + } + return &NWFilter{ptr: ptr}, nil +} + +func (c *Connect) LookupNWFilterByName(name string) (*NWFilter, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virNWFilterLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &NWFilter{ptr: ptr}, nil +} + +func (c *Connect) LookupNWFilterByUUIDString(uuid string) (*NWFilter, error) { + cUuid := C.CString(uuid) + defer C.free(unsafe.Pointer(cUuid)) + ptr := C.virNWFilterLookupByUUIDString(c.ptr, cUuid) + if ptr == nil { + return nil, GetLastError() + } + return &NWFilter{ptr: ptr}, nil +} + +func (c *Connect) LookupNWFilterByUUID(uuid []byte) (*NWFilter, error) { + if len(uuid) != C.VIR_UUID_BUFLEN { + return nil, fmt.Errorf("UUID must be exactly %d bytes in size", + int(C.VIR_UUID_BUFLEN)) + } + cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) + for i := 0; i < C.VIR_UUID_BUFLEN; i++ { + cUuid[i] = C.uchar(uuid[i]) + } + ptr := C.virNWFilterLookupByUUID(c.ptr, &cUuid[0]) + if ptr == nil { + return nil, GetLastError() + } + return &NWFilter{ptr: ptr}, nil +} + +func (c *Connect) LookupStorageVolByKey(key string) (*StorageVol, error) { + cKey := C.CString(key) + defer C.free(unsafe.Pointer(cKey)) + ptr := C.virStorageVolLookupByKey(c.ptr, cKey) + if ptr == nil { + return nil, GetLastError() + } + return &StorageVol{ptr: ptr}, nil +} + +func (c *Connect) LookupStorageVolByPath(path string) (*StorageVol, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + ptr := C.virStorageVolLookupByPath(c.ptr, cPath) + if ptr == nil { + return nil, GetLastError() + } + return &StorageVol{ptr: ptr}, nil +} + +func (c *Connect) SecretDefineXML(xmlConfig string, flags uint32) (*Secret, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virSecretDefineXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Secret{ptr: ptr}, nil +} + +func (c *Connect) LookupSecretByUUID(uuid []byte) (*Secret, error) { + if len(uuid) != C.VIR_UUID_BUFLEN { + return nil, fmt.Errorf("UUID must be exactly %d bytes in size", + int(C.VIR_UUID_BUFLEN)) + } + cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) + for i := 0; i < C.VIR_UUID_BUFLEN; i++ { + cUuid[i] = C.uchar(uuid[i]) + } + ptr := C.virSecretLookupByUUID(c.ptr, &cUuid[0]) + if ptr == nil { + return nil, GetLastError() + } + return &Secret{ptr: ptr}, nil +} + +func (c *Connect) LookupSecretByUUIDString(uuid string) (*Secret, error) { + cUuid := C.CString(uuid) + defer C.free(unsafe.Pointer(cUuid)) + ptr := C.virSecretLookupByUUIDString(c.ptr, cUuid) + if ptr == nil { + return nil, GetLastError() + } + return &Secret{ptr: ptr}, nil +} + +func (c *Connect) LookupSecretByUsage(usageType SecretUsageType, usageID string) (*Secret, error) { + cUsageID := C.CString(usageID) + defer C.free(unsafe.Pointer(cUsageID)) + ptr := C.virSecretLookupByUsage(c.ptr, C.int(usageType), cUsageID) + if ptr == nil { + return nil, GetLastError() + } + return &Secret{ptr: ptr}, nil +} + +func (c *Connect) LookupDeviceByName(id string) (*NodeDevice, error) { + cName := C.CString(id) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virNodeDeviceLookupByName(c.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &NodeDevice{ptr: ptr}, nil +} + +func (c *Connect) LookupDeviceSCSIHostByWWN(wwnn, wwpn string, flags uint32) (*NodeDevice, error) { + cWwnn := C.CString(wwnn) + cWwpn := C.CString(wwpn) + defer C.free(unsafe.Pointer(cWwnn)) + defer C.free(unsafe.Pointer(cWwpn)) + ptr := C.virNodeDeviceLookupSCSIHostByWWN(c.ptr, cWwnn, cWwpn, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &NodeDevice{ptr: ptr}, nil +} + +func (c *Connect) DeviceCreateXML(xmlConfig string, flags uint32) (*NodeDevice, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virNodeDeviceCreateXML(c.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &NodeDevice{ptr: ptr}, nil +} + +func (c *Connect) ListAllInterfaces(flags ConnectListAllInterfacesFlags) ([]Interface, error) { + var cList *C.virInterfacePtr + numIfaces := C.virConnectListAllInterfaces(c.ptr, (**C.virInterfacePtr)(&cList), C.uint(flags)) + if numIfaces == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numIfaces), + Cap: int(numIfaces), + } + var ifaces []Interface + slice := *(*[]C.virInterfacePtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + ifaces = append(ifaces, Interface{ptr}) + } + C.free(unsafe.Pointer(cList)) + return ifaces, nil +} + +func (c *Connect) ListAllNetworks(flags ConnectListAllNetworksFlags) ([]Network, error) { + var cList *C.virNetworkPtr + numNets := C.virConnectListAllNetworks(c.ptr, (**C.virNetworkPtr)(&cList), C.uint(flags)) + if numNets == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numNets), + Cap: int(numNets), + } + var nets []Network + slice := *(*[]C.virNetworkPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + nets = append(nets, Network{ptr}) + } + C.free(unsafe.Pointer(cList)) + return nets, nil +} + +func (c *Connect) ListAllDomains(flags ConnectListAllDomainsFlags) ([]Domain, error) { + var cList *C.virDomainPtr + numDomains := C.virConnectListAllDomains(c.ptr, (**C.virDomainPtr)(&cList), C.uint(flags)) + if numDomains == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numDomains), + Cap: int(numDomains), + } + var domains []Domain + slice := *(*[]C.virDomainPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + domains = append(domains, Domain{ptr}) + } + C.free(unsafe.Pointer(cList)) + return domains, nil +} + +func (c *Connect) ListAllNWFilters(flags uint32) ([]NWFilter, error) { + var cList *C.virNWFilterPtr + numNWFilters := C.virConnectListAllNWFilters(c.ptr, (**C.virNWFilterPtr)(&cList), C.uint(flags)) + if numNWFilters == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numNWFilters), + Cap: int(numNWFilters), + } + var filters []NWFilter + slice := *(*[]C.virNWFilterPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + filters = append(filters, NWFilter{ptr}) + } + C.free(unsafe.Pointer(cList)) + return filters, nil +} + +func (c *Connect) ListAllStoragePools(flags ConnectListAllStoragePoolsFlags) ([]StoragePool, error) { + var cList *C.virStoragePoolPtr + numPools := C.virConnectListAllStoragePools(c.ptr, (**C.virStoragePoolPtr)(&cList), C.uint(flags)) + if numPools == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numPools), + Cap: int(numPools), + } + var pools []StoragePool + slice := *(*[]C.virStoragePoolPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, StoragePool{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} + +func (c *Connect) ListAllSecrets(flags ConnectListAllSecretsFlags) ([]Secret, error) { + var cList *C.virSecretPtr + numPools := C.virConnectListAllSecrets(c.ptr, (**C.virSecretPtr)(&cList), C.uint(flags)) + if numPools == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numPools), + Cap: int(numPools), + } + var pools []Secret + slice := *(*[]C.virSecretPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, Secret{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} + +func (c *Connect) ListAllNodeDevices(flags ConnectListAllNodeDeviceFlags) ([]NodeDevice, error) { + var cList *C.virNodeDevicePtr + numPools := C.virConnectListAllNodeDevices(c.ptr, (**C.virNodeDevicePtr)(&cList), C.uint(flags)) + if numPools == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numPools), + Cap: int(numPools), + } + var pools []NodeDevice + slice := *(*[]C.virNodeDevicePtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, NodeDevice{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} + +func (c *Connect) InterfaceChangeBegin(flags uint32) error { + ret := C.virInterfaceChangeBegin(c.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) InterfaceChangeCommit(flags uint32) error { + ret := C.virInterfaceChangeCommit(c.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) InterfaceChangeRollback(flags uint32) error { + ret := C.virInterfaceChangeRollback(c.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) AllocPages(pageSizes map[int]int64, startCell int, cellCount uint, flags NodeAllocPagesFlags) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 1002009 { + return 0, GetNotImplementedError("virNodeAllocPages") + } + cpages := make([]C.uint, len(pageSizes)) + ccounts := make([]C.ulonglong, len(pageSizes)) + + i := 0 + for key, val := range pageSizes { + cpages[i] = C.uint(key) + ccounts[i] = C.ulonglong(val) + i++ + } + + ret := C.virNodeAllocPagesCompat(c.ptr, C.uint(len(pageSizes)), (*C.uint)(unsafe.Pointer(&cpages)), + (*C.ulonglong)(unsafe.Pointer(&ccounts)), C.int(startCell), C.uint(cellCount), C.uint(flags)) + if ret == -1 { + return 0, GetLastError() + } + + return int(ret), nil +} + +func (c *Connect) GetCPUMap(flags uint32) (map[int]bool, uint, error) { + var ccpumap *C.uchar + var conline C.uint + ret := C.virNodeGetCPUMap(c.ptr, &ccpumap, &conline, C.uint(flags)) + if ret == -1 { + return map[int]bool{}, 0, GetLastError() + } + defer C.free(unsafe.Pointer(ccpumap)) + + cpumapbytes := C.GoBytes(unsafe.Pointer(ccpumap), C.int(ret/8)) + + cpumap := make(map[int]bool, 0) + for i := 0; i < int(ret); i++ { + idx := int(i / 8) + val := byte(cpumapbytes[idx]) + shift := i % 8 + cpumap[i] = (val & (1 << uint(shift))) == 1 + } + + return cpumap, uint(conline), nil +} + +type NodeCPUStats struct { + KernelSet bool + Kernel uint64 + UserSet bool + User uint64 + IdleSet bool + Idle uint64 + IowaitSet bool + Iowait uint64 + IntrSet bool + Intr uint64 + UtilizationSet bool + Utilization uint64 +} + +func (c *Connect) GetCPUStats(cpuNum int, flags uint32) (*NodeCPUStats, error) { + var nparams C.int + + ret := C.virNodeGetCPUStats(c.ptr, C.int(cpuNum), nil, &nparams, C.uint(0)) + if ret == -1 { + return nil, GetLastError() + } + + params := make([]C.virNodeCPUStats, nparams) + ret = C.virNodeGetCPUStats(c.ptr, C.int(cpuNum), (*C.virNodeCPUStats)(unsafe.Pointer(¶ms[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + stats := &NodeCPUStats{} + for i := 0; i < int(nparams); i++ { + param := params[i] + field := C.GoString((*C.char)(unsafe.Pointer(¶m.field))) + switch field { + case C.VIR_NODE_CPU_STATS_KERNEL: + stats.KernelSet = true + stats.Kernel = uint64(param.value) + case C.VIR_NODE_CPU_STATS_USER: + stats.UserSet = true + stats.User = uint64(param.value) + case C.VIR_NODE_CPU_STATS_IDLE: + stats.IdleSet = true + stats.Idle = uint64(param.value) + case C.VIR_NODE_CPU_STATS_IOWAIT: + stats.IowaitSet = true + stats.Iowait = uint64(param.value) + case C.VIR_NODE_CPU_STATS_INTR: + stats.IntrSet = true + stats.Intr = uint64(param.value) + case C.VIR_NODE_CPU_STATS_UTILIZATION: + stats.UtilizationSet = true + stats.Utilization = uint64(param.value) + } + } + + return stats, nil +} + +func (c *Connect) GetCellsFreeMemory(startCell int, maxCells int) ([]uint64, error) { + cmem := make([]C.ulonglong, maxCells) + ret := C.virNodeGetCellsFreeMemory(c.ptr, (*C.ulonglong)(unsafe.Pointer(&cmem[0])), C.int(startCell), C.int(maxCells)) + if ret == -1 { + return []uint64{}, GetLastError() + } + + mem := make([]uint64, ret) + for i := 0; i < int(ret); i++ { + mem[i] = uint64(cmem[i]) + } + + return mem, nil +} + +func (c *Connect) GetFreeMemory() (uint64, error) { + ret := C.virNodeGetFreeMemory(c.ptr) + if ret == 0 { + return 0, GetLastError() + } + + return (uint64)(ret), nil +} + +func (c *Connect) GetFreePages(pageSizes []uint64, startCell int, maxCells uint, flags uint32) ([]uint64, error) { + if C.LIBVIR_VERSION_NUMBER < 1002006 { + return []uint64{}, GetNotImplementedError("virNodeGetFreePages") + } + cpageSizes := make([]C.uint, len(pageSizes)) + ccounts := make([]C.ulonglong, len(pageSizes)*int(maxCells)) + + for i := 0; i < len(pageSizes); i++ { + cpageSizes[i] = C.uint(pageSizes[i]) + } + + ret := C.virNodeGetFreePagesCompat(c.ptr, C.uint(len(pageSizes)), (*C.uint)(unsafe.Pointer(&cpageSizes)), C.int(startCell), + C.uint(maxCells), (*C.ulonglong)(unsafe.Pointer(&ccounts)), C.uint(flags)) + if ret == -1 { + return []uint64{}, GetLastError() + } + + counts := make([]uint64, ret) + for i := 0; i < int(ret); i++ { + counts[i] = uint64(ccounts[i]) + } + + return counts, nil +} + +type NodeMemoryParameters struct { + ShmPagesToScanSet bool + ShmPagesToScan uint + ShmSleepMillisecsSet bool + ShmSleepMillisecs uint + ShmPagesSharedSet bool + ShmPagesShared uint64 + ShmPagesSharingSet bool + ShmPagesSharing uint64 + ShmPagesUnsharedSet bool + ShmPagesUnshared uint64 + ShmPagesVolatileSet bool + ShmPagesVolatile uint64 + ShmFullScansSet bool + ShmFullScans uint64 + ShmMergeAcrossNodesSet bool + ShmMergeAcrossNodes uint +} + +func getMemoryParameterFieldInfo(params *NodeMemoryParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_NODE_MEMORY_SHARED_PAGES_TO_SCAN: typedParamsFieldInfo{ + set: ¶ms.ShmPagesToScanSet, + ui: ¶ms.ShmPagesToScan, + }, + C.VIR_NODE_MEMORY_SHARED_SLEEP_MILLISECS: typedParamsFieldInfo{ + set: ¶ms.ShmSleepMillisecsSet, + ui: ¶ms.ShmSleepMillisecs, + }, + C.VIR_NODE_MEMORY_SHARED_MERGE_ACROSS_NODES: typedParamsFieldInfo{ + set: ¶ms.ShmMergeAcrossNodesSet, + ui: ¶ms.ShmMergeAcrossNodes, + }, + C.VIR_NODE_MEMORY_SHARED_PAGES_SHARED: typedParamsFieldInfo{ + set: ¶ms.ShmPagesSharedSet, + ul: ¶ms.ShmPagesShared, + }, + C.VIR_NODE_MEMORY_SHARED_PAGES_SHARING: typedParamsFieldInfo{ + set: ¶ms.ShmPagesSharingSet, + ul: ¶ms.ShmPagesSharing, + }, + C.VIR_NODE_MEMORY_SHARED_PAGES_UNSHARED: typedParamsFieldInfo{ + set: ¶ms.ShmPagesUnsharedSet, + ul: ¶ms.ShmPagesUnshared, + }, + C.VIR_NODE_MEMORY_SHARED_PAGES_VOLATILE: typedParamsFieldInfo{ + set: ¶ms.ShmPagesVolatileSet, + ul: ¶ms.ShmPagesVolatile, + }, + C.VIR_NODE_MEMORY_SHARED_FULL_SCANS: typedParamsFieldInfo{ + set: ¶ms.ShmFullScansSet, + ul: ¶ms.ShmFullScans, + }, + } +} + +func (c *Connect) GetMemoryParameters(flags uint32) (*NodeMemoryParameters, error) { + params := &NodeMemoryParameters{} + info := getMemoryParameterFieldInfo(params) + + var nparams C.int + + ret := C.virNodeGetMemoryParameters(c.ptr, nil, &nparams, C.uint(0)) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virNodeGetMemoryParameters(c.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +type NodeMemoryStats struct { + TotalSet bool + Total uint64 + FreeSet bool + Free uint64 + BuffersSet bool + Buffers uint64 + CachedSet bool + Cached uint64 +} + +func (c *Connect) GetMemoryStats(cellNum int, flags uint32) (*NodeMemoryStats, error) { + var nparams C.int + + ret := C.virNodeGetMemoryStats(c.ptr, C.int(cellNum), nil, &nparams, 0) + if ret == -1 { + return nil, GetLastError() + } + + params := make([]C.virNodeMemoryStats, nparams) + ret = C.virNodeGetMemoryStats(c.ptr, C.int(cellNum), (*C.virNodeMemoryStats)(unsafe.Pointer(¶ms[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + stats := &NodeMemoryStats{} + for i := 0; i < int(nparams); i++ { + param := params[i] + field := C.GoString((*C.char)(unsafe.Pointer(¶m.field))) + switch field { + case C.VIR_NODE_MEMORY_STATS_TOTAL: + stats.TotalSet = true + stats.Total = uint64(param.value) + case C.VIR_NODE_MEMORY_STATS_FREE: + stats.FreeSet = true + stats.Free = uint64(param.value) + case C.VIR_NODE_MEMORY_STATS_BUFFERS: + stats.BuffersSet = true + stats.Buffers = uint64(param.value) + case C.VIR_NODE_MEMORY_STATS_CACHED: + stats.CachedSet = true + stats.Cached = uint64(param.value) + } + } + + return stats, nil +} + +type NodeSecurityModel struct { + Model string + Doi string +} + +func (c *Connect) GetSecurityModel() (*NodeSecurityModel, error) { + var cmodel C.virSecurityModel + ret := C.virNodeGetSecurityModel(c.ptr, &cmodel) + if ret == -1 { + return nil, GetLastError() + } + + return &NodeSecurityModel{ + Model: C.GoString((*C.char)(unsafe.Pointer(&cmodel.model))), + Doi: C.GoString((*C.char)(unsafe.Pointer(&cmodel.doi))), + }, nil +} + +func (c *Connect) SetMemoryParameters(params *NodeMemoryParameters, flags uint32) error { + info := getMemoryParameterFieldInfo(params) + + var nparams C.int + + ret := C.virNodeGetMemoryParameters(c.ptr, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virNodeGetMemoryParameters(c.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virNodeSetMemoryParameters(c.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +func (c *Connect) SuspendForDuration(target NodeSuspendTarget, duration uint64, flags uint32) error { + ret := C.virNodeSuspendForDuration(c.ptr, C.uint(target), C.ulonglong(duration), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) DomainSaveImageDefineXML(file string, xml string, flags DomainSaveRestoreFlags) error { + cfile := C.CString(file) + defer C.free(unsafe.Pointer(cfile)) + cxml := C.CString(xml) + defer C.free(unsafe.Pointer(cxml)) + + ret := C.virDomainSaveImageDefineXML(c.ptr, cfile, cxml, C.uint(flags)) + + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (c *Connect) DomainSaveImageGetXMLDesc(file string, flags DomainXMLFlags) (string, error) { + cfile := C.CString(file) + defer C.free(unsafe.Pointer(cfile)) + + ret := C.virDomainSaveImageGetXMLDesc(c.ptr, cfile, C.uint(flags)) + + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) BaselineCPU(xmlCPUs []string, flags ConnectBaselineCPUFlags) (string, error) { + cxmlCPUs := make([]*C.char, len(xmlCPUs)) + for i := 0; i < len(xmlCPUs); i++ { + cxmlCPUs[i] = C.CString(xmlCPUs[i]) + defer C.free(unsafe.Pointer(cxmlCPUs[i])) + } + + ret := C.virConnectBaselineCPU(c.ptr, &cxmlCPUs[0], C.uint(len(xmlCPUs)), C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) CompareCPU(xmlDesc string, flags ConnectCompareCPUFlags) (CPUCompareResult, error) { + cxmlDesc := C.CString(xmlDesc) + defer C.free(unsafe.Pointer(cxmlDesc)) + + ret := C.virConnectCompareCPU(c.ptr, cxmlDesc, C.uint(flags)) + if ret == C.VIR_CPU_COMPARE_ERROR { + return CPU_COMPARE_ERROR, GetLastError() + } + + return CPUCompareResult(ret), nil +} + +func (c *Connect) DomainXMLFromNative(nativeFormat string, nativeConfig string, flags uint32) (string, error) { + cnativeFormat := C.CString(nativeFormat) + defer C.free(unsafe.Pointer(cnativeFormat)) + cnativeConfig := C.CString(nativeConfig) + defer C.free(unsafe.Pointer(cnativeConfig)) + + ret := C.virConnectDomainXMLFromNative(c.ptr, cnativeFormat, cnativeConfig, C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) DomainXMLToNative(nativeFormat string, domainXml string, flags uint32) (string, error) { + cnativeFormat := C.CString(nativeFormat) + defer C.free(unsafe.Pointer(cnativeFormat)) + cdomainXml := C.CString(domainXml) + defer C.free(unsafe.Pointer(cdomainXml)) + + ret := C.virConnectDomainXMLToNative(c.ptr, cnativeFormat, cdomainXml, C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) GetCPUModelNames(arch string, flags uint32) ([]string, error) { + carch := C.CString(arch) + defer C.free(unsafe.Pointer(carch)) + + var cmodels **C.char + ret := C.virConnectGetCPUModelNames(c.ptr, carch, &cmodels, C.uint(flags)) + if ret == -1 { + return []string{}, GetLastError() + } + + models := make([]string, int(ret)) + for i := 0; i < int(ret); i++ { + cmodel := *(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cmodels)) + (unsafe.Sizeof(*cmodels) * uintptr(i)))) + + defer C.free(unsafe.Pointer(cmodel)) + models[i] = C.GoString(cmodel) + } + defer C.free(unsafe.Pointer(cmodels)) + + return models, nil +} + +func (c *Connect) GetDomainCapabilities(emulatorbin string, arch string, machine string, virttype string, flags uint32) (string, error) { + if C.LIBVIR_VERSION_NUMBER < 1002007 { + return "", GetNotImplementedError("virConnectGetDomainCapabilities") + } + var cemulatorbin *C.char + if emulatorbin != "" { + cemulatorbin = C.CString(emulatorbin) + defer C.free(unsafe.Pointer(cemulatorbin)) + } + var carch *C.char + if arch != "" { + carch = C.CString(arch) + defer C.free(unsafe.Pointer(carch)) + } + var cmachine *C.char + if machine != "" { + cmachine = C.CString(machine) + defer C.free(unsafe.Pointer(cmachine)) + } + var cvirttype *C.char + if virttype != "" { + cvirttype = C.CString(virttype) + defer C.free(unsafe.Pointer(cvirttype)) + } + + ret := C.virConnectGetDomainCapabilitiesCompat(c.ptr, cemulatorbin, carch, cmachine, cvirttype, C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) GetVersion() (uint32, error) { + var hvVer C.ulong + ret := C.virConnectGetVersion(c.ptr, &hvVer) + if ret == -1 { + return 0, GetLastError() + } + + return uint32(hvVer), nil +} + +func (c *Connect) FindStoragePoolSources(pooltype string, srcSpec string, flags uint32) (string, error) { + cpooltype := C.CString(pooltype) + defer C.free(unsafe.Pointer(cpooltype)) + var csrcSpec *C.char + if srcSpec != "" { + csrcSpec := C.CString(srcSpec) + defer C.free(unsafe.Pointer(csrcSpec)) + } + ret := C.virConnectFindStoragePoolSources(c.ptr, cpooltype, csrcSpec, C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +func (c *Connect) DomainRestore(srcFile string) error { + cPath := C.CString(srcFile) + defer C.free(unsafe.Pointer(cPath)) + if result := C.virDomainRestore(c.ptr, cPath); result == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) DomainRestoreFlags(srcFile, xmlConf string, flags DomainSaveRestoreFlags) error { + cPath := C.CString(srcFile) + defer C.free(unsafe.Pointer(cPath)) + var cXmlConf *C.char + if xmlConf != "" { + cXmlConf = C.CString(xmlConf) + defer C.free(unsafe.Pointer(cXmlConf)) + } + if result := C.virDomainRestoreFlags(c.ptr, cPath, cXmlConf, C.uint(flags)); result == -1 { + return GetLastError() + } + return nil +} + +func (c *Connect) NewStream(flags StreamFlags) (*Stream, error) { + virStream := C.virStreamNew(c.ptr, C.uint(flags)) + if virStream == nil { + return nil, GetLastError() + } + + return &Stream{ + ptr: virStream, + }, nil +} + +type DomainStatsState struct { + StateSet bool + State DomainState + ReasonSet bool + Reason int +} + +func getDomainStatsStateFieldInfo(params *DomainStatsState) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "state.state": typedParamsFieldInfo{ + set: ¶ms.StateSet, + i: (*int)(unsafe.Pointer(¶ms.State)), + }, + "state.reason": typedParamsFieldInfo{ + set: ¶ms.ReasonSet, + i: ¶ms.Reason, + }, + } +} + +type DomainStatsCPU struct { + TimeSet bool + Time uint64 + UserSet bool + User uint64 + SystemSet bool + System uint64 +} + +func getDomainStatsCPUFieldInfo(params *DomainStatsCPU) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "cpu.time": typedParamsFieldInfo{ + set: ¶ms.TimeSet, + ul: ¶ms.Time, + }, + "cpu.user": typedParamsFieldInfo{ + set: ¶ms.UserSet, + ul: ¶ms.User, + }, + "cpu.system": typedParamsFieldInfo{ + set: ¶ms.SystemSet, + ul: ¶ms.System, + }, + } +} + +type DomainStatsBalloon struct { + CurrentSet bool + Current uint64 + MaximumSet bool + Maximum uint64 +} + +func getDomainStatsBalloonFieldInfo(params *DomainStatsBalloon) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "balloon.current": typedParamsFieldInfo{ + set: ¶ms.CurrentSet, + ul: ¶ms.Current, + }, + "balloon.maximum": typedParamsFieldInfo{ + set: ¶ms.MaximumSet, + ul: ¶ms.Maximum, + }, + } +} + +type DomainStatsVcpu struct { + StateSet bool + State VcpuState + TimeSet bool + Time uint64 +} + +func getDomainStatsVcpuFieldInfo(idx int, params *DomainStatsVcpu) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + fmt.Sprintf("vcpu.%d.state", idx): typedParamsFieldInfo{ + set: ¶ms.StateSet, + i: (*int)(unsafe.Pointer(¶ms.State)), + }, + fmt.Sprintf("vcpu.%d.time", idx): typedParamsFieldInfo{ + set: ¶ms.TimeSet, + ul: ¶ms.Time, + }, + } +} + +type DomainStatsNet struct { + NameSet bool + Name string + RxBytesSet bool + RxBytes uint64 + RxPktsSet bool + RxPkts uint64 + RxErrsSet bool + RxErrs uint64 + RxDropSet bool + RxDrop uint64 + TxBytesSet bool + TxBytes uint64 + TxPktsSet bool + TxPkts uint64 + TxErrsSet bool + TxErrs uint64 + TxDropSet bool + TxDrop uint64 +} + +func getDomainStatsNetFieldInfo(idx int, params *DomainStatsNet) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + fmt.Sprintf("net.%d.name", idx): typedParamsFieldInfo{ + set: ¶ms.NameSet, + s: ¶ms.Name, + }, + fmt.Sprintf("net.%d.rx.bytes", idx): typedParamsFieldInfo{ + set: ¶ms.RxBytesSet, + ul: ¶ms.RxBytes, + }, + fmt.Sprintf("net.%d.rx.pkts", idx): typedParamsFieldInfo{ + set: ¶ms.RxPktsSet, + ul: ¶ms.RxPkts, + }, + fmt.Sprintf("net.%d.rx.errs", idx): typedParamsFieldInfo{ + set: ¶ms.RxErrsSet, + ul: ¶ms.RxErrs, + }, + fmt.Sprintf("net.%d.rx.drop", idx): typedParamsFieldInfo{ + set: ¶ms.RxDropSet, + ul: ¶ms.RxDrop, + }, + fmt.Sprintf("net.%d.tx.bytes", idx): typedParamsFieldInfo{ + set: ¶ms.TxBytesSet, + ul: ¶ms.TxBytes, + }, + fmt.Sprintf("net.%d.tx.pkts", idx): typedParamsFieldInfo{ + set: ¶ms.TxPktsSet, + ul: ¶ms.TxPkts, + }, + fmt.Sprintf("net.%d.tx.errs", idx): typedParamsFieldInfo{ + set: ¶ms.TxErrsSet, + ul: ¶ms.TxErrs, + }, + fmt.Sprintf("net.%d.tx.drop", idx): typedParamsFieldInfo{ + set: ¶ms.TxDropSet, + ul: ¶ms.TxDrop, + }, + } +} + +type DomainStatsBlock struct { + NameSet bool + Name string + BackingIndexSet bool + BackingIndex uint + PathSet bool + Path string + RdReqsSet bool + RdReqs uint64 + RdBytesSet bool + RdBytes uint64 + RdTimesSet bool + RdTimes uint64 + WrReqsSet bool + WrReqs uint64 + WrBytesSet bool + WrBytes uint64 + WrTimesSet bool + WrTimes uint64 + FlReqsSet bool + FlReqs uint64 + FlTimesSet bool + FlTimes uint64 + ErrorsSet bool + Errors uint64 + AllocationSet bool + Allocation uint64 + CapacitySet bool + Capacity uint64 + PhysicalSet bool + Physical uint64 +} + +func getDomainStatsBlockFieldInfo(idx int, params *DomainStatsBlock) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + fmt.Sprintf("block.%d.name", idx): typedParamsFieldInfo{ + set: ¶ms.NameSet, + s: ¶ms.Name, + }, + fmt.Sprintf("block.%d.backingIndex", idx): typedParamsFieldInfo{ + set: ¶ms.BackingIndexSet, + ui: ¶ms.BackingIndex, + }, + fmt.Sprintf("block.%d.path", idx): typedParamsFieldInfo{ + set: ¶ms.PathSet, + s: ¶ms.Path, + }, + fmt.Sprintf("block.%d.rd.reqs", idx): typedParamsFieldInfo{ + set: ¶ms.RdReqsSet, + ul: ¶ms.RdReqs, + }, + fmt.Sprintf("block.%d.rd.bytes", idx): typedParamsFieldInfo{ + set: ¶ms.RdBytesSet, + ul: ¶ms.RdBytes, + }, + fmt.Sprintf("block.%d.rd.times", idx): typedParamsFieldInfo{ + set: ¶ms.RdTimesSet, + ul: ¶ms.RdTimes, + }, + fmt.Sprintf("block.%d.wr.reqs", idx): typedParamsFieldInfo{ + set: ¶ms.WrReqsSet, + ul: ¶ms.WrReqs, + }, + fmt.Sprintf("block.%d.wr.bytes", idx): typedParamsFieldInfo{ + set: ¶ms.WrBytesSet, + ul: ¶ms.WrBytes, + }, + fmt.Sprintf("block.%d.wr.times", idx): typedParamsFieldInfo{ + set: ¶ms.WrTimesSet, + ul: ¶ms.WrTimes, + }, + fmt.Sprintf("block.%d.fl.reqs", idx): typedParamsFieldInfo{ + set: ¶ms.FlReqsSet, + ul: ¶ms.FlReqs, + }, + fmt.Sprintf("block.%d.fl.times", idx): typedParamsFieldInfo{ + set: ¶ms.FlTimesSet, + ul: ¶ms.FlTimes, + }, + fmt.Sprintf("block.%d.errors", idx): typedParamsFieldInfo{ + set: ¶ms.ErrorsSet, + ul: ¶ms.Errors, + }, + fmt.Sprintf("block.%d.allocation", idx): typedParamsFieldInfo{ + set: ¶ms.AllocationSet, + ul: ¶ms.Allocation, + }, + fmt.Sprintf("block.%d.capacity", idx): typedParamsFieldInfo{ + set: ¶ms.CapacitySet, + ul: ¶ms.Capacity, + }, + fmt.Sprintf("block.%d.physical", idx): typedParamsFieldInfo{ + set: ¶ms.PhysicalSet, + ul: ¶ms.Physical, + }, + } +} + +type DomainStatsPerf struct { + CmtSet bool + Cmt uint64 + MbmtSet bool + Mbmt uint64 + MbmlSet bool + Mbml uint64 + CacheMissesSet bool + CacheMisses uint64 + CacheReferencesSet bool + CacheReferences uint64 + InstructionsSet bool + Instructions uint64 + CpuCyclesSet bool + CpuCycles uint64 + BranchInstructionsSet bool + BranchInstructions uint64 + BranchMissesSet bool + BranchMisses uint64 + BusCyclesSet bool + BusCycles uint64 + StalledCyclesFrontendSet bool + StalledCyclesFrontend uint64 + StalledCyclesBackendSet bool + StalledCyclesBackend uint64 + RefCpuCyclesSet bool + RefCpuCycles uint64 + CpuClockSet bool + CpuClock uint64 + TaskClockSet bool + TaskClock uint64 + PageFaultsSet bool + PageFaults uint64 + ContextSwitchesSet bool + ContextSwitches uint64 + CpuMigrationsSet bool + CpuMigrations uint64 + PageFaultsMinSet bool + PageFaultsMin uint64 + PageFaultsMajSet bool + PageFaultsMaj uint64 + AlignmentFaultsSet bool + AlignmentFaults uint64 + EmulationFaultsSet bool + EmulationFaults uint64 +} + +func getDomainStatsPerfFieldInfo(params *DomainStatsPerf) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "perf.cmt": typedParamsFieldInfo{ + set: ¶ms.CmtSet, + ul: ¶ms.Cmt, + }, + "perf.mbmt": typedParamsFieldInfo{ + set: ¶ms.MbmtSet, + ul: ¶ms.Mbmt, + }, + "perf.mbml": typedParamsFieldInfo{ + set: ¶ms.MbmlSet, + ul: ¶ms.Mbml, + }, + "perf.cache_misses": typedParamsFieldInfo{ + set: ¶ms.CacheMissesSet, + ul: ¶ms.CacheMisses, + }, + "perf.cache_references": typedParamsFieldInfo{ + set: ¶ms.CacheReferencesSet, + ul: ¶ms.CacheReferences, + }, + "perf.instructions": typedParamsFieldInfo{ + set: ¶ms.InstructionsSet, + ul: ¶ms.Instructions, + }, + "perf.cpu_cycles": typedParamsFieldInfo{ + set: ¶ms.CpuCyclesSet, + ul: ¶ms.CpuCycles, + }, + "perf.branch_instructions": typedParamsFieldInfo{ + set: ¶ms.BranchInstructionsSet, + ul: ¶ms.BranchInstructions, + }, + "perf.branch_misses": typedParamsFieldInfo{ + set: ¶ms.BranchMissesSet, + ul: ¶ms.BranchMisses, + }, + "perf.bus_cycles": typedParamsFieldInfo{ + set: ¶ms.BusCyclesSet, + ul: ¶ms.BusCycles, + }, + "perf.stalled_cycles_frontend": typedParamsFieldInfo{ + set: ¶ms.StalledCyclesFrontendSet, + ul: ¶ms.StalledCyclesFrontend, + }, + "perf.stalled_cycles_backend": typedParamsFieldInfo{ + set: ¶ms.StalledCyclesBackendSet, + ul: ¶ms.StalledCyclesBackend, + }, + "perf.ref_cpu_cycles": typedParamsFieldInfo{ + set: ¶ms.RefCpuCyclesSet, + ul: ¶ms.RefCpuCycles, + }, + "perf.cpu_clock": typedParamsFieldInfo{ + set: ¶ms.CpuClockSet, + ul: ¶ms.CpuClock, + }, + "perf.task_clock": typedParamsFieldInfo{ + set: ¶ms.TaskClockSet, + ul: ¶ms.TaskClock, + }, + "perf.page_faults": typedParamsFieldInfo{ + set: ¶ms.PageFaultsSet, + ul: ¶ms.PageFaults, + }, + "perf.context_switches": typedParamsFieldInfo{ + set: ¶ms.ContextSwitchesSet, + ul: ¶ms.ContextSwitches, + }, + "perf.cpu_migrations": typedParamsFieldInfo{ + set: ¶ms.CpuMigrationsSet, + ul: ¶ms.CpuMigrations, + }, + "perf.page_faults_min": typedParamsFieldInfo{ + set: ¶ms.PageFaultsMinSet, + ul: ¶ms.PageFaultsMin, + }, + "perf.page_faults_maj": typedParamsFieldInfo{ + set: ¶ms.PageFaultsMajSet, + ul: ¶ms.PageFaultsMaj, + }, + "perf.alignment_faults": typedParamsFieldInfo{ + set: ¶ms.AlignmentFaultsSet, + ul: ¶ms.AlignmentFaults, + }, + "perf.emulation_faults": typedParamsFieldInfo{ + set: ¶ms.EmulationFaultsSet, + ul: ¶ms.EmulationFaults, + }, + } +} + +type DomainStats struct { + Domain *Domain + State *DomainStatsState + Cpu *DomainStatsCPU + Balloon *DomainStatsBalloon + Vcpu []DomainStatsVcpu + Net []DomainStatsNet + Block []DomainStatsBlock + Perf *DomainStatsPerf +} + +type domainStatsLengths struct { + VcpuCurrentSet bool + VcpuCurrent uint + VcpuMaximumSet bool + VcpuMaximum uint + NetCountSet bool + NetCount uint + BlockCountSet bool + BlockCount uint +} + +func getDomainStatsLengthsFieldInfo(params *domainStatsLengths) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "vcpu.current": typedParamsFieldInfo{ + set: ¶ms.VcpuCurrentSet, + ui: ¶ms.VcpuCurrent, + }, + "vcpu.maximum": typedParamsFieldInfo{ + set: ¶ms.VcpuMaximumSet, + ui: ¶ms.VcpuMaximum, + }, + "net.count": typedParamsFieldInfo{ + set: ¶ms.NetCountSet, + ui: ¶ms.NetCount, + }, + "block.count": typedParamsFieldInfo{ + set: ¶ms.BlockCountSet, + ui: ¶ms.BlockCount, + }, + } +} + +func (c *Connect) GetAllDomainStats(doms []*Domain, statsTypes DomainStatsTypes, flags ConnectGetAllDomainStatsFlags) ([]DomainStats, error) { + if C.LIBVIR_VERSION_NUMBER < 1002008 { + return []DomainStats{}, GetNotImplementedError("virConnectGetAllDomainStats") + } + var ret C.int + var cstats *C.virDomainStatsRecordPtr + if len(doms) > 0 { + cdoms := make([]C.virDomainPtr, len(doms)+1) + for i := 0; i < len(doms); i++ { + cdoms[i] = doms[i].ptr + } + + ret = C.virDomainListGetStatsCompat(&cdoms[0], C.uint(statsTypes), &cstats, C.uint(flags)) + } else { + ret = C.virConnectGetAllDomainStatsCompat(c.ptr, C.uint(statsTypes), &cstats, C.uint(flags)) + } + if ret == -1 { + return []DomainStats{}, GetLastError() + } + + defer C.virDomainStatsRecordListFreeCompat(cstats) + + stats := make([]DomainStats, ret) + for i := 0; i < int(ret); i++ { + cdomstats := *(*C.virDomainStatsRecordPtr)(unsafe.Pointer(uintptr(unsafe.Pointer(cstats)) + (unsafe.Sizeof(*cstats) * uintptr(i)))) + + domstats := DomainStats{ + Domain: &Domain{ptr: cdomstats.dom}, + } + + state := &DomainStatsState{} + stateInfo := getDomainStatsStateFieldInfo(state) + + count, err := typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), stateInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.State = state + } + + cpu := &DomainStatsCPU{} + cpuInfo := getDomainStatsCPUFieldInfo(cpu) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), cpuInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.Cpu = cpu + } + + balloon := &DomainStatsBalloon{} + balloonInfo := getDomainStatsBalloonFieldInfo(balloon) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), balloonInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.Balloon = balloon + } + + perf := &DomainStatsPerf{} + perfInfo := getDomainStatsPerfFieldInfo(perf) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), perfInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.Perf = perf + } + + lengths := domainStatsLengths{} + lengthsInfo := getDomainStatsLengthsFieldInfo(&lengths) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), lengthsInfo) + if err != nil { + return []DomainStats{}, err + } + + if !lengths.VcpuMaximumSet && lengths.VcpuCurrentSet { + lengths.VcpuMaximum = lengths.VcpuCurrent + } + + if lengths.VcpuMaximum > 0 { + + domstats.Vcpu = make([]DomainStatsVcpu, lengths.VcpuMaximum) + for j := 0; j < int(lengths.VcpuMaximum); j++ { + vcpu := DomainStatsVcpu{} + vcpuInfo := getDomainStatsVcpuFieldInfo(j, &vcpu) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), vcpuInfo) + if err != nil { + return []DomainStats{}, err + } + if count == 0 { + vcpu.StateSet = true + vcpu.State = VCPU_OFFLINE + } + domstats.Vcpu[j] = vcpu + } + } + + if lengths.BlockCountSet && lengths.BlockCount > 0 { + domstats.Block = make([]DomainStatsBlock, lengths.BlockCount) + for j := 0; j < int(lengths.BlockCount); j++ { + block := DomainStatsBlock{} + blockInfo := getDomainStatsBlockFieldInfo(j, &block) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), blockInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.Block[j] = block + } + } + } + + if lengths.NetCountSet && lengths.NetCount > 0 { + domstats.Net = make([]DomainStatsNet, lengths.NetCount) + for j := 0; j < int(lengths.NetCount); j++ { + net := DomainStatsNet{} + netInfo := getDomainStatsNetFieldInfo(j, &net) + + count, err = typedParamsUnpackLen(cdomstats.params, int(cdomstats.nparams), netInfo) + if err != nil { + return []DomainStats{}, err + } + if count != 0 { + domstats.Net[j] = net + } + } + } + + stats[i] = domstats + } + + return stats, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.go new file mode 100644 index 000000000000..cb0467d9bb6a --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.go @@ -0,0 +1,71 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "connect_cfuncs.h" +#include "callbacks_cfuncs.h" + +extern void closeCallback(virConnectPtr, int, long); +void closeCallback_cgo(virConnectPtr conn, int reason, void *opaque) +{ + closeCallback(conn, reason, (long)opaque); +} + +int virConnectRegisterCloseCallback_cgo(virConnectPtr c, virConnectCloseFunc cb, long goCallbackId) +{ + void *id = (void*)goCallbackId; + return virConnectRegisterCloseCallback(c, cb, id, freeGoCallback_cgo); +} + +#include + +extern int connectAuthCallback(virConnectCredentialPtr, unsigned int, int); +int connectAuthCallback_cgo(virConnectCredentialPtr cred, unsigned int ncred, void *cbdata) +{ + int *callbackID = cbdata; + + return connectAuthCallback(cred, ncred, *callbackID); +} + +virConnectPtr virConnectOpenAuthWrap(const char *name, int *credtype, uint ncredtype, int callbackID, unsigned int flags) +{ + virConnectAuth auth = { + .credtype = credtype, + .ncredtype = ncredtype, + .cb = connectAuthCallback_cgo, + .cbdata = &callbackID, + }; + + return virConnectOpenAuth(name, &auth, flags); +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.h new file mode 100644 index 000000000000..592fe982d2f6 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/connect_cfuncs.h @@ -0,0 +1,34 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_CONNECT_CFUNCS_H__ +#define LIBVIRT_GO_CONNECT_CFUNCS_H__ +void closeCallback_cgo(virConnectPtr conn, int reason, void *opaque); +int virConnectRegisterCloseCallback_cgo(virConnectPtr c, virConnectCloseFunc cb, long goCallbackId); + +virConnectPtr virConnectOpenAuthWrap(const char *name, int *credtype, uint ncredtype, int callbackID, unsigned int flags); + +#endif /* LIBVIRT_GO_CONNECT_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/connect_compat.go b/vendor/github.com/libvirt/libvirt-go/connect_compat.go new file mode 100644 index 000000000000..683f400f3bba --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/connect_compat.go @@ -0,0 +1,120 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "connect_compat.h" + +int virNodeGetFreePagesCompat(virConnectPtr conn, + unsigned int npages, + unsigned int *pages, + int startcell, + unsigned int cellcount, + unsigned long long *counts, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002006 + assert(0); // Caller should have checked version +#else + return virNodeGetFreePages(conn, npages, pages, startcell, cellcount, counts, flags); +#endif +} + +char * virConnectGetDomainCapabilitiesCompat(virConnectPtr conn, + const char *emulatorbin, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002007 + assert(0); // Caller should have checked version +#else + return virConnectGetDomainCapabilities(conn, emulatorbin, arch, machine, virttype, flags); +#endif +} + +int virConnectGetAllDomainStatsCompat(virConnectPtr conn, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002008 + assert(0); // Caller should have checked version +#else + return virConnectGetAllDomainStats(conn, stats, retStats, flags); +#endif +} + +int virDomainListGetStatsCompat(virDomainPtr *doms, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002008 + assert(0); // Caller should have checked version +#else + return virDomainListGetStats(doms, stats, retStats, flags); +#endif +} + +void virDomainStatsRecordListFreeCompat(virDomainStatsRecordPtr *stats) +{ +} + +int virNodeAllocPagesCompat(virConnectPtr conn, + unsigned int npages, + unsigned int *pageSizes, + unsigned long long *pageCounts, + int startCell, + unsigned int cellCount, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002009 + assert(0); // Caller should have checked version +#else + return virNodeAllocPages(conn, npages, pageSizes, pageCounts, startCell, cellCount, flags); +#endif +} + + +virDomainPtr virDomainDefineXMLFlagsCompat(virConnectPtr conn, + const char *xml, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002012 + assert(0); // Caller should have checked version +#else + return virDomainDefineXMLFlags(conn, xml, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/connect_compat.h b/vendor/github.com/libvirt/libvirt-go/connect_compat.h new file mode 100644 index 000000000000..f2b0de6630e5 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/connect_compat.h @@ -0,0 +1,215 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_CONNECT_COMPAT_H__ +#define LIBVIRT_GO_CONNECT_COMPAT_H__ + +/* 1.2.1 */ + +#ifndef VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER +#define VIR_CONNECT_LIST_STORAGE_POOLS_GLUSTER 1 << 16 +#endif + + +/* 1.2.2 */ + +#ifndef VIR_NODE_CPU_STATS_INTR +#define VIR_NODE_CPU_STATS_INTR "intr" +#endif + + +/* 1.2.6 */ + +#ifndef VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE +#define VIR_CONNECT_COMPARE_CPU_FAIL_INCOMPATIBLE 1 << 0 +#endif + +int virNodeGetFreePagesCompat(virConnectPtr conn, + unsigned int npages, + unsigned int *pages, + int startcell, + unsigned int cellcount, + unsigned long long *counts, + unsigned int flags); + + +/* 1.2.7 */ + +char * virConnectGetDomainCapabilitiesCompat(virConnectPtr conn, + const char *emulatorbin, + const char *arch, + const char *machine, + const char *virttype, + unsigned int flags); + + +/* 1.2.8 */ + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_ACTIVE 1 << 0 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_INACTIVE 1 << 1 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT 1 << 2 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_TRANSIENT 1 << 3 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_RUNNING 1 << 4 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_PAUSED 1 << 5 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_SHUTOFF 1 << 6 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_OTHER 1 << 7 +#endif + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_ENFORCE_STATS 1U << 31 +#endif + +#ifndef VIR_CONNECT_LIST_STORAGE_POOLS_ZFS +#define VIR_CONNECT_LIST_STORAGE_POOLS_ZFS 1 << 17 +#endif + +#if LIBVIR_VERSION_NUMBER < 1002008 +typedef struct _virDomainStatsRecord virDomainStatsRecord; +typedef virDomainStatsRecord *virDomainStatsRecordPtr; +struct _virDomainStatsRecord { + virDomainPtr dom; + virTypedParameterPtr params; + int nparams; +}; +#endif + +int virConnectGetAllDomainStatsCompat(virConnectPtr conn, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags); + +int virDomainListGetStatsCompat(virDomainPtr *doms, + unsigned int stats, + virDomainStatsRecordPtr **retStats, + unsigned int flags); + +void virDomainStatsRecordListFreeCompat(virDomainStatsRecordPtr *stats); + + +/* 1.2.9 */ +#ifndef VIR_NODE_ALLOC_PAGES_ADD +#define VIR_NODE_ALLOC_PAGES_ADD 0 +#endif + +#ifndef VIR_NODE_ALLOC_PAGES_SET +#define VIR_NODE_ALLOC_PAGES_SET 1 << 0 +#endif + +int virNodeAllocPagesCompat(virConnectPtr conn, + unsigned int npages, + unsigned int *pageSizes, + unsigned long long *pageCounts, + int startCell, + unsigned int cellCount, + unsigned int flags); + + +/* 1.2.11 */ + +#ifndef VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED +#define VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_CONNECTED 1 +#endif + +#ifndef VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED +#define VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_STATE_DISCONNECTED 2 +#endif + +#ifndef VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN +#define VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_UNKNOWN 0 +#endif + +#ifndef VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED +#define VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_DOMAIN_STARTED 1 +#endif + +#ifndef VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL +#define VIR_CONNECT_DOMAIN_EVENT_AGENT_LIFECYCLE_REASON_CHANNEL 2 +#endif + + +/* 1.2.12 */ + +#ifndef VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING +#define VIR_CONNECT_GET_ALL_DOMAINS_STATS_BACKING 1 << 30 +#endif + +virDomainPtr virDomainDefineXMLFlagsCompat(virConnectPtr conn, + const char *xml, + unsigned int flags); + +/* 1.2.14 */ + +#ifndef VIR_CONNECT_BASELINE_CPU_MIGRATABLE +#define VIR_CONNECT_BASELINE_CPU_MIGRATABLE 1 << 1 +#endif + +/* 3.1.0 */ + +#ifndef VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE +#define VIR_CONNECT_LIST_STORAGE_POOLS_VSTORAGE 1 << 18 +#endif + +#ifndef VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM +#define VIR_CONNECT_LIST_NODE_DEVICES_CAP_DRM 1 << 12 +#endif + +/* 3.4.0 */ + +#ifndef VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES +#define VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV_TYPES 1 << 13 +#endif + +#ifndef VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV +#define VIR_CONNECT_LIST_NODE_DEVICES_CAP_MDEV 1 << 14 +#endif + +#ifndef VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV +#define VIR_CONNECT_LIST_NODE_DEVICES_CAP_CCW_DEV 1 << 15 +#endif + +#endif /* LIBVIRT_GO_CONNECT_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/doc.go b/vendor/github.com/libvirt/libvirt-go/doc.go new file mode 100644 index 000000000000..55d75b0cac3f --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/doc.go @@ -0,0 +1,141 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +// Package libvirt provides a Go binding to the libvirt C library +// +// Through conditional compilation it supports libvirt versions 1.2.0 onwards. +// This is done automatically, with no requirement to use magic Go build tags. +// If an API was not available in the particular version of libvirt this package +// was built against, an error will be returned with a code of ERR_NO_SUPPORT. +// This is the same code seen if using a new libvirt library to talk to an old +// libvirtd lacking the API, or if a hypervisor does not support a given feature, +// so an application can easily handle all scenarios together. +// +// The Go binding is a fairly direct mapping of the underling C API which seeks +// to maximise the use of the Go type system to allow strong compiler type +// checking. The following rules describe how APIs/constants are mapped from C +// to Go +// +// For structs, the 'vir' prefix and 'Ptr' suffix are removed from the name. +// e.g. virConnectPtr in C becomes 'Connect' in Go. +// +// For structs which are reference counted at the C level, it is neccessary to +// explicitly release the reference at the Go level. e.g. if a Go method returns +// a '* Domain' struct, it is neccessary to call 'Free' on this when no longer +// required. The use of 'defer' is recommended for this purpose +// +// dom, err := conn.LookupDomainByName("myguest") +// if err != nil { +// ... +// } +// defer dom.Free() +// +// If multiple goroutines are using the same libvirt object struct, it may +// not be possible to determine which goroutine should call 'Free'. In such +// scenarios each new goroutine should call 'Ref' to obtain a private reference +// on the underlying C struct. All goroutines can call 'Free' unconditionally +// with the final one causing the release of the C object. +// +// For methods, the 'vir' prefix and object name prefix are remove from the name. +// The C functions become methods with an object receiver. e.g. +// 'virDomainScreenshot' in C becomes 'Screenshot' with a 'Domain *' receiver. +// +// For methods which accept a 'unsigned int flags' parameter in the C level, +// the corresponding Go parameter will be a named type corresponding to the +// C enum that defines the valid flags. For example, the ListAllDomains +// method takes a 'flags ConnectListAllDomainsFlags' parameter. If there are +// not currently any flags defined for a method in the C API, then the Go +// method parameter will be declared as a "flags uint32". Callers should always +// pass the literal integer value 0 for such parameters, without forcing any +// specific type. This will allow compatibility with future updates to the +// libvirt-go binding which may replace the 'uint32' type with a enum type +// at a later date. +// +// For enums, the VIR_ prefix is removed from the name. The enums get a dedicated +// type defined in Go. e.g. the VIR_NODE_SUSPEND_TARGET_MEM enum constant in C, +// becomes NODE_SUSPEND_TARGET_MEM with a type of NodeSuspendTarget. +// +// Methods accepting or returning virTypedParameter arrays in C will map the +// parameters into a Go struct. The struct will contain two fields for each +// possible parameter. One boolean field with a suffix of 'Set' indicates whether +// the parameter has a value set, and the other custom typed field provides the +// parameter value. This makes it possible to distinguish a parameter with a +// default value of '0' from a parameter which is 0 because it isn't supported by +// the hypervisor. If the C API defines additional typed parameters, then the +// corresponding Go struct will be extended to have further fields. +// e.g. the GetMemoryStats method in Go (which is backed by +// virNodeGetMemoryStats in C) will return a NodeMemoryStats struct containing +// the typed parameter values. +// +// stats, err := conn.GetMemoryParameters() +// if err != nil { +// .... +// } +// if stats.TotalSet { +// fmt.Printf("Total memory: %d KB", stats.Total) +// } +// +// Every method that can fail will include an 'error' object as the last return +// value. This will be an instance of the Error struct if an error occurred. To +// check for specific libvirt error codes, it is neccessary to cast the error. +// +// err := storage_vol.Wipe(0) +// if err != nil { +// lverr, ok := err.(libvirt.Error) +// if ok && lverr.Code == libvirt.ERR_NO_SUPPORT { +// fmt.Println("Wiping storage volumes is not supported"); +// } else { +// fmt.Println("Error wiping storage volume: %s", err) +// } +// } +// +// Example usage +// +// To connect to libvirt +// +// import ( +// libvirt "github.com/libvirt/libvirt-go" +// ) +// conn, err := libvirt.NewConnect("qemu:///system") +// if err != nil { +// ... +// } +// defer conn.Close() +// +// doms, err := conn.ListAllDomains(libvirt.CONNECT_LIST_DOMAINS_ACTIVE) +// if err != nil { +// ... +// } +// +// fmt.Printf("%d running domains:\n", len(doms)) +// for _, dom := range doms { +// name, err := dom.GetName() +// if err == nil { +// fmt.Printf(" %s\n", name) +// } +// dom.Free() +// } +// +package libvirt diff --git a/vendor/github.com/libvirt/libvirt-go/domain.go b/vendor/github.com/libvirt/libvirt-go/domain.go new file mode 100644 index 000000000000..f2ac6fc5f426 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain.go @@ -0,0 +1,4305 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "domain_compat.h" +*/ +import "C" + +import ( + "fmt" + "os" + "reflect" + "strconv" + "strings" + "unsafe" +) + +const ( + DOMAIN_SEND_KEY_MAX_KEYS = uint32(C.VIR_DOMAIN_SEND_KEY_MAX_KEYS) +) + +type DomainState int + +const ( + DOMAIN_NOSTATE = DomainState(C.VIR_DOMAIN_NOSTATE) + DOMAIN_RUNNING = DomainState(C.VIR_DOMAIN_RUNNING) + DOMAIN_BLOCKED = DomainState(C.VIR_DOMAIN_BLOCKED) + DOMAIN_PAUSED = DomainState(C.VIR_DOMAIN_PAUSED) + DOMAIN_SHUTDOWN = DomainState(C.VIR_DOMAIN_SHUTDOWN) + DOMAIN_CRASHED = DomainState(C.VIR_DOMAIN_CRASHED) + DOMAIN_PMSUSPENDED = DomainState(C.VIR_DOMAIN_PMSUSPENDED) + DOMAIN_SHUTOFF = DomainState(C.VIR_DOMAIN_SHUTOFF) +) + +type DomainMetadataType int + +const ( + DOMAIN_METADATA_DESCRIPTION = DomainMetadataType(C.VIR_DOMAIN_METADATA_DESCRIPTION) + DOMAIN_METADATA_TITLE = DomainMetadataType(C.VIR_DOMAIN_METADATA_TITLE) + DOMAIN_METADATA_ELEMENT = DomainMetadataType(C.VIR_DOMAIN_METADATA_ELEMENT) +) + +type DomainVcpuFlags int + +const ( + DOMAIN_VCPU_CONFIG = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_CONFIG) + DOMAIN_VCPU_CURRENT = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_CURRENT) + DOMAIN_VCPU_LIVE = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_LIVE) + DOMAIN_VCPU_MAXIMUM = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_MAXIMUM) + DOMAIN_VCPU_GUEST = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_GUEST) + DOMAIN_VCPU_HOTPLUGGABLE = DomainVcpuFlags(C.VIR_DOMAIN_VCPU_HOTPLUGGABLE) +) + +type DomainModificationImpact int + +const ( + DOMAIN_AFFECT_CONFIG = DomainModificationImpact(C.VIR_DOMAIN_AFFECT_CONFIG) + DOMAIN_AFFECT_CURRENT = DomainModificationImpact(C.VIR_DOMAIN_AFFECT_CURRENT) + DOMAIN_AFFECT_LIVE = DomainModificationImpact(C.VIR_DOMAIN_AFFECT_LIVE) +) + +type DomainMemoryModFlags int + +const ( + DOMAIN_MEM_CONFIG = DomainMemoryModFlags(C.VIR_DOMAIN_MEM_CONFIG) + DOMAIN_MEM_CURRENT = DomainMemoryModFlags(C.VIR_DOMAIN_MEM_CURRENT) + DOMAIN_MEM_LIVE = DomainMemoryModFlags(C.VIR_DOMAIN_MEM_LIVE) + DOMAIN_MEM_MAXIMUM = DomainMemoryModFlags(C.VIR_DOMAIN_MEM_MAXIMUM) +) + +type DomainDestroyFlags int + +const ( + DOMAIN_DESTROY_DEFAULT = DomainDestroyFlags(C.VIR_DOMAIN_DESTROY_DEFAULT) + DOMAIN_DESTROY_GRACEFUL = DomainDestroyFlags(C.VIR_DOMAIN_DESTROY_GRACEFUL) +) + +type DomainShutdownFlags int + +const ( + DOMAIN_SHUTDOWN_DEFAULT = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_DEFAULT) + DOMAIN_SHUTDOWN_ACPI_POWER_BTN = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_ACPI_POWER_BTN) + DOMAIN_SHUTDOWN_GUEST_AGENT = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_GUEST_AGENT) + DOMAIN_SHUTDOWN_INITCTL = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_INITCTL) + DOMAIN_SHUTDOWN_SIGNAL = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_SIGNAL) + DOMAIN_SHUTDOWN_PARAVIRT = DomainShutdownFlags(C.VIR_DOMAIN_SHUTDOWN_PARAVIRT) +) + +type DomainUndefineFlagsValues int + +const ( + DOMAIN_UNDEFINE_MANAGED_SAVE = DomainUndefineFlagsValues(C.VIR_DOMAIN_UNDEFINE_MANAGED_SAVE) // Also remove any managed save + DOMAIN_UNDEFINE_SNAPSHOTS_METADATA = DomainUndefineFlagsValues(C.VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA) // If last use of domain, then also remove any snapshot metadata + DOMAIN_UNDEFINE_NVRAM = DomainUndefineFlagsValues(C.VIR_DOMAIN_UNDEFINE_NVRAM) // Also remove any nvram file + DOMAIN_UNDEFINE_KEEP_NVRAM = DomainUndefineFlagsValues(C.VIR_DOMAIN_UNDEFINE_KEEP_NVRAM) // Keep nvram file +) + +type DomainDeviceModifyFlags int + +const ( + DOMAIN_DEVICE_MODIFY_CONFIG = DomainDeviceModifyFlags(C.VIR_DOMAIN_DEVICE_MODIFY_CONFIG) + DOMAIN_DEVICE_MODIFY_CURRENT = DomainDeviceModifyFlags(C.VIR_DOMAIN_DEVICE_MODIFY_CURRENT) + DOMAIN_DEVICE_MODIFY_LIVE = DomainDeviceModifyFlags(C.VIR_DOMAIN_DEVICE_MODIFY_LIVE) + DOMAIN_DEVICE_MODIFY_FORCE = DomainDeviceModifyFlags(C.VIR_DOMAIN_DEVICE_MODIFY_FORCE) +) + +type DomainCreateFlags int + +const ( + DOMAIN_NONE = DomainCreateFlags(C.VIR_DOMAIN_NONE) + DOMAIN_START_PAUSED = DomainCreateFlags(C.VIR_DOMAIN_START_PAUSED) + DOMAIN_START_AUTODESTROY = DomainCreateFlags(C.VIR_DOMAIN_START_AUTODESTROY) + DOMAIN_START_BYPASS_CACHE = DomainCreateFlags(C.VIR_DOMAIN_START_BYPASS_CACHE) + DOMAIN_START_FORCE_BOOT = DomainCreateFlags(C.VIR_DOMAIN_START_FORCE_BOOT) + DOMAIN_START_VALIDATE = DomainCreateFlags(C.VIR_DOMAIN_START_VALIDATE) +) + +const DOMAIN_MEMORY_PARAM_UNLIMITED = C.VIR_DOMAIN_MEMORY_PARAM_UNLIMITED + +type DomainEventType int + +const ( + DOMAIN_EVENT_DEFINED = DomainEventType(C.VIR_DOMAIN_EVENT_DEFINED) + DOMAIN_EVENT_UNDEFINED = DomainEventType(C.VIR_DOMAIN_EVENT_UNDEFINED) + DOMAIN_EVENT_STARTED = DomainEventType(C.VIR_DOMAIN_EVENT_STARTED) + DOMAIN_EVENT_SUSPENDED = DomainEventType(C.VIR_DOMAIN_EVENT_SUSPENDED) + DOMAIN_EVENT_RESUMED = DomainEventType(C.VIR_DOMAIN_EVENT_RESUMED) + DOMAIN_EVENT_STOPPED = DomainEventType(C.VIR_DOMAIN_EVENT_STOPPED) + DOMAIN_EVENT_SHUTDOWN = DomainEventType(C.VIR_DOMAIN_EVENT_SHUTDOWN) + DOMAIN_EVENT_PMSUSPENDED = DomainEventType(C.VIR_DOMAIN_EVENT_PMSUSPENDED) + DOMAIN_EVENT_CRASHED = DomainEventType(C.VIR_DOMAIN_EVENT_CRASHED) +) + +type DomainEventWatchdogAction int + +// The action that is to be taken due to the watchdog device firing +const ( + // No action, watchdog ignored + DOMAIN_EVENT_WATCHDOG_NONE = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_NONE) + + // Guest CPUs are paused + DOMAIN_EVENT_WATCHDOG_PAUSE = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_PAUSE) + + // Guest CPUs are reset + DOMAIN_EVENT_WATCHDOG_RESET = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_RESET) + + // Guest is forcibly powered off + DOMAIN_EVENT_WATCHDOG_POWEROFF = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF) + + // Guest is requested to gracefully shutdown + DOMAIN_EVENT_WATCHDOG_SHUTDOWN = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN) + + // No action, a debug message logged + DOMAIN_EVENT_WATCHDOG_DEBUG = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_DEBUG) + + // Inject a non-maskable interrupt into guest + DOMAIN_EVENT_WATCHDOG_INJECTNMI = DomainEventWatchdogAction(C.VIR_DOMAIN_EVENT_WATCHDOG_INJECTNMI) +) + +type DomainEventIOErrorAction int + +// The action that is to be taken due to an IO error occurring +const ( + // No action, IO error ignored + DOMAIN_EVENT_IO_ERROR_NONE = DomainEventIOErrorAction(C.VIR_DOMAIN_EVENT_IO_ERROR_NONE) + + // Guest CPUs are paused + DOMAIN_EVENT_IO_ERROR_PAUSE = DomainEventIOErrorAction(C.VIR_DOMAIN_EVENT_IO_ERROR_PAUSE) + + // IO error reported to guest OS + DOMAIN_EVENT_IO_ERROR_REPORT = DomainEventIOErrorAction(C.VIR_DOMAIN_EVENT_IO_ERROR_REPORT) +) + +type DomainEventGraphicsPhase int + +// The phase of the graphics client connection +const ( + // Initial socket connection established + DOMAIN_EVENT_GRAPHICS_CONNECT = DomainEventGraphicsPhase(C.VIR_DOMAIN_EVENT_GRAPHICS_CONNECT) + + // Authentication & setup completed + DOMAIN_EVENT_GRAPHICS_INITIALIZE = DomainEventGraphicsPhase(C.VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE) + + // Final socket disconnection + DOMAIN_EVENT_GRAPHICS_DISCONNECT = DomainEventGraphicsPhase(C.VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT) +) + +type DomainEventGraphicsAddressType int + +const ( + // IPv4 address + DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4 = DomainEventGraphicsAddressType(C.VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4) + + // IPv6 address + DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6 = DomainEventGraphicsAddressType(C.VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6) + + // UNIX socket path + DOMAIN_EVENT_GRAPHICS_ADDRESS_UNIX = DomainEventGraphicsAddressType(C.VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_UNIX) +) + +type DomainBlockJobType int + +const ( + // Placeholder + DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = DomainBlockJobType(C.VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN) + + // Block Pull (virDomainBlockPull, or virDomainBlockRebase without + // flags), job ends on completion + DOMAIN_BLOCK_JOB_TYPE_PULL = DomainBlockJobType(C.VIR_DOMAIN_BLOCK_JOB_TYPE_PULL) + + // Block Copy (virDomainBlockCopy, or virDomainBlockRebase with + // flags), job exists as long as mirroring is active + DOMAIN_BLOCK_JOB_TYPE_COPY = DomainBlockJobType(C.VIR_DOMAIN_BLOCK_JOB_TYPE_COPY) + + // Block Commit (virDomainBlockCommit without flags), job ends on + // completion + DOMAIN_BLOCK_JOB_TYPE_COMMIT = DomainBlockJobType(C.VIR_DOMAIN_BLOCK_JOB_TYPE_COMMIT) + + // Active Block Commit (virDomainBlockCommit with flags), job + // exists as long as sync is active + DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT = DomainBlockJobType(C.VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT) +) + +type DomainRunningReason int + +const ( + DOMAIN_RUNNING_UNKNOWN = DomainRunningReason(C.VIR_DOMAIN_RUNNING_UNKNOWN) + DOMAIN_RUNNING_BOOTED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_BOOTED) /* normal startup from boot */ + DOMAIN_RUNNING_MIGRATED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_MIGRATED) /* migrated from another host */ + DOMAIN_RUNNING_RESTORED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_RESTORED) /* restored from a state file */ + DOMAIN_RUNNING_FROM_SNAPSHOT = DomainRunningReason(C.VIR_DOMAIN_RUNNING_FROM_SNAPSHOT) /* restored from snapshot */ + DOMAIN_RUNNING_UNPAUSED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_UNPAUSED) /* returned from paused state */ + DOMAIN_RUNNING_MIGRATION_CANCELED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_MIGRATION_CANCELED) /* returned from migration */ + DOMAIN_RUNNING_SAVE_CANCELED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_SAVE_CANCELED) /* returned from failed save process */ + DOMAIN_RUNNING_WAKEUP = DomainRunningReason(C.VIR_DOMAIN_RUNNING_WAKEUP) /* returned from pmsuspended due to wakeup event */ + DOMAIN_RUNNING_CRASHED = DomainRunningReason(C.VIR_DOMAIN_RUNNING_CRASHED) /* resumed from crashed */ + DOMAIN_RUNNING_POSTCOPY = DomainRunningReason(C.VIR_DOMAIN_RUNNING_POSTCOPY) /* running in post-copy migration mode */ +) + +type DomainPausedReason int + +const ( + DOMAIN_PAUSED_UNKNOWN = DomainPausedReason(C.VIR_DOMAIN_PAUSED_UNKNOWN) /* the reason is unknown */ + DOMAIN_PAUSED_USER = DomainPausedReason(C.VIR_DOMAIN_PAUSED_USER) /* paused on user request */ + DOMAIN_PAUSED_MIGRATION = DomainPausedReason(C.VIR_DOMAIN_PAUSED_MIGRATION) /* paused for offline migration */ + DOMAIN_PAUSED_SAVE = DomainPausedReason(C.VIR_DOMAIN_PAUSED_SAVE) /* paused for save */ + DOMAIN_PAUSED_DUMP = DomainPausedReason(C.VIR_DOMAIN_PAUSED_DUMP) /* paused for offline core dump */ + DOMAIN_PAUSED_IOERROR = DomainPausedReason(C.VIR_DOMAIN_PAUSED_IOERROR) /* paused due to a disk I/O error */ + DOMAIN_PAUSED_WATCHDOG = DomainPausedReason(C.VIR_DOMAIN_PAUSED_WATCHDOG) /* paused due to a watchdog event */ + DOMAIN_PAUSED_FROM_SNAPSHOT = DomainPausedReason(C.VIR_DOMAIN_PAUSED_FROM_SNAPSHOT) /* paused after restoring from snapshot */ + DOMAIN_PAUSED_SHUTTING_DOWN = DomainPausedReason(C.VIR_DOMAIN_PAUSED_SHUTTING_DOWN) /* paused during shutdown process */ + DOMAIN_PAUSED_SNAPSHOT = DomainPausedReason(C.VIR_DOMAIN_PAUSED_SNAPSHOT) /* paused while creating a snapshot */ + DOMAIN_PAUSED_CRASHED = DomainPausedReason(C.VIR_DOMAIN_PAUSED_CRASHED) /* paused due to a guest crash */ + DOMAIN_PAUSED_STARTING_UP = DomainPausedReason(C.VIR_DOMAIN_PAUSED_STARTING_UP) /* the domainis being started */ + DOMAIN_PAUSED_POSTCOPY = DomainPausedReason(C.VIR_DOMAIN_PAUSED_POSTCOPY) /* paused for post-copy migration */ + DOMAIN_PAUSED_POSTCOPY_FAILED = DomainPausedReason(C.VIR_DOMAIN_PAUSED_POSTCOPY_FAILED) /* paused after failed post-copy */ +) + +type DomainXMLFlags int + +const ( + DOMAIN_XML_SECURE = DomainXMLFlags(C.VIR_DOMAIN_XML_SECURE) /* dump security sensitive information too */ + DOMAIN_XML_INACTIVE = DomainXMLFlags(C.VIR_DOMAIN_XML_INACTIVE) /* dump inactive domain information */ + DOMAIN_XML_UPDATE_CPU = DomainXMLFlags(C.VIR_DOMAIN_XML_UPDATE_CPU) /* update guest CPU requirements according to host CPU */ + DOMAIN_XML_MIGRATABLE = DomainXMLFlags(C.VIR_DOMAIN_XML_MIGRATABLE) /* dump XML suitable for migration */ +) + +type DomainEventDefinedDetailType int + +const ( + DOMAIN_EVENT_DEFINED_ADDED = DomainEventDefinedDetailType(C.VIR_DOMAIN_EVENT_DEFINED_ADDED) + DOMAIN_EVENT_DEFINED_UPDATED = DomainEventDefinedDetailType(C.VIR_DOMAIN_EVENT_DEFINED_UPDATED) + DOMAIN_EVENT_DEFINED_RENAMED = DomainEventDefinedDetailType(C.VIR_DOMAIN_EVENT_DEFINED_RENAMED) + DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT = DomainEventDefinedDetailType(C.VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT) +) + +type DomainEventUndefinedDetailType int + +const ( + DOMAIN_EVENT_UNDEFINED_REMOVED = DomainEventUndefinedDetailType(C.VIR_DOMAIN_EVENT_UNDEFINED_REMOVED) + DOMAIN_EVENT_UNDEFINED_RENAMED = DomainEventUndefinedDetailType(C.VIR_DOMAIN_EVENT_UNDEFINED_RENAMED) +) + +type DomainEventStartedDetailType int + +const ( + DOMAIN_EVENT_STARTED_BOOTED = DomainEventStartedDetailType(C.VIR_DOMAIN_EVENT_STARTED_BOOTED) + DOMAIN_EVENT_STARTED_MIGRATED = DomainEventStartedDetailType(C.VIR_DOMAIN_EVENT_STARTED_MIGRATED) + DOMAIN_EVENT_STARTED_RESTORED = DomainEventStartedDetailType(C.VIR_DOMAIN_EVENT_STARTED_RESTORED) + DOMAIN_EVENT_STARTED_FROM_SNAPSHOT = DomainEventStartedDetailType(C.VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT) + DOMAIN_EVENT_STARTED_WAKEUP = DomainEventStartedDetailType(C.VIR_DOMAIN_EVENT_STARTED_WAKEUP) +) + +type DomainEventSuspendedDetailType int + +const ( + DOMAIN_EVENT_SUSPENDED_PAUSED = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_PAUSED) + DOMAIN_EVENT_SUSPENDED_MIGRATED = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_MIGRATED) + DOMAIN_EVENT_SUSPENDED_IOERROR = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_IOERROR) + DOMAIN_EVENT_SUSPENDED_WATCHDOG = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_WATCHDOG) + DOMAIN_EVENT_SUSPENDED_RESTORED = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_RESTORED) + DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT) + DOMAIN_EVENT_SUSPENDED_API_ERROR = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_API_ERROR) + DOMAIN_EVENT_SUSPENDED_POSTCOPY = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY) + DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED = DomainEventSuspendedDetailType(C.VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED) +) + +type DomainEventResumedDetailType int + +const ( + DOMAIN_EVENT_RESUMED_UNPAUSED = DomainEventResumedDetailType(C.VIR_DOMAIN_EVENT_RESUMED_UNPAUSED) + DOMAIN_EVENT_RESUMED_MIGRATED = DomainEventResumedDetailType(C.VIR_DOMAIN_EVENT_RESUMED_MIGRATED) + DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT = DomainEventResumedDetailType(C.VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT) + DOMAIN_EVENT_RESUMED_POSTCOPY = DomainEventResumedDetailType(C.VIR_DOMAIN_EVENT_RESUMED_POSTCOPY) +) + +type DomainEventStoppedDetailType int + +const ( + DOMAIN_EVENT_STOPPED_SHUTDOWN = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN) + DOMAIN_EVENT_STOPPED_DESTROYED = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_DESTROYED) + DOMAIN_EVENT_STOPPED_CRASHED = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_CRASHED) + DOMAIN_EVENT_STOPPED_MIGRATED = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_MIGRATED) + DOMAIN_EVENT_STOPPED_SAVED = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_SAVED) + DOMAIN_EVENT_STOPPED_FAILED = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_FAILED) + DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT = DomainEventStoppedDetailType(C.VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT) +) + +type DomainEventShutdownDetailType int + +const ( + DOMAIN_EVENT_SHUTDOWN_FINISHED = DomainEventShutdownDetailType(C.VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED) + DOMAIN_EVENT_SHUTDOWN_GUEST = DomainEventShutdownDetailType(C.VIR_DOMAIN_EVENT_SHUTDOWN_GUEST) + DOMAIN_EVENT_SHUTDOWN_HOST = DomainEventShutdownDetailType(C.VIR_DOMAIN_EVENT_SHUTDOWN_HOST) +) + +type DomainMemoryStatTags int + +const ( + DOMAIN_MEMORY_STAT_LAST = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_NR) + DOMAIN_MEMORY_STAT_SWAP_IN = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_SWAP_IN) + DOMAIN_MEMORY_STAT_SWAP_OUT = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_SWAP_OUT) + DOMAIN_MEMORY_STAT_MAJOR_FAULT = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_MAJOR_FAULT) + DOMAIN_MEMORY_STAT_MINOR_FAULT = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_MINOR_FAULT) + DOMAIN_MEMORY_STAT_UNUSED = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_UNUSED) + DOMAIN_MEMORY_STAT_AVAILABLE = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_AVAILABLE) + DOMAIN_MEMORY_STAT_ACTUAL_BALLOON = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_ACTUAL_BALLOON) + DOMAIN_MEMORY_STAT_RSS = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_RSS) + DOMAIN_MEMORY_STAT_USABLE = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_USABLE) + DOMAIN_MEMORY_STAT_LAST_UPDATE = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE) + DOMAIN_MEMORY_STAT_NR = DomainMemoryStatTags(C.VIR_DOMAIN_MEMORY_STAT_NR) +) + +type DomainCPUStatsTags string + +const ( + DOMAIN_CPU_STATS_CPUTIME = DomainCPUStatsTags(C.VIR_DOMAIN_CPU_STATS_CPUTIME) + DOMAIN_CPU_STATS_SYSTEMTIME = DomainCPUStatsTags(C.VIR_DOMAIN_CPU_STATS_SYSTEMTIME) + DOMAIN_CPU_STATS_USERTIME = DomainCPUStatsTags(C.VIR_DOMAIN_CPU_STATS_USERTIME) + DOMAIN_CPU_STATS_VCPUTIME = DomainCPUStatsTags(C.VIR_DOMAIN_CPU_STATS_VCPUTIME) +) + +type DomainInterfaceAddressesSource int + +const ( + DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE = DomainInterfaceAddressesSource(C.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE) + DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT = DomainInterfaceAddressesSource(C.VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT) +) + +type KeycodeSet int + +const ( + KEYCODE_SET_LINUX = KeycodeSet(C.VIR_KEYCODE_SET_LINUX) + KEYCODE_SET_XT = KeycodeSet(C.VIR_KEYCODE_SET_XT) + KEYCODE_SET_ATSET1 = KeycodeSet(C.VIR_KEYCODE_SET_ATSET1) + KEYCODE_SET_ATSET2 = KeycodeSet(C.VIR_KEYCODE_SET_ATSET2) + KEYCODE_SET_ATSET3 = KeycodeSet(C.VIR_KEYCODE_SET_ATSET3) + KEYCODE_SET_OSX = KeycodeSet(C.VIR_KEYCODE_SET_OSX) + KEYCODE_SET_XT_KBD = KeycodeSet(C.VIR_KEYCODE_SET_XT_KBD) + KEYCODE_SET_USB = KeycodeSet(C.VIR_KEYCODE_SET_USB) + KEYCODE_SET_WIN32 = KeycodeSet(C.VIR_KEYCODE_SET_WIN32) + KEYCODE_SET_RFB = KeycodeSet(C.VIR_KEYCODE_SET_RFB) +) + +type ConnectDomainEventBlockJobStatus int + +const ( + DOMAIN_BLOCK_JOB_COMPLETED = ConnectDomainEventBlockJobStatus(C.VIR_DOMAIN_BLOCK_JOB_COMPLETED) + DOMAIN_BLOCK_JOB_FAILED = ConnectDomainEventBlockJobStatus(C.VIR_DOMAIN_BLOCK_JOB_FAILED) + DOMAIN_BLOCK_JOB_CANCELED = ConnectDomainEventBlockJobStatus(C.VIR_DOMAIN_BLOCK_JOB_CANCELED) + DOMAIN_BLOCK_JOB_READY = ConnectDomainEventBlockJobStatus(C.VIR_DOMAIN_BLOCK_JOB_READY) +) + +type ConnectDomainEventDiskChangeReason int + +const ( + // OldSrcPath is set + DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START = ConnectDomainEventDiskChangeReason(C.VIR_DOMAIN_EVENT_DISK_CHANGE_MISSING_ON_START) + DOMAIN_EVENT_DISK_DROP_MISSING_ON_START = ConnectDomainEventDiskChangeReason(C.VIR_DOMAIN_EVENT_DISK_DROP_MISSING_ON_START) +) + +type ConnectDomainEventTrayChangeReason int + +const ( + DOMAIN_EVENT_TRAY_CHANGE_OPEN = ConnectDomainEventTrayChangeReason(C.VIR_DOMAIN_EVENT_TRAY_CHANGE_OPEN) + DOMAIN_EVENT_TRAY_CHANGE_CLOSE = ConnectDomainEventTrayChangeReason(C.VIR_DOMAIN_EVENT_TRAY_CHANGE_CLOSE) +) + +type DomainProcessSignal int + +const ( + DOMAIN_PROCESS_SIGNAL_NOP = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_NOP) + DOMAIN_PROCESS_SIGNAL_HUP = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_HUP) + DOMAIN_PROCESS_SIGNAL_INT = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_INT) + DOMAIN_PROCESS_SIGNAL_QUIT = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_QUIT) + DOMAIN_PROCESS_SIGNAL_ILL = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_ILL) + DOMAIN_PROCESS_SIGNAL_TRAP = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_TRAP) + DOMAIN_PROCESS_SIGNAL_ABRT = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_ABRT) + DOMAIN_PROCESS_SIGNAL_BUS = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_BUS) + DOMAIN_PROCESS_SIGNAL_FPE = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_FPE) + DOMAIN_PROCESS_SIGNAL_KILL = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_KILL) + + DOMAIN_PROCESS_SIGNAL_USR1 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_USR1) + DOMAIN_PROCESS_SIGNAL_SEGV = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_SEGV) + DOMAIN_PROCESS_SIGNAL_USR2 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_USR2) + DOMAIN_PROCESS_SIGNAL_PIPE = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_PIPE) + DOMAIN_PROCESS_SIGNAL_ALRM = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_ALRM) + DOMAIN_PROCESS_SIGNAL_TERM = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_TERM) + DOMAIN_PROCESS_SIGNAL_STKFLT = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_STKFLT) + DOMAIN_PROCESS_SIGNAL_CHLD = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_CHLD) + DOMAIN_PROCESS_SIGNAL_CONT = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_CONT) + DOMAIN_PROCESS_SIGNAL_STOP = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_STOP) + + DOMAIN_PROCESS_SIGNAL_TSTP = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_TSTP) + DOMAIN_PROCESS_SIGNAL_TTIN = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_TTIN) + DOMAIN_PROCESS_SIGNAL_TTOU = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_TTOU) + DOMAIN_PROCESS_SIGNAL_URG = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_URG) + DOMAIN_PROCESS_SIGNAL_XCPU = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_XCPU) + DOMAIN_PROCESS_SIGNAL_XFSZ = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_XFSZ) + DOMAIN_PROCESS_SIGNAL_VTALRM = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_VTALRM) + DOMAIN_PROCESS_SIGNAL_PROF = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_PROF) + DOMAIN_PROCESS_SIGNAL_WINCH = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_WINCH) + DOMAIN_PROCESS_SIGNAL_POLL = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_POLL) + + DOMAIN_PROCESS_SIGNAL_PWR = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_PWR) + DOMAIN_PROCESS_SIGNAL_SYS = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_SYS) + DOMAIN_PROCESS_SIGNAL_RT0 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT0) + DOMAIN_PROCESS_SIGNAL_RT1 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT1) + DOMAIN_PROCESS_SIGNAL_RT2 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT2) + DOMAIN_PROCESS_SIGNAL_RT3 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT3) + DOMAIN_PROCESS_SIGNAL_RT4 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT4) + DOMAIN_PROCESS_SIGNAL_RT5 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT5) + DOMAIN_PROCESS_SIGNAL_RT6 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT6) + DOMAIN_PROCESS_SIGNAL_RT7 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT7) + + DOMAIN_PROCESS_SIGNAL_RT8 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT8) + DOMAIN_PROCESS_SIGNAL_RT9 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT9) + DOMAIN_PROCESS_SIGNAL_RT10 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT10) + DOMAIN_PROCESS_SIGNAL_RT11 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT11) + DOMAIN_PROCESS_SIGNAL_RT12 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT12) + DOMAIN_PROCESS_SIGNAL_RT13 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT13) + DOMAIN_PROCESS_SIGNAL_RT14 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT14) + DOMAIN_PROCESS_SIGNAL_RT15 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT15) + DOMAIN_PROCESS_SIGNAL_RT16 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT16) + DOMAIN_PROCESS_SIGNAL_RT17 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT17) + DOMAIN_PROCESS_SIGNAL_RT18 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT18) + + DOMAIN_PROCESS_SIGNAL_RT19 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT19) + DOMAIN_PROCESS_SIGNAL_RT20 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT20) + DOMAIN_PROCESS_SIGNAL_RT21 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT21) + DOMAIN_PROCESS_SIGNAL_RT22 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT22) + DOMAIN_PROCESS_SIGNAL_RT23 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT23) + DOMAIN_PROCESS_SIGNAL_RT24 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT24) + DOMAIN_PROCESS_SIGNAL_RT25 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT25) + DOMAIN_PROCESS_SIGNAL_RT26 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT26) + DOMAIN_PROCESS_SIGNAL_RT27 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT27) + + DOMAIN_PROCESS_SIGNAL_RT28 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT28) + DOMAIN_PROCESS_SIGNAL_RT29 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT29) + DOMAIN_PROCESS_SIGNAL_RT30 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT30) + DOMAIN_PROCESS_SIGNAL_RT31 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT31) + DOMAIN_PROCESS_SIGNAL_RT32 = DomainProcessSignal(C.VIR_DOMAIN_PROCESS_SIGNAL_RT32) +) + +type DomainBlockedReason int + +const ( + DOMAIN_BLOCKED_UNKNOWN = DomainBlockedReason(C.VIR_DOMAIN_BLOCKED_UNKNOWN) +) + +type DomainControlState int + +const ( + DOMAIN_CONTROL_OK = DomainControlState(C.VIR_DOMAIN_CONTROL_OK) + DOMAIN_CONTROL_JOB = DomainControlState(C.VIR_DOMAIN_CONTROL_JOB) + DOMAIN_CONTROL_OCCUPIED = DomainControlState(C.VIR_DOMAIN_CONTROL_OCCUPIED) + DOMAIN_CONTROL_ERROR = DomainControlState(C.VIR_DOMAIN_CONTROL_ERROR) +) + +type DomainControlErrorReason int + +const ( + DOMAIN_CONTROL_ERROR_REASON_NONE = DomainControlErrorReason(C.VIR_DOMAIN_CONTROL_ERROR_REASON_NONE) + DOMAIN_CONTROL_ERROR_REASON_UNKNOWN = DomainControlErrorReason(C.VIR_DOMAIN_CONTROL_ERROR_REASON_UNKNOWN) + DOMAIN_CONTROL_ERROR_REASON_MONITOR = DomainControlErrorReason(C.VIR_DOMAIN_CONTROL_ERROR_REASON_MONITOR) + DOMAIN_CONTROL_ERROR_REASON_INTERNAL = DomainControlErrorReason(C.VIR_DOMAIN_CONTROL_ERROR_REASON_INTERNAL) +) + +type DomainCrashedReason int + +const ( + DOMAIN_CRASHED_UNKNOWN = DomainCrashedReason(C.VIR_DOMAIN_CRASHED_UNKNOWN) + DOMAIN_CRASHED_PANICKED = DomainCrashedReason(C.VIR_DOMAIN_CRASHED_PANICKED) +) + +type DomainEventCrashedDetailType int + +const ( + DOMAIN_EVENT_CRASHED_PANICKED = DomainEventCrashedDetailType(C.VIR_DOMAIN_EVENT_CRASHED_PANICKED) +) + +type DomainEventPMSuspendedDetailType int + +const ( + DOMAIN_EVENT_PMSUSPENDED_MEMORY = DomainEventPMSuspendedDetailType(C.VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY) + DOMAIN_EVENT_PMSUSPENDED_DISK = DomainEventPMSuspendedDetailType(C.VIR_DOMAIN_EVENT_PMSUSPENDED_DISK) +) + +type DomainNostateReason int + +const ( + DOMAIN_NOSTATE_UNKNOWN = DomainNostateReason(C.VIR_DOMAIN_NOSTATE_UNKNOWN) +) + +type DomainPMSuspendedReason int + +const ( + DOMAIN_PMSUSPENDED_UNKNOWN = DomainPMSuspendedReason(C.VIR_DOMAIN_PMSUSPENDED_UNKNOWN) +) + +type DomainPMSuspendedDiskReason int + +const ( + DOMAIN_PMSUSPENDED_DISK_UNKNOWN = DomainPMSuspendedDiskReason(C.VIR_DOMAIN_PMSUSPENDED_DISK_UNKNOWN) +) + +type DomainShutdownReason int + +const ( + DOMAIN_SHUTDOWN_UNKNOWN = DomainShutdownReason(C.VIR_DOMAIN_SHUTDOWN_UNKNOWN) + DOMAIN_SHUTDOWN_USER = DomainShutdownReason(C.VIR_DOMAIN_SHUTDOWN_USER) +) + +type DomainShutoffReason int + +const ( + DOMAIN_SHUTOFF_UNKNOWN = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_UNKNOWN) + DOMAIN_SHUTOFF_SHUTDOWN = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_SHUTDOWN) + DOMAIN_SHUTOFF_DESTROYED = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_DESTROYED) + DOMAIN_SHUTOFF_CRASHED = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_CRASHED) + DOMAIN_SHUTOFF_MIGRATED = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_MIGRATED) + DOMAIN_SHUTOFF_SAVED = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_SAVED) + DOMAIN_SHUTOFF_FAILED = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_FAILED) + DOMAIN_SHUTOFF_FROM_SNAPSHOT = DomainShutoffReason(C.VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT) +) + +type DomainBlockCommitFlags int + +const ( + DOMAIN_BLOCK_COMMIT_SHALLOW = DomainBlockCommitFlags(C.VIR_DOMAIN_BLOCK_COMMIT_SHALLOW) + DOMAIN_BLOCK_COMMIT_DELETE = DomainBlockCommitFlags(C.VIR_DOMAIN_BLOCK_COMMIT_DELETE) + DOMAIN_BLOCK_COMMIT_ACTIVE = DomainBlockCommitFlags(C.VIR_DOMAIN_BLOCK_COMMIT_ACTIVE) + DOMAIN_BLOCK_COMMIT_RELATIVE = DomainBlockCommitFlags(C.VIR_DOMAIN_BLOCK_COMMIT_RELATIVE) + DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES = DomainBlockCommitFlags(C.VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES) +) + +type DomainBlockCopyFlags int + +const ( + DOMAIN_BLOCK_COPY_SHALLOW = DomainBlockCopyFlags(C.VIR_DOMAIN_BLOCK_COPY_SHALLOW) + DOMAIN_BLOCK_COPY_REUSE_EXT = DomainBlockCopyFlags(C.VIR_DOMAIN_BLOCK_COPY_REUSE_EXT) +) + +type DomainBlockRebaseFlags int + +const ( + DOMAIN_BLOCK_REBASE_SHALLOW = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_SHALLOW) + DOMAIN_BLOCK_REBASE_REUSE_EXT = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) + DOMAIN_BLOCK_REBASE_COPY_RAW = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_COPY_RAW) + DOMAIN_BLOCK_REBASE_COPY = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_COPY) + DOMAIN_BLOCK_REBASE_RELATIVE = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_RELATIVE) + DOMAIN_BLOCK_REBASE_COPY_DEV = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV) + DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES = DomainBlockRebaseFlags(C.VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES) +) + +type DomainBlockJobAbortFlags int + +const ( + DOMAIN_BLOCK_JOB_ABORT_ASYNC = DomainBlockJobAbortFlags(C.VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC) + DOMAIN_BLOCK_JOB_ABORT_PIVOT = DomainBlockJobAbortFlags(C.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT) +) + +type DomainBlockJobInfoFlags int + +const ( + DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES = DomainBlockJobInfoFlags(C.VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES) +) + +type DomainBlockJobSetSpeedFlags int + +const ( + DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES = DomainBlockJobSetSpeedFlags(C.VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES) +) + +type DomainBlockPullFlags int + +const ( + DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES = DomainBlockPullFlags(C.VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES) +) + +type DomainBlockResizeFlags int + +const ( + DOMAIN_BLOCK_RESIZE_BYTES = DomainBlockResizeFlags(C.VIR_DOMAIN_BLOCK_RESIZE_BYTES) +) + +type Domain struct { + ptr C.virDomainPtr +} + +type DomainChannelFlags int + +const ( + DOMAIN_CHANNEL_FORCE = DomainChannelFlags(C.VIR_DOMAIN_CHANNEL_FORCE) +) + +type DomainConsoleFlags int + +const ( + DOMAIN_CONSOLE_FORCE = DomainConsoleFlags(C.VIR_DOMAIN_CONSOLE_FORCE) + DOMAIN_CONSOLE_SAFE = DomainConsoleFlags(C.VIR_DOMAIN_CONSOLE_SAFE) +) + +type DomainCoreDumpFormat int + +const ( + DOMAIN_CORE_DUMP_FORMAT_RAW = DomainCoreDumpFormat(C.VIR_DOMAIN_CORE_DUMP_FORMAT_RAW) + DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB = DomainCoreDumpFormat(C.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB) + DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO = DomainCoreDumpFormat(C.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO) + DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY = DomainCoreDumpFormat(C.VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY) +) + +type DomainDefineFlags int + +const ( + DOMAIN_DEFINE_VALIDATE = DomainDefineFlags(C.VIR_DOMAIN_DEFINE_VALIDATE) +) + +type DomainJobType int + +const ( + DOMAIN_JOB_NONE = DomainJobType(C.VIR_DOMAIN_JOB_NONE) + DOMAIN_JOB_BOUNDED = DomainJobType(C.VIR_DOMAIN_JOB_BOUNDED) + DOMAIN_JOB_UNBOUNDED = DomainJobType(C.VIR_DOMAIN_JOB_UNBOUNDED) + DOMAIN_JOB_COMPLETED = DomainJobType(C.VIR_DOMAIN_JOB_COMPLETED) + DOMAIN_JOB_FAILED = DomainJobType(C.VIR_DOMAIN_JOB_FAILED) + DOMAIN_JOB_CANCELLED = DomainJobType(C.VIR_DOMAIN_JOB_CANCELLED) +) + +type DomainGetJobStatsFlags int + +const ( + DOMAIN_JOB_STATS_COMPLETED = DomainGetJobStatsFlags(C.VIR_DOMAIN_JOB_STATS_COMPLETED) +) + +type DomainNumatuneMemMode int + +const ( + DOMAIN_NUMATUNE_MEM_STRICT = DomainNumatuneMemMode(C.VIR_DOMAIN_NUMATUNE_MEM_STRICT) + DOMAIN_NUMATUNE_MEM_PREFERRED = DomainNumatuneMemMode(C.VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) + DOMAIN_NUMATUNE_MEM_INTERLEAVE = DomainNumatuneMemMode(C.VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) +) + +type DomainOpenGraphicsFlags int + +const ( + DOMAIN_OPEN_GRAPHICS_SKIPAUTH = DomainOpenGraphicsFlags(C.VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) +) + +type DomainSetUserPasswordFlags int + +const ( + DOMAIN_PASSWORD_ENCRYPTED = DomainSetUserPasswordFlags(C.VIR_DOMAIN_PASSWORD_ENCRYPTED) +) + +type DomainRebootFlagValues int + +const ( + DOMAIN_REBOOT_DEFAULT = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_DEFAULT) + DOMAIN_REBOOT_ACPI_POWER_BTN = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_ACPI_POWER_BTN) + DOMAIN_REBOOT_GUEST_AGENT = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_GUEST_AGENT) + DOMAIN_REBOOT_INITCTL = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_INITCTL) + DOMAIN_REBOOT_SIGNAL = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_SIGNAL) + DOMAIN_REBOOT_PARAVIRT = DomainRebootFlagValues(C.VIR_DOMAIN_REBOOT_PARAVIRT) +) + +type DomainSaveRestoreFlags int + +const ( + DOMAIN_SAVE_BYPASS_CACHE = DomainSaveRestoreFlags(C.VIR_DOMAIN_SAVE_BYPASS_CACHE) + DOMAIN_SAVE_RUNNING = DomainSaveRestoreFlags(C.VIR_DOMAIN_SAVE_RUNNING) + DOMAIN_SAVE_PAUSED = DomainSaveRestoreFlags(C.VIR_DOMAIN_SAVE_PAUSED) +) + +type DomainSetTimeFlags int + +const ( + DOMAIN_TIME_SYNC = DomainSetTimeFlags(C.VIR_DOMAIN_TIME_SYNC) +) + +type DomainDiskErrorCode int + +const ( + DOMAIN_DISK_ERROR_NONE = DomainDiskErrorCode(C.VIR_DOMAIN_DISK_ERROR_NONE) + DOMAIN_DISK_ERROR_UNSPEC = DomainDiskErrorCode(C.VIR_DOMAIN_DISK_ERROR_UNSPEC) + DOMAIN_DISK_ERROR_NO_SPACE = DomainDiskErrorCode(C.VIR_DOMAIN_DISK_ERROR_NO_SPACE) +) + +type DomainStatsTypes int + +const ( + DOMAIN_STATS_STATE = DomainStatsTypes(C.VIR_DOMAIN_STATS_STATE) + DOMAIN_STATS_CPU_TOTAL = DomainStatsTypes(C.VIR_DOMAIN_STATS_CPU_TOTAL) + DOMAIN_STATS_BALLOON = DomainStatsTypes(C.VIR_DOMAIN_STATS_BALLOON) + DOMAIN_STATS_VCPU = DomainStatsTypes(C.VIR_DOMAIN_STATS_VCPU) + DOMAIN_STATS_INTERFACE = DomainStatsTypes(C.VIR_DOMAIN_STATS_INTERFACE) + DOMAIN_STATS_BLOCK = DomainStatsTypes(C.VIR_DOMAIN_STATS_BLOCK) + DOMAIN_STATS_PERF = DomainStatsTypes(C.VIR_DOMAIN_STATS_PERF) +) + +type DomainCoreDumpFlags int + +const ( + DUMP_CRASH = DomainCoreDumpFlags(C.VIR_DUMP_CRASH) + DUMP_LIVE = DomainCoreDumpFlags(C.VIR_DUMP_LIVE) + DUMP_BYPASS_CACHE = DomainCoreDumpFlags(C.VIR_DUMP_BYPASS_CACHE) + DUMP_RESET = DomainCoreDumpFlags(C.VIR_DUMP_RESET) + DUMP_MEMORY_ONLY = DomainCoreDumpFlags(C.VIR_DUMP_MEMORY_ONLY) +) + +type DomainMemoryFlags int + +const ( + MEMORY_VIRTUAL = DomainMemoryFlags(C.VIR_MEMORY_VIRTUAL) + MEMORY_PHYSICAL = DomainMemoryFlags(C.VIR_MEMORY_PHYSICAL) +) + +type DomainMigrateFlags int + +const ( + MIGRATE_LIVE = DomainMigrateFlags(C.VIR_MIGRATE_LIVE) + MIGRATE_PEER2PEER = DomainMigrateFlags(C.VIR_MIGRATE_PEER2PEER) + MIGRATE_TUNNELLED = DomainMigrateFlags(C.VIR_MIGRATE_TUNNELLED) + MIGRATE_PERSIST_DEST = DomainMigrateFlags(C.VIR_MIGRATE_PERSIST_DEST) + MIGRATE_UNDEFINE_SOURCE = DomainMigrateFlags(C.VIR_MIGRATE_UNDEFINE_SOURCE) + MIGRATE_PAUSED = DomainMigrateFlags(C.VIR_MIGRATE_PAUSED) + MIGRATE_NON_SHARED_DISK = DomainMigrateFlags(C.VIR_MIGRATE_NON_SHARED_DISK) + MIGRATE_NON_SHARED_INC = DomainMigrateFlags(C.VIR_MIGRATE_NON_SHARED_INC) + MIGRATE_CHANGE_PROTECTION = DomainMigrateFlags(C.VIR_MIGRATE_CHANGE_PROTECTION) + MIGRATE_UNSAFE = DomainMigrateFlags(C.VIR_MIGRATE_UNSAFE) + MIGRATE_OFFLINE = DomainMigrateFlags(C.VIR_MIGRATE_OFFLINE) + MIGRATE_COMPRESSED = DomainMigrateFlags(C.VIR_MIGRATE_COMPRESSED) + MIGRATE_ABORT_ON_ERROR = DomainMigrateFlags(C.VIR_MIGRATE_ABORT_ON_ERROR) + MIGRATE_AUTO_CONVERGE = DomainMigrateFlags(C.VIR_MIGRATE_AUTO_CONVERGE) + MIGRATE_RDMA_PIN_ALL = DomainMigrateFlags(C.VIR_MIGRATE_RDMA_PIN_ALL) + MIGRATE_POSTCOPY = DomainMigrateFlags(C.VIR_MIGRATE_POSTCOPY) + MIGRATE_TLS = DomainMigrateFlags(C.VIR_MIGRATE_TLS) +) + +type VcpuState int + +const ( + VCPU_OFFLINE = VcpuState(C.VIR_VCPU_OFFLINE) + VCPU_RUNNING = VcpuState(C.VIR_VCPU_RUNNING) + VCPU_BLOCKED = VcpuState(C.VIR_VCPU_BLOCKED) +) + +type DomainJobOperationType int + +const ( + DOMAIN_JOB_OPERATION_UNKNOWN = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_UNKNOWN) + DOMAIN_JOB_OPERATION_START = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_START) + DOMAIN_JOB_OPERATION_SAVE = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_SAVE) + DOMAIN_JOB_OPERATION_RESTORE = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_RESTORE) + DOMAIN_JOB_OPERATION_MIGRATION_IN = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN) + DOMAIN_JOB_OPERATION_MIGRATION_OUT = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT) + DOMAIN_JOB_OPERATION_SNAPSHOT = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_SNAPSHOT) + DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT) + DOMAIN_JOB_OPERATION_DUMP = DomainJobOperationType(C.VIR_DOMAIN_JOB_OPERATION_DUMP) +) + +type DomainBlockInfo struct { + Capacity uint64 + Allocation uint64 + Physical uint64 +} + +type DomainInfo struct { + State DomainState + MaxMem uint64 + Memory uint64 + NrVirtCpu uint + CpuTime uint64 +} + +type DomainMemoryStat struct { + Tag int32 + Val uint64 +} + +type DomainVcpuInfo struct { + Number uint32 + State int32 + CpuTime uint64 + Cpu int32 + CpuMap []bool +} + +func (d *Domain) Free() error { + ret := C.virDomainFree(d.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Domain) Ref() error { + ret := C.virDomainRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Create() error { + result := C.virDomainCreate(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) CreateWithFlags(flags DomainCreateFlags) error { + result := C.virDomainCreateWithFlags(d.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) CreateWithFiles(files []os.File, flags DomainCreateFlags) error { + cfiles := make([]C.int, len(files)) + for i := 0; i < len(files); i++ { + cfiles[i] = C.int(files[i].Fd()) + } + result := C.virDomainCreateWithFiles(d.ptr, C.uint(len(files)), &cfiles[0], C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Destroy() error { + result := C.virDomainDestroy(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Shutdown() error { + result := C.virDomainShutdown(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Reboot(flags DomainRebootFlagValues) error { + result := C.virDomainReboot(d.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) IsActive() (bool, error) { + result := C.virDomainIsActive(d.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (d *Domain) IsPersistent() (bool, error) { + result := C.virDomainIsPersistent(d.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (d *Domain) IsUpdated() (bool, error) { + result := C.virDomainIsUpdated(d.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (d *Domain) SetAutostart(autostart bool) error { + var cAutostart C.int + switch autostart { + case true: + cAutostart = 1 + default: + cAutostart = 0 + } + result := C.virDomainSetAutostart(d.ptr, cAutostart) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) GetAutostart() (bool, error) { + var out C.int + result := C.virDomainGetAutostart(d.ptr, (*C.int)(unsafe.Pointer(&out))) + if result == -1 { + return false, GetLastError() + } + switch out { + case 1: + return true, nil + default: + return false, nil + } +} + +func (d *Domain) GetBlockInfo(disk string, flag uint) (*DomainBlockInfo, error) { + var cinfo C.virDomainBlockInfo + cDisk := C.CString(disk) + defer C.free(unsafe.Pointer(cDisk)) + result := C.virDomainGetBlockInfo(d.ptr, cDisk, &cinfo, C.uint(flag)) + if result == -1 { + return nil, GetLastError() + } + + return &DomainBlockInfo{ + Capacity: uint64(cinfo.capacity), + Allocation: uint64(cinfo.allocation), + Physical: uint64(cinfo.physical), + }, nil +} + +func (d *Domain) GetName() (string, error) { + name := C.virDomainGetName(d.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (d *Domain) GetState() (DomainState, int, error) { + var cState C.int + var cReason C.int + result := C.virDomainGetState(d.ptr, + (*C.int)(unsafe.Pointer(&cState)), + (*C.int)(unsafe.Pointer(&cReason)), + 0) + if int(result) == -1 { + return 0, 0, GetLastError() + } + return DomainState(cState), int(cReason), nil +} + +func (d *Domain) GetID() (uint, error) { + id := uint(C.virDomainGetID(d.ptr)) + if id == ^uint(0) { + return id, GetLastError() + } + return id, nil +} + +func (d *Domain) GetUUID() ([]byte, error) { + var cUuid [C.VIR_UUID_BUFLEN](byte) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virDomainGetUUID(d.ptr, (*C.uchar)(cuidPtr)) + if result != 0 { + return []byte{}, GetLastError() + } + return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil +} + +func (d *Domain) GetUUIDString() (string, error) { + var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virDomainGetUUIDString(d.ptr, (*C.char)(cuidPtr)) + if result != 0 { + return "", GetLastError() + } + return C.GoString((*C.char)(cuidPtr)), nil +} + +func (d *Domain) GetInfo() (*DomainInfo, error) { + var cinfo C.virDomainInfo + result := C.virDomainGetInfo(d.ptr, &cinfo) + if result == -1 { + return nil, GetLastError() + } + return &DomainInfo{ + State: DomainState(cinfo.state), + MaxMem: uint64(cinfo.maxMem), + Memory: uint64(cinfo.memory), + NrVirtCpu: uint(cinfo.nrVirtCpu), + CpuTime: uint64(cinfo.cpuTime), + }, nil +} + +func (d *Domain) GetXMLDesc(flags DomainXMLFlags) (string, error) { + result := C.virDomainGetXMLDesc(d.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +type DomainCPUStats struct { + CpuTimeSet bool + CpuTime uint64 + UserTimeSet bool + UserTime uint64 + SystemTimeSet bool + SystemTime uint64 + VcpuTimeSet bool + VcpuTime uint64 +} + +func getCPUStatsFieldInfo(params *DomainCPUStats) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_CPU_STATS_CPUTIME: typedParamsFieldInfo{ + set: ¶ms.CpuTimeSet, + ul: ¶ms.CpuTime, + }, + C.VIR_DOMAIN_CPU_STATS_USERTIME: typedParamsFieldInfo{ + set: ¶ms.UserTimeSet, + ul: ¶ms.UserTime, + }, + C.VIR_DOMAIN_CPU_STATS_SYSTEMTIME: typedParamsFieldInfo{ + set: ¶ms.SystemTimeSet, + ul: ¶ms.SystemTime, + }, + C.VIR_DOMAIN_CPU_STATS_VCPUTIME: typedParamsFieldInfo{ + set: ¶ms.VcpuTimeSet, + ul: ¶ms.VcpuTime, + }, + } +} + +func (d *Domain) GetCPUStats(startCpu int, nCpus uint, flags uint32) ([]DomainCPUStats, error) { + if nCpus == 0 { + if startCpu == -1 { + nCpus = 1 + } else { + ret := C.virDomainGetCPUStats(d.ptr, nil, 0, 0, 0, 0) + if ret == -1 { + return []DomainCPUStats{}, GetLastError() + } + nCpus = uint(ret) + } + } + + ret := C.virDomainGetCPUStats(d.ptr, nil, 0, C.int(startCpu), C.uint(nCpus), 0) + if ret == -1 { + return []DomainCPUStats{}, GetLastError() + } + nparams := uint(ret) + + var cparams []C.virTypedParameter + var nallocparams uint + if startCpu == -1 { + nallocparams = nparams + } else { + nallocparams = nparams * nCpus + } + cparams = make([]C.virTypedParameter, nallocparams) + ret = C.virDomainGetCPUStats(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), C.uint(nparams), C.int(startCpu), C.uint(nCpus), C.uint(flags)) + if ret == -1 { + return []DomainCPUStats{}, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), C.int(nallocparams)) + + stats := make([]DomainCPUStats, nCpus) + for i := 0; i < int(nCpus); i++ { + offset := i * int(nparams) + info := getCPUStatsFieldInfo(&stats[i]) + cparamscpu := cparams[offset : offset+int(ret)] + _, err := typedParamsUnpack(cparamscpu, info) + if err != nil { + return []DomainCPUStats{}, err + } + } + return stats, nil +} + +type DomainInterfaceParameters struct { + BandwidthInAverageSet bool + BandwidthInAverage uint + BandwidthInPeakSet bool + BandwidthInPeak uint + BandwidthInBurstSet bool + BandwidthInBurst uint + BandwidthInFloorSet bool + BandwidthInFloor uint + BandwidthOutAverageSet bool + BandwidthOutAverage uint + BandwidthOutPeakSet bool + BandwidthOutPeak uint + BandwidthOutBurstSet bool + BandwidthOutBurst uint +} + +func getInterfaceParameterFieldInfo(params *DomainInterfaceParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_BANDWIDTH_IN_AVERAGE: typedParamsFieldInfo{ + set: ¶ms.BandwidthInAverageSet, + ui: ¶ms.BandwidthInAverage, + }, + C.VIR_DOMAIN_BANDWIDTH_IN_PEAK: typedParamsFieldInfo{ + set: ¶ms.BandwidthInPeakSet, + ui: ¶ms.BandwidthInPeak, + }, + C.VIR_DOMAIN_BANDWIDTH_IN_BURST: typedParamsFieldInfo{ + set: ¶ms.BandwidthInBurstSet, + ui: ¶ms.BandwidthInBurst, + }, + C.VIR_DOMAIN_BANDWIDTH_IN_FLOOR: typedParamsFieldInfo{ + set: ¶ms.BandwidthInFloorSet, + ui: ¶ms.BandwidthInFloor, + }, + C.VIR_DOMAIN_BANDWIDTH_OUT_AVERAGE: typedParamsFieldInfo{ + set: ¶ms.BandwidthOutAverageSet, + ui: ¶ms.BandwidthOutAverage, + }, + C.VIR_DOMAIN_BANDWIDTH_OUT_PEAK: typedParamsFieldInfo{ + set: ¶ms.BandwidthOutPeakSet, + ui: ¶ms.BandwidthOutPeak, + }, + C.VIR_DOMAIN_BANDWIDTH_OUT_BURST: typedParamsFieldInfo{ + set: ¶ms.BandwidthOutBurstSet, + ui: ¶ms.BandwidthOutBurst, + }, + } +} + +func (d *Domain) GetInterfaceParameters(device string, flags DomainModificationImpact) (*DomainInterfaceParameters, error) { + params := &DomainInterfaceParameters{} + info := getInterfaceParameterFieldInfo(params) + + var nparams C.int + + cdevice := C.CString(device) + defer C.free(unsafe.Pointer(cdevice)) + ret := C.virDomainGetInterfaceParameters(d.ptr, cdevice, nil, &nparams, C.uint(0)) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetInterfaceParameters(d.ptr, cdevice, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetInterfaceParameters(device string, params *DomainInterfaceParameters, flags DomainModificationImpact) error { + info := getInterfaceParameterFieldInfo(params) + + var nparams C.int + + cdevice := C.CString(device) + defer C.free(unsafe.Pointer(cdevice)) + ret := C.virDomainGetInterfaceParameters(d.ptr, cdevice, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetInterfaceParameters(d.ptr, cdevice, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetInterfaceParameters(d.ptr, cdevice, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +func (d *Domain) GetMetadata(tipus DomainMetadataType, uri string, flags DomainModificationImpact) (string, error) { + var cUri *C.char + if uri != "" { + cUri = C.CString(uri) + defer C.free(unsafe.Pointer(cUri)) + } + + result := C.virDomainGetMetadata(d.ptr, C.int(tipus), cUri, C.uint(flags)) + if result == nil { + return "", GetLastError() + + } + defer C.free(unsafe.Pointer(result)) + return C.GoString(result), nil +} + +func (d *Domain) SetMetadata(metaDataType DomainMetadataType, metaDataCont, uriKey, uri string, flags DomainModificationImpact) error { + var cMetaDataCont *C.char + var cUriKey *C.char + var cUri *C.char + + if metaDataCont != "" { + cMetaDataCont = C.CString(metaDataCont) + defer C.free(unsafe.Pointer(cMetaDataCont)) + } + + if metaDataType == DOMAIN_METADATA_ELEMENT { + if uriKey != "" { + cUriKey = C.CString(uriKey) + defer C.free(unsafe.Pointer(cUriKey)) + } + cUri = C.CString(uri) + defer C.free(unsafe.Pointer(cUri)) + } + result := C.virDomainSetMetadata(d.ptr, C.int(metaDataType), cMetaDataCont, cUriKey, cUri, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Undefine() error { + result := C.virDomainUndefine(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) UndefineFlags(flags DomainUndefineFlagsValues) error { + result := C.virDomainUndefineFlags(d.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetMaxMemory(memory uint) error { + result := C.virDomainSetMaxMemory(d.ptr, C.ulong(memory)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetMemory(memory uint64) error { + result := C.virDomainSetMemory(d.ptr, C.ulong(memory)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetMemoryFlags(memory uint64, flags DomainMemoryModFlags) error { + result := C.virDomainSetMemoryFlags(d.ptr, C.ulong(memory), C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetMemoryStatsPeriod(period int, flags DomainMemoryModFlags) error { + result := C.virDomainSetMemoryStatsPeriod(d.ptr, C.int(period), C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetVcpus(vcpu uint) error { + result := C.virDomainSetVcpus(d.ptr, C.uint(vcpu)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SetVcpusFlags(vcpu uint, flags DomainVcpuFlags) error { + result := C.virDomainSetVcpusFlags(d.ptr, C.uint(vcpu), C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Suspend() error { + result := C.virDomainSuspend(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Resume() error { + result := C.virDomainResume(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) AbortJob() error { + result := C.virDomainAbortJob(d.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) DestroyFlags(flags DomainDestroyFlags) error { + result := C.virDomainDestroyFlags(d.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) ShutdownFlags(flags DomainShutdownFlags) error { + result := C.virDomainShutdownFlags(d.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) AttachDevice(xml string) error { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainAttachDevice(d.ptr, cXml) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) AttachDeviceFlags(xml string, flags DomainDeviceModifyFlags) error { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainAttachDeviceFlags(d.ptr, cXml, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) DetachDevice(xml string) error { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainDetachDevice(d.ptr, cXml) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) DetachDeviceFlags(xml string, flags DomainDeviceModifyFlags) error { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainDetachDeviceFlags(d.ptr, cXml, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) UpdateDeviceFlags(xml string, flags DomainDeviceModifyFlags) error { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainUpdateDeviceFlags(d.ptr, cXml, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) Screenshot(stream *Stream, screen, flags uint32) (string, error) { + cType := C.virDomainScreenshot(d.ptr, stream.ptr, C.uint(screen), C.uint(flags)) + if cType == nil { + return "", GetLastError() + } + defer C.free(unsafe.Pointer(cType)) + + mimeType := C.GoString(cType) + return mimeType, nil +} + +func (d *Domain) SendKey(codeset, holdtime uint, keycodes []uint, flags uint32) error { + result := C.virDomainSendKey(d.ptr, C.uint(codeset), C.uint(holdtime), (*C.uint)(unsafe.Pointer(&keycodes[0])), C.int(len(keycodes)), C.uint(flags)) + if result == -1 { + return GetLastError() + } + + return nil +} + +type DomainBlockStats struct { + RdBytesSet bool + RdBytes int64 + RdReqSet bool + RdReq int64 + RdTotalTimesSet bool + RdTotalTimes int64 + WrBytesSet bool + WrBytes int64 + WrReqSet bool + WrReq int64 + WrTotalTimesSet bool + WrTotalTimes int64 + FlushReqSet bool + FlushReq int64 + FlushTotalTimesSet bool + FlushTotalTimes int64 + ErrsSet bool + Errs int64 +} + +func getBlockStatsFieldInfo(params *DomainBlockStats) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_BLOCK_STATS_READ_BYTES: typedParamsFieldInfo{ + set: ¶ms.RdBytesSet, + l: ¶ms.RdBytes, + }, + C.VIR_DOMAIN_BLOCK_STATS_READ_REQ: typedParamsFieldInfo{ + set: ¶ms.RdReqSet, + l: ¶ms.RdReq, + }, + C.VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES: typedParamsFieldInfo{ + set: ¶ms.RdTotalTimesSet, + l: ¶ms.RdTotalTimes, + }, + C.VIR_DOMAIN_BLOCK_STATS_WRITE_BYTES: typedParamsFieldInfo{ + set: ¶ms.WrBytesSet, + l: ¶ms.WrBytes, + }, + C.VIR_DOMAIN_BLOCK_STATS_WRITE_REQ: typedParamsFieldInfo{ + set: ¶ms.WrReqSet, + l: ¶ms.WrReq, + }, + C.VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES: typedParamsFieldInfo{ + set: ¶ms.WrTotalTimesSet, + l: ¶ms.WrTotalTimes, + }, + C.VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ: typedParamsFieldInfo{ + set: ¶ms.FlushReqSet, + l: ¶ms.FlushReq, + }, + C.VIR_DOMAIN_BLOCK_STATS_FLUSH_TOTAL_TIMES: typedParamsFieldInfo{ + set: ¶ms.FlushTotalTimesSet, + l: ¶ms.FlushTotalTimes, + }, + C.VIR_DOMAIN_BLOCK_STATS_ERRS: typedParamsFieldInfo{ + set: ¶ms.ErrsSet, + l: ¶ms.Errs, + }, + } +} + +func (d *Domain) BlockStatsFlags(disk string, flags uint32) (*DomainBlockStats, error) { + params := &DomainBlockStats{} + info := getBlockStatsFieldInfo(params) + + var nparams C.int + + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + ret := C.virDomainBlockStatsFlags(d.ptr, cdisk, nil, &nparams, C.uint(0)) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainBlockStatsFlags(d.ptr, cdisk, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) BlockStats(path string) (*DomainBlockStats, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + size := C.size_t(unsafe.Sizeof(C.struct__virDomainBlockStats{})) + + cStats := (C.virDomainBlockStatsPtr)(C.malloc(size)) + defer C.free(unsafe.Pointer(cStats)) + + result := C.virDomainBlockStats(d.ptr, cPath, (C.virDomainBlockStatsPtr)(cStats), size) + + if result != 0 { + return nil, GetLastError() + } + return &DomainBlockStats{ + WrReqSet: true, + WrReq: int64(cStats.wr_req), + RdReqSet: true, + RdReq: int64(cStats.rd_req), + RdBytesSet: true, + RdBytes: int64(cStats.rd_bytes), + WrBytesSet: true, + WrBytes: int64(cStats.wr_bytes), + }, nil +} + +type DomainInterfaceStats struct { + RxBytesSet bool + RxBytes int64 + RxPacketsSet bool + RxPackets int64 + RxErrsSet bool + RxErrs int64 + RxDropSet bool + RxDrop int64 + TxBytesSet bool + TxBytes int64 + TxPacketsSet bool + TxPackets int64 + TxErrsSet bool + TxErrs int64 + TxDropSet bool + TxDrop int64 +} + +func (d *Domain) InterfaceStats(path string) (*DomainInterfaceStats, error) { + cPath := C.CString(path) + defer C.free(unsafe.Pointer(cPath)) + + size := C.size_t(unsafe.Sizeof(C.struct__virDomainInterfaceStats{})) + + cStats := (C.virDomainInterfaceStatsPtr)(C.malloc(size)) + defer C.free(unsafe.Pointer(cStats)) + + result := C.virDomainInterfaceStats(d.ptr, cPath, (C.virDomainInterfaceStatsPtr)(cStats), size) + + if result != 0 { + return nil, GetLastError() + } + return &DomainInterfaceStats{ + RxBytesSet: true, + RxBytes: int64(cStats.rx_bytes), + RxPacketsSet: true, + RxPackets: int64(cStats.rx_packets), + RxErrsSet: true, + RxErrs: int64(cStats.rx_errs), + RxDropSet: true, + RxDrop: int64(cStats.rx_drop), + TxBytesSet: true, + TxBytes: int64(cStats.tx_bytes), + TxPacketsSet: true, + TxPackets: int64(cStats.tx_packets), + TxErrsSet: true, + TxErrs: int64(cStats.tx_errs), + TxDropSet: true, + TxDrop: int64(cStats.tx_drop), + }, nil +} + +func (d *Domain) MemoryStats(nrStats uint32, flags uint32) ([]DomainMemoryStat, error) { + ptr := make([]C.virDomainMemoryStatStruct, nrStats) + + result := C.virDomainMemoryStats( + d.ptr, (C.virDomainMemoryStatPtr)(unsafe.Pointer(&ptr[0])), + C.uint(nrStats), C.uint(flags)) + + if result == -1 { + return []DomainMemoryStat{}, GetLastError() + } + + out := make([]DomainMemoryStat, result) + for i := 0; i < int(result); i++ { + out = append(out, DomainMemoryStat{ + Tag: int32(ptr[i].tag), + Val: uint64(ptr[i].val), + }) + } + return out, nil +} + +func (d *Domain) GetVcpus() ([]DomainVcpuInfo, error) { + var cnodeinfo C.virNodeInfo + ret := C.virNodeGetInfo(C.virDomainGetConnect(d.ptr), &cnodeinfo) + if ret == -1 { + return []DomainVcpuInfo{}, GetLastError() + } + + var cdominfo C.virDomainInfo + ret = C.virDomainGetInfo(d.ptr, &cdominfo) + if ret == -1 { + return []DomainVcpuInfo{}, GetLastError() + } + + nvcpus := int(cdominfo.nrVirtCpu) + npcpus := int(cnodeinfo.nodes * cnodeinfo.sockets * cnodeinfo.cores * cnodeinfo.threads) + maplen := ((npcpus + 7) / 8) + ccpumaps := make([]C.uchar, maplen*nvcpus) + cinfo := make([]C.virVcpuInfo, nvcpus) + + ret = C.virDomainGetVcpus(d.ptr, &cinfo[0], C.int(nvcpus), &ccpumaps[0], C.int(maplen)) + if ret == -1 { + return []DomainVcpuInfo{}, GetLastError() + } + + info := make([]DomainVcpuInfo, int(ret)) + for i := 0; i < int(ret); i++ { + affinity := make([]bool, npcpus) + for j := 0; j < npcpus; j++ { + byte := (i * maplen) + (j / 8) + bit := j % 8 + + affinity[j] = (ccpumaps[byte] & (1 << uint(bit))) != 0 + } + + info[i] = DomainVcpuInfo{ + Number: uint32(cinfo[i].number), + State: int32(cinfo[i].state), + CpuTime: uint64(cinfo[i].cpuTime), + Cpu: int32(cinfo[i].cpu), + CpuMap: affinity, + } + } + + return info, nil +} + +func (d *Domain) GetVcpusFlags(flags DomainVcpuFlags) (int32, error) { + result := C.virDomainGetVcpusFlags(d.ptr, C.uint(flags)) + if result == -1 { + return 0, GetLastError() + } + return int32(result), nil +} + +func (d *Domain) PinVcpu(vcpu uint, cpuMap []bool) error { + maplen := (len(cpuMap) + 7) / 8 + ccpumap := make([]C.uchar, maplen) + for i := 0; i < len(cpuMap); i++ { + if cpuMap[i] { + byte := i / 8 + bit := i % 8 + ccpumap[byte] |= (1 << uint(bit)) + } + } + + result := C.virDomainPinVcpu(d.ptr, C.uint(vcpu), &ccpumap[0], C.int(maplen)) + + if result == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) PinVcpuFlags(vcpu uint, cpuMap []bool, flags DomainModificationImpact) error { + maplen := (len(cpuMap) + 7) / 8 + ccpumap := make([]C.uchar, maplen) + for i := 0; i < len(cpuMap); i++ { + if cpuMap[i] { + byte := i / 8 + bit := i % 8 + ccpumap[byte] |= (1 << uint(bit)) + } + } + + result := C.virDomainPinVcpuFlags(d.ptr, C.uint(vcpu), &ccpumap[0], C.int(maplen), C.uint(flags)) + + if result == -1 { + return GetLastError() + } + + return nil +} + +type DomainIPAddress struct { + Type int + Addr string + Prefix uint +} + +type DomainInterface struct { + Name string + Hwaddr string + Addrs []DomainIPAddress +} + +func (d *Domain) ListAllInterfaceAddresses(src DomainInterfaceAddressesSource) ([]DomainInterface, error) { + if C.LIBVIR_VERSION_NUMBER < 1002014 { + return []DomainInterface{}, GetNotImplementedError("virDomainInterfaceAddresses") + } + + var cList *C.virDomainInterfacePtr + numIfaces := int(C.virDomainInterfaceAddressesCompat(d.ptr, (**C.virDomainInterfacePtr)(&cList), C.uint(src), 0)) + if numIfaces == -1 { + return nil, GetLastError() + } + + ifaces := make([]DomainInterface, numIfaces) + + for i := 0; i < numIfaces; i++ { + var ciface *C.virDomainInterface + ciface = *(**C.virDomainInterface)(unsafe.Pointer(uintptr(unsafe.Pointer(cList)) + (unsafe.Sizeof(ciface) * uintptr(i)))) + + ifaces[i].Name = C.GoString(ciface.name) + ifaces[i].Hwaddr = C.GoString(ciface.hwaddr) + + numAddr := int(ciface.naddrs) + + ifaces[i].Addrs = make([]DomainIPAddress, numAddr) + + for k := 0; k < numAddr; k++ { + var caddr *C.virDomainIPAddress + caddr = (*C.virDomainIPAddress)(unsafe.Pointer(uintptr(unsafe.Pointer(ciface.addrs)) + (unsafe.Sizeof(*caddr) * uintptr(k)))) + ifaces[i].Addrs[k] = DomainIPAddress{} + ifaces[i].Addrs[k].Type = int(caddr._type) + ifaces[i].Addrs[k].Addr = C.GoString(caddr.addr) + ifaces[i].Addrs[k].Prefix = uint(caddr.prefix) + + } + C.virDomainInterfaceFreeCompat(ciface) + } + C.free(unsafe.Pointer(cList)) + return ifaces, nil +} + +func (d *Domain) SnapshotCurrent(flags uint32) (*DomainSnapshot, error) { + result := C.virDomainSnapshotCurrent(d.ptr, C.uint(flags)) + if result == nil { + return nil, GetLastError() + } + return &DomainSnapshot{ptr: result}, nil + +} + +func (d *Domain) SnapshotNum(flags DomainSnapshotListFlags) (int, error) { + result := int(C.virDomainSnapshotNum(d.ptr, C.uint(flags))) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (d *Domain) SnapshotLookupByName(name string, flags uint32) (*DomainSnapshot, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virDomainSnapshotLookupByName(d.ptr, cName, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &DomainSnapshot{ptr: ptr}, nil +} + +func (d *Domain) SnapshotListNames(flags DomainSnapshotListFlags) ([]string, error) { + const maxNames = 1024 + var names [maxNames](*C.char) + namesPtr := unsafe.Pointer(&names) + numNames := C.virDomainSnapshotListNames( + d.ptr, + (**C.char)(namesPtr), + maxNames, C.uint(flags)) + if numNames == -1 { + return nil, GetLastError() + } + goNames := make([]string, numNames) + for k := 0; k < int(numNames); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (d *Domain) ListAllSnapshots(flags DomainSnapshotListFlags) ([]DomainSnapshot, error) { + var cList *C.virDomainSnapshotPtr + numVols := C.virDomainListAllSnapshots(d.ptr, (**C.virDomainSnapshotPtr)(&cList), C.uint(flags)) + if numVols == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numVols), + Cap: int(numVols), + } + var pools []DomainSnapshot + slice := *(*[]C.virDomainSnapshotPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, DomainSnapshot{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} + +func (d *Domain) BlockCommit(disk string, base string, top string, bandwidth uint64, flags DomainBlockCommitFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + var cbase *C.char + if base != "" { + cbase = C.CString(base) + defer C.free(unsafe.Pointer(cbase)) + } + var ctop *C.char + if top != "" { + ctop = C.CString(top) + defer C.free(unsafe.Pointer(ctop)) + } + ret := C.virDomainBlockCommit(d.ptr, cdisk, cbase, ctop, C.ulong(bandwidth), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +type DomainBlockCopyParameters struct { + BandwidthSet bool + Bandwidth uint64 + GranularitySet bool + Granularity uint + BufSizeSet bool + BufSize uint64 +} + +func getBlockCopyParameterFieldInfo(params *DomainBlockCopyParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_BLOCK_COPY_BANDWIDTH: typedParamsFieldInfo{ + set: ¶ms.BandwidthSet, + ul: ¶ms.Bandwidth, + }, + C.VIR_DOMAIN_BLOCK_COPY_GRANULARITY: typedParamsFieldInfo{ + set: ¶ms.GranularitySet, + ui: ¶ms.Granularity, + }, + C.VIR_DOMAIN_BLOCK_COPY_BUF_SIZE: typedParamsFieldInfo{ + set: ¶ms.BufSizeSet, + ul: ¶ms.BufSize, + }, + } +} + +func (d *Domain) BlockCopy(disk string, destxml string, params *DomainBlockCopyParameters, flags DomainBlockCopyFlags) error { + if C.LIBVIR_VERSION_NUMBER < 1002008 { + return GetNotImplementedError("virDomainBlockCopy") + } + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + cdestxml := C.CString(destxml) + defer C.free(unsafe.Pointer(cdestxml)) + + info := getBlockCopyParameterFieldInfo(params) + + cparams, err := typedParamsPackNew(info) + if err != nil { + return err + } + nparams := len(*cparams) + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams)) + + ret := C.virDomainBlockCopyCompat(d.ptr, cdisk, cdestxml, (*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) BlockJobAbort(disk string, flags DomainBlockJobAbortFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + ret := C.virDomainBlockJobAbort(d.ptr, cdisk, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) BlockJobSetSpeed(disk string, bandwidth uint64, flags DomainBlockJobSetSpeedFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + ret := C.virDomainBlockJobSetSpeed(d.ptr, cdisk, C.ulong(bandwidth), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) BlockPull(disk string, bandwidth uint64, flags DomainBlockPullFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + ret := C.virDomainBlockPull(d.ptr, cdisk, C.ulong(bandwidth), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) BlockRebase(disk string, base string, bandwidth uint64, flags DomainBlockRebaseFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + var cbase *C.char + if base != "" { + cbase := C.CString(base) + defer C.free(unsafe.Pointer(cbase)) + } + ret := C.virDomainBlockRebase(d.ptr, cdisk, cbase, C.ulong(bandwidth), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) BlockResize(disk string, size uint64, flags DomainBlockResizeFlags) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + ret := C.virDomainBlockResize(d.ptr, cdisk, C.ulonglong(size), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) BlockPeek(disk string, offset uint64, size uint64, flags uint32) ([]byte, error) { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + data := make([]byte, size) + ret := C.virDomainBlockPeek(d.ptr, cdisk, C.ulonglong(offset), C.size_t(size), + unsafe.Pointer(&data[0]), C.uint(flags)) + if ret == -1 { + return []byte{}, GetLastError() + } + + return data, nil +} + +func (d *Domain) MemoryPeek(start uint64, size uint64, flags DomainMemoryFlags) ([]byte, error) { + data := make([]byte, size) + ret := C.virDomainMemoryPeek(d.ptr, C.ulonglong(start), C.size_t(size), + unsafe.Pointer(&data[0]), C.uint(flags)) + if ret == -1 { + return []byte{}, GetLastError() + } + + return data, nil +} + +func (d *Domain) Migrate(dconn *Connect, flags DomainMigrateFlags, dname string, uri string, bandwidth uint64) (*Domain, error) { + var cdname *C.char + if dname != "" { + cdname = C.CString(dname) + defer C.free(unsafe.Pointer(cdname)) + } + var curi *C.char + if uri != "" { + curi = C.CString(uri) + defer C.free(unsafe.Pointer(curi)) + } + + ret := C.virDomainMigrate(d.ptr, dconn.ptr, C.ulong(flags), cdname, curi, C.ulong(bandwidth)) + if ret == nil { + return nil, GetLastError() + } + + return &Domain{ + ptr: ret, + }, nil +} + +func (d *Domain) Migrate2(dconn *Connect, dxml string, flags DomainMigrateFlags, dname string, uri string, bandwidth uint64) (*Domain, error) { + var cdxml *C.char + if dxml != "" { + cdxml = C.CString(dxml) + defer C.free(unsafe.Pointer(cdxml)) + } + var cdname *C.char + if dname != "" { + cdname = C.CString(dname) + defer C.free(unsafe.Pointer(cdname)) + } + var curi *C.char + if uri != "" { + curi = C.CString(uri) + defer C.free(unsafe.Pointer(curi)) + } + + ret := C.virDomainMigrate2(d.ptr, dconn.ptr, cdxml, C.ulong(flags), cdname, curi, C.ulong(bandwidth)) + if ret == nil { + return nil, GetLastError() + } + + return &Domain{ + ptr: ret, + }, nil +} + +type DomainMigrateParameters struct { + URISet bool + URI string + DestNameSet bool + DestName string + DestXMLSet bool + DestXML string + PersistXMLSet bool + PersistXML string + BandwidthSet bool + Bandwidth uint64 + GraphicsURISet bool + GraphicsURI string + ListenAddressSet bool + ListenAddress string + MigrateDisksSet bool + MigrateDisks []string + DisksPortSet bool + DisksPort int + CompressionSet bool + Compression string + CompressionMTLevelSet bool + CompressionMTLevel int + CompressionMTThreadsSet bool + CompressionMTThreads int + CompressionMTDThreadsSet bool + CompressionMTDThreads int + CompressionXBZRLECacheSet bool + CompressionXBZRLECache uint64 + AutoConvergeInitialSet bool + AutoConvergeInitial int + AutoConvergeIncrementSet bool + AutoConvergeIncrement int +} + +func getMigrateParameterFieldInfo(params *DomainMigrateParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_MIGRATE_PARAM_URI: typedParamsFieldInfo{ + set: ¶ms.URISet, + s: ¶ms.URI, + }, + C.VIR_MIGRATE_PARAM_DEST_NAME: typedParamsFieldInfo{ + set: ¶ms.DestNameSet, + s: ¶ms.DestName, + }, + C.VIR_MIGRATE_PARAM_DEST_XML: typedParamsFieldInfo{ + set: ¶ms.DestXMLSet, + s: ¶ms.DestXML, + }, + C.VIR_MIGRATE_PARAM_PERSIST_XML: typedParamsFieldInfo{ + set: ¶ms.PersistXMLSet, + s: ¶ms.PersistXML, + }, + C.VIR_MIGRATE_PARAM_BANDWIDTH: typedParamsFieldInfo{ + set: ¶ms.BandwidthSet, + ul: ¶ms.Bandwidth, + }, + C.VIR_MIGRATE_PARAM_GRAPHICS_URI: typedParamsFieldInfo{ + set: ¶ms.GraphicsURISet, + s: ¶ms.GraphicsURI, + }, + C.VIR_MIGRATE_PARAM_LISTEN_ADDRESS: typedParamsFieldInfo{ + set: ¶ms.ListenAddressSet, + s: ¶ms.ListenAddress, + }, + C.VIR_MIGRATE_PARAM_MIGRATE_DISKS: typedParamsFieldInfo{ + set: ¶ms.MigrateDisksSet, + sl: ¶ms.MigrateDisks, + }, + C.VIR_MIGRATE_PARAM_DISKS_PORT: typedParamsFieldInfo{ + set: ¶ms.DisksPortSet, + i: ¶ms.DisksPort, + }, + C.VIR_MIGRATE_PARAM_COMPRESSION: typedParamsFieldInfo{ + set: ¶ms.CompressionSet, + s: ¶ms.Compression, + }, + C.VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL: typedParamsFieldInfo{ + set: ¶ms.CompressionMTLevelSet, + i: ¶ms.CompressionMTLevel, + }, + C.VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS: typedParamsFieldInfo{ + set: ¶ms.CompressionMTThreadsSet, + i: ¶ms.CompressionMTThreads, + }, + C.VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS: typedParamsFieldInfo{ + set: ¶ms.CompressionMTDThreadsSet, + i: ¶ms.CompressionMTDThreads, + }, + C.VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE: typedParamsFieldInfo{ + set: ¶ms.CompressionXBZRLECacheSet, + ul: ¶ms.CompressionXBZRLECache, + }, + C.VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL: typedParamsFieldInfo{ + set: ¶ms.AutoConvergeInitialSet, + i: ¶ms.AutoConvergeInitial, + }, + C.VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT: typedParamsFieldInfo{ + set: ¶ms.AutoConvergeIncrementSet, + i: ¶ms.AutoConvergeIncrement, + }, + } +} + +func (d *Domain) Migrate3(dconn *Connect, params *DomainMigrateParameters, flags DomainMigrateFlags) (*Domain, error) { + + info := getMigrateParameterFieldInfo(params) + cparams, err := typedParamsPackNew(info) + if err != nil { + return nil, err + } + nparams := len(*cparams) + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams)) + + ret := C.virDomainMigrate3(d.ptr, dconn.ptr, (*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.uint(nparams), C.uint(flags)) + if ret == nil { + return nil, GetLastError() + } + + return &Domain{ + ptr: ret, + }, nil +} + +func (d *Domain) MigrateToURI(duri string, flags DomainMigrateFlags, dname string, bandwidth uint64) error { + cduri := C.CString(duri) + defer C.free(unsafe.Pointer(cduri)) + + var cdname *C.char + if dname != "" { + cdname = C.CString(dname) + defer C.free(unsafe.Pointer(cdname)) + } + + ret := C.virDomainMigrateToURI(d.ptr, cduri, C.ulong(flags), cdname, C.ulong(bandwidth)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateToURI2(dconnuri string, miguri string, dxml string, flags DomainMigrateFlags, dname string, bandwidth uint64) error { + var cdconnuri *C.char + if dconnuri != "" { + cdconnuri = C.CString(dconnuri) + defer C.free(unsafe.Pointer(cdconnuri)) + } + var cmiguri *C.char + if miguri != "" { + cmiguri = C.CString(miguri) + defer C.free(unsafe.Pointer(cmiguri)) + } + var cdxml *C.char + if dxml != "" { + cdxml = C.CString(dxml) + defer C.free(unsafe.Pointer(cdxml)) + } + var cdname *C.char + if dname != "" { + cdname = C.CString(dname) + defer C.free(unsafe.Pointer(cdname)) + } + + ret := C.virDomainMigrateToURI2(d.ptr, cdconnuri, cmiguri, cdxml, C.ulong(flags), cdname, C.ulong(bandwidth)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateToURI3(dconnuri string, params *DomainMigrateParameters, flags DomainMigrateFlags) error { + var cdconnuri *C.char + if dconnuri != "" { + cdconnuri = C.CString(dconnuri) + defer C.free(unsafe.Pointer(cdconnuri)) + } + + info := getMigrateParameterFieldInfo(params) + cparams, err := typedParamsPackNew(info) + if err != nil { + return err + } + nparams := len(*cparams) + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.int(nparams)) + + ret := C.virDomainMigrateToURI3(d.ptr, cdconnuri, (*C.virTypedParameter)(unsafe.Pointer(&(*cparams)[0])), C.uint(nparams), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateGetCompressionCache(flags uint32) (uint64, error) { + var cacheSize C.ulonglong + + ret := C.virDomainMigrateGetCompressionCache(d.ptr, &cacheSize, C.uint(flags)) + if ret == -1 { + return 0, GetLastError() + } + + return uint64(cacheSize), nil +} + +func (d *Domain) MigrateSetCompressionCache(size uint64, flags uint32) error { + ret := C.virDomainMigrateSetCompressionCache(d.ptr, C.ulonglong(size), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateGetMaxSpeed(flags uint32) (uint64, error) { + var maxSpeed C.ulong + + ret := C.virDomainMigrateGetMaxSpeed(d.ptr, &maxSpeed, C.uint(flags)) + if ret == -1 { + return 0, GetLastError() + } + + return uint64(maxSpeed), nil +} + +func (d *Domain) MigrateSetMaxSpeed(speed uint64, flags uint32) error { + ret := C.virDomainMigrateSetMaxSpeed(d.ptr, C.ulong(speed), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateSetMaxDowntime(downtime uint64, flags uint32) error { + ret := C.virDomainMigrateSetMaxDowntime(d.ptr, C.ulonglong(downtime), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) MigrateStartPostCopy(flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 1003003 { + return GetNotImplementedError("virDomainMigrateStartPostCopy") + } + + ret := C.virDomainMigrateStartPostCopyCompat(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +type DomainBlkioParameters struct { + WeightSet bool + Weight uint + DeviceWeightSet bool + DeviceWeight string + DeviceReadIopsSet bool + DeviceReadIops string + DeviceWriteIopsSet bool + DeviceWriteIops string + DeviceReadBpsSet bool + DeviceReadBps string + DeviceWriteBpsSet bool + DeviceWriteBps string +} + +func getBlkioParametersFieldInfo(params *DomainBlkioParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_BLKIO_WEIGHT: typedParamsFieldInfo{ + set: ¶ms.WeightSet, + ui: ¶ms.Weight, + }, + C.VIR_DOMAIN_BLKIO_DEVICE_WEIGHT: typedParamsFieldInfo{ + set: ¶ms.DeviceWeightSet, + s: ¶ms.DeviceWeight, + }, + C.VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS: typedParamsFieldInfo{ + set: ¶ms.DeviceReadIopsSet, + s: ¶ms.DeviceReadIops, + }, + C.VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS: typedParamsFieldInfo{ + set: ¶ms.DeviceWriteIopsSet, + s: ¶ms.DeviceWriteIops, + }, + C.VIR_DOMAIN_BLKIO_DEVICE_READ_BPS: typedParamsFieldInfo{ + set: ¶ms.DeviceReadBpsSet, + s: ¶ms.DeviceReadBps, + }, + C.VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS: typedParamsFieldInfo{ + set: ¶ms.DeviceWriteBpsSet, + s: ¶ms.DeviceWriteBps, + }, + } +} + +func (d *Domain) GetBlkioParameters(flags DomainModificationImpact) (*DomainBlkioParameters, error) { + params := &DomainBlkioParameters{} + info := getBlkioParametersFieldInfo(params) + + var nparams C.int + ret := C.virDomainGetBlkioParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetBlkioParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetBlkioParameters(params *DomainBlkioParameters, flags DomainModificationImpact) error { + info := getBlkioParametersFieldInfo(params) + + var nparams C.int + + ret := C.virDomainGetBlkioParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetBlkioParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetBlkioParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +type DomainBlockIoTuneParameters struct { + TotalBytesSecSet bool + TotalBytesSec uint64 + ReadBytesSecSet bool + ReadBytesSec uint64 + WriteBytesSecSet bool + WriteBytesSec uint64 + TotalIopsSecSet bool + TotalIopsSec uint64 + ReadIopsSecSet bool + ReadIopsSec uint64 + WriteIopsSecSet bool + WriteIopsSec uint64 + TotalBytesSecMaxSet bool + TotalBytesSecMax uint64 + ReadBytesSecMaxSet bool + ReadBytesSecMax uint64 + WriteBytesSecMaxSet bool + WriteBytesSecMax uint64 + TotalIopsSecMaxSet bool + TotalIopsSecMax uint64 + ReadIopsSecMaxSet bool + ReadIopsSecMax uint64 + WriteIopsSecMaxSet bool + WriteIopsSecMax uint64 + TotalBytesSecMaxLengthSet bool + TotalBytesSecMaxLength uint64 + ReadBytesSecMaxLengthSet bool + ReadBytesSecMaxLength uint64 + WriteBytesSecMaxLengthSet bool + WriteBytesSecMaxLength uint64 + TotalIopsSecMaxLengthSet bool + TotalIopsSecMaxLength uint64 + ReadIopsSecMaxLengthSet bool + ReadIopsSecMaxLength uint64 + WriteIopsSecMaxLengthSet bool + WriteIopsSecMaxLength uint64 + SizeIopsSecSet bool + SizeIopsSec uint64 + GroupNameSet bool + GroupName string +} + +func getBlockIoTuneParametersFieldInfo(params *DomainBlockIoTuneParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecSet, + ul: ¶ms.TotalBytesSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecSet, + ul: ¶ms.ReadBytesSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecSet, + ul: ¶ms.WriteBytesSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecSet, + ul: ¶ms.TotalIopsSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecSet, + ul: ¶ms.ReadIopsSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecSet, + ul: ¶ms.WriteIopsSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecMaxSet, + ul: ¶ms.TotalBytesSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecMaxSet, + ul: ¶ms.ReadBytesSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecMaxSet, + ul: ¶ms.WriteBytesSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecMaxSet, + ul: ¶ms.TotalIopsSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecMaxSet, + ul: ¶ms.ReadIopsSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecMaxSet, + ul: ¶ms.WriteIopsSecMax, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecMaxLengthSet, + ul: ¶ms.TotalBytesSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecMaxLengthSet, + ul: ¶ms.ReadBytesSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecMaxLengthSet, + ul: ¶ms.WriteBytesSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecMaxLengthSet, + ul: ¶ms.TotalIopsSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecMaxLengthSet, + ul: ¶ms.ReadIopsSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecMaxLengthSet, + ul: ¶ms.WriteIopsSecMaxLength, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.SizeIopsSecSet, + ul: ¶ms.SizeIopsSec, + }, + C.VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME: typedParamsFieldInfo{ + set: ¶ms.GroupNameSet, + s: ¶ms.GroupName, + }, + } +} + +func (d *Domain) GetBlockIoTune(disk string, flags DomainModificationImpact) (*DomainBlockIoTuneParameters, error) { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + + params := &DomainBlockIoTuneParameters{} + info := getBlockIoTuneParametersFieldInfo(params) + + var nparams C.int + ret := C.virDomainGetBlockIoTune(d.ptr, cdisk, nil, &nparams, 0) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetBlockIoTune(d.ptr, cdisk, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetBlockIoTune(disk string, params *DomainBlockIoTuneParameters, flags DomainModificationImpact) error { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + + info := getBlockIoTuneParametersFieldInfo(params) + + var nparams C.int + + ret := C.virDomainGetBlockIoTune(d.ptr, cdisk, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetBlockIoTune(d.ptr, cdisk, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetBlockIoTune(d.ptr, cdisk, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +type DomainBlockJobInfo struct { + Type DomainBlockJobType + Bandwidth uint64 + Cur uint64 + End uint64 +} + +func (d *Domain) GetBlockJobInfo(disk string, flags DomainBlockJobInfoFlags) (*DomainBlockJobInfo, error) { + cdisk := C.CString(disk) + defer C.free(unsafe.Pointer(cdisk)) + + var cinfo C.virDomainBlockJobInfo + + ret := C.virDomainGetBlockJobInfo(d.ptr, cdisk, &cinfo, C.uint(flags)) + + if ret == -1 { + return nil, GetLastError() + } + + return &DomainBlockJobInfo{ + Type: DomainBlockJobType(cinfo._type), + Bandwidth: uint64(cinfo.bandwidth), + Cur: uint64(cinfo.cur), + End: uint64(cinfo.end), + }, nil +} + +type DomainControlInfo struct { + State DomainControlState + Details int + StateTime uint64 +} + +func (d *Domain) GetControlInfo(flags uint32) (*DomainControlInfo, error) { + + var cinfo C.virDomainControlInfo + + ret := C.virDomainGetControlInfo(d.ptr, &cinfo, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + return &DomainControlInfo{ + State: DomainControlState(cinfo.state), + Details: int(cinfo.details), + StateTime: uint64(cinfo.stateTime), + }, nil +} + +type DomainDiskError struct { + Disk string + Error DomainDiskErrorCode +} + +func (d *Domain) GetDiskErrors(flags uint32) ([]DomainDiskError, error) { + ret := C.virDomainGetDiskErrors(d.ptr, nil, 0, 0) + if ret == -1 { + return []DomainDiskError{}, GetLastError() + } + + maxerrors := ret + cerrors := make([]C.virDomainDiskError, maxerrors) + + ret = C.virDomainGetDiskErrors(d.ptr, (*C.virDomainDiskError)(unsafe.Pointer(&cerrors[0])), C.uint(maxerrors), C.uint(flags)) + if ret == -1 { + return []DomainDiskError{}, GetLastError() + } + + errors := make([]DomainDiskError, maxerrors) + + for i, cerror := range cerrors { + errors[i] = DomainDiskError{ + Disk: C.GoString(cerror.disk), + Error: DomainDiskErrorCode(cerror.error), + } + C.free(unsafe.Pointer(cerror.disk)) + } + + return errors, nil +} + +func (d *Domain) GetHostname(flags uint32) (string, error) { + ret := C.virDomainGetHostname(d.ptr, C.uint(flags)) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +type DomainJobInfo struct { + Type DomainJobType + TimeElapsedSet bool + TimeElapsed uint64 + TimeElapsedNetSet bool + TimeElapsedNet uint64 + TimeRemainingSet bool + TimeRemaining uint64 + DowntimeSet bool + Downtime uint64 + DowntimeNetSet bool + DowntimeNet uint64 + SetupTimeSet bool + SetupTime uint64 + DataTotalSet bool + DataTotal uint64 + DataProcessedSet bool + DataProcessed uint64 + DataRemainingSet bool + DataRemaining uint64 + MemTotalSet bool + MemTotal uint64 + MemProcessedSet bool + MemProcessed uint64 + MemRemainingSet bool + MemRemaining uint64 + MemConstantSet bool + MemConstant uint64 + MemNormalSet bool + MemNormal uint64 + MemNormalBytesSet bool + MemNormalBytes uint64 + MemBpsSet bool + MemBps uint64 + MemDirtyRateSet bool + MemDirtyRate uint64 + MemIterationSet bool + MemIteration uint64 + DiskTotalSet bool + DiskTotal uint64 + DiskProcessedSet bool + DiskProcessed uint64 + DiskRemainingSet bool + DiskRemaining uint64 + DiskBpsSet bool + DiskBps uint64 + CompressionCacheSet bool + CompressionCache uint64 + CompressionBytesSet bool + CompressionBytes uint64 + CompressionPagesSet bool + CompressionPages uint64 + CompressionCacheMissesSet bool + CompressionCacheMisses uint64 + CompressionOverflowSet bool + CompressionOverflow uint64 + AutoConvergeThrottleSet bool + AutoConvergeThrottle int + OperationSet bool + Operation DomainJobOperationType +} + +func (d *Domain) GetJobInfo() (*DomainJobInfo, error) { + var cinfo C.virDomainJobInfo + + ret := C.virDomainGetJobInfo(d.ptr, &cinfo) + if ret == -1 { + return nil, GetLastError() + } + + return &DomainJobInfo{ + Type: DomainJobType(cinfo._type), + TimeElapsedSet: true, + TimeElapsed: uint64(cinfo.timeElapsed), + TimeRemainingSet: true, + TimeRemaining: uint64(cinfo.timeRemaining), + DataTotalSet: true, + DataTotal: uint64(cinfo.dataTotal), + DataProcessedSet: true, + DataProcessed: uint64(cinfo.dataProcessed), + DataRemainingSet: true, + DataRemaining: uint64(cinfo.dataRemaining), + MemTotalSet: true, + MemTotal: uint64(cinfo.memTotal), + MemProcessedSet: true, + MemProcessed: uint64(cinfo.memProcessed), + MemRemainingSet: true, + MemRemaining: uint64(cinfo.memRemaining), + DiskTotalSet: true, + DiskTotal: uint64(cinfo.fileTotal), + DiskProcessedSet: true, + DiskProcessed: uint64(cinfo.fileProcessed), + DiskRemainingSet: true, + DiskRemaining: uint64(cinfo.fileRemaining), + }, nil +} + +func getDomainJobInfoFieldInfo(params *DomainJobInfo) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_JOB_TIME_ELAPSED: typedParamsFieldInfo{ + set: ¶ms.TimeElapsedSet, + ul: ¶ms.TimeElapsed, + }, + C.VIR_DOMAIN_JOB_TIME_ELAPSED_NET: typedParamsFieldInfo{ + set: ¶ms.TimeElapsedNetSet, + ul: ¶ms.TimeElapsedNet, + }, + C.VIR_DOMAIN_JOB_TIME_REMAINING: typedParamsFieldInfo{ + set: ¶ms.TimeRemainingSet, + ul: ¶ms.TimeRemaining, + }, + C.VIR_DOMAIN_JOB_DOWNTIME: typedParamsFieldInfo{ + set: ¶ms.DowntimeSet, + ul: ¶ms.Downtime, + }, + C.VIR_DOMAIN_JOB_DOWNTIME_NET: typedParamsFieldInfo{ + set: ¶ms.DowntimeNetSet, + ul: ¶ms.DowntimeNet, + }, + C.VIR_DOMAIN_JOB_SETUP_TIME: typedParamsFieldInfo{ + set: ¶ms.SetupTimeSet, + ul: ¶ms.SetupTime, + }, + C.VIR_DOMAIN_JOB_DATA_TOTAL: typedParamsFieldInfo{ + set: ¶ms.DataTotalSet, + ul: ¶ms.DataTotal, + }, + C.VIR_DOMAIN_JOB_DATA_PROCESSED: typedParamsFieldInfo{ + set: ¶ms.DataProcessedSet, + ul: ¶ms.DataProcessed, + }, + C.VIR_DOMAIN_JOB_DATA_REMAINING: typedParamsFieldInfo{ + set: ¶ms.DataRemainingSet, + ul: ¶ms.DataRemaining, + }, + C.VIR_DOMAIN_JOB_MEMORY_TOTAL: typedParamsFieldInfo{ + set: ¶ms.MemTotalSet, + ul: ¶ms.MemTotal, + }, + C.VIR_DOMAIN_JOB_MEMORY_PROCESSED: typedParamsFieldInfo{ + set: ¶ms.MemProcessedSet, + ul: ¶ms.MemProcessed, + }, + C.VIR_DOMAIN_JOB_MEMORY_REMAINING: typedParamsFieldInfo{ + set: ¶ms.MemRemainingSet, + ul: ¶ms.MemRemaining, + }, + C.VIR_DOMAIN_JOB_MEMORY_CONSTANT: typedParamsFieldInfo{ + set: ¶ms.MemConstantSet, + ul: ¶ms.MemConstant, + }, + C.VIR_DOMAIN_JOB_MEMORY_NORMAL: typedParamsFieldInfo{ + set: ¶ms.MemNormalSet, + ul: ¶ms.MemNormal, + }, + C.VIR_DOMAIN_JOB_MEMORY_NORMAL_BYTES: typedParamsFieldInfo{ + set: ¶ms.MemNormalBytesSet, + ul: ¶ms.MemNormalBytes, + }, + C.VIR_DOMAIN_JOB_MEMORY_BPS: typedParamsFieldInfo{ + set: ¶ms.MemBpsSet, + ul: ¶ms.MemBps, + }, + C.VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE: typedParamsFieldInfo{ + set: ¶ms.MemDirtyRateSet, + ul: ¶ms.MemDirtyRate, + }, + C.VIR_DOMAIN_JOB_MEMORY_ITERATION: typedParamsFieldInfo{ + set: ¶ms.MemIterationSet, + ul: ¶ms.MemIteration, + }, + C.VIR_DOMAIN_JOB_DISK_TOTAL: typedParamsFieldInfo{ + set: ¶ms.DiskTotalSet, + ul: ¶ms.DiskTotal, + }, + C.VIR_DOMAIN_JOB_DISK_PROCESSED: typedParamsFieldInfo{ + set: ¶ms.DiskProcessedSet, + ul: ¶ms.DiskProcessed, + }, + C.VIR_DOMAIN_JOB_DISK_REMAINING: typedParamsFieldInfo{ + set: ¶ms.DiskRemainingSet, + ul: ¶ms.DiskRemaining, + }, + C.VIR_DOMAIN_JOB_DISK_BPS: typedParamsFieldInfo{ + set: ¶ms.DiskBpsSet, + ul: ¶ms.DiskBps, + }, + C.VIR_DOMAIN_JOB_COMPRESSION_CACHE: typedParamsFieldInfo{ + set: ¶ms.CompressionCacheSet, + ul: ¶ms.CompressionCache, + }, + C.VIR_DOMAIN_JOB_COMPRESSION_BYTES: typedParamsFieldInfo{ + set: ¶ms.CompressionBytesSet, + ul: ¶ms.CompressionBytes, + }, + C.VIR_DOMAIN_JOB_COMPRESSION_PAGES: typedParamsFieldInfo{ + set: ¶ms.CompressionPagesSet, + ul: ¶ms.CompressionPages, + }, + C.VIR_DOMAIN_JOB_COMPRESSION_CACHE_MISSES: typedParamsFieldInfo{ + set: ¶ms.CompressionCacheMissesSet, + ul: ¶ms.CompressionCacheMisses, + }, + C.VIR_DOMAIN_JOB_COMPRESSION_OVERFLOW: typedParamsFieldInfo{ + set: ¶ms.CompressionOverflowSet, + ul: ¶ms.CompressionOverflow, + }, + C.VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE: typedParamsFieldInfo{ + set: ¶ms.AutoConvergeThrottleSet, + i: ¶ms.AutoConvergeThrottle, + }, + C.VIR_DOMAIN_JOB_OPERATION: typedParamsFieldInfo{ + set: ¶ms.OperationSet, + i: (*int)(¶ms.Operation), + }, + } +} + +func (d *Domain) GetJobStats(flags DomainGetJobStatsFlags) (*DomainJobInfo, error) { + var cparams *C.virTypedParameter + var nparams C.int + var jobtype C.int + ret := C.virDomainGetJobStats(d.ptr, &jobtype, (*C.virTypedParameterPtr)(unsafe.Pointer(&cparams)), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + defer C.virTypedParamsFree(cparams, nparams) + + params := DomainJobInfo{} + info := getDomainJobInfoFieldInfo(¶ms) + + _, err := typedParamsUnpackLen(cparams, int(nparams), info) + if err != nil { + return nil, GetLastError() + } + + return ¶ms, nil +} + +func (d *Domain) GetMaxMemory() (uint64, error) { + ret := C.virDomainGetMaxMemory(d.ptr) + if ret == 0 { + return 0, GetLastError() + } + + return uint64(ret), nil +} + +func (d *Domain) GetMaxVcpus() (uint, error) { + ret := C.virDomainGetMaxVcpus(d.ptr) + if ret == -1 { + return 0, GetLastError() + } + + return uint(ret), nil +} + +func (d *Domain) GetOSType() (string, error) { + ret := C.virDomainGetOSType(d.ptr) + if ret == nil { + return "", GetLastError() + } + + defer C.free(unsafe.Pointer(ret)) + + return C.GoString(ret), nil +} + +type DomainMemoryParameters struct { + HardLimitSet bool + HardLimit uint64 + SoftLimitSet bool + SoftLimit uint64 + MinGuaranteeSet bool + MinGuarantee uint64 + SwapHardLimitSet bool + SwapHardLimit uint64 +} + +func getDomainMemoryParametersFieldInfo(params *DomainMemoryParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_MEMORY_HARD_LIMIT: typedParamsFieldInfo{ + set: ¶ms.HardLimitSet, + ul: ¶ms.HardLimit, + }, + C.VIR_DOMAIN_MEMORY_SOFT_LIMIT: typedParamsFieldInfo{ + set: ¶ms.SoftLimitSet, + ul: ¶ms.SoftLimit, + }, + C.VIR_DOMAIN_MEMORY_MIN_GUARANTEE: typedParamsFieldInfo{ + set: ¶ms.MinGuaranteeSet, + ul: ¶ms.MinGuarantee, + }, + C.VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT: typedParamsFieldInfo{ + set: ¶ms.SwapHardLimitSet, + ul: ¶ms.SwapHardLimit, + }, + } +} + +func (d *Domain) GetMemoryParameters(flags DomainModificationImpact) (*DomainMemoryParameters, error) { + params := &DomainMemoryParameters{} + info := getDomainMemoryParametersFieldInfo(params) + + var nparams C.int + ret := C.virDomainGetMemoryParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetMemoryParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetMemoryParameters(params *DomainMemoryParameters, flags DomainModificationImpact) error { + info := getDomainMemoryParametersFieldInfo(params) + + var nparams C.int + + ret := C.virDomainGetMemoryParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetMemoryParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetMemoryParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +type DomainNumaParameters struct { + NodesetSet bool + Nodeset string + ModeSet bool + Mode DomainNumatuneMemMode +} + +func getDomainNumaParametersFieldInfo(params *DomainNumaParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_NUMA_NODESET: typedParamsFieldInfo{ + set: ¶ms.NodesetSet, + s: ¶ms.Nodeset, + }, + C.VIR_DOMAIN_NUMA_MODE: typedParamsFieldInfo{ + set: ¶ms.ModeSet, + i: (*int)(¶ms.Mode), + }, + } +} + +func (d *Domain) GetNumaParameters(flags DomainModificationImpact) (*DomainNumaParameters, error) { + params := &DomainNumaParameters{} + info := getDomainNumaParametersFieldInfo(params) + + var nparams C.int + ret := C.virDomainGetNumaParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return nil, GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetNumaParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetNumaParameters(params *DomainNumaParameters, flags DomainModificationImpact) error { + info := getDomainNumaParametersFieldInfo(params) + + var nparams C.int + + ret := C.virDomainGetNumaParameters(d.ptr, nil, &nparams, 0) + if ret == -1 { + return GetLastError() + } + + cparams := make([]C.virTypedParameter, nparams) + ret = C.virDomainGetNumaParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetNumaParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +type DomainPerfEvents struct { + CmtSet bool + Cmt bool + MbmtSet bool + Mbmt bool + MbmlSet bool + Mbml bool + CacheMissesSet bool + CacheMisses bool + CacheReferencesSet bool + CacheReferences bool + InstructionsSet bool + Instructions bool + CpuCyclesSet bool + CpuCycles bool + BranchInstructionsSet bool + BranchInstructions bool + BranchMissesSet bool + BranchMisses bool + BusCyclesSet bool + BusCycles bool + StalledCyclesFrontendSet bool + StalledCyclesFrontend bool + StalledCyclesBackendSet bool + StalledCyclesBackend bool + RefCpuCyclesSet bool + RefCpuCycles bool + CpuClockSet bool + CpuClock bool + TaskClockSet bool + TaskClock bool + PageFaultsSet bool + PageFaults bool + ContextSwitchesSet bool + ContextSwitches bool + CpuMigrationsSet bool + CpuMigrations bool + PageFaultsMinSet bool + PageFaultsMin bool + PageFaultsMajSet bool + PageFaultsMaj bool + AlignmentFaultsSet bool + AlignmentFaults bool + EmulationFaultsSet bool + EmulationFaults bool +} + +/* Remember to also update DomainStatsPerf in connect.go when adding to the stuct above */ + +func getDomainPerfEventsFieldInfo(params *DomainPerfEvents) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_PERF_PARAM_CMT: typedParamsFieldInfo{ + set: ¶ms.CmtSet, + b: ¶ms.Cmt, + }, + C.VIR_PERF_PARAM_MBMT: typedParamsFieldInfo{ + set: ¶ms.MbmtSet, + b: ¶ms.Mbmt, + }, + C.VIR_PERF_PARAM_MBML: typedParamsFieldInfo{ + set: ¶ms.MbmlSet, + b: ¶ms.Mbml, + }, + C.VIR_PERF_PARAM_CACHE_MISSES: typedParamsFieldInfo{ + set: ¶ms.CacheMissesSet, + b: ¶ms.CacheMisses, + }, + C.VIR_PERF_PARAM_CACHE_REFERENCES: typedParamsFieldInfo{ + set: ¶ms.CacheReferencesSet, + b: ¶ms.CacheReferences, + }, + C.VIR_PERF_PARAM_INSTRUCTIONS: typedParamsFieldInfo{ + set: ¶ms.InstructionsSet, + b: ¶ms.Instructions, + }, + C.VIR_PERF_PARAM_CPU_CYCLES: typedParamsFieldInfo{ + set: ¶ms.CpuCyclesSet, + b: ¶ms.CpuCycles, + }, + C.VIR_PERF_PARAM_BRANCH_INSTRUCTIONS: typedParamsFieldInfo{ + set: ¶ms.BranchInstructionsSet, + b: ¶ms.BranchInstructions, + }, + C.VIR_PERF_PARAM_BRANCH_MISSES: typedParamsFieldInfo{ + set: ¶ms.BranchMissesSet, + b: ¶ms.BranchMisses, + }, + C.VIR_PERF_PARAM_BUS_CYCLES: typedParamsFieldInfo{ + set: ¶ms.BusCyclesSet, + b: ¶ms.BusCycles, + }, + C.VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND: typedParamsFieldInfo{ + set: ¶ms.StalledCyclesFrontendSet, + b: ¶ms.StalledCyclesFrontend, + }, + C.VIR_PERF_PARAM_STALLED_CYCLES_BACKEND: typedParamsFieldInfo{ + set: ¶ms.StalledCyclesBackendSet, + b: ¶ms.StalledCyclesBackend, + }, + C.VIR_PERF_PARAM_REF_CPU_CYCLES: typedParamsFieldInfo{ + set: ¶ms.RefCpuCyclesSet, + b: ¶ms.RefCpuCycles, + }, + C.VIR_PERF_PARAM_CPU_CLOCK: typedParamsFieldInfo{ + set: ¶ms.CpuClockSet, + b: ¶ms.CpuClock, + }, + C.VIR_PERF_PARAM_TASK_CLOCK: typedParamsFieldInfo{ + set: ¶ms.TaskClockSet, + b: ¶ms.TaskClock, + }, + C.VIR_PERF_PARAM_PAGE_FAULTS: typedParamsFieldInfo{ + set: ¶ms.PageFaultsSet, + b: ¶ms.PageFaults, + }, + C.VIR_PERF_PARAM_CONTEXT_SWITCHES: typedParamsFieldInfo{ + set: ¶ms.ContextSwitchesSet, + b: ¶ms.ContextSwitches, + }, + C.VIR_PERF_PARAM_CPU_MIGRATIONS: typedParamsFieldInfo{ + set: ¶ms.CpuMigrationsSet, + b: ¶ms.CpuMigrations, + }, + C.VIR_PERF_PARAM_PAGE_FAULTS_MIN: typedParamsFieldInfo{ + set: ¶ms.PageFaultsMinSet, + b: ¶ms.PageFaultsMin, + }, + C.VIR_PERF_PARAM_PAGE_FAULTS_MAJ: typedParamsFieldInfo{ + set: ¶ms.PageFaultsMajSet, + b: ¶ms.PageFaultsMaj, + }, + C.VIR_PERF_PARAM_ALIGNMENT_FAULTS: typedParamsFieldInfo{ + set: ¶ms.AlignmentFaultsSet, + b: ¶ms.AlignmentFaults, + }, + C.VIR_PERF_PARAM_EMULATION_FAULTS: typedParamsFieldInfo{ + set: ¶ms.EmulationFaultsSet, + b: ¶ms.EmulationFaults, + }, + } +} + +func (d *Domain) GetPerfEvents(flags DomainModificationImpact) (*DomainPerfEvents, error) { + if C.LIBVIR_VERSION_NUMBER < 1003003 { + return nil, GetNotImplementedError("virDomainGetPerfEvents") + } + + params := &DomainPerfEvents{} + info := getDomainPerfEventsFieldInfo(params) + + var cparams *C.virTypedParameter + var nparams C.int + ret := C.virDomainGetPerfEventsCompat(d.ptr, (*C.virTypedParameterPtr)(unsafe.Pointer(&cparams)), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsFree(cparams, nparams) + + _, err := typedParamsUnpackLen(cparams, int(nparams), info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetPerfEvents(params *DomainPerfEvents, flags DomainModificationImpact) error { + if C.LIBVIR_VERSION_NUMBER < 1003003 { + return GetNotImplementedError("virDomainSetPerfEvents") + } + + info := getDomainPerfEventsFieldInfo(params) + + var cparams *C.virTypedParameter + var nparams C.int + ret := C.virDomainGetPerfEventsCompat(d.ptr, (*C.virTypedParameterPtr)(unsafe.Pointer(&cparams)), &nparams, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + defer C.virTypedParamsFree(cparams, nparams) + + err := typedParamsPackLen(cparams, int(nparams), info) + if err != nil { + return err + } + + ret = C.virDomainSetPerfEventsCompat(d.ptr, cparams, nparams, C.uint(flags)) + + return nil +} + +type DomainSchedulerParameters struct { + Type string + CpuSharesSet bool + CpuShares uint64 + GlobalPeriodSet bool + GlobalPeriod uint64 + GlobalQuotaSet bool + GlobalQuota uint64 + VcpuPeriodSet bool + VcpuPeriod uint64 + VcpuQuotaSet bool + VcpuQuota uint64 + EmulatorPeriodSet bool + EmulatorPeriod uint64 + EmulatorQuotaSet bool + EmulatorQuota uint64 + IothreadPeriodSet bool + IothreadPeriod uint64 + IothreadQuotaSet bool + IothreadQuota uint64 + WeightSet bool + Weight uint + CapSet bool + Cap uint + ReservationSet bool + Reservation int64 + LimitSet bool + Limit int64 + SharesSet bool + Shares int +} + +func getDomainSchedulerParametersFieldInfo(params *DomainSchedulerParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_SCHEDULER_CPU_SHARES: typedParamsFieldInfo{ + set: ¶ms.CpuSharesSet, + ul: ¶ms.CpuShares, + }, + C.VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD: typedParamsFieldInfo{ + set: ¶ms.GlobalPeriodSet, + ul: ¶ms.GlobalPeriod, + }, + C.VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA: typedParamsFieldInfo{ + set: ¶ms.GlobalQuotaSet, + ul: ¶ms.GlobalQuota, + }, + C.VIR_DOMAIN_SCHEDULER_EMULATOR_PERIOD: typedParamsFieldInfo{ + set: ¶ms.EmulatorPeriodSet, + ul: ¶ms.EmulatorPeriod, + }, + C.VIR_DOMAIN_SCHEDULER_EMULATOR_QUOTA: typedParamsFieldInfo{ + set: ¶ms.EmulatorQuotaSet, + ul: ¶ms.EmulatorQuota, + }, + C.VIR_DOMAIN_SCHEDULER_VCPU_PERIOD: typedParamsFieldInfo{ + set: ¶ms.VcpuPeriodSet, + ul: ¶ms.VcpuPeriod, + }, + C.VIR_DOMAIN_SCHEDULER_VCPU_QUOTA: typedParamsFieldInfo{ + set: ¶ms.VcpuQuotaSet, + ul: ¶ms.VcpuQuota, + }, + C.VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD: typedParamsFieldInfo{ + set: ¶ms.IothreadPeriodSet, + ul: ¶ms.IothreadPeriod, + }, + C.VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA: typedParamsFieldInfo{ + set: ¶ms.IothreadQuotaSet, + ul: ¶ms.IothreadQuota, + }, + C.VIR_DOMAIN_SCHEDULER_WEIGHT: typedParamsFieldInfo{ + set: ¶ms.WeightSet, + ui: ¶ms.Weight, + }, + C.VIR_DOMAIN_SCHEDULER_CAP: typedParamsFieldInfo{ + set: ¶ms.CapSet, + ui: ¶ms.Cap, + }, + C.VIR_DOMAIN_SCHEDULER_RESERVATION: typedParamsFieldInfo{ + set: ¶ms.ReservationSet, + l: ¶ms.Reservation, + }, + C.VIR_DOMAIN_SCHEDULER_LIMIT: typedParamsFieldInfo{ + set: ¶ms.LimitSet, + l: ¶ms.Limit, + }, + C.VIR_DOMAIN_SCHEDULER_SHARES: typedParamsFieldInfo{ + set: ¶ms.SharesSet, + i: ¶ms.Shares, + }, + } +} + +func (d *Domain) GetSchedulerParameters() (*DomainSchedulerParameters, error) { + params := &DomainSchedulerParameters{} + info := getDomainSchedulerParametersFieldInfo(params) + + var nparams C.int + schedtype := C.virDomainGetSchedulerType(d.ptr, &nparams) + if schedtype == nil { + return nil, GetLastError() + } + + defer C.free(unsafe.Pointer(schedtype)) + if nparams == 0 { + return &DomainSchedulerParameters{ + Type: C.GoString(schedtype), + }, nil + } + + cparams := make([]C.virTypedParameter, nparams) + ret := C.virDomainGetSchedulerParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams) + if ret == -1 { + return nil, GetLastError() + } + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) GetSchedulerParametersFlags(flags DomainModificationImpact) (*DomainSchedulerParameters, error) { + params := &DomainSchedulerParameters{} + info := getDomainSchedulerParametersFieldInfo(params) + + var nparams C.int + schedtype := C.virDomainGetSchedulerType(d.ptr, &nparams) + if schedtype == nil { + return nil, GetLastError() + } + + defer C.free(unsafe.Pointer(schedtype)) + if nparams == 0 { + return &DomainSchedulerParameters{ + Type: C.GoString(schedtype), + }, nil + } + + cparams := make([]C.virTypedParameter, nparams) + ret := C.virDomainGetSchedulerParametersFlags(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + _, err := typedParamsUnpack(cparams, info) + if err != nil { + return nil, err + } + + return params, nil +} + +func (d *Domain) SetSchedulerParameters(params *DomainSchedulerParameters) error { + info := getDomainSchedulerParametersFieldInfo(params) + + var nparams C.int + schedtype := C.virDomainGetSchedulerType(d.ptr, &nparams) + if schedtype == nil { + return GetLastError() + } + + defer C.free(unsafe.Pointer(schedtype)) + if nparams == 0 { + return nil + } + + cparams := make([]C.virTypedParameter, nparams) + ret := C.virDomainGetSchedulerParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams) + if ret == -1 { + return GetLastError() + } + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetSchedulerParameters(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + return nil +} + +func (d *Domain) SetSchedulerParametersFlags(params *DomainSchedulerParameters, flags DomainModificationImpact) error { + info := getDomainSchedulerParametersFieldInfo(params) + + var nparams C.int + schedtype := C.virDomainGetSchedulerType(d.ptr, &nparams) + if schedtype == nil { + return GetLastError() + } + + defer C.free(unsafe.Pointer(schedtype)) + if nparams == 0 { + return nil + } + + cparams := make([]C.virTypedParameter, nparams) + ret := C.virDomainGetSchedulerParametersFlags(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), &nparams, 0) + if ret == -1 { + return GetLastError() + } + defer C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams) + + err := typedParamsPack(cparams, info) + if err != nil { + return err + } + + ret = C.virDomainSetSchedulerParametersFlags(d.ptr, (*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), nparams, C.uint(flags)) + + return nil +} + +type SecurityLabel struct { + Label string + Enforcing bool +} + +func (d *Domain) GetSecurityLabel() (*SecurityLabel, error) { + var clabel C.virSecurityLabel + + ret := C.virDomainGetSecurityLabel(d.ptr, &clabel) + if ret == -1 { + return nil, GetLastError() + } + + return &SecurityLabel{ + Label: C.GoString((*C.char)(unsafe.Pointer(&clabel.label))), + Enforcing: clabel.enforcing == 1, + }, nil +} + +func (d *Domain) GetSecurityLabelList() ([]SecurityLabel, error) { + var clabels *C.virSecurityLabel + + ret := C.virDomainGetSecurityLabelList(d.ptr, (*C.virSecurityLabelPtr)(unsafe.Pointer(&clabels))) + if ret == -1 { + return []SecurityLabel{}, GetLastError() + } + + labels := make([]SecurityLabel, ret) + for i := 0; i < int(ret); i++ { + var clabel *C.virSecurityLabel + clabel = (*C.virSecurityLabel)(unsafe.Pointer(uintptr(unsafe.Pointer(clabels)) + (unsafe.Sizeof(*clabel) * uintptr(i)))) + labels[i] = SecurityLabel{ + Label: C.GoString((*C.char)(unsafe.Pointer(&clabel.label))), + Enforcing: clabel.enforcing == 1, + } + } + + return labels, nil +} + +func (d *Domain) GetTime(flags uint32) (int64, uint, error) { + if C.LIBVIR_VERSION_NUMBER < 1002005 { + return 0, 0, GetNotImplementedError("virDomainGetTime") + } + var secs C.longlong + var nsecs C.uint + ret := C.virDomainGetTimeCompat(d.ptr, &secs, &nsecs, C.uint(flags)) + if ret == -1 { + return 0, 0, GetLastError() + } + + return int64(secs), uint(nsecs), nil +} + +func (d *Domain) SetTime(secs int64, nsecs uint, flags DomainSetTimeFlags) error { + if C.LIBVIR_VERSION_NUMBER < 1002005 { + return GetNotImplementedError("virDomainSetTime") + } + + ret := C.virDomainSetTimeCompat(d.ptr, C.longlong(secs), C.uint(nsecs), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) SetUserPassword(user string, password string, flags DomainSetUserPasswordFlags) error { + if C.LIBVIR_VERSION_NUMBER < 1002015 { + return GetNotImplementedError("virDomainSetUserPassword") + } + cuser := C.CString(user) + cpassword := C.CString(password) + + defer C.free(unsafe.Pointer(cuser)) + defer C.free(unsafe.Pointer(cpassword)) + + ret := C.virDomainSetUserPasswordCompat(d.ptr, cuser, cpassword, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) ManagedSave(flags DomainSaveRestoreFlags) error { + ret := C.virDomainManagedSave(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) HasManagedSaveImage(flags uint32) (bool, error) { + result := C.virDomainHasManagedSaveImage(d.ptr, C.uint(flags)) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (d *Domain) ManagedSaveRemove(flags uint32) error { + ret := C.virDomainManagedSaveRemove(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) Rename(name string, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 1002019 { + return GetNotImplementedError("virDomainRename") + } + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + ret := C.virDomainRenameCompat(d.ptr, cname, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) Reset(flags uint32) error { + ret := C.virDomainReset(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) SendProcessSignal(pid int64, signum DomainProcessSignal, flags uint32) error { + ret := C.virDomainSendProcessSignal(d.ptr, C.longlong(pid), C.uint(signum), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) InjectNMI(flags uint32) error { + ret := C.virDomainInjectNMI(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) CoreDump(to string, flags DomainCoreDumpFlags) error { + cto := C.CString(to) + defer C.free(unsafe.Pointer(cto)) + + ret := C.virDomainCoreDump(d.ptr, cto, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) CoreDumpWithFormat(to string, format DomainCoreDumpFormat, flags DomainCoreDumpFlags) error { + if C.LIBVIR_VERSION_NUMBER < 1002003 { + GetNotImplementedError("virDomainCoreDumpWithFormat") + } + cto := C.CString(to) + defer C.free(unsafe.Pointer(cto)) + + ret := C.virDomainCoreDumpWithFormatCompat(d.ptr, cto, C.uint(format), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) HasCurrentSnapshot(flags uint32) (bool, error) { + result := C.virDomainHasCurrentSnapshot(d.ptr, C.uint(flags)) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (d *Domain) FSFreeze(mounts []string, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 1002005 { + return GetNotImplementedError("virDomainFSFreeze") + } + cmounts := make([](*C.char), len(mounts)) + + for i := 0; i < len(mounts); i++ { + cmounts[i] = C.CString(mounts[i]) + defer C.free(unsafe.Pointer(cmounts[i])) + } + + nmounts := len(mounts) + ret := C.virDomainFSFreezeCompat(d.ptr, (**C.char)(unsafe.Pointer(&cmounts[0])), C.uint(nmounts), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) FSThaw(mounts []string, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 1002005 { + return GetNotImplementedError("virDomainFSThaw") + } + cmounts := make([](*C.char), len(mounts)) + + for i := 0; i < len(mounts); i++ { + cmounts[i] = C.CString(mounts[i]) + defer C.free(unsafe.Pointer(cmounts[i])) + } + + nmounts := len(mounts) + ret := C.virDomainFSThawCompat(d.ptr, (**C.char)(unsafe.Pointer(&cmounts[0])), C.uint(nmounts), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) FSTrim(mount string, minimum uint64, flags uint32) error { + cmount := C.CString(mount) + defer C.free(unsafe.Pointer(cmount)) + + ret := C.virDomainFSTrim(d.ptr, cmount, C.ulonglong(minimum), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +type DomainFSInfo struct { + MountPoint string + Name string + FSType string + DevAlias []string +} + +func (d *Domain) GetFSInfo(flags uint32) ([]DomainFSInfo, error) { + if C.LIBVIR_VERSION_NUMBER < 1002011 { + return []DomainFSInfo{}, GetNotImplementedError("virDomainGetFSInfo") + } + var cfsinfolist **C.virDomainFSInfo + + ret := C.virDomainGetFSInfoCompat(d.ptr, (**C.virDomainFSInfoPtr)(unsafe.Pointer(&cfsinfolist)), C.uint(flags)) + if ret == -1 { + return []DomainFSInfo{}, GetLastError() + } + + fsinfo := make([]DomainFSInfo, int(ret)) + + for i := 0; i < int(ret); i++ { + cfsinfo := (*C.virDomainFSInfo)(*(**C.virDomainFSInfo)(unsafe.Pointer(uintptr(unsafe.Pointer(cfsinfolist)) + (unsafe.Sizeof(*cfsinfolist) * uintptr(i))))) + + aliases := make([]string, int(cfsinfo.ndevAlias)) + for j := 0; j < int(cfsinfo.ndevAlias); j++ { + calias := (*C.char)(*(**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cfsinfo.devAlias)) + (unsafe.Sizeof(*cfsinfo) * uintptr(j))))) + aliases[j] = C.GoString(calias) + } + fsinfo[i] = DomainFSInfo{ + MountPoint: C.GoString(cfsinfo.mountpoint), + Name: C.GoString(cfsinfo.name), + FSType: C.GoString(cfsinfo.fstype), + DevAlias: aliases, + } + + C.virDomainFSInfoFreeCompat(cfsinfo) + } + C.free(unsafe.Pointer(cfsinfolist)) + + return fsinfo, nil +} + +func (d *Domain) PMSuspendForDuration(target NodeSuspendTarget, duration uint64, flags uint32) error { + ret := C.virDomainPMSuspendForDuration(d.ptr, C.uint(target), C.ulonglong(duration), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) PMWakeup(flags uint32) error { + ret := C.virDomainPMWakeup(d.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) AddIOThread(id uint, flags DomainModificationImpact) error { + if C.LIBVIR_VERSION_NUMBER < 1002015 { + return GetNotImplementedError("virDomainAddIOThread") + } + ret := C.virDomainAddIOThreadCompat(d.ptr, C.uint(id), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) DelIOThread(id uint, flags DomainModificationImpact) error { + if C.LIBVIR_VERSION_NUMBER < 1002015 { + return GetNotImplementedError("virDomainDelIOThread") + } + ret := C.virDomainDelIOThreadCompat(d.ptr, C.uint(id), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) GetEmulatorPinInfo(flags DomainModificationImpact) ([]bool, error) { + var cnodeinfo C.virNodeInfo + ret := C.virNodeGetInfo(C.virDomainGetConnect(d.ptr), &cnodeinfo) + if ret == -1 { + return []bool{}, GetLastError() + } + + ncpus := cnodeinfo.nodes * cnodeinfo.sockets * cnodeinfo.cores * cnodeinfo.threads + maplen := int((ncpus + 7) / 8) + ccpumaps := make([]C.uchar, maplen) + ret = C.virDomainGetEmulatorPinInfo(d.ptr, &ccpumaps[0], C.int(maplen), C.uint(flags)) + if ret == -1 { + return []bool{}, GetLastError() + } + + cpumaps := make([]bool, ncpus) + for i := 0; i < int(ncpus); i++ { + byte := i / 8 + bit := i % 8 + cpumaps[i] = (ccpumaps[byte] & (1 << uint(bit))) != 0 + } + + return cpumaps, nil +} + +type DomainIOThreadInfo struct { + IOThreadID uint + CpuMap []bool +} + +func (d *Domain) GetIOThreadInfo(flags DomainModificationImpact) ([]DomainIOThreadInfo, error) { + if C.LIBVIR_VERSION_NUMBER < 1002014 { + return []DomainIOThreadInfo{}, GetNotImplementedError("virDomaingetIOThreadInfo") + } + var cinfolist **C.virDomainIOThreadInfo + + ret := C.virDomainGetIOThreadInfoCompat(d.ptr, (**C.virDomainIOThreadInfoPtr)(unsafe.Pointer(&cinfolist)), C.uint(flags)) + if ret == -1 { + return []DomainIOThreadInfo{}, GetLastError() + } + + info := make([]DomainIOThreadInfo, int(ret)) + + for i := 0; i < int(ret); i++ { + cinfo := (*(**C.virDomainIOThreadInfo)(unsafe.Pointer(uintptr(unsafe.Pointer(cinfolist)) + (unsafe.Sizeof(*cinfolist) * uintptr(i))))) + + ncpus := int(cinfo.cpumaplen * 8) + cpumap := make([]bool, ncpus) + for j := 0; j < ncpus; j++ { + byte := j / 8 + bit := j % 8 + + cpumapbyte := *(*C.uchar)(unsafe.Pointer(uintptr(unsafe.Pointer(cinfo.cpumap)) + (unsafe.Sizeof(*cinfo.cpumap) * uintptr(byte)))) + cpumap[j] = (cpumapbyte & (1 << uint(bit))) != 0 + } + + info[i] = DomainIOThreadInfo{ + IOThreadID: uint(cinfo.iothread_id), + CpuMap: cpumap, + } + + C.virDomainIOThreadInfoFreeCompat(cinfo) + } + C.free(unsafe.Pointer(cinfolist)) + + return info, nil +} + +func (d *Domain) GetVcpuPinInfo(flags DomainModificationImpact) ([][]bool, error) { + var cnodeinfo C.virNodeInfo + ret := C.virNodeGetInfo(C.virDomainGetConnect(d.ptr), &cnodeinfo) + if ret == -1 { + return [][]bool{}, GetLastError() + } + + var cdominfo C.virDomainInfo + ret = C.virDomainGetInfo(d.ptr, &cdominfo) + if ret == -1 { + return [][]bool{}, GetLastError() + } + + nvcpus := int(cdominfo.nrVirtCpu) + npcpus := int(cnodeinfo.nodes * cnodeinfo.sockets * cnodeinfo.cores * cnodeinfo.threads) + maplen := ((npcpus + 7) / 8) + ccpumaps := make([]C.uchar, maplen*nvcpus) + + ret = C.virDomainGetVcpuPinInfo(d.ptr, C.int(nvcpus), &ccpumaps[0], C.int(maplen), C.uint(flags)) + if ret == -1 { + return [][]bool{}, GetLastError() + } + + cpumaps := make([][]bool, nvcpus) + for i := 0; i < nvcpus; i++ { + cpumaps[i] = make([]bool, npcpus) + for j := 0; j < npcpus; j++ { + byte := (i * maplen) + (j / 8) + bit := j % 8 + + if (ccpumaps[byte] & (1 << uint(bit))) != 0 { + cpumaps[i][j] = true + } + } + } + + return cpumaps, nil +} + +func (d *Domain) PinEmulator(cpumap []bool, flags DomainModificationImpact) error { + + maplen := (len(cpumap) + 7) / 8 + ccpumaps := make([]C.uchar, maplen) + for i := 0; i < len(cpumap); i++ { + if cpumap[i] { + byte := i / 8 + bit := i % 8 + + ccpumaps[byte] |= (1 << uint(bit)) + } + } + + ret := C.virDomainPinEmulator(d.ptr, &ccpumaps[0], C.int(maplen), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) PinIOThread(iothreadid uint, cpumap []bool, flags DomainModificationImpact) error { + if C.LIBVIR_VERSION_NUMBER < 1002014 { + return GetNotImplementedError("virDomainPinIOThread") + } + + maplen := (len(cpumap) + 7) / 8 + ccpumaps := make([]C.uchar, maplen) + for i := 0; i < len(cpumap); i++ { + if cpumap[i] { + byte := i / 8 + bit := i % 8 + + ccpumaps[byte] |= (1 << uint(bit)) + } + } + + ret := C.virDomainPinIOThreadCompat(d.ptr, C.uint(iothreadid), &ccpumaps[0], C.int(maplen), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) OpenChannel(name string, stream *Stream, flags DomainChannelFlags) error { + cname := C.CString(name) + defer C.free(unsafe.Pointer(cname)) + + ret := C.virDomainOpenChannel(d.ptr, cname, stream.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) OpenConsole(devname string, stream *Stream, flags DomainConsoleFlags) error { + var cdevname *C.char + if devname != "" { + cdevname = C.CString(devname) + defer C.free(unsafe.Pointer(cdevname)) + } + + ret := C.virDomainOpenConsole(d.ptr, cdevname, stream.ptr, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) OpenGraphics(idx uint, file os.File, flags DomainOpenGraphicsFlags) error { + ret := C.virDomainOpenGraphics(d.ptr, C.uint(idx), C.int(file.Fd()), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) OpenGraphicsFD(idx uint, flags DomainOpenGraphicsFlags) (*os.File, error) { + if C.LIBVIR_VERSION_NUMBER < 1002008 { + return nil, GetNotImplementedError("virDomainOpenGraphicsFD") + } + ret := C.virDomainOpenGraphicsFDCompat(d.ptr, C.uint(idx), C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + return os.NewFile(uintptr(ret), "graphics"), nil +} + +func (d *Domain) CreateSnapshotXML(xml string, flags DomainSnapshotCreateFlags) (*DomainSnapshot, error) { + cXml := C.CString(xml) + defer C.free(unsafe.Pointer(cXml)) + result := C.virDomainSnapshotCreateXML(d.ptr, cXml, C.uint(flags)) + if result == nil { + return nil, GetLastError() + } + return &DomainSnapshot{ptr: result}, nil +} + +func (d *Domain) Save(destFile string) error { + cPath := C.CString(destFile) + defer C.free(unsafe.Pointer(cPath)) + result := C.virDomainSave(d.ptr, cPath) + if result == -1 { + return GetLastError() + } + return nil +} + +func (d *Domain) SaveFlags(destFile string, destXml string, flags DomainSaveRestoreFlags) error { + cDestFile := C.CString(destFile) + cDestXml := C.CString(destXml) + defer C.free(unsafe.Pointer(cDestXml)) + defer C.free(unsafe.Pointer(cDestFile)) + result := C.virDomainSaveFlags(d.ptr, cDestFile, cDestXml, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +type DomainGuestVcpus struct { + Vcpus []bool + Online []bool + Offlinable []bool +} + +func getDomainGuestVcpusParametersFieldInfo(VcpusSet *bool, Vcpus *string, OnlineSet *bool, Online *string, OfflinableSet *bool, Offlinable *string) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + "vcpus": typedParamsFieldInfo{ + set: VcpusSet, + s: Vcpus, + }, + "online": typedParamsFieldInfo{ + set: OnlineSet, + s: Online, + }, + "offlinable": typedParamsFieldInfo{ + set: OfflinableSet, + s: Offlinable, + }, + } +} + +func parseCPUString(cpumapstr string) ([]bool, error) { + pieces := strings.Split(cpumapstr, ",") + var cpumap []bool + for _, piece := range pieces { + if len(piece) < 1 { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + invert := false + if piece[0] == '^' { + invert = true + piece = piece[1:] + } + pair := strings.Split(piece, "-") + var start, end int + var err error + if len(pair) == 1 { + start, err = strconv.Atoi(pair[0]) + if err != nil { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + end, err = strconv.Atoi(pair[0]) + if err != nil { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + } else if len(pair) == 2 { + start, err = strconv.Atoi(pair[0]) + if err != nil { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + end, err = strconv.Atoi(pair[1]) + if err != nil { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + } else { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + if start > end { + return []bool{}, fmt.Errorf("Malformed cpu map string %s", cpumapstr) + } + if (end + 1) > len(cpumap) { + newcpumap := make([]bool, end+1) + copy(newcpumap, cpumap) + cpumap = newcpumap + } + + for i := start; i <= end; i++ { + if invert { + cpumap[i] = false + } else { + cpumap[i] = true + } + } + } + + return cpumap, nil +} + +func (d *Domain) GetGuestVcpus(flags uint32) (*DomainGuestVcpus, error) { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return nil, GetNotImplementedError("virDomainGetGuestVcpus") + } + + var VcpusSet, OnlineSet, OfflinableSet bool + var VcpusStr, OnlineStr, OfflinableStr string + info := getDomainGuestVcpusParametersFieldInfo(&VcpusSet, &VcpusStr, &OnlineSet, &OnlineStr, &OfflinableSet, &OfflinableStr) + + var cparams C.virTypedParameterPtr + var nparams C.uint + ret := C.virDomainGetGuestVcpusCompat(d.ptr, &cparams, &nparams, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + defer C.virTypedParamsFree(cparams, C.int(nparams)) + + _, err := typedParamsUnpackLen(cparams, int(nparams), info) + if err != nil { + return nil, err + } + + return &DomainGuestVcpus{}, nil +} + +func (d *Domain) SetGuestVcpus(cpus []bool, state bool, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return GetNotImplementedError("virDomainSetGuestVcpus") + } + + cpumap := "" + for i := 0; i < len(cpus); i++ { + if cpus[i] { + if cpumap == "" { + cpumap = string(i) + } else { + cpumap += "," + string(i) + } + } + } + + var cstate C.int + if state { + cstate = 1 + } else { + cstate = 0 + } + ccpumap := C.CString(cpumap) + defer C.free(unsafe.Pointer(ccpumap)) + ret := C.virDomainSetGuestVcpusCompat(d.ptr, ccpumap, cstate, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) SetVcpu(cpus []bool, state bool, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 3001000 { + return GetNotImplementedError("virDomainSetVcpu") + } + + cpumap := "" + for i := 0; i < len(cpus); i++ { + if cpus[i] { + if cpumap == "" { + cpumap = string(i) + } else { + cpumap += "," + string(i) + } + } + } + + var cstate C.int + if state { + cstate = 1 + } else { + cstate = 0 + } + ccpumap := C.CString(cpumap) + defer C.free(unsafe.Pointer(ccpumap)) + ret := C.virDomainSetVcpuCompat(d.ptr, ccpumap, cstate, C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (d *Domain) SetBlockThreshold(dev string, threshold uint64, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 3002000 { + return GetNotImplementedError("virDomainSetBlockThreshold") + } + + cdev := C.CString(dev) + defer C.free(unsafe.Pointer(cdev)) + ret := C.virDomainSetBlockThresholdCompat(d.ptr, cdev, C.ulonglong(threshold), C.uint(flags)) + if ret == -1 { + return GetLastError() + } + + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/domain_compat.go b/vendor/github.com/libvirt/libvirt-go/domain_compat.go new file mode 100644 index 000000000000..81ac004eb5bc --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_compat.go @@ -0,0 +1,315 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "domain_compat.h" + +int virDomainCoreDumpWithFormatCompat(virDomainPtr domain, + const char *to, + unsigned int dumpformat, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002003 + assert(0); // Caller should have checked version +#else + return virDomainCoreDumpWithFormat(domain, to, dumpformat, flags); +#endif +} + + +int virDomainGetTimeCompat(virDomainPtr dom, + long long *seconds, + unsigned int *nseconds, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002005 + assert(0); // Caller should have checked version +#else + return virDomainGetTime(dom, seconds, nseconds, flags); +#endif +} + +int virDomainSetTimeCompat(virDomainPtr dom, + long long seconds, + unsigned int nseconds, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002005 + assert(0); // Caller should have checked version +#else + return virDomainSetTime(dom, seconds, nseconds, flags); +#endif +} + +int virDomainFSFreezeCompat(virDomainPtr dom, + const char **mountpoints, + unsigned int nmountpoints, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002005 + assert(0); // Caller should have checked version +#else + return virDomainFSFreeze(dom, mountpoints, nmountpoints, flags); +#endif +} + +int virDomainFSThawCompat(virDomainPtr dom, + const char **mountpoints, + unsigned int nmountpoints, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002005 + assert(0); // Caller should have checked version +#else + return virDomainFSThaw(dom, mountpoints, nmountpoints, flags); +#endif +} + +int virDomainBlockCopyCompat(virDomainPtr dom, const char *disk, + const char *destxml, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002008 + assert(0); // Caller should have checked version +#else + return virDomainBlockCopy(dom, disk, destxml, params, nparams, flags); +#endif +} + +int virDomainOpenGraphicsFDCompat(virDomainPtr dom, + unsigned int idx, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002008 + assert(0); // Caller should have checked version +#else + return virDomainOpenGraphicsFD(dom, idx, flags); +#endif +} + +void virDomainFSInfoFreeCompat(virDomainFSInfoPtr info) +{ +} + +int virDomainGetFSInfoCompat(virDomainPtr dom, + virDomainFSInfoPtr **info, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002011 + assert(0); // Caller should have checked version +#else + return virDomainGetFSInfo(dom, info, flags); +#endif +} + +int virDomainInterfaceAddressesCompat(virDomainPtr dom, + virDomainInterfacePtr **ifaces, + unsigned int source, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002014 + assert(0); // Caller should have checked version +#else + return virDomainInterfaceAddresses(dom, ifaces, source, flags); +#endif +} + +void virDomainInterfaceFreeCompat(virDomainInterfacePtr iface) +{ +} + +void virDomainIOThreadInfoFreeCompat(virDomainIOThreadInfoPtr info) +{ +} + +int virDomainGetIOThreadInfoCompat(virDomainPtr domain, + virDomainIOThreadInfoPtr **info, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002014 + assert(0); // Caller should have checked version +#else + return virDomainGetIOThreadInfo(domain, info, flags); +#endif +} +int virDomainPinIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002014 + assert(0); // Caller should have checked version +#else + return virDomainPinIOThread(domain, iothread_id, cpumap, maplen, flags); +#endif +} + +int virDomainAddIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002015 + assert(0); // Caller should have checked version +#else + return virDomainAddIOThread(domain, iothread_id, flags); +#endif +} + + +int virDomainDelIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002015 + assert(0); // Caller should have checked version +#else + return virDomainDelIOThread(domain, iothread_id, flags); +#endif +} + + +int virDomainSetUserPasswordCompat(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002016 + assert(0); // Caller should have checked version +#else + return virDomainSetUserPassword(dom, user, password, flags); +#endif +} + + +int virDomainRenameCompat(virDomainPtr dom, + const char *new_name, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002019 + assert(0); // Caller should have checked version +#else + return virDomainRename(dom, new_name, flags); +#endif +} + + +int virDomainGetPerfEventsCompat(virDomainPtr dom, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1003003 + assert(0); // Caller should have checked version +#else + return virDomainGetPerfEvents(dom, params, nparams, flags); +#endif +} + + +int virDomainSetPerfEventsCompat(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1003003 + assert(0); // Caller should have checked version +#else + return virDomainSetPerfEvents(dom, params, nparams, flags); +#endif +} + + +int virDomainMigrateStartPostCopyCompat(virDomainPtr domain, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1003003 + assert(0); // Caller should have checked version +#else + return virDomainMigrateStartPostCopy(domain, flags); +#endif +} + + +int virDomainGetGuestVcpusCompat(virDomainPtr domain, + virTypedParameterPtr *params, + unsigned int *nparams, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 2000000 + assert(0); // Caller should have checked version +#else + return virDomainGetGuestVcpus(domain, params, nparams, flags); +#endif +} + + +int virDomainSetGuestVcpusCompat(virDomainPtr domain, + const char *cpumap, + int state, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 2000000 + assert(0); // Caller should have checked version +#else + return virDomainSetGuestVcpus(domain, cpumap, state, flags); +#endif +} + +int virDomainSetVcpuCompat(virDomainPtr domain, + const char *cpumap, + int state, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3001000 + assert(0); // Caller should have checked version +#else + return virDomainSetVcpu(domain, cpumap, state, flags); +#endif +} + + +int virDomainSetBlockThresholdCompat(virDomainPtr domain, + const char *dev, + unsigned long long threshold, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3002000 + assert(0); // Caller should have checked version +#else + return virDomainSetBlockThreshold(domain, dev, threshold, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/domain_compat.h b/vendor/github.com/libvirt/libvirt-go/domain_compat.h new file mode 100644 index 000000000000..8f218eff0c54 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_compat.h @@ -0,0 +1,955 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_DOMAIN_COMPAT_H__ +#define LIBVIRT_GO_DOMAIN_COMPAT_H__ + +/* 1.2.2 */ + +#ifndef VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS +#define VIR_DOMAIN_BLKIO_DEVICE_READ_IOPS "device_read_iops_sec" +#endif + +#ifndef VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS +#define VIR_DOMAIN_BLKIO_DEVICE_WRITE_IOPS "device_write_iops_sec" +#endif + +#ifndef VIR_DOMAIN_BLKIO_DEVICE_READ_BPS +#define VIR_DOMAIN_BLKIO_DEVICE_READ_BPS "device_read_bytes_sec" +#endif + +#ifndef VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS +#define VIR_DOMAIN_BLKIO_DEVICE_WRITE_BPS "device_write_bytes_sec" +#endif + + +/* 1.2.3 */ + +#ifndef VIR_DOMAIN_CORE_DUMP_FORMAT_RAW +#define VIR_DOMAIN_CORE_DUMP_FORMAT_RAW 0 +#endif + +#ifndef VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB +#define VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_ZLIB 1 +#endif + +#ifndef VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO +#define VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_LZO 2 +#endif + +#ifndef VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY +#define VIR_DOMAIN_CORE_DUMP_FORMAT_KDUMP_SNAPPY 3 +#endif + +#ifndef VIR_MIGRATE_AUTO_CONVERGE +#define VIR_MIGRATE_AUTO_CONVERGE 1 << 13 +#endif + +int virDomainCoreDumpWithFormatCompat(virDomainPtr domain, + const char *to, + unsigned int dumpformat, + unsigned int flags); + + +/* 1.2.5 */ + +#ifndef VIR_DOMAIN_REBOOT_PARAVIRT +#define VIR_DOMAIN_REBOOT_PARAVIRT 1 << 4 +#endif + +#ifndef VIR_DOMAIN_SHUTDOWN_PARAVIRT +#define VIR_DOMAIN_SHUTDOWN_PARAVIRT 1 << 4 +#endif + +#ifndef VIR_DOMAIN_TIME_SYNC +#define VIR_DOMAIN_TIME_SYNC 1 << 0 +#endif + +int virDomainGetTimeCompat(virDomainPtr dom, + long long *seconds, + unsigned int *nseconds, + unsigned int flags); + +int virDomainSetTimeCompat(virDomainPtr dom, + long long seconds, + unsigned int nseconds, + unsigned int flags); + +int virDomainFSFreezeCompat(virDomainPtr dom, + const char **mountpoints, + unsigned int nmountpoints, + unsigned int flags); + +int virDomainFSThawCompat(virDomainPtr dom, + const char **mountpoints, + unsigned int nmountpoints, + unsigned int flags); + + +/* 1.2.6 */ + +#ifndef VIR_DOMAIN_BLOCK_COMMIT_ACTIVE +#define VIR_DOMAIN_BLOCK_COMMIT_ACTIVE 1 << 2 +#endif + +#ifndef VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT +#define VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT 4 +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 +#define VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2 16 +#endif + + +/* 1.2.7 */ + +#ifndef VIR_DOMAIN_BLOCK_COMMIT_RELATIVE +#define VIR_DOMAIN_BLOCK_COMMIT_RELATIVE 1 << 3 +#endif + +#ifndef VIR_DOMAIN_BLOCK_REBASE_RELATIVE +#define VIR_DOMAIN_BLOCK_REBASE_RELATIVE 1 << 4 +#endif + + +/* 1.2.8 */ + +#ifndef VIR_DOMAIN_BLOCK_COPY_SHALLOW +#define VIR_DOMAIN_BLOCK_COPY_SHALLOW 1 << 0 +#endif + +#ifndef VIR_DOMAIN_BLOCK_COPY_REUSE_EXT +#define VIR_DOMAIN_BLOCK_COPY_REUSE_EXT 1 << 1 +#endif + +#ifndef VIR_DOMAIN_BLOCK_COPY_BANDWIDTH +#define VIR_DOMAIN_BLOCK_COPY_BANDWIDTH "bandwidth" +#endif + +#ifndef VIR_DOMAIN_BLOCK_COPY_GRANULARITY +#define VIR_DOMAIN_BLOCK_COPY_GRANULARITY "granularity" +#endif + +#ifndef VIR_DOMAIN_BLOCK_COPY_BUF_SIZE +#define VIR_DOMAIN_BLOCK_COPY_BUF_SIZE "buf-size" +#endif + +#ifndef VIR_DOMAIN_STATS_STATE +#define VIR_DOMAIN_STATS_STATE 1 << 0 +#endif + +int virDomainBlockCopyCompat(virDomainPtr dom, const char *disk, + const char *destxml, + virTypedParameterPtr params, + int nparams, + unsigned int flags); + +int virDomainOpenGraphicsFDCompat(virDomainPtr dom, + unsigned int idx, + unsigned int flags); + + +/* 1.2.9 */ + +#ifndef VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES +#define VIR_DOMAIN_BLOCK_COMMIT_BANDWIDTH_BYTES 1 << 4 +#endif + +#ifndef VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES +#define VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES 1 << 0 +#endif + +#ifndef VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES +#define VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES 1 << 0 +#endif + +#ifndef VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES +#define VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES 1 << 6 +#endif + +#ifndef VIR_DOMAIN_BLOCK_REBASE_COPY_DEV +#define VIR_DOMAIN_BLOCK_REBASE_COPY_DEV 1 << 5 +#endif + +#ifndef VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES +#define VIR_DOMAIN_BLOCK_REBASE_BANDWIDTH_BYTES 1 << 6 +#endif + +#ifndef VIR_DOMAIN_JOB_DISK_BPS +#define VIR_DOMAIN_JOB_DISK_BPS "disk_bps" +#endif + +#ifndef VIR_DOMAIN_JOB_MEMORY_BPS +#define VIR_DOMAIN_JOB_MEMORY_BPS "memory_bps" +#endif + +#ifndef VIR_DOMAIN_JOB_SETUP_TIME +#define VIR_DOMAIN_JOB_SETUP_TIME "setup_time" +#endif + +#ifndef VIR_DOMAIN_JOB_STATS_COMPLETED +#define VIR_DOMAIN_JOB_STATS_COMPLETED 1 << 0 +#endif + +#ifndef VIR_DOMAIN_STATS_CPU_TOTAL +#define VIR_DOMAIN_STATS_CPU_TOTAL 1 << 1 +#endif + +#ifndef VIR_DOMAIN_STATS_BALLOON +#define VIR_DOMAIN_STATS_BALLOON 1 << 2 +#endif + +#ifndef VIR_DOMAIN_STATS_VCPU +#define VIR_DOMAIN_STATS_VCPU 1 << 3 +#endif + +#ifndef VIR_DOMAIN_STATS_INTERFACE +#define VIR_DOMAIN_STATS_INTERFACE 1 << 4 +#endif + +#ifndef VIR_DOMAIN_STATS_BLOCK +#define VIR_DOMAIN_STATS_BLOCK 1 << 5 +#endif + +#ifndef VIR_DOMAIN_UNDEFINE_NVRAM +#define VIR_DOMAIN_UNDEFINE_NVRAM 1 << 2 +#endif + +#ifndef VIR_MIGRATE_RDMA_PIN_ALL +#define VIR_MIGRATE_RDMA_PIN_ALL 1 << 14 +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_TUNABLE +#define VIR_DOMAIN_EVENT_ID_TUNABLE 17 +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_DISK +#define VIR_DOMAIN_TUNABLE_BLKDEV_DISK "blkdeviotune.disk" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC "blkdeviotune.total_bytes_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC "blkdeviotune.read_bytes_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC "blkdeviotune.write_bytes_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC "blkdeviotune.total_iops_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC "blkdeviotune.read_iops_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC "blkdeviotune.write_iops_sec" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES +#define VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES "cputune.cpu_shares" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN +#define VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN "cputune.emulatorpin" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD +#define VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD "cputune.emulator_period" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA +#define VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA "cputune.emulator_quota" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD +#define VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD "cputune.vcpu_period" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA +#define VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA "cputune.vcpu_quota" +#endif + + + +/* 1.2.11 */ + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX "blkdeviotune.total_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX "blkdeviotune.read_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX "blkdeviotune.write_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX "blkdeviotune.total_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX "blkdeviotune.read_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX "blkdeviotune.write_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_SIZE_IOPS_SEC +#define VIR_DOMAIN_TUNABLE_BLKDEV_SIZE_IOPS_SEC "blkdeviotune.size_iops_sec" +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE +#define VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE 18 +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX "total_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX "read_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX "write_bytes_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX "total_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX "read_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX "write_iops_sec_max" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC +#define VIR_DOMAIN_BLOCK_IOTUNE_SIZE_IOPS_SEC "size_iops_sec" +#endif + +#if LIBVIR_VERSION_NUMBER < 1002011 +typedef struct _virDomainFSInfo virDomainFSInfo; +typedef virDomainFSInfo *virDomainFSInfoPtr; +struct _virDomainFSInfo { + char *mountpoint; /* path to mount point */ + char *name; /* device name in the guest (e.g. "sda1") */ + char *fstype; /* filesystem type */ + size_t ndevAlias; /* number of elements in devAlias */ + char **devAlias; /* array of disk device aliases */ +}; +#endif + +void virDomainFSInfoFreeCompat(virDomainFSInfoPtr info); + +int virDomainGetFSInfoCompat(virDomainPtr dom, + virDomainFSInfoPtr **info, + unsigned int flags); + + +/* 1.2.12 */ + +#ifndef VIR_DOMAIN_DEFINE_VALIDATE +#define VIR_DOMAIN_DEFINE_VALIDATE 1 << 0 +#endif + +#ifndef VIR_DOMAIN_START_VALIDATE +#define VIR_DOMAIN_START_VALIDATE 1 << 4 +#endif + + +/* 1.2.14 */ + +#ifndef VIR_DOMAIN_CONTROL_ERROR_REASON_NONE +#define VIR_DOMAIN_CONTROL_ERROR_REASON_NONE 0 +#endif + +#ifndef VIR_DOMAIN_CONTROL_ERROR_REASON_UNKNOWN +#define VIR_DOMAIN_CONTROL_ERROR_REASON_UNKNOWN 1 +#endif + +#ifndef VIR_DOMAIN_CONTROL_ERROR_REASON_MONITOR +#define VIR_DOMAIN_CONTROL_ERROR_REASON_MONITOR 2 +#endif + +#ifndef VIR_DOMAIN_CONTROL_ERROR_REASON_INTERNAL +#define VIR_DOMAIN_CONTROL_ERROR_REASON_INTERNAL 3 +#endif + +#ifndef VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE +#define VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_LEASE 0 +#endif + +#ifndef VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT +#define VIR_DOMAIN_INTERFACE_ADDRESSES_SRC_AGENT 1 +#endif + +#ifndef VIR_DOMAIN_PAUSED_STARTING_UP +#define VIR_DOMAIN_PAUSED_STARTING_UP 11 +#endif + +#if LIBVIR_VERSION_NUMBER < 1002014 +typedef struct _virDomainIOThreadInfo virDomainIOThreadInfo; +typedef virDomainIOThreadInfo *virDomainIOThreadInfoPtr; +struct _virDomainIOThreadInfo { + unsigned int iothread_id; /* IOThread ID */ + unsigned char *cpumap; /* CPU map for thread. A pointer to an */ + /* array of real CPUs (in 8-bit bytes) */ + int cpumaplen; /* cpumap size */ +}; + +typedef struct _virDomainInterfaceIPAddress virDomainIPAddress; +typedef virDomainIPAddress *virDomainIPAddressPtr; +struct _virDomainInterfaceIPAddress { + int type; /* virIPAddrType */ + char *addr; /* IP address */ + unsigned int prefix; /* IP address prefix */ +}; + +typedef struct _virDomainInterface virDomainInterface; +typedef virDomainInterface *virDomainInterfacePtr; +struct _virDomainInterface { + char *name; /* interface name */ + char *hwaddr; /* hardware address, may be NULL */ + unsigned int naddrs; /* number of items in @addrs */ + virDomainIPAddressPtr addrs; /* array of IP addresses */ +}; +#endif + +int virDomainInterfaceAddressesCompat(virDomainPtr dom, + virDomainInterfacePtr **ifaces, + unsigned int source, + unsigned int flags); + +void virDomainInterfaceFreeCompat(virDomainInterfacePtr iface); + +void virDomainIOThreadInfoFreeCompat(virDomainIOThreadInfoPtr info); + +int virDomainGetIOThreadInfoCompat(virDomainPtr domain, + virDomainIOThreadInfoPtr **info, + unsigned int flags); +int virDomainPinIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned char *cpumap, + int maplen, + unsigned int flags); + + +/* 1.2.15 */ + +#ifndef VIR_DOMAIN_JOB_DOWNTIME_NET +#define VIR_DOMAIN_JOB_DOWNTIME_NET "downtime_net" +#endif + +#ifndef VIR_DOMAIN_JOB_TIME_ELAPSED_NET +#define VIR_DOMAIN_JOB_TIME_ELAPSED_NET "time_elapsed_net" +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_DEVICE_ADDED +#define VIR_DOMAIN_EVENT_ID_DEVICE_ADDED 19 +#endif + +int virDomainAddIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned int flags); +int virDomainDelIOThreadCompat(virDomainPtr domain, + unsigned int iothread_id, + unsigned int flags); + + +/* 1.2.16 */ + +#ifndef VIR_DOMAIN_PASSWORD_ENCRYPTED +#define VIR_DOMAIN_PASSWORD_ENCRYPTED 1 << 0 +#endif + +int virDomainSetUserPasswordCompat(virDomainPtr dom, + const char *user, + const char *password, + unsigned int flags); + + +/* 1.2.17 */ + +#ifndef VIR_DOMAIN_EVENT_WATCHDOG_INJECTNMI +#define VIR_DOMAIN_EVENT_WATCHDOG_INJECTNMI 6 +#endif + +#ifndef VIR_MIGRATE_PARAM_MIGRATE_DISKS +#define VIR_MIGRATE_PARAM_MIGRATE_DISKS "migrate_disks" +#endif + + +/* 1.2.19 */ + +#ifndef VIR_DOMAIN_BANDWIDTH_IN_FLOOR +#define VIR_DOMAIN_BANDWIDTH_IN_FLOOR "inbound.floor" +#endif + +#ifndef VIR_DOMAIN_EVENT_DEFINED_RENAMED +#define VIR_DOMAIN_EVENT_DEFINED_RENAMED 2 +#endif + +#ifndef VIR_DOMAIN_EVENT_UNDEFINED_RENAMED +#define VIR_DOMAIN_EVENT_UNDEFINED_RENAMED 1 +#endif + +int virDomainRenameCompat(virDomainPtr dom, + const char *new_name, + unsigned int flags); + + +/* 1.3.1 */ + +#ifndef VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE +#define VIR_DOMAIN_JOB_MEMORY_DIRTY_RATE "memory_dirty_rate" +#endif + +#ifndef VIR_DOMAIN_JOB_MEMORY_ITERATION +#define VIR_DOMAIN_JOB_MEMORY_ITERATION "memory_iteration" +#endif + + +/* 1.3.2 */ + +#ifndef VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION +#define VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION 20 +#endif + + +/* 1.3.3 */ + +#ifndef VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT +#define VIR_DOMAIN_EVENT_DEFINED_FROM_SNAPSHOT 3 +#endif + +#ifndef VIR_DOMAIN_EVENT_RESUMED_POSTCOPY +#define VIR_DOMAIN_EVENT_RESUMED_POSTCOPY 3 +#endif + +#ifndef VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY +#define VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY 7 +#endif + +#ifndef VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED +#define VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY_FAILED 8 +#endif + +#ifndef VIR_DOMAIN_PAUSED_POSTCOPY +#define VIR_DOMAIN_PAUSED_POSTCOPY 12 +#endif + +#ifndef VIR_DOMAIN_PAUSED_POSTCOPY_FAILED +#define VIR_DOMAIN_PAUSED_POSTCOPY_FAILED 13 +#endif + +#ifndef VIR_DOMAIN_RUNNING_POSTCOPY +#define VIR_DOMAIN_RUNNING_POSTCOPY 10 +#endif + +#ifndef VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD +#define VIR_DOMAIN_SCHEDULER_GLOBAL_PERIOD "global_period" +#endif + +#ifndef VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA +#define VIR_DOMAIN_SCHEDULER_GLOBAL_QUOTA "global_quota" +#endif + +#ifndef VIR_DOMAIN_STATS_PERF +#define VIR_DOMAIN_STATS_PERF (1 << 6) +#endif + +#ifndef VIR_MIGRATE_PARAM_DISKS_PORT +#define VIR_MIGRATE_PARAM_DISKS_PORT "disks_port" +#endif + +#ifndef VIR_PERF_PARAM_CMT +#define VIR_PERF_PARAM_CMT "cmt" +#endif + +#ifndef VIR_MIGRATE_POSTCOPY +#define VIR_MIGRATE_POSTCOPY (1 << 15) +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_JOB_COMPLETED +#define VIR_DOMAIN_EVENT_ID_JOB_COMPLETED 21 +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD +#define VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD "cputune.global_period" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA +#define VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA "cputune.global_quota" +#endif + +int virDomainGetPerfEventsCompat(virDomainPtr dom, + virTypedParameterPtr *params, + int *nparams, + unsigned int flags); +int virDomainSetPerfEventsCompat(virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + unsigned int flags); +int virDomainMigrateStartPostCopyCompat(virDomainPtr domain, + unsigned int flags); + + +/* 1.3.4 */ + +#ifndef VIR_MIGRATE_PARAM_COMPRESSION +#define VIR_MIGRATE_PARAM_COMPRESSION "compression" +#endif + +#ifndef VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS +#define VIR_MIGRATE_PARAM_COMPRESSION_MT_THREADS "compression.mt.threads" +#endif + +#ifndef VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS +#define VIR_MIGRATE_PARAM_COMPRESSION_MT_DTHREADS "compression.mt.dthreads" +#endif + +#ifndef VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL +#define VIR_MIGRATE_PARAM_COMPRESSION_MT_LEVEL "compression.mt.level" +#endif + +#ifndef VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE +#define VIR_MIGRATE_PARAM_COMPRESSION_XBZRLE_CACHE "compression.xbzrle.cache" +#endif + +#ifndef VIR_MIGRATE_PARAM_PERSIST_XML +#define VIR_MIGRATE_PARAM_PERSIST_XML "persistent_xml" +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED +#define VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED 22 +#endif + + +/* 1.3.5 */ + +#ifndef VIR_PERF_PARAM_MBML +#define VIR_PERF_PARAM_MBML "mbml" +#endif + +#ifndef VIR_PERF_PARAM_MBMT +#define VIR_PERF_PARAM_MBMT "mbmt" +#endif + + +/* 2.0.0 */ + +#ifndef VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE +#define VIR_DOMAIN_JOB_AUTO_CONVERGE_THROTTLE "auto_converge_throttle" +#endif + +#ifndef VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL +#define VIR_MIGRATE_PARAM_AUTO_CONVERGE_INITIAL "auto_converge.initial" +#endif + +#ifndef VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT +#define VIR_MIGRATE_PARAM_AUTO_CONVERGE_INCREMENT "auto_converge.increment" +#endif + +int virDomainGetGuestVcpusCompat(virDomainPtr domain, + virTypedParameterPtr *params, + unsigned int *nparams, + unsigned int flags); + +int virDomainSetGuestVcpusCompat(virDomainPtr domain, + const char *cpumap, + int state, + unsigned int flags); + + +/* 2.1.0 */ + +#ifndef VIR_DOMAIN_MEMORY_STAT_USABLE +#define VIR_DOMAIN_MEMORY_STAT_USABLE 8 +#endif + +#ifndef VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE +#define VIR_DOMAIN_MEMORY_STAT_LAST_UPDATE 9 +#endif + +/* 2.2.0 */ + +#ifndef VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD +#define VIR_DOMAIN_SCHEDULER_IOTHREAD_PERIOD "iothread_period" +#endif + +#ifndef VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA +#define VIR_DOMAIN_SCHEDULER_IOTHREAD_QUOTA "iothread_quota" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD +#define VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD "cputune.iothread_period" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA +# define VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA "cputune.iothread_quota" +#endif + + +/* 2.3.0 */ + +#ifndef VIR_DOMAIN_UNDEFINE_KEEP_NVRAM +#define VIR_DOMAIN_UNDEFINE_KEEP_NVRAM (1 << 3) +#endif + +#ifndef VIR_PERF_PARAM_CACHE_MISSES +#define VIR_PERF_PARAM_CACHE_MISSES "cache_misses" +#endif + +#ifndef VIR_PERF_PARAM_CACHE_REFERENCES +#define VIR_PERF_PARAM_CACHE_REFERENCES "cache_references" +#endif + +#ifndef VIR_PERF_PARAM_INSTRUCTIONS +#define VIR_PERF_PARAM_INSTRUCTIONS "instructions" +#endif + +#ifndef VIR_PERF_PARAM_CPU_CYCLES +#define VIR_PERF_PARAM_CPU_CYCLES "cpu_cycles" +#endif + + +/* 2.4.0 */ + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC_MAX_LENGTH "read_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC_MAX_LENGTH "read_iops_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC_MAX_LENGTH "total_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC_MAX_LENGTH "total_iops_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC_MAX_LENGTH "write_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC_MAX_LENGTH "write_iopcs_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX_LENGTH "blkdeviotune.total_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX_LENGTH "blkdeviotune.read_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX_LENGTH "blkdeviotune.write_bytes_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX_LENGTH "blkdeviotune.total_iops_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX_LENGTH "blkdeviotune.read_iops_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX_LENGTH +#define VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX_LENGTH "blkdeviotune.write_iops_sec_max_length" +#endif + +#ifndef VIR_DOMAIN_VCPU_HOTPLUGGABLE +#define VIR_DOMAIN_VCPU_HOTPLUGGABLE (1 << 4) +#endif + +/* 3.0.0 */ + +#ifndef VIR_PERF_PARAM_BRANCH_INSTRUCTIONS +#define VIR_PERF_PARAM_BRANCH_INSTRUCTIONS "branch_instructions" +#endif + +#ifndef VIR_PERF_PARAM_BRANCH_MISSES +#define VIR_PERF_PARAM_BRANCH_MISSES "branch_misses" +#endif + +#ifndef VIR_PERF_PARAM_BUS_CYCLES +#define VIR_PERF_PARAM_BUS_CYCLES "bus_cycles" +#endif + +#ifndef VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND +#define VIR_PERF_PARAM_STALLED_CYCLES_FRONTEND "stalled_cycles_frontend" +#endif + +#ifndef VIR_PERF_PARAM_STALLED_CYCLES_BACKEND +#define VIR_PERF_PARAM_STALLED_CYCLES_BACKEND "stalled_cycles_backend" +#endif + +#ifndef VIR_PERF_PARAM_REF_CPU_CYCLES +#define VIR_PERF_PARAM_REF_CPU_CYCLES "ref_cpu_cycles" +#endif + +#ifndef VIR_PERF_PARAM_CPU_CLOCK +#define VIR_PERF_PARAM_CPU_CLOCK "cpu_clock" +#endif + +#ifndef VIR_PERF_PARAM_TASK_CLOCK +#define VIR_PERF_PARAM_TASK_CLOCK "task_clock" +#endif + +#ifndef VIR_PERF_PARAM_PAGE_FAULTS +#define VIR_PERF_PARAM_PAGE_FAULTS "page_faults" +#endif + +#ifndef VIR_PERF_PARAM_CONTEXT_SWITCHES +#define VIR_PERF_PARAM_CONTEXT_SWITCHES "context_switches" +#endif + +#ifndef VIR_PERF_PARAM_CPU_MIGRATIONS +#define VIR_PERF_PARAM_CPU_MIGRATIONS "cpu_migrations" +#endif + +#ifndef VIR_PERF_PARAM_PAGE_FAULTS_MIN +#define VIR_PERF_PARAM_PAGE_FAULTS_MIN "page_faults_min" +#endif + +#ifndef VIR_PERF_PARAM_PAGE_FAULTS_MAJ +#define VIR_PERF_PARAM_PAGE_FAULTS_MAJ "page_faults_maj" +#endif + +#ifndef VIR_PERF_PARAM_ALIGNMENT_FAULTS +#define VIR_PERF_PARAM_ALIGNMENT_FAULTS "alignment_faults" +#endif + +#ifndef VIR_PERF_PARAM_EMULATION_FAULTS +#define VIR_PERF_PARAM_EMULATION_FAULTS "emulation_faults" +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_METADATA_CHANGE +#define VIR_DOMAIN_EVENT_ID_METADATA_CHANGE 23 +#endif + +#ifndef VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME +#define VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME "group_name" +#endif + +#ifndef VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME +#define VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME "blkdeviotune.group_name" +#endif + +/* 3.1.0 */ + +int virDomainSetVcpuCompat(virDomainPtr domain, + const char *cpumap, + int state, + unsigned int flags); + +/* 3.2.0 */ + +#ifndef VIR_MIGRATE_TLS +#define VIR_MIGRATE_TLS 1 << 16 +#endif + +#ifndef VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD +#define VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD 24 +#endif + +int virDomainSetBlockThresholdCompat(virDomainPtr domain, + const char *dev, + unsigned long long threshold, + unsigned int flags); + +/* 3.3.0 */ + +#ifndef VIR_DOMAIN_JOB_OPERATION +#define VIR_DOMAIN_JOB_OPERATION "operation" +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_UNKNOWN +#define VIR_DOMAIN_JOB_OPERATION_UNKNOWN 0 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_START +#define VIR_DOMAIN_JOB_OPERATION_START 1 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_SAVE +#define VIR_DOMAIN_JOB_OPERATION_SAVE 2 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_RESTORE +#define VIR_DOMAIN_JOB_OPERATION_RESTORE 3 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN +#define VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN 4 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT +#define VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT 5 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_SNAPSHOT +#define VIR_DOMAIN_JOB_OPERATION_SNAPSHOT 6 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT +#define VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT 7 +#endif + +#ifndef VIR_DOMAIN_JOB_OPERATION_DUMP +#define VIR_DOMAIN_JOB_OPERATION_DUMP 8 +#endif + + +/* 3.4.0 */ + +#ifndef VIR_DOMAIN_EVENT_SHUTDOWN_GUEST +#define VIR_DOMAIN_EVENT_SHUTDOWN_GUEST 1 +#endif + +#ifndef VIR_DOMAIN_EVENT_SHUTDOWN_HOST +#define VIR_DOMAIN_EVENT_SHUTDOWN_HOST 2 +#endif + + +#endif /* LIBVIRT_GO_DOMAIN_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/domain_events.go b/vendor/github.com/libvirt/libvirt-go/domain_events.go new file mode 100644 index 000000000000..ba3804389d5f --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_events.go @@ -0,0 +1,1608 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include "domain_events_cfuncs.h" +#include "domain_compat.h" +*/ +import "C" + +type DomainEventGenericCallback func(c *Connect, d *Domain) + +type DomainEventLifecycle struct { + Event DomainEventType + // TODO: we can make Detail typesafe somehow ? + Detail int +} + +type DomainEventLifecycleCallback func(c *Connect, d *Domain, event *DomainEventLifecycle) + +type DomainEventRTCChange struct { + Utcoffset int64 +} + +type DomainEventRTCChangeCallback func(c *Connect, d *Domain, event *DomainEventRTCChange) + +type DomainEventWatchdog struct { + Action DomainEventWatchdogAction +} + +type DomainEventWatchdogCallback func(c *Connect, d *Domain, event *DomainEventWatchdog) + +type DomainEventIOError struct { + SrcPath string + DevAlias string + Action DomainEventIOErrorAction +} + +type DomainEventIOErrorCallback func(c *Connect, d *Domain, event *DomainEventIOError) + +type DomainEventGraphicsAddress struct { + Family DomainEventGraphicsAddressType + Node string + Service string +} + +type DomainEventGraphicsSubjectIdentity struct { + Type string + Name string +} + +type DomainEventGraphics struct { + Phase DomainEventGraphicsPhase + Local DomainEventGraphicsAddress + Remote DomainEventGraphicsAddress + AuthScheme string + Subject []DomainEventGraphicsSubjectIdentity +} + +type DomainEventGraphicsCallback func(c *Connect, d *Domain, event *DomainEventGraphics) + +type DomainEventIOErrorReason struct { + SrcPath string + DevAlias string + Action DomainEventIOErrorAction + Reason string +} + +type DomainEventIOErrorReasonCallback func(c *Connect, d *Domain, event *DomainEventIOErrorReason) + +type DomainEventBlockJob struct { + Disk string + Type DomainBlockJobType + Status ConnectDomainEventBlockJobStatus +} + +type DomainEventBlockJobCallback func(c *Connect, d *Domain, event *DomainEventBlockJob) + +type DomainEventDiskChange struct { + OldSrcPath string + NewSrcPath string + DevAlias string + Reason ConnectDomainEventDiskChangeReason +} + +type DomainEventDiskChangeCallback func(c *Connect, d *Domain, event *DomainEventDiskChange) + +type DomainEventTrayChange struct { + DevAlias string + Reason ConnectDomainEventTrayChangeReason +} + +type DomainEventTrayChangeCallback func(c *Connect, d *Domain, event *DomainEventTrayChange) + +type DomainEventPMSuspend struct { + Reason int +} + +type DomainEventPMSuspendCallback func(c *Connect, d *Domain, event *DomainEventPMSuspend) + +type DomainEventPMWakeup struct { + Reason int +} + +type DomainEventPMWakeupCallback func(c *Connect, d *Domain, event *DomainEventPMWakeup) + +type DomainEventPMSuspendDisk struct { + Reason int +} + +type DomainEventPMSuspendDiskCallback func(c *Connect, d *Domain, event *DomainEventPMSuspendDisk) + +type DomainEventBalloonChange struct { + Actual uint64 +} + +type DomainEventBalloonChangeCallback func(c *Connect, d *Domain, event *DomainEventBalloonChange) + +type DomainEventDeviceRemoved struct { + DevAlias string +} + +type DomainEventDeviceRemovedCallback func(c *Connect, d *Domain, event *DomainEventDeviceRemoved) + +type DomainEventTunableCpuPin struct { + VcpuPinSet bool + VcpuPin [][]bool + EmulatorPinSet bool + EmulatorPin []bool + IOThreadPinSet bool + IOThreadPin [][]bool +} + +type DomainEventTunable struct { + CpuSched *DomainSchedulerParameters + CpuPin *DomainEventTunableCpuPin + BlkdevDiskSet bool + BlkdevDisk string + BlkdevTune *DomainBlockIoTuneParameters +} + +type DomainEventTunableCallback func(c *Connect, d *Domain, event *DomainEventTunable) + +type DomainEventAgentLifecycle struct { + State ConnectDomainEventAgentLifecycleState + Reason ConnectDomainEventAgentLifecycleReason +} + +type DomainEventAgentLifecycleCallback func(c *Connect, d *Domain, event *DomainEventAgentLifecycle) + +type DomainEventDeviceAdded struct { + DevAlias string +} + +type DomainEventDeviceAddedCallback func(c *Connect, d *Domain, event *DomainEventDeviceAdded) + +type DomainEventMigrationIteration struct { + Iteration int +} + +type DomainEventMigrationIterationCallback func(c *Connect, d *Domain, event *DomainEventMigrationIteration) + +type DomainEventJobCompleted struct { + Info DomainJobInfo +} + +type DomainEventJobCompletedCallback func(c *Connect, d *Domain, event *DomainEventJobCompleted) + +type DomainEventDeviceRemovalFailed struct { + DevAlias string +} + +type DomainEventDeviceRemovalFailedCallback func(c *Connect, d *Domain, event *DomainEventDeviceRemovalFailed) + +type DomainEventMetadataChange struct { + Type int + NSURI string +} + +type DomainEventMetadataChangeCallback func(c *Connect, d *Domain, event *DomainEventMetadataChange) + +type DomainEventBlockThreshold struct { + Dev string + Path string + Threshold uint64 + Excess uint64 +} + +type DomainEventBlockThresholdCallback func(c *Connect, d *Domain, event *DomainEventBlockThreshold) + +//export domainEventLifecycleCallback +func domainEventLifecycleCallback(c C.virConnectPtr, d C.virDomainPtr, + event int, detail int, + goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventLifecycle{ + Event: DomainEventType(event), + Detail: detail, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) +} + +//export domainEventGenericCallback +func domainEventGenericCallback(c C.virConnectPtr, d C.virDomainPtr, + goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventGenericCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain) +} + +//export domainEventRTCChangeCallback +func domainEventRTCChangeCallback(c C.virConnectPtr, d C.virDomainPtr, + utcoffset int64, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventRTCChange{ + Utcoffset: utcoffset, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventRTCChangeCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventWatchdogCallback +func domainEventWatchdogCallback(c C.virConnectPtr, d C.virDomainPtr, + action int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventWatchdog{ + Action: DomainEventWatchdogAction(action), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventWatchdogCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventIOErrorCallback +func domainEventIOErrorCallback(c C.virConnectPtr, d C.virDomainPtr, + srcPath *C.char, devAlias *C.char, action int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventIOError{ + SrcPath: C.GoString(srcPath), + DevAlias: C.GoString(devAlias), + Action: DomainEventIOErrorAction(action), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventIOErrorCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventGraphicsCallback +func domainEventGraphicsCallback(c C.virConnectPtr, d C.virDomainPtr, + phase int, + local C.virDomainEventGraphicsAddressPtr, + remote C.virDomainEventGraphicsAddressPtr, + authScheme *C.char, + subject C.virDomainEventGraphicsSubjectPtr, + goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + subjectGo := make([]DomainEventGraphicsSubjectIdentity, subject.nidentity) + nidentities := int(subject.nidentity) + identities := (*[1 << 30]C.virDomainEventGraphicsSubjectIdentity)(unsafe.Pointer(&subject.identities))[:nidentities:nidentities] + for _, identity := range identities { + subjectGo = append(subjectGo, + DomainEventGraphicsSubjectIdentity{ + Type: C.GoString(identity._type), + Name: C.GoString(identity.name), + }, + ) + } + + eventDetails := &DomainEventGraphics{ + Phase: DomainEventGraphicsPhase(phase), + Local: DomainEventGraphicsAddress{ + Family: DomainEventGraphicsAddressType(local.family), + Node: C.GoString(local.node), + Service: C.GoString(local.service), + }, + Remote: DomainEventGraphicsAddress{ + Family: DomainEventGraphicsAddressType(remote.family), + Node: C.GoString(remote.node), + Service: C.GoString(remote.service), + }, + AuthScheme: C.GoString(authScheme), + Subject: subjectGo, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventGraphicsCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventIOErrorReasonCallback +func domainEventIOErrorReasonCallback(c C.virConnectPtr, d C.virDomainPtr, + srcPath *C.char, devAlias *C.char, action int, reason *C.char, + goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventIOErrorReason{ + SrcPath: C.GoString(srcPath), + DevAlias: C.GoString(devAlias), + Action: DomainEventIOErrorAction(action), + Reason: C.GoString(reason), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventIOErrorReasonCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventBlockJobCallback +func domainEventBlockJobCallback(c C.virConnectPtr, d C.virDomainPtr, + disk *C.char, _type int, status int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventBlockJob{ + Disk: C.GoString(disk), + Type: DomainBlockJobType(_type), + Status: ConnectDomainEventBlockJobStatus(status), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventBlockJobCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventDiskChangeCallback +func domainEventDiskChangeCallback(c C.virConnectPtr, d C.virDomainPtr, + oldSrcPath *C.char, newSrcPath *C.char, devAlias *C.char, + reason int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventDiskChange{ + OldSrcPath: C.GoString(oldSrcPath), + NewSrcPath: C.GoString(newSrcPath), + DevAlias: C.GoString(devAlias), + Reason: ConnectDomainEventDiskChangeReason(reason), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventDiskChangeCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventTrayChangeCallback +func domainEventTrayChangeCallback(c C.virConnectPtr, d C.virDomainPtr, + devAlias *C.char, reason int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventTrayChange{ + DevAlias: C.GoString(devAlias), + Reason: ConnectDomainEventTrayChangeReason(reason), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventTrayChangeCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventPMSuspendCallback +func domainEventPMSuspendCallback(c C.virConnectPtr, d C.virDomainPtr, + reason int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventPMSuspend{ + Reason: reason, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventPMSuspendCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventPMWakeupCallback +func domainEventPMWakeupCallback(c C.virConnectPtr, d C.virDomainPtr, + reason int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventPMWakeup{ + Reason: reason, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventPMWakeupCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventPMSuspendDiskCallback +func domainEventPMSuspendDiskCallback(c C.virConnectPtr, d C.virDomainPtr, + reason int, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventPMSuspendDisk{ + Reason: reason, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventPMSuspendDiskCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventBalloonChangeCallback +func domainEventBalloonChangeCallback(c C.virConnectPtr, d C.virDomainPtr, + actual uint64, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventBalloonChange{ + Actual: actual, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventBalloonChangeCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventDeviceRemovedCallback +func domainEventDeviceRemovedCallback(c C.virConnectPtr, d C.virDomainPtr, + devAlias *C.char, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventDeviceRemoved{ + DevAlias: C.GoString(devAlias), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventDeviceRemovedCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventMetadataChangeCallback +func domainEventMetadataChangeCallback(c C.virConnectPtr, d C.virDomainPtr, + mtype int, nsuri *C.char, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventMetadataChange{ + Type: (int)(mtype), + NSURI: C.GoString(nsuri), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventMetadataChangeCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +func getDomainTuneSchedulerParametersFieldInfo(params *DomainSchedulerParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_TUNABLE_CPU_CPU_SHARES: typedParamsFieldInfo{ + set: ¶ms.CpuSharesSet, + ul: ¶ms.CpuShares, + }, + C.VIR_DOMAIN_TUNABLE_CPU_GLOBAL_PERIOD: typedParamsFieldInfo{ + set: ¶ms.GlobalPeriodSet, + ul: ¶ms.GlobalPeriod, + }, + C.VIR_DOMAIN_TUNABLE_CPU_GLOBAL_QUOTA: typedParamsFieldInfo{ + set: ¶ms.GlobalQuotaSet, + ul: ¶ms.GlobalQuota, + }, + C.VIR_DOMAIN_TUNABLE_CPU_EMULATOR_PERIOD: typedParamsFieldInfo{ + set: ¶ms.EmulatorPeriodSet, + ul: ¶ms.EmulatorPeriod, + }, + C.VIR_DOMAIN_TUNABLE_CPU_EMULATOR_QUOTA: typedParamsFieldInfo{ + set: ¶ms.EmulatorQuotaSet, + ul: ¶ms.EmulatorQuota, + }, + C.VIR_DOMAIN_TUNABLE_CPU_VCPU_PERIOD: typedParamsFieldInfo{ + set: ¶ms.VcpuPeriodSet, + ul: ¶ms.VcpuPeriod, + }, + C.VIR_DOMAIN_TUNABLE_CPU_VCPU_QUOTA: typedParamsFieldInfo{ + set: ¶ms.VcpuQuotaSet, + ul: ¶ms.VcpuQuota, + }, + C.VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_PERIOD: typedParamsFieldInfo{ + set: ¶ms.IothreadPeriodSet, + ul: ¶ms.IothreadPeriod, + }, + C.VIR_DOMAIN_TUNABLE_CPU_IOTHREAD_QUOTA: typedParamsFieldInfo{ + set: ¶ms.IothreadQuotaSet, + ul: ¶ms.IothreadQuota, + }, + } +} + +func getTuneBlockIoTuneParametersFieldInfo(params *DomainBlockIoTuneParameters) map[string]typedParamsFieldInfo { + return map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecSet, + ul: ¶ms.TotalBytesSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecSet, + ul: ¶ms.ReadBytesSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecSet, + ul: ¶ms.WriteBytesSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecSet, + ul: ¶ms.TotalIopsSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecSet, + ul: ¶ms.ReadIopsSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecSet, + ul: ¶ms.WriteIopsSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecMaxSet, + ul: ¶ms.TotalBytesSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecMaxSet, + ul: ¶ms.ReadBytesSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecMaxSet, + ul: ¶ms.WriteBytesSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecMaxSet, + ul: ¶ms.TotalIopsSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecMaxSet, + ul: ¶ms.ReadIopsSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecMaxSet, + ul: ¶ms.WriteIopsSecMax, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.TotalBytesSecMaxLengthSet, + ul: ¶ms.TotalBytesSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.ReadBytesSecMaxLengthSet, + ul: ¶ms.ReadBytesSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_BYTES_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.WriteBytesSecMaxLengthSet, + ul: ¶ms.WriteBytesSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_TOTAL_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.TotalIopsSecMaxLengthSet, + ul: ¶ms.TotalIopsSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_READ_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.ReadIopsSecMaxLengthSet, + ul: ¶ms.ReadIopsSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_WRITE_IOPS_SEC_MAX_LENGTH: typedParamsFieldInfo{ + set: ¶ms.WriteIopsSecMaxLengthSet, + ul: ¶ms.WriteIopsSecMaxLength, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_SIZE_IOPS_SEC: typedParamsFieldInfo{ + set: ¶ms.SizeIopsSecSet, + ul: ¶ms.SizeIopsSec, + }, + C.VIR_DOMAIN_TUNABLE_BLKDEV_GROUP_NAME: typedParamsFieldInfo{ + set: ¶ms.GroupNameSet, + s: ¶ms.GroupName, + }, + } +} + +type domainEventTunablePinTemp struct { + VcpuPinSet bool + VcpuPin []string + EmulatorPinSet bool + EmulatorPin string + IOThreadPinSet bool + IOThreadPin []string +} + +func getDomainPinTempFieldInfo(numvcpu int, numiothread int, params *domainEventTunablePinTemp) map[string]typedParamsFieldInfo { + ret := map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN: typedParamsFieldInfo{ + set: ¶ms.EmulatorPinSet, + s: ¶ms.EmulatorPin, + }, + } + for i := 0; i < numvcpu; i++ { + ret[fmt.Sprintf("cputune.vcpupin%d", i)] = typedParamsFieldInfo{ + s: ¶ms.VcpuPin[i], + } + } + for i := 0; i < numiothread; i++ { + ret[fmt.Sprintf("cputune.iothreadpin%u", i)] = typedParamsFieldInfo{ + s: ¶ms.IOThreadPin[i], + } + } + + return ret +} + +func countPinInfo(cparams C.virTypedParameterPtr, nparams C.int) (int, int) { + maxvcpus := 0 + maxiothreads := 0 + for i := 0; i < int(nparams); i++ { + var cparam *C.virTypedParameter + cparam = (*C.virTypedParameter)(unsafe.Pointer(uintptr(unsafe.Pointer(cparams)) + unsafe.Sizeof(*cparam)*uintptr(i))) + name := C.GoString((*C.char)(unsafe.Pointer(&cparam.field))) + + var vcpu int + _, err := fmt.Scanf(name, "cputune.vcpupin%d", &vcpu) + if err == nil { + if vcpu > maxvcpus { + maxvcpus = vcpu + } + } + + var iothread int + _, err = fmt.Scanf(name, "cputune.iothreadpin%d", &iothread) + if err == nil { + if iothread > maxiothreads { + maxiothreads = iothread + } + } + } + + return maxvcpus + 1, maxiothreads + 1 +} + +func domainEventTunableGetPin(params C.virTypedParameterPtr, nparams C.int) *DomainEventTunableCpuPin { + var pin domainEventTunablePinTemp + numvcpus, numiothreads := countPinInfo(params, nparams) + pinInfo := getDomainPinTempFieldInfo(numvcpus, numiothreads, &pin) + + num, err := typedParamsUnpackLen(params, int(nparams), pinInfo) + if num == 0 || err != nil { + return nil + } + + info := &DomainEventTunableCpuPin{} + + if pin.VcpuPinSet { + info.VcpuPinSet = true + info.VcpuPin = make([][]bool, len(pin.VcpuPin)) + + for i := 0; i < len(pin.VcpuPin); i++ { + bits, err := parseCPUString(pin.VcpuPin[i]) + if err == nil { + info.VcpuPin[i] = bits + } + } + } + + if pin.EmulatorPinSet { + bits, err := parseCPUString(pin.EmulatorPin) + if err == nil { + info.EmulatorPinSet = true + info.EmulatorPin = bits + } + } + + if pin.IOThreadPinSet { + info.IOThreadPinSet = true + info.IOThreadPin = make([][]bool, len(pin.IOThreadPin)) + + for i := 0; i < len(pin.IOThreadPin); i++ { + bits, err := parseCPUString(pin.IOThreadPin[i]) + if err == nil { + info.IOThreadPin[i] = bits + } + } + } + + return info +} + +//export domainEventTunableCallback +func domainEventTunableCallback(c C.virConnectPtr, d C.virDomainPtr, params C.virTypedParameterPtr, nparams C.int, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventTunable{} + + pin := domainEventTunableGetPin(params, nparams) + if pin != nil { + eventDetails.CpuPin = pin + } + + var sched DomainSchedulerParameters + schedInfo := getDomainTuneSchedulerParametersFieldInfo(&sched) + + num, _ := typedParamsUnpackLen(params, int(nparams), schedInfo) + if num > 0 { + eventDetails.CpuSched = &sched + } + + blknameInfo := map[string]typedParamsFieldInfo{ + C.VIR_DOMAIN_TUNABLE_BLKDEV_DISK: typedParamsFieldInfo{ + set: &eventDetails.BlkdevDiskSet, + s: &eventDetails.BlkdevDisk, + }, + } + typedParamsUnpackLen(params, int(nparams), blknameInfo) + + var blktune DomainBlockIoTuneParameters + blktuneInfo := getTuneBlockIoTuneParametersFieldInfo(&blktune) + + num, _ = typedParamsUnpackLen(params, int(nparams), blktuneInfo) + if num > 0 { + eventDetails.BlkdevTune = &blktune + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventTunableCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventAgentLifecycleCallback +func domainEventAgentLifecycleCallback(c C.virConnectPtr, d C.virDomainPtr, state C.int, reason C.int, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventAgentLifecycle{ + State: ConnectDomainEventAgentLifecycleState(state), + Reason: ConnectDomainEventAgentLifecycleReason(reason), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventAgentLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventDeviceAddedCallback +func domainEventDeviceAddedCallback(c C.virConnectPtr, d C.virDomainPtr, devalias *C.char, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventDeviceAdded{ + DevAlias: C.GoString(devalias), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventDeviceAddedCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventMigrationIterationCallback +func domainEventMigrationIterationCallback(c C.virConnectPtr, d C.virDomainPtr, iteration C.int, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventMigrationIteration{ + Iteration: int(iteration), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventMigrationIterationCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventJobCompletedCallback +func domainEventJobCompletedCallback(c C.virConnectPtr, d C.virDomainPtr, params C.virTypedParameterPtr, nparams C.int, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventJobCompleted{} + info := getDomainJobInfoFieldInfo(&eventDetails.Info) + + typedParamsUnpackLen(params, int(nparams), info) + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventJobCompletedCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventDeviceRemovalFailedCallback +func domainEventDeviceRemovalFailedCallback(c C.virConnectPtr, d C.virDomainPtr, devalias *C.char, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventDeviceRemovalFailed{ + DevAlias: C.GoString(devalias), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventDeviceRemovalFailedCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +//export domainEventBlockThresholdCallback +func domainEventBlockThresholdCallback(c C.virConnectPtr, d C.virDomainPtr, dev *C.char, path *C.char, threshold C.ulonglong, excess C.ulonglong, goCallbackId int) { + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainEventBlockThreshold{ + Dev: C.GoString(dev), + Path: C.GoString(path), + Threshold: uint64(threshold), + Excess: uint64(excess), + } + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainEventBlockThresholdCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +func (c *Connect) DomainEventLifecycleRegister(dom *Domain, callback DomainEventLifecycleCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventLifecycleCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_LIFECYCLE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventRebootRegister(dom *Domain, callback DomainEventGenericCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventGenericCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_REBOOT, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventRTCChangeRegister(dom *Domain, callback DomainEventRTCChangeCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventRTCChangeCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_RTC_CHANGE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventWatchdogRegister(dom *Domain, callback DomainEventWatchdogCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventWatchdogCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_WATCHDOG, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventIOErrorRegister(dom *Domain, callback DomainEventIOErrorCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventIOErrorCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_IO_ERROR, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventGraphicsRegister(dom *Domain, callback DomainEventGraphicsCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventGraphicsCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_GRAPHICS, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventIOErrorReasonRegister(dom *Domain, callback DomainEventIOErrorReasonCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventIOErrorReasonCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventControlErrorRegister(dom *Domain, callback DomainEventGenericCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventGenericCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_CONTROL_ERROR, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventBlockJobRegister(dom *Domain, callback DomainEventBlockJobCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventBlockJobCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_BLOCK_JOB, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventDiskChangeRegister(dom *Domain, callback DomainEventDiskChangeCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventDiskChangeCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_DISK_CHANGE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventTrayChangeRegister(dom *Domain, callback DomainEventTrayChangeCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventTrayChangeCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_TRAY_CHANGE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventPMWakeupRegister(dom *Domain, callback DomainEventPMWakeupCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventPMWakeupCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_PMWAKEUP, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventPMSuspendRegister(dom *Domain, callback DomainEventPMSuspendCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventPMSuspendCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_PMSUSPEND, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventBalloonChangeRegister(dom *Domain, callback DomainEventBalloonChangeCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventBalloonChangeCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventPMSuspendDiskRegister(dom *Domain, callback DomainEventPMSuspendDiskCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventPMSuspendDiskCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventDeviceRemovedRegister(dom *Domain, callback DomainEventDeviceRemovedCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventDeviceRemovedCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventBlockJob2Register(dom *Domain, callback DomainEventBlockJobCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventBlockJobCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventTunableRegister(dom *Domain, callback DomainEventTunableCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventTunableCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_TUNABLE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventAgentLifecycleRegister(dom *Domain, callback DomainEventAgentLifecycleCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventAgentLifecycleCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventDeviceAddedRegister(dom *Domain, callback DomainEventDeviceAddedCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventDeviceAddedCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_DEVICE_ADDED, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventMigrationIterationRegister(dom *Domain, callback DomainEventMigrationIterationCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventMigrationIterationCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventJobCompletedRegister(dom *Domain, callback DomainEventJobCompletedCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventJobCompletedCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventDeviceRemovalFailedRegister(dom *Domain, callback DomainEventDeviceRemovalFailedCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventDeviceRemovalFailedCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventMetadataChangeRegister(dom *Domain, callback DomainEventMetadataChangeCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventMetadataChangeCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_METADATA_CHANGE, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventBlockThresholdRegister(dom *Domain, callback DomainEventBlockThresholdCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainEventBlockThresholdCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainEventRegisterAny_cgo(c.ptr, cdom, + C.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainEventDeregister(callbackId int) error { + // Deregister the callback + if i := int(C.virConnectDomainEventDeregisterAny(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} + +func (e DomainEventLifecycle) String() string { + var detail, event string + switch e.Event { + case DOMAIN_EVENT_DEFINED: + event = "defined" + switch DomainEventDefinedDetailType(e.Detail) { + case DOMAIN_EVENT_DEFINED_ADDED: + detail = "added" + case DOMAIN_EVENT_DEFINED_UPDATED: + detail = "updated" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_UNDEFINED: + event = "undefined" + switch DomainEventUndefinedDetailType(e.Detail) { + case DOMAIN_EVENT_UNDEFINED_REMOVED: + detail = "removed" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_STARTED: + event = "started" + switch DomainEventStartedDetailType(e.Detail) { + case DOMAIN_EVENT_STARTED_BOOTED: + detail = "booted" + case DOMAIN_EVENT_STARTED_MIGRATED: + detail = "migrated" + case DOMAIN_EVENT_STARTED_RESTORED: + detail = "restored" + case DOMAIN_EVENT_STARTED_FROM_SNAPSHOT: + detail = "snapshot" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_SUSPENDED: + event = "suspended" + switch DomainEventSuspendedDetailType(e.Detail) { + case DOMAIN_EVENT_SUSPENDED_PAUSED: + detail = "paused" + case DOMAIN_EVENT_SUSPENDED_MIGRATED: + detail = "migrated" + case DOMAIN_EVENT_SUSPENDED_IOERROR: + detail = "I/O error" + case DOMAIN_EVENT_SUSPENDED_WATCHDOG: + detail = "watchdog" + case DOMAIN_EVENT_SUSPENDED_RESTORED: + detail = "restored" + case DOMAIN_EVENT_SUSPENDED_FROM_SNAPSHOT: + detail = "snapshot" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_RESUMED: + event = "resumed" + switch DomainEventResumedDetailType(e.Detail) { + case DOMAIN_EVENT_RESUMED_UNPAUSED: + detail = "unpaused" + case DOMAIN_EVENT_RESUMED_MIGRATED: + detail = "migrated" + case DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT: + detail = "snapshot" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_STOPPED: + event = "stopped" + switch DomainEventStoppedDetailType(e.Detail) { + case DOMAIN_EVENT_STOPPED_SHUTDOWN: + detail = "shutdown" + case DOMAIN_EVENT_STOPPED_DESTROYED: + detail = "destroyed" + case DOMAIN_EVENT_STOPPED_CRASHED: + detail = "crashed" + case DOMAIN_EVENT_STOPPED_MIGRATED: + detail = "migrated" + case DOMAIN_EVENT_STOPPED_SAVED: + detail = "saved" + case DOMAIN_EVENT_STOPPED_FAILED: + detail = "failed" + case DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT: + detail = "snapshot" + default: + detail = "unknown" + } + + case DOMAIN_EVENT_SHUTDOWN: + event = "shutdown" + switch DomainEventShutdownDetailType(e.Detail) { + case DOMAIN_EVENT_SHUTDOWN_FINISHED: + detail = "finished" + default: + detail = "unknown" + } + + default: + event = "unknown" + } + + return fmt.Sprintf("Domain event=%q detail=%q", event, detail) +} + +func (e DomainEventRTCChange) String() string { + return fmt.Sprintf("RTC change offset=%d", e.Utcoffset) +} + +func (e DomainEventWatchdog) String() string { + return fmt.Sprintf("Watchdog action=%d", e.Action) +} + +func (e DomainEventIOError) String() string { + return fmt.Sprintf("I/O error path=%q alias=%q action=%d", + e.SrcPath, e.DevAlias, e.Action) +} + +func (e DomainEventGraphics) String() string { + var phase string + switch e.Phase { + case DOMAIN_EVENT_GRAPHICS_CONNECT: + phase = "connected" + case DOMAIN_EVENT_GRAPHICS_INITIALIZE: + phase = "initialized" + case DOMAIN_EVENT_GRAPHICS_DISCONNECT: + phase = "disconnected" + default: + phase = "unknown" + } + + return fmt.Sprintf("Graphics phase=%q", phase) +} + +func (e DomainEventIOErrorReason) String() string { + return fmt.Sprintf("IO error path=%q alias=%q action=%d reason=%q", + e.SrcPath, e.DevAlias, e.Action, e.Reason) +} + +func (e DomainEventBlockJob) String() string { + return fmt.Sprintf("Block job disk=%q status=%d type=%d", + e.Disk, e.Status, e.Type) +} + +func (e DomainEventDiskChange) String() string { + return fmt.Sprintf("Disk change old=%q new=%q alias=%q reason=%d", + e.OldSrcPath, e.NewSrcPath, e.DevAlias, e.Reason) +} + +func (e DomainEventTrayChange) String() string { + return fmt.Sprintf("Tray change dev=%q reason=%d", + e.DevAlias, e.Reason) +} + +func (e DomainEventBalloonChange) String() string { + return fmt.Sprintf("Ballon change %d", e.Actual) +} + +func (e DomainEventDeviceRemoved) String() string { + return fmt.Sprintf("Device %q removed ", e.DevAlias) +} diff --git a/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.go new file mode 100644 index 000000000000..c9de165c67c6 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.go @@ -0,0 +1,238 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "domain_events_cfuncs.h" +#include "callbacks_cfuncs.h" +#include + +extern void domainEventLifecycleCallback(virConnectPtr, virDomainPtr, int, int, int); +void domainEventLifecycleCallback_cgo(virConnectPtr c, virDomainPtr d, + int event, int detail, void *data) +{ + domainEventLifecycleCallback(c, d, event, detail, (int)(intptr_t)data); +} + +extern void domainEventGenericCallback(virConnectPtr, virDomainPtr, int); +void domainEventGenericCallback_cgo(virConnectPtr c, virDomainPtr d, void *data) +{ + domainEventGenericCallback(c, d, (int)(intptr_t)data); +} + +extern void domainEventRTCChangeCallback(virConnectPtr, virDomainPtr, long long, int); +void domainEventRTCChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + long long utcoffset, void *data) +{ + domainEventRTCChangeCallback(c, d, utcoffset, (int)(intptr_t)data); +} + +extern void domainEventWatchdogCallback(virConnectPtr, virDomainPtr, int, int); +void domainEventWatchdogCallback_cgo(virConnectPtr c, virDomainPtr d, + int action, void *data) +{ + domainEventWatchdogCallback(c, d, action, (int)(intptr_t)data); +} + +extern void domainEventIOErrorCallback(virConnectPtr, virDomainPtr, const char *, const char *, int, int); +void domainEventIOErrorCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *srcPath, const char *devAlias, + int action, void *data) +{ + domainEventIOErrorCallback(c, d, srcPath, devAlias, action, (int)(intptr_t)data); +} + +extern void domainEventGraphicsCallback(virConnectPtr, virDomainPtr, int, const virDomainEventGraphicsAddress *, + const virDomainEventGraphicsAddress *, const char *, + const virDomainEventGraphicsSubject *, int); +void domainEventGraphicsCallback_cgo(virConnectPtr c, virDomainPtr d, + int phase, const virDomainEventGraphicsAddress *local, + const virDomainEventGraphicsAddress *remote, + const char *authScheme, + const virDomainEventGraphicsSubject *subject, void *data) +{ + domainEventGraphicsCallback(c, d, phase, local, remote, authScheme, subject, (int)(intptr_t)data); +} + +extern void domainEventIOErrorReasonCallback(virConnectPtr, virDomainPtr, const char *, const char *, + int, const char *, int); +void domainEventIOErrorReasonCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *srcPath, const char *devAlias, + int action, const char *reason, void *data) +{ + domainEventIOErrorReasonCallback(c, d, srcPath, devAlias, action, reason, (int)(intptr_t)data); +} + +extern void domainEventBlockJobCallback(virConnectPtr, virDomainPtr, const char *, int, int, int); +void domainEventBlockJobCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *disk, int type, int status, void *data) +{ + domainEventBlockJobCallback(c, d, disk, type, status, (int)(intptr_t)data); +} + +extern void domainEventDiskChangeCallback(virConnectPtr, virDomainPtr, const char *, const char *, + const char *, int, int); +void domainEventDiskChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *oldSrcPath, const char *newSrcPath, + const char *devAlias, int reason, void *data) +{ + domainEventDiskChangeCallback(c, d, oldSrcPath, newSrcPath, devAlias, reason, (int)(intptr_t)data); +} + +extern void domainEventTrayChangeCallback(virConnectPtr, virDomainPtr, const char *, int, int); +void domainEventTrayChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *devAlias, int reason, void *data) +{ + domainEventTrayChangeCallback(c, d, devAlias, reason, (int)(intptr_t)data); +} + +extern void domainEventPMSuspendCallback(virConnectPtr, virDomainPtr, int, int); +void domainEventPMSuspendCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void *data) +{ + domainEventPMSuspendCallback(c, d, reason, (int)(intptr_t)data); +} + +extern void domainEventPMWakeupCallback(virConnectPtr, virDomainPtr, int, int); +void domainEventPMWakeupCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void *data) +{ + domainEventPMWakeupCallback(c, d, reason, (int)(intptr_t)data); +} + +extern void domainEventPMSuspendDiskCallback(virConnectPtr, virDomainPtr, int, int); +void domainEventPMSuspendDiskCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void *data) +{ + domainEventPMSuspendDiskCallback(c, d, reason, (int)(intptr_t)data); +} + +extern void domainEventBalloonChangeCallback(virConnectPtr, virDomainPtr, unsigned long long, int); +void domainEventBalloonChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + unsigned long long actual, void *data) +{ + domainEventBalloonChangeCallback(c, d, actual, (int)(intptr_t)data); +} + +extern void domainEventDeviceRemovedCallback(virConnectPtr, virDomainPtr, const char *, int); +void domainEventDeviceRemovedCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *devAlias, void *data) +{ + domainEventDeviceRemovedCallback(c, d, devAlias, (int)(intptr_t)data); +} + +extern void domainEventTunableCallback(virConnectPtr, virDomainPtr, virTypedParameterPtr, int, int); +void domainEventTunableCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + void *opaque) +{ + domainEventTunableCallback(conn, dom, params, nparams, (int)(intptr_t)opaque); +} + +extern void domainEventAgentLifecycleCallback(virConnectPtr, virDomainPtr, int, int, int); +void domainEventAgentLifecycleCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int state, + int reason, + void *opaque) +{ + domainEventAgentLifecycleCallback(conn, dom, state, reason, (int)(intptr_t)opaque); +} + +extern void domainEventDeviceAddedCallback(virConnectPtr, virDomainPtr, const char *, int); +void domainEventDeviceAddedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque) +{ + domainEventDeviceAddedCallback(conn, dom, devAlias, (int)(intptr_t)opaque); +} + +extern void domainEventMigrationIterationCallback(virConnectPtr, virDomainPtr, int, int); +void domainEventMigrationIterationCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int iteration, + void *opaque) +{ + domainEventMigrationIterationCallback(conn, dom, iteration, (int)(intptr_t)opaque); +} + +extern void domainEventJobCompletedCallback(virConnectPtr, virDomainPtr, virTypedParameterPtr, int, int); +void domainEventJobCompletedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + void *opaque) +{ + domainEventJobCompletedCallback(conn, dom, params, nparams, (int)(intptr_t)opaque); +} + +extern void domainEventDeviceRemovalFailedCallback(virConnectPtr, virDomainPtr, const char *, int); +void domainEventDeviceRemovalFailedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque) +{ + domainEventDeviceRemovalFailedCallback(conn, dom, devAlias, (int)(intptr_t)opaque); +} + +extern void domainEventMetadataChangeCallback(virConnectPtr, virDomainPtr, int, const char *, int); +void domainEventMetadataChangeCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int type, + const char *nsuri, + void *opaque) +{ + domainEventMetadataChangeCallback(conn, dom, type, nsuri, (int)(intptr_t)opaque); +} + +extern void domainEventBlockThresholdCallback(virConnectPtr, virDomainPtr, const char *, const char *, unsigned long long, unsigned long long, int); +void domainEventBlockThresholdCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *dev, + const char *path, + unsigned long long threshold, + unsigned long long excess, + void *opaque) +{ + domainEventBlockThresholdCallback(conn, dom, dev, path, threshold, excess, (int)(intptr_t)opaque); +} + +int virConnectDomainEventRegisterAny_cgo(virConnectPtr c, virDomainPtr d, + int eventID, virConnectDomainEventGenericCallback cb, + long goCallbackId) { + void* id = (void*)goCallbackId; + return virConnectDomainEventRegisterAny(c, d, eventID, cb, id, freeGoCallback_cgo); +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.h new file mode 100644 index 000000000000..423a1ccc3a43 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_events_cfuncs.h @@ -0,0 +1,124 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ + +void domainEventLifecycleCallback_cgo(virConnectPtr c, virDomainPtr d, + int event, int detail, void* data); + +void domainEventGenericCallback_cgo(virConnectPtr c, virDomainPtr d, void* data); + +void domainEventRTCChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + long long utcoffset, void* data); + +void domainEventWatchdogCallback_cgo(virConnectPtr c, virDomainPtr d, + int action, void* data); + +void domainEventIOErrorCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *srcPath, const char *devAlias, + int action, void* data); + +void domainEventGraphicsCallback_cgo(virConnectPtr c, virDomainPtr d, + int phase, const virDomainEventGraphicsAddress *local, + const virDomainEventGraphicsAddress *remote, + const char *authScheme, + const virDomainEventGraphicsSubject *subject, void* data); + +void domainEventIOErrorReasonCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *srcPath, const char *devAlias, + int action, const char *reason, void* data); + +void domainEventBlockJobCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *disk, int type, int status, void* data); + +void domainEventDiskChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *oldSrcPath, const char *newSrcPath, + const char *devAlias, int reason, void* data); + +void domainEventTrayChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *devAlias, int reason, void* data); + +void domainEventPMSuspendCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void* data); + +void domainEventPMWakeupCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void* data); + +void domainEventPMSuspendDiskCallback_cgo(virConnectPtr c, virDomainPtr d, + int reason, void* data); + +void domainEventBalloonChangeCallback_cgo(virConnectPtr c, virDomainPtr d, + unsigned long long actual, void* data); + +void domainEventDeviceRemovedCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *devAlias, void* data); +void domainEventTunableCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + void *opaque); +void domainEventAgentLifecycleCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int state, + int reason, + void *opaque); +void domainEventDeviceAddedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque); +void domainEventMigrationIterationCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int iteration, + void *opaque); +void domainEventJobCompletedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + virTypedParameterPtr params, + int nparams, + void *opaque); +void domainEventDeviceRemovalFailedCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *devAlias, + void *opaque); +void domainEventMetadataChangeCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + int type, + const char *nsuri, + void *opaque); +void domainEventBlockThresholdCallback_cgo(virConnectPtr conn, + virDomainPtr dom, + const char *dev, + const char *path, + unsigned long long threshold, + unsigned long long excess, + void *opaque); + +int virConnectDomainEventRegisterAny_cgo(virConnectPtr c, virDomainPtr d, + int eventID, virConnectDomainEventGenericCallback cb, + long goCallbackId); + + +#endif /* LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/domain_snapshot.go b/vendor/github.com/libvirt/libvirt-go/domain_snapshot.go new file mode 100644 index 000000000000..17c9c0cacc81 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/domain_snapshot.go @@ -0,0 +1,217 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +*/ +import "C" + +import ( + "reflect" + "unsafe" +) + +type DomainSnapshotCreateFlags int + +const ( + DOMAIN_SNAPSHOT_CREATE_REDEFINE = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE) + DOMAIN_SNAPSHOT_CREATE_CURRENT = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT) + DOMAIN_SNAPSHOT_CREATE_NO_METADATA = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA) + DOMAIN_SNAPSHOT_CREATE_HALT = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_HALT) + DOMAIN_SNAPSHOT_CREATE_DISK_ONLY = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY) + DOMAIN_SNAPSHOT_CREATE_REUSE_EXT = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) + DOMAIN_SNAPSHOT_CREATE_QUIESCE = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE) + DOMAIN_SNAPSHOT_CREATE_ATOMIC = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC) + DOMAIN_SNAPSHOT_CREATE_LIVE = DomainSnapshotCreateFlags(C.VIR_DOMAIN_SNAPSHOT_CREATE_LIVE) +) + +type DomainSnapshotListFlags int + +const ( + DOMAIN_SNAPSHOT_LIST_ROOTS = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS) + DOMAIN_SNAPSHOT_LIST_DESCENDANTS = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_DESCENDANTS) + DOMAIN_SNAPSHOT_LIST_LEAVES = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_LEAVES) + DOMAIN_SNAPSHOT_LIST_NO_LEAVES = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_NO_LEAVES) + DOMAIN_SNAPSHOT_LIST_METADATA = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_METADATA) + DOMAIN_SNAPSHOT_LIST_NO_METADATA = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_NO_METADATA) + DOMAIN_SNAPSHOT_LIST_INACTIVE = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE) + DOMAIN_SNAPSHOT_LIST_ACTIVE = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE) + DOMAIN_SNAPSHOT_LIST_DISK_ONLY = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY) + DOMAIN_SNAPSHOT_LIST_INTERNAL = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_INTERNAL) + DOMAIN_SNAPSHOT_LIST_EXTERNAL = DomainSnapshotListFlags(C.VIR_DOMAIN_SNAPSHOT_LIST_EXTERNAL) +) + +type DomainSnapshotRevertFlags int + +const ( + DOMAIN_SNAPSHOT_REVERT_RUNNING = DomainSnapshotRevertFlags(C.VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING) + DOMAIN_SNAPSHOT_REVERT_PAUSED = DomainSnapshotRevertFlags(C.VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED) + DOMAIN_SNAPSHOT_REVERT_FORCE = DomainSnapshotRevertFlags(C.VIR_DOMAIN_SNAPSHOT_REVERT_FORCE) +) + +type DomainSnapshotDeleteFlags int + +const ( + DOMAIN_SNAPSHOT_DELETE_CHILDREN = DomainSnapshotDeleteFlags(C.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN) + DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY = DomainSnapshotDeleteFlags(C.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY) + DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY = DomainSnapshotDeleteFlags(C.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN_ONLY) +) + +type DomainSnapshot struct { + ptr C.virDomainSnapshotPtr +} + +func (s *DomainSnapshot) Free() error { + ret := C.virDomainSnapshotFree(s.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *DomainSnapshot) Ref() error { + ret := C.virDomainSnapshotRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (s *DomainSnapshot) Delete(flags DomainSnapshotDeleteFlags) error { + result := C.virDomainSnapshotDelete(s.ptr, C.uint(flags)) + if result != 0 { + return GetLastError() + } + return nil +} + +func (s *DomainSnapshot) RevertToSnapshot(flags DomainSnapshotRevertFlags) error { + result := C.virDomainRevertToSnapshot(s.ptr, C.uint(flags)) + if result != 0 { + return GetLastError() + } + return nil +} + +func (s *DomainSnapshot) IsCurrent(flags uint32) (bool, error) { + result := C.virDomainSnapshotIsCurrent(s.ptr, C.uint(flags)) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (s *DomainSnapshot) HasMetadata(flags uint32) (bool, error) { + result := C.virDomainSnapshotHasMetadata(s.ptr, C.uint(flags)) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (s *DomainSnapshot) GetXMLDesc(flags DomainXMLFlags) (string, error) { + result := C.virDomainSnapshotGetXMLDesc(s.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (s *DomainSnapshot) GetName() (string, error) { + name := C.virDomainSnapshotGetName(s.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (s *DomainSnapshot) GetParent(flags uint32) (*DomainSnapshot, error) { + ptr := C.virDomainSnapshotGetParent(s.ptr, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &DomainSnapshot{ptr: ptr}, nil +} + +func (s *DomainSnapshot) NumChildren(flags DomainSnapshotListFlags) (int, error) { + result := int(C.virDomainSnapshotNumChildren(s.ptr, C.uint(flags))) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (s *DomainSnapshot) ListChildrenNames(flags DomainSnapshotListFlags) ([]string, error) { + const maxNames = 1024 + var names [maxNames](*C.char) + namesPtr := unsafe.Pointer(&names) + numNames := C.virDomainSnapshotListChildrenNames( + s.ptr, + (**C.char)(namesPtr), + maxNames, C.uint(flags)) + if numNames == -1 { + return nil, GetLastError() + } + goNames := make([]string, numNames) + for k := 0; k < int(numNames); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (d *DomainSnapshot) ListAllChildren(flags DomainSnapshotListFlags) ([]DomainSnapshot, error) { + var cList *C.virDomainSnapshotPtr + numVols := C.virDomainSnapshotListAllChildren(d.ptr, (**C.virDomainSnapshotPtr)(&cList), C.uint(flags)) + if numVols == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numVols), + Cap: int(numVols), + } + var pools []DomainSnapshot + slice := *(*[]C.virDomainSnapshotPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, DomainSnapshot{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/error.go b/vendor/github.com/libvirt/libvirt-go/error.go new file mode 100644 index 000000000000..24d4b09fa7bb --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/error.go @@ -0,0 +1,601 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "error_compat.h" + +void ignoreErrorFunc(void *userData, virErrorPtr error) { + // no-op +} +*/ +import "C" + +import ( + "fmt" +) + +func init() { + C.virSetErrorFunc(nil, (C.virErrorFunc)(C.ignoreErrorFunc)) + C.virInitialize() +} + +type ErrorLevel int + +const ( + ERR_NONE = ErrorLevel(C.VIR_ERR_NONE) + ERR_WARNING = ErrorLevel(C.VIR_ERR_WARNING) + ERR_ERROR = ErrorLevel(C.VIR_ERR_ERROR) +) + +type ErrorNumber int + +const ( + ERR_OK = ErrorNumber(C.VIR_ERR_OK) + + // internal error + ERR_INTERNAL_ERROR = ErrorNumber(C.VIR_ERR_INTERNAL_ERROR) + + // memory allocation failure + ERR_NO_MEMORY = ErrorNumber(C.VIR_ERR_NO_MEMORY) + + // no support for this function + ERR_NO_SUPPORT = ErrorNumber(C.VIR_ERR_NO_SUPPORT) + + // could not resolve hostname + ERR_UNKNOWN_HOST = ErrorNumber(C.VIR_ERR_UNKNOWN_HOST) + + // can't connect to hypervisor + ERR_NO_CONNECT = ErrorNumber(C.VIR_ERR_NO_CONNECT) + + // invalid connection object + ERR_INVALID_CONN = ErrorNumber(C.VIR_ERR_INVALID_CONN) + + // invalid domain object + ERR_INVALID_DOMAIN = ErrorNumber(C.VIR_ERR_INVALID_DOMAIN) + + // invalid function argument + ERR_INVALID_ARG = ErrorNumber(C.VIR_ERR_INVALID_ARG) + + // a command to hypervisor failed + ERR_OPERATION_FAILED = ErrorNumber(C.VIR_ERR_OPERATION_FAILED) + + // a HTTP GET command to failed + ERR_GET_FAILED = ErrorNumber(C.VIR_ERR_GET_FAILED) + + // a HTTP POST command to failed + ERR_POST_FAILED = ErrorNumber(C.VIR_ERR_POST_FAILED) + + // unexpected HTTP error code + ERR_HTTP_ERROR = ErrorNumber(C.VIR_ERR_HTTP_ERROR) + + // failure to serialize an S-Expr + ERR_SEXPR_SERIAL = ErrorNumber(C.VIR_ERR_SEXPR_SERIAL) + + // could not open Xen hypervisor control + ERR_NO_XEN = ErrorNumber(C.VIR_ERR_NO_XEN) + + // failure doing an hypervisor call + ERR_XEN_CALL = ErrorNumber(C.VIR_ERR_XEN_CALL) + + // unknown OS type + ERR_OS_TYPE = ErrorNumber(C.VIR_ERR_OS_TYPE) + + // missing kernel information + ERR_NO_KERNEL = ErrorNumber(C.VIR_ERR_NO_KERNEL) + + // missing root device information + ERR_NO_ROOT = ErrorNumber(C.VIR_ERR_NO_ROOT) + + // missing source device information + ERR_NO_SOURCE = ErrorNumber(C.VIR_ERR_NO_SOURCE) + + // missing target device information + ERR_NO_TARGET = ErrorNumber(C.VIR_ERR_NO_TARGET) + + // missing domain name information + ERR_NO_NAME = ErrorNumber(C.VIR_ERR_NO_NAME) + + // missing domain OS information + ERR_NO_OS = ErrorNumber(C.VIR_ERR_NO_OS) + + // missing domain devices information + ERR_NO_DEVICE = ErrorNumber(C.VIR_ERR_NO_DEVICE) + + // could not open Xen Store control + ERR_NO_XENSTORE = ErrorNumber(C.VIR_ERR_NO_XENSTORE) + + // too many drivers registered + ERR_DRIVER_FULL = ErrorNumber(C.VIR_ERR_DRIVER_FULL) + + // not supported by the drivers (DEPRECATED) + ERR_CALL_FAILED = ErrorNumber(C.VIR_ERR_CALL_FAILED) + + // an XML description is not well formed or broken + ERR_XML_ERROR = ErrorNumber(C.VIR_ERR_XML_ERROR) + + // the domain already exist + ERR_DOM_EXIST = ErrorNumber(C.VIR_ERR_DOM_EXIST) + + // operation forbidden on read-only connections + ERR_OPERATION_DENIED = ErrorNumber(C.VIR_ERR_OPERATION_DENIED) + + // failed to open a conf file + ERR_OPEN_FAILED = ErrorNumber(C.VIR_ERR_OPEN_FAILED) + + // failed to read a conf file + ERR_READ_FAILED = ErrorNumber(C.VIR_ERR_READ_FAILED) + + // failed to parse a conf file + ERR_PARSE_FAILED = ErrorNumber(C.VIR_ERR_PARSE_FAILED) + + // failed to parse the syntax of a conf file + ERR_CONF_SYNTAX = ErrorNumber(C.VIR_ERR_CONF_SYNTAX) + + // failed to write a conf file + ERR_WRITE_FAILED = ErrorNumber(C.VIR_ERR_WRITE_FAILED) + + // detail of an XML error + ERR_XML_DETAIL = ErrorNumber(C.VIR_ERR_XML_DETAIL) + + // invalid network object + ERR_INVALID_NETWORK = ErrorNumber(C.VIR_ERR_INVALID_NETWORK) + + // the network already exist + ERR_NETWORK_EXIST = ErrorNumber(C.VIR_ERR_NETWORK_EXIST) + + // general system call failure + ERR_SYSTEM_ERROR = ErrorNumber(C.VIR_ERR_SYSTEM_ERROR) + + // some sort of RPC error + ERR_RPC = ErrorNumber(C.VIR_ERR_RPC) + + // error from a GNUTLS call + ERR_GNUTLS_ERROR = ErrorNumber(C.VIR_ERR_GNUTLS_ERROR) + + // failed to start network + WAR_NO_NETWORK = ErrorNumber(C.VIR_WAR_NO_NETWORK) + + // domain not found or unexpectedly disappeared + ERR_NO_DOMAIN = ErrorNumber(C.VIR_ERR_NO_DOMAIN) + + // network not found + ERR_NO_NETWORK = ErrorNumber(C.VIR_ERR_NO_NETWORK) + + // invalid MAC address + ERR_INVALID_MAC = ErrorNumber(C.VIR_ERR_INVALID_MAC) + + // authentication failed + ERR_AUTH_FAILED = ErrorNumber(C.VIR_ERR_AUTH_FAILED) + + // invalid storage pool object + ERR_INVALID_STORAGE_POOL = ErrorNumber(C.VIR_ERR_INVALID_STORAGE_POOL) + + // invalid storage vol object + ERR_INVALID_STORAGE_VOL = ErrorNumber(C.VIR_ERR_INVALID_STORAGE_VOL) + + // failed to start storage + WAR_NO_STORAGE = ErrorNumber(C.VIR_WAR_NO_STORAGE) + + // storage pool not found + ERR_NO_STORAGE_POOL = ErrorNumber(C.VIR_ERR_NO_STORAGE_POOL) + + // storage volume not found + ERR_NO_STORAGE_VOL = ErrorNumber(C.VIR_ERR_NO_STORAGE_VOL) + + // failed to start node driver + WAR_NO_NODE = ErrorNumber(C.VIR_WAR_NO_NODE) + + // invalid node device object + ERR_INVALID_NODE_DEVICE = ErrorNumber(C.VIR_ERR_INVALID_NODE_DEVICE) + + // node device not found + ERR_NO_NODE_DEVICE = ErrorNumber(C.VIR_ERR_NO_NODE_DEVICE) + + // security model not found + ERR_NO_SECURITY_MODEL = ErrorNumber(C.VIR_ERR_NO_SECURITY_MODEL) + + // operation is not applicable at this time + ERR_OPERATION_INVALID = ErrorNumber(C.VIR_ERR_OPERATION_INVALID) + + // failed to start interface driver + WAR_NO_INTERFACE = ErrorNumber(C.VIR_WAR_NO_INTERFACE) + + // interface driver not running + ERR_NO_INTERFACE = ErrorNumber(C.VIR_ERR_NO_INTERFACE) + + // invalid interface object + ERR_INVALID_INTERFACE = ErrorNumber(C.VIR_ERR_INVALID_INTERFACE) + + // more than one matching interface found + ERR_MULTIPLE_INTERFACES = ErrorNumber(C.VIR_ERR_MULTIPLE_INTERFACES) + + // failed to start nwfilter driver + WAR_NO_NWFILTER = ErrorNumber(C.VIR_WAR_NO_NWFILTER) + + // invalid nwfilter object + ERR_INVALID_NWFILTER = ErrorNumber(C.VIR_ERR_INVALID_NWFILTER) + + // nw filter pool not found + ERR_NO_NWFILTER = ErrorNumber(C.VIR_ERR_NO_NWFILTER) + + // nw filter pool not found + ERR_BUILD_FIREWALL = ErrorNumber(C.VIR_ERR_BUILD_FIREWALL) + + // failed to start secret storage + WAR_NO_SECRET = ErrorNumber(C.VIR_WAR_NO_SECRET) + + // invalid secret + ERR_INVALID_SECRET = ErrorNumber(C.VIR_ERR_INVALID_SECRET) + + // secret not found + ERR_NO_SECRET = ErrorNumber(C.VIR_ERR_NO_SECRET) + + // unsupported configuration construct + ERR_CONFIG_UNSUPPORTED = ErrorNumber(C.VIR_ERR_CONFIG_UNSUPPORTED) + + // timeout occurred during operation + ERR_OPERATION_TIMEOUT = ErrorNumber(C.VIR_ERR_OPERATION_TIMEOUT) + + // a migration worked, but making the VM persist on the dest host failed + ERR_MIGRATE_PERSIST_FAILED = ErrorNumber(C.VIR_ERR_MIGRATE_PERSIST_FAILED) + + // a synchronous hook script failed + ERR_HOOK_SCRIPT_FAILED = ErrorNumber(C.VIR_ERR_HOOK_SCRIPT_FAILED) + + // invalid domain snapshot + ERR_INVALID_DOMAIN_SNAPSHOT = ErrorNumber(C.VIR_ERR_INVALID_DOMAIN_SNAPSHOT) + + // domain snapshot not found + ERR_NO_DOMAIN_SNAPSHOT = ErrorNumber(C.VIR_ERR_NO_DOMAIN_SNAPSHOT) + + // stream pointer not valid + ERR_INVALID_STREAM = ErrorNumber(C.VIR_ERR_INVALID_STREAM) + + // valid API use but unsupported by the given driver + ERR_ARGUMENT_UNSUPPORTED = ErrorNumber(C.VIR_ERR_ARGUMENT_UNSUPPORTED) + + // storage pool probe failed + ERR_STORAGE_PROBE_FAILED = ErrorNumber(C.VIR_ERR_STORAGE_PROBE_FAILED) + + // storage pool already built + ERR_STORAGE_POOL_BUILT = ErrorNumber(C.VIR_ERR_STORAGE_POOL_BUILT) + + // force was not requested for a risky domain snapshot revert + ERR_SNAPSHOT_REVERT_RISKY = ErrorNumber(C.VIR_ERR_SNAPSHOT_REVERT_RISKY) + + // operation on a domain was canceled/aborted by user + ERR_OPERATION_ABORTED = ErrorNumber(C.VIR_ERR_OPERATION_ABORTED) + + // authentication cancelled + ERR_AUTH_CANCELLED = ErrorNumber(C.VIR_ERR_AUTH_CANCELLED) + + // The metadata is not present + ERR_NO_DOMAIN_METADATA = ErrorNumber(C.VIR_ERR_NO_DOMAIN_METADATA) + + // Migration is not safe + ERR_MIGRATE_UNSAFE = ErrorNumber(C.VIR_ERR_MIGRATE_UNSAFE) + + // integer overflow + ERR_OVERFLOW = ErrorNumber(C.VIR_ERR_OVERFLOW) + + // action prevented by block copy job + ERR_BLOCK_COPY_ACTIVE = ErrorNumber(C.VIR_ERR_BLOCK_COPY_ACTIVE) + + // The requested operation is not supported + ERR_OPERATION_UNSUPPORTED = ErrorNumber(C.VIR_ERR_OPERATION_UNSUPPORTED) + + // error in ssh transport driver + ERR_SSH = ErrorNumber(C.VIR_ERR_SSH) + + // guest agent is unresponsive, not running or not usable + ERR_AGENT_UNRESPONSIVE = ErrorNumber(C.VIR_ERR_AGENT_UNRESPONSIVE) + + // resource is already in use + ERR_RESOURCE_BUSY = ErrorNumber(C.VIR_ERR_RESOURCE_BUSY) + + // operation on the object/resource was denied + ERR_ACCESS_DENIED = ErrorNumber(C.VIR_ERR_ACCESS_DENIED) + + // error from a dbus service + ERR_DBUS_SERVICE = ErrorNumber(C.VIR_ERR_DBUS_SERVICE) + + // the storage vol already exists + ERR_STORAGE_VOL_EXIST = ErrorNumber(C.VIR_ERR_STORAGE_VOL_EXIST) + + // given CPU is incompatible with host CPU + ERR_CPU_INCOMPATIBLE = ErrorNumber(C.VIR_ERR_CPU_INCOMPATIBLE) + + // XML document doesn't validate against schema + ERR_XML_INVALID_SCHEMA = ErrorNumber(C.VIR_ERR_XML_INVALID_SCHEMA) + + // Finish API succeeded but it is expected to return NULL */ + ERR_MIGRATE_FINISH_OK = ErrorNumber(C.VIR_ERR_MIGRATE_FINISH_OK) + + // authentication unavailable + ERR_AUTH_UNAVAILABLE = ErrorNumber(C.VIR_ERR_AUTH_UNAVAILABLE) + + // Server was not found + ERR_NO_SERVER = ErrorNumber(C.VIR_ERR_NO_SERVER) + + // Client was not found + ERR_NO_CLIENT = ErrorNumber(C.VIR_ERR_NO_CLIENT) + + // guest agent replies with wrong id to guest sync command + ERR_AGENT_UNSYNCED = ErrorNumber(C.VIR_ERR_AGENT_UNSYNCED) + + // error in libssh transport driver + ERR_LIBSSH = ErrorNumber(C.VIR_ERR_LIBSSH) +) + +type ErrorDomain int + +const ( + FROM_NONE = ErrorDomain(C.VIR_FROM_NONE) + + // Error at Xen hypervisor layer + FROM_XEN = ErrorDomain(C.VIR_FROM_XEN) + + // Error at connection with xend daemon + FROM_XEND = ErrorDomain(C.VIR_FROM_XEND) + + // Error at connection with xen store + FROM_XENSTORE = ErrorDomain(C.VIR_FROM_XENSTORE) + + // Error in the S-Expression code + FROM_SEXPR = ErrorDomain(C.VIR_FROM_SEXPR) + + // Error in the XML code + FROM_XML = ErrorDomain(C.VIR_FROM_XML) + + // Error when operating on a domain + FROM_DOM = ErrorDomain(C.VIR_FROM_DOM) + + // Error in the XML-RPC code + FROM_RPC = ErrorDomain(C.VIR_FROM_RPC) + + // Error in the proxy code; unused since 0.8.6 + FROM_PROXY = ErrorDomain(C.VIR_FROM_PROXY) + + // Error in the configuration file handling + FROM_CONF = ErrorDomain(C.VIR_FROM_CONF) + + // Error at the QEMU daemon + FROM_QEMU = ErrorDomain(C.VIR_FROM_QEMU) + + // Error when operating on a network + FROM_NET = ErrorDomain(C.VIR_FROM_NET) + + // Error from test driver + FROM_TEST = ErrorDomain(C.VIR_FROM_TEST) + + // Error from remote driver + FROM_REMOTE = ErrorDomain(C.VIR_FROM_REMOTE) + + // Error from OpenVZ driver + FROM_OPENVZ = ErrorDomain(C.VIR_FROM_OPENVZ) + + // Error at Xen XM layer + FROM_XENXM = ErrorDomain(C.VIR_FROM_XENXM) + + // Error in the Linux Stats code + FROM_STATS_LINUX = ErrorDomain(C.VIR_FROM_STATS_LINUX) + + // Error from Linux Container driver + FROM_LXC = ErrorDomain(C.VIR_FROM_LXC) + + // Error from storage driver + FROM_STORAGE = ErrorDomain(C.VIR_FROM_STORAGE) + + // Error from network config + FROM_NETWORK = ErrorDomain(C.VIR_FROM_NETWORK) + + // Error from domain config + FROM_DOMAIN = ErrorDomain(C.VIR_FROM_DOMAIN) + + // Error at the UML driver + FROM_UML = ErrorDomain(C.VIR_FROM_UML) + + // Error from node device monitor + FROM_NODEDEV = ErrorDomain(C.VIR_FROM_NODEDEV) + + // Error from xen inotify layer + FROM_XEN_INOTIFY = ErrorDomain(C.VIR_FROM_XEN_INOTIFY) + + // Error from security framework + FROM_SECURITY = ErrorDomain(C.VIR_FROM_SECURITY) + + // Error from VirtualBox driver + FROM_VBOX = ErrorDomain(C.VIR_FROM_VBOX) + + // Error when operating on an interface + FROM_INTERFACE = ErrorDomain(C.VIR_FROM_INTERFACE) + + // The OpenNebula driver no longer exists. Retained for ABI/API compat only + FROM_ONE = ErrorDomain(C.VIR_FROM_ONE) + + // Error from ESX driver + FROM_ESX = ErrorDomain(C.VIR_FROM_ESX) + + // Error from IBM power hypervisor + FROM_PHYP = ErrorDomain(C.VIR_FROM_PHYP) + + // Error from secret storage + FROM_SECRET = ErrorDomain(C.VIR_FROM_SECRET) + + // Error from CPU driver + FROM_CPU = ErrorDomain(C.VIR_FROM_CPU) + + // Error from XenAPI + FROM_XENAPI = ErrorDomain(C.VIR_FROM_XENAPI) + + // Error from network filter driver + FROM_NWFILTER = ErrorDomain(C.VIR_FROM_NWFILTER) + + // Error from Synchronous hooks + FROM_HOOK = ErrorDomain(C.VIR_FROM_HOOK) + + // Error from domain snapshot + FROM_DOMAIN_SNAPSHOT = ErrorDomain(C.VIR_FROM_DOMAIN_SNAPSHOT) + + // Error from auditing subsystem + FROM_AUDIT = ErrorDomain(C.VIR_FROM_AUDIT) + + // Error from sysinfo/SMBIOS + FROM_SYSINFO = ErrorDomain(C.VIR_FROM_SYSINFO) + + // Error from I/O streams + FROM_STREAMS = ErrorDomain(C.VIR_FROM_STREAMS) + + // Error from VMware driver + FROM_VMWARE = ErrorDomain(C.VIR_FROM_VMWARE) + + // Error from event loop impl + FROM_EVENT = ErrorDomain(C.VIR_FROM_EVENT) + + // Error from libxenlight driver + FROM_LIBXL = ErrorDomain(C.VIR_FROM_LIBXL) + + // Error from lock manager + FROM_LOCKING = ErrorDomain(C.VIR_FROM_LOCKING) + + // Error from Hyper-V driver + FROM_HYPERV = ErrorDomain(C.VIR_FROM_HYPERV) + + // Error from capabilities + FROM_CAPABILITIES = ErrorDomain(C.VIR_FROM_CAPABILITIES) + + // Error from URI handling + FROM_URI = ErrorDomain(C.VIR_FROM_URI) + + // Error from auth handling + FROM_AUTH = ErrorDomain(C.VIR_FROM_AUTH) + + // Error from DBus + FROM_DBUS = ErrorDomain(C.VIR_FROM_DBUS) + + // Error from Parallels + FROM_PARALLELS = ErrorDomain(C.VIR_FROM_PARALLELS) + + // Error from Device + FROM_DEVICE = ErrorDomain(C.VIR_FROM_DEVICE) + + // Error from libssh2 connection transport + FROM_SSH = ErrorDomain(C.VIR_FROM_SSH) + + // Error from lockspace + FROM_LOCKSPACE = ErrorDomain(C.VIR_FROM_LOCKSPACE) + + // Error from initctl device communication + FROM_INITCTL = ErrorDomain(C.VIR_FROM_INITCTL) + + // Error from identity code + FROM_IDENTITY = ErrorDomain(C.VIR_FROM_IDENTITY) + + // Error from cgroups + FROM_CGROUP = ErrorDomain(C.VIR_FROM_CGROUP) + + // Error from access control manager + FROM_ACCESS = ErrorDomain(C.VIR_FROM_ACCESS) + + // Error from systemd code + FROM_SYSTEMD = ErrorDomain(C.VIR_FROM_SYSTEMD) + + // Error from bhyve driver + FROM_BHYVE = ErrorDomain(C.VIR_FROM_BHYVE) + + // Error from crypto code + FROM_CRYPTO = ErrorDomain(C.VIR_FROM_CRYPTO) + + // Error from firewall + FROM_FIREWALL = ErrorDomain(C.VIR_FROM_FIREWALL) + + // Erorr from polkit code + FROM_POLKIT = ErrorDomain(C.VIR_FROM_POLKIT) + + // Error from thread utils + FROM_THREAD = ErrorDomain(C.VIR_FROM_THREAD) + + // Error from admin backend + FROM_ADMIN = ErrorDomain(C.VIR_FROM_ADMIN) + + // Error from log manager + FROM_LOGGING = ErrorDomain(C.VIR_FROM_LOGGING) + + // Error from Xen xl config code + FROM_XENXL = ErrorDomain(C.VIR_FROM_XENXL) + + // Error from perf + FROM_PERF = ErrorDomain(C.VIR_FROM_PERF) + + // Error from libssh + FROM_LIBSSH = ErrorDomain(C.VIR_FROM_LIBSSH) +) + +type Error struct { + Code ErrorNumber + Domain ErrorDomain + Message string + Level ErrorLevel +} + +func (err Error) Error() string { + return fmt.Sprintf("virError(Code=%d, Domain=%d, Message='%s')", + err.Code, err.Domain, err.Message) +} + +func GetLastError() Error { + err := C.virGetLastError() + if err == nil { + return Error{ + Code: ERR_OK, + Domain: FROM_NONE, + Message: "Missing error", + Level: ERR_NONE, + } + } + virErr := Error{ + Code: ErrorNumber(err.code), + Domain: ErrorDomain(err.domain), + Message: C.GoString(err.message), + Level: ErrorLevel(err.level), + } + C.virResetError(err) + return virErr +} + +func GetNotImplementedError(apiname string) Error { + return Error{ + Code: ERR_NO_SUPPORT, + Domain: FROM_NONE, + Message: fmt.Sprintf("Function '%s' not available in the libvirt library used during Go build", apiname), + Level: ERR_ERROR, + } +} diff --git a/vendor/github.com/libvirt/libvirt-go/error_compat.h b/vendor/github.com/libvirt/libvirt-go/error_compat.h new file mode 100644 index 000000000000..665ec0795a01 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/error_compat.h @@ -0,0 +1,144 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_ERROR_COMPAT_H__ +#define LIBVIRT_GO_ERROR_COMPAT_H__ + +/* 1.2.2 */ + +#ifndef VIR_FROM_BHYVE +#define VIR_FROM_BHYVE 57 +#endif + + +/* 1.2.3 */ + +#ifndef VIR_FROM_CRYPTO +#define VIR_FROM_CRYPTO 58 +#endif + + +/* 1.2.4 */ + +#ifndef VIR_FROM_FIREWALL +#define VIR_FROM_FIREWALL 59 +#endif + + +/* 1.2.6 */ + +#ifndef VIR_ERR_CPU_INCOMPATIBLE +#define VIR_ERR_CPU_INCOMPATIBLE 91 +#endif + + +/* 1.2.9 */ + +#ifndef VIR_FROM_POLKIT +#define VIR_FROM_POLKIT 60 +#endif + + +/* 1.2.12 */ + +#ifndef VIR_ERR_XML_INVALID_SCHEMA +#define VIR_ERR_XML_INVALID_SCHEMA 92 +#endif + + +/* 1.2.14 */ + +#ifndef VIR_FROM_THREAD +#define VIR_FROM_THREAD 61 +#endif + + +/* 1.2.17 */ + +#ifndef VIR_FROM_ADMIN +#define VIR_FROM_ADMIN 62 +#endif + + +/* 1.2.18 */ + +#ifndef VIR_ERR_MIGRATE_FINISH_OK +#define VIR_ERR_MIGRATE_FINISH_OK 93 +#endif + + +/* 1.3.0 */ + +#ifndef VIR_FROM_LOGGING +#define VIR_FROM_LOGGING 63 +#endif + +/* 1.3.2 */ + +#ifndef VIR_FROM_XENXL +#define VIR_FROM_XENXL 64 +#endif + + +/* 1.3.3 */ + +#ifndef VIR_FROM_PERF +#define VIR_FROM_PERF 65 +#endif + +#ifndef VIR_ERR_AUTH_UNAVAILABLE +#define VIR_ERR_AUTH_UNAVAILABLE 94 +#endif + +#ifndef VIR_ERR_NO_SERVER +#define VIR_ERR_NO_SERVER 95 +#endif + + +/* 1.3.5 */ + +#ifndef VIR_ERR_NO_CLIENT +#define VIR_ERR_NO_CLIENT 96 +#endif + + +/* 2.3.0 */ + +#ifndef VIR_ERR_AGENT_UNSYNCED +#define VIR_ERR_AGENT_UNSYNCED 97 +#endif + +/* 2.5.0 */ + +#ifndef VIR_ERR_LIBSSH +#define VIR_ERR_LIBSSH 98 +#endif + +#ifndef VIR_FROM_LIBSSH +#define VIR_FROM_LIBSSH 66 +#endif + +#endif /* LIBVIRT_GO_ERROR_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/events.go b/vendor/github.com/libvirt/libvirt-go/events.go new file mode 100644 index 000000000000..5ad90bd125d2 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/events.go @@ -0,0 +1,234 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "events_cfuncs.h" +*/ +import "C" + +type EventHandleType int + +const ( + EVENT_HANDLE_READABLE = EventHandleType(C.VIR_EVENT_HANDLE_READABLE) + EVENT_HANDLE_WRITABLE = EventHandleType(C.VIR_EVENT_HANDLE_WRITABLE) + EVENT_HANDLE_ERROR = EventHandleType(C.VIR_EVENT_HANDLE_ERROR) + EVENT_HANDLE_HANGUP = EventHandleType(C.VIR_EVENT_HANDLE_HANGUP) +) + +func EventRegisterDefaultImpl() error { + if i := int(C.virEventRegisterDefaultImpl()); i != 0 { + return GetLastError() + } + return nil +} + +func EventRunDefaultImpl() error { + if i := int(C.virEventRunDefaultImpl()); i != 0 { + return GetLastError() + } + return nil +} + +type EventHandleCallback func(watch int, file int, events EventHandleType) + +//export eventHandleCallback +func eventHandleCallback(watch int, fd int, events int, callbackID int) { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(EventHandleCallback) + if !ok { + panic("Incorrect event handle callback data") + } + + callback(watch, fd, (EventHandleType)(events)) +} + +func EventAddHandle(fd int, events EventHandleType, callback EventHandleCallback) (int, error) { + callbackID := registerCallbackId(callback) + + ret := C.virEventAddHandle_cgo((C.int)(fd), (C.int)(events), (C.int)(callbackID)) + if ret == -1 { + return 0, GetLastError() + } + + return int(ret), nil +} + +func EventUpdateHandle(watch int, events EventHandleType) { + C.virEventUpdateHandle((C.int)(watch), (C.int)(events)) +} + +func EventRemoveHandle(watch int) { + C.virEventRemoveHandle((C.int)(watch)) +} + +type EventTimeoutCallback func(timer int) + +//export eventTimeoutCallback +func eventTimeoutCallback(timer int, callbackID int) { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(EventTimeoutCallback) + if !ok { + panic("Incorrect event timeout callback data") + } + + callback(timer) +} + +func EventAddTimeout(freq int, callback EventTimeoutCallback) (int, error) { + callbackID := registerCallbackId(callback) + + ret := C.virEventAddTimeout_cgo((C.int)(freq), (C.int)(callbackID)) + if ret == -1 { + return 0, GetLastError() + } + + return int(ret), nil +} + +func EventUpdateTimeout(timer int, freq int) { + C.virEventUpdateTimeout((C.int)(timer), (C.int)(freq)) +} + +func EventRemoveTimeout(timer int) { + C.virEventRemoveTimeout((C.int)(timer)) +} + +type EventHandleCallbackInfo struct { + callback uintptr + opaque uintptr + free uintptr +} + +type EventTimeoutCallbackInfo struct { + callback uintptr + opaque uintptr + free uintptr +} + +func (i *EventHandleCallbackInfo) Invoke(watch int, fd int, event EventHandleType) { + C.eventHandleCallbackInvoke(C.int(watch), C.int(fd), C.int(event), C.uintptr_t(i.callback), C.uintptr_t(i.opaque)) +} + +func (i *EventTimeoutCallbackInfo) Invoke(timer int) { + C.eventTimeoutCallbackInvoke(C.int(timer), C.uintptr_t(i.callback), C.uintptr_t(i.opaque)) +} + +func (i *EventHandleCallbackInfo) Free() { + C.eventHandleCallbackFree(C.uintptr_t(i.free), C.uintptr_t(i.opaque)) +} + +func (i *EventTimeoutCallbackInfo) Free() { + C.eventTimeoutCallbackFree(C.uintptr_t(i.free), C.uintptr_t(i.opaque)) +} + +type EventLoop interface { + AddHandleFunc(fd int, event EventHandleType, callback *EventHandleCallbackInfo) int + UpdateHandleFunc(watch int, event EventHandleType) + RemoveHandleFunc(watch int) int + AddTimeoutFunc(freq int, callback *EventTimeoutCallbackInfo) int + UpdateTimeoutFunc(timer int, freq int) + RemoveTimeoutFunc(timer int) int +} + +var eventLoopImpl EventLoop + +func EventRegisterImpl(impl EventLoop) { + eventLoopImpl = impl + C.virEventRegisterImpl_cgo() +} + +//export eventAddHandleFunc +func eventAddHandleFunc(fd C.int, event C.int, callback uintptr, opaque uintptr, free uintptr) C.int { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + cbinfo := &EventHandleCallbackInfo{ + callback: callback, + opaque: opaque, + free: free, + } + + return C.int(eventLoopImpl.AddHandleFunc(int(fd), EventHandleType(event), cbinfo)) +} + +//export eventUpdateHandleFunc +func eventUpdateHandleFunc(watch C.int, event C.int) { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + eventLoopImpl.UpdateHandleFunc(int(watch), EventHandleType(event)) +} + +//export eventRemoveHandleFunc +func eventRemoveHandleFunc(watch C.int) { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + eventLoopImpl.RemoveHandleFunc(int(watch)) +} + +//export eventAddTimeoutFunc +func eventAddTimeoutFunc(freq C.int, callback uintptr, opaque uintptr, free uintptr) C.int { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + cbinfo := &EventTimeoutCallbackInfo{ + callback: callback, + opaque: opaque, + free: free, + } + + return C.int(eventLoopImpl.AddTimeoutFunc(int(freq), cbinfo)) +} + +//export eventUpdateTimeoutFunc +func eventUpdateTimeoutFunc(timer C.int, freq C.int) { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + eventLoopImpl.UpdateTimeoutFunc(int(timer), int(freq)) +} + +//export eventRemoveTimeoutFunc +func eventRemoveTimeoutFunc(timer C.int) { + if eventLoopImpl == nil { + panic("Event loop impl is missing") + } + + eventLoopImpl.RemoveTimeoutFunc(int(timer)) +} diff --git a/vendor/github.com/libvirt/libvirt-go/events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/events_cfuncs.go new file mode 100644 index 000000000000..acd7b45c17bc --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/events_cfuncs.go @@ -0,0 +1,132 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include +#include "events_cfuncs.h" + +void eventHandleCallback(int watch, int fd, int events, int callbackID); + +static void eventAddHandleHelper(int watch, int fd, int events, void *opaque) +{ + eventHandleCallback(watch, fd, events, (int)(intptr_t)opaque); +} + +int virEventAddHandle_cgo(int fd, int events, int callbackID) +{ + return virEventAddHandle(fd, events, eventAddHandleHelper, (void *)(intptr_t)callbackID, NULL); +} + +void eventTimeoutCallback(int timer, int callbackID); + +static void eventAddTimeoutHelper(int timer, void *opaque) +{ + eventTimeoutCallback(timer, (int)(intptr_t)opaque); +} + +int virEventAddTimeout_cgo(int freq, int callbackID) +{ + return virEventAddTimeout(freq, eventAddTimeoutHelper, (void *)(intptr_t)callbackID, NULL); +} + +int eventAddHandleFunc(int fd, int event, uintptr_t callback, uintptr_t opaque, uintptr_t freecb); +void eventUpdateHandleFunc(int watch, int event); +int eventRemoveHandleFunc(int watch); +int eventAddTimeoutFunc(int freq, uintptr_t callback, uintptr_t opaque, uintptr_t freecb); +void eventUpdateTimeoutFunc(int timer, int freq); +int eventRemoveTimeoutFunc(int timer); + +int eventAddHandleFuncHelper(int fd, int event, virEventHandleCallback callback, void *opaque, virFreeCallback freecb) +{ + return eventAddHandleFunc(fd, event, (uintptr_t)callback, (uintptr_t)opaque, (uintptr_t)freecb); +} + +void eventUpdateHandleFuncHelper(int watch, int event) +{ + eventUpdateHandleFunc(watch, event); +} + +int eventRemoveHandleFuncHelper(int watch) +{ + return eventRemoveHandleFunc(watch); +} + +int eventAddTimeoutFuncHelper(int freq, virEventTimeoutCallback callback, void *opaque, virFreeCallback freecb) +{ + return eventAddTimeoutFunc(freq, (uintptr_t)callback, (uintptr_t)opaque, (uintptr_t)freecb); +} + +void eventUpdateTimeoutFuncHelper(int timer, int freq) +{ + eventUpdateTimeoutFunc(timer, freq); +} + +int eventRemoveTimeoutFuncHelper(int timer) +{ + return eventRemoveTimeoutFunc(timer); +} + + +void virEventRegisterImpl_cgo(void) +{ + virEventRegisterImpl(eventAddHandleFuncHelper, + eventUpdateHandleFuncHelper, + eventRemoveHandleFuncHelper, + eventAddTimeoutFuncHelper, + eventUpdateTimeoutFuncHelper, + eventRemoveTimeoutFuncHelper); +} + +void eventHandleCallbackInvoke(int watch, int fd, int events, uintptr_t callback, uintptr_t opaque) +{ + ((virEventHandleCallback)callback)(watch, fd, events, (void *)opaque); +} + +void eventTimeoutCallbackInvoke(int timer, uintptr_t callback, uintptr_t opaque) +{ + ((virEventTimeoutCallback)callback)(timer, (void *)opaque); +} + + +void eventHandleCallbackFree(uintptr_t callback, uintptr_t opaque) +{ + ((virFreeCallback)callback)((void *)opaque); +} + +void eventTimeoutCallbackFree(uintptr_t callback, uintptr_t opaque) +{ + ((virFreeCallback)callback)((void *)opaque); +} + + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/events_cfuncs.h new file mode 100644 index 000000000000..79e70ee21aa1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/events_cfuncs.h @@ -0,0 +1,39 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_EVENTS_CFUNCS_H__ + +int virEventAddHandle_cgo(int fd, int events, int callbackID); +int virEventAddTimeout_cgo(int freq, int callbackID); +void virEventRegisterImpl_cgo(void); + +void eventHandleCallbackInvoke(int watch, int fd, int events, uintptr_t callback, uintptr_t opaque); +void eventTimeoutCallbackInvoke(int timer, uintptr_t callback, uintptr_t opaque); +void eventHandleCallbackFree(uintptr_t callback, uintptr_t opaque); +void eventTimeoutCallbackFree(uintptr_t callback, uintptr_t opaque); + +#endif /* LIBVIRT_GO_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/interface.go b/vendor/github.com/libvirt/libvirt-go/interface.go new file mode 100644 index 000000000000..472556e04592 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/interface.go @@ -0,0 +1,128 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +*/ +import "C" + +import ( + "unsafe" +) + +type InterfaceXMLFlags int + +const ( + INTERFACE_XML_INACTIVE = InterfaceXMLFlags(C.VIR_INTERFACE_XML_INACTIVE) +) + +type Interface struct { + ptr C.virInterfacePtr +} + +func (n *Interface) Create(flags uint32) error { + result := C.virInterfaceCreate(n.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Interface) Destroy(flags uint32) error { + result := C.virInterfaceDestroy(n.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Interface) IsActive() (bool, error) { + result := C.virInterfaceIsActive(n.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (n *Interface) GetMACString() (string, error) { + result := C.virInterfaceGetMACString(n.ptr) + if result == nil { + return "", GetLastError() + } + mac := C.GoString(result) + return mac, nil +} + +func (n *Interface) GetName() (string, error) { + result := C.virInterfaceGetName(n.ptr) + if result == nil { + return "", GetLastError() + } + name := C.GoString(result) + return name, nil +} + +func (n *Interface) GetXMLDesc(flags InterfaceXMLFlags) (string, error) { + result := C.virInterfaceGetXMLDesc(n.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (n *Interface) Undefine() error { + result := C.virInterfaceUndefine(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Interface) Free() error { + ret := C.virInterfaceFree(n.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Interface) Ref() error { + ret := C.virInterfaceRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/libvirtd.conf b/vendor/github.com/libvirt/libvirt-go/libvirtd.conf new file mode 100644 index 000000000000..1c31a2414498 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/libvirtd.conf @@ -0,0 +1,6 @@ +listen_tls = 0 +listen_tcp = 1 +tcp_port = "16509" +listen_addr = "127.0.0.1" +auth_unix_rw = "none" +auth_tcp = "sasl" diff --git a/vendor/github.com/libvirt/libvirt-go/lxc.go b/vendor/github.com/libvirt/libvirt-go/lxc.go new file mode 100644 index 000000000000..cf1c67b6dd24 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/lxc.go @@ -0,0 +1,154 @@ +// +build !without_lxc + +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +// Can't rely on pkg-config for libvirt-lxc since it was not +// installed until 2.6.0 onwards +#cgo LDFLAGS: -lvirt-lxc +#include +#include +#include +#include +#include +#include "lxc_compat.h" +*/ +import "C" + +import ( + "os" + "unsafe" +) + +func (d *Domain) LxcOpenNamespace(flags uint32) ([]os.File, error) { + var cfdlist *C.int + + ret := C.virDomainLxcOpenNamespace(d.ptr, &cfdlist, C.uint(flags)) + if ret == -1 { + return []os.File{}, GetLastError() + } + fdlist := make([]os.File, ret) + for i := 0; i < int(ret); i++ { + var cfd C.int + cfd = *(*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(cfdlist)) + (unsafe.Sizeof(cfd) * uintptr(i)))) + fdlist[i] = *os.NewFile(uintptr(cfd), "namespace") + } + defer C.free(unsafe.Pointer(cfdlist)) + return fdlist, nil +} + +func (d *Domain) LxcEnterNamespace(fdlist []os.File, flags uint32) ([]os.File, error) { + var coldfdlist *C.int + var ncoldfdlist C.uint + cfdlist := make([]C.int, len(fdlist)) + for i := 0; i < len(fdlist); i++ { + cfdlist[i] = C.int(fdlist[i].Fd()) + } + + ret := C.virDomainLxcEnterNamespace(d.ptr, C.uint(len(fdlist)), &cfdlist[0], &ncoldfdlist, &coldfdlist, C.uint(flags)) + if ret == -1 { + return []os.File{}, GetLastError() + } + oldfdlist := make([]os.File, ncoldfdlist) + for i := 0; i < int(ncoldfdlist); i++ { + var cfd C.int + cfd = *(*C.int)(unsafe.Pointer(uintptr(unsafe.Pointer(coldfdlist)) + (unsafe.Sizeof(cfd) * uintptr(i)))) + oldfdlist[i] = *os.NewFile(uintptr(cfd), "namespace") + } + defer C.free(unsafe.Pointer(coldfdlist)) + return oldfdlist, nil +} + +func DomainLxcEnterSecurityLabel(model *NodeSecurityModel, label *SecurityLabel, flags uint32) (*SecurityLabel, error) { + var cmodel C.virSecurityModel + var clabel C.virSecurityLabel + var coldlabel C.virSecurityLabel + + cmodelstrlen := len(model.Model) + if cmodelstrlen > (C.VIR_SECURITY_MODEL_BUFLEN - 1) { + cmodelstrlen = C.VIR_SECURITY_MODEL_BUFLEN - 1 + } + cmodelstr := C.CString(model.Model) + defer C.free(unsafe.Pointer(cmodelstr)) + + cdoistrlen := len(model.Doi) + if cdoistrlen >= (C.VIR_SECURITY_DOI_BUFLEN - 1) { + cdoistrlen = C.VIR_SECURITY_DOI_BUFLEN - 1 + } + cdoistr := C.CString(model.Doi) + defer C.free(unsafe.Pointer(cdoistr)) + + C.memcpy(unsafe.Pointer(&cmodel.model), unsafe.Pointer(cmodelstr), C.size_t(cmodelstrlen)) + C.memcpy(unsafe.Pointer(&cmodel.doi), unsafe.Pointer(cdoistr), C.size_t(cdoistrlen)) + + clabelstrlen := len(label.Label) + if clabelstrlen > (C.VIR_SECURITY_LABEL_BUFLEN - 1) { + clabelstrlen = C.VIR_SECURITY_LABEL_BUFLEN - 1 + } + clabelstr := C.CString(label.Label) + defer C.free(unsafe.Pointer(clabelstr)) + + C.memcpy(unsafe.Pointer(&clabel.label), unsafe.Pointer(clabelstr), C.size_t(clabelstrlen)) + if label.Enforcing { + clabel.enforcing = 1 + } else { + clabel.enforcing = 0 + } + + ret := C.virDomainLxcEnterSecurityLabel(&cmodel, &clabel, &coldlabel, C.uint(flags)) + if ret == -1 { + return nil, GetLastError() + } + + var oldlabel SecurityLabel + + oldlabel.Label = C.GoString((*C.char)(unsafe.Pointer(&coldlabel.label))) + if coldlabel.enforcing != 0 { + oldlabel.Enforcing = true + } else { + oldlabel.Enforcing = false + } + + return &oldlabel, nil +} + +func (d *Domain) DomainLxcEnterCGroup(flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return GetNotImplementedError("virDomainLxcEnterCGroup") + } + + ret := C.virDomainLxcEnterCGroupCompat(d.ptr, C.uint(flags)) + + if ret == -1 { + return GetLastError() + } + + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/lxc_compat.go b/vendor/github.com/libvirt/libvirt-go/lxc_compat.go new file mode 100644 index 000000000000..a13014470e8d --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/lxc_compat.go @@ -0,0 +1,51 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +// Can't rely on pkg-config for libvirt-lxc since it was not +// installed until 2.6.0 onwards +#cgo LDFLAGS: -lvirt-lxc +#include +#include +#include +#include "lxc_compat.h" + +int virDomainLxcEnterCGroupCompat(virDomainPtr domain, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 2000000 + assert(0); // Caller should have checked version +#else + return virDomainLxcEnterCGroup(domain, flags); +#endif +} + + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/lxc_compat.h b/vendor/github.com/libvirt/libvirt-go/lxc_compat.h new file mode 100644 index 000000000000..088485c9def1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/lxc_compat.h @@ -0,0 +1,36 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_LXC_COMPAT_H__ +#define LIBVIRT_GO_LXC_COMPAT_H__ + +/* 2.0.0 */ + +int virDomainLxcEnterCGroupCompat(virDomainPtr domain, + unsigned int flags); + + +#endif /* LIBVIRT_GO_LXC_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/network.go b/vendor/github.com/libvirt/libvirt-go/network.go new file mode 100644 index 000000000000..f8cc7eecdfa9 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network.go @@ -0,0 +1,305 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "network_compat.h" +*/ +import "C" + +import ( + "reflect" + "time" + "unsafe" +) + +type IPAddrType int + +const ( + IP_ADDR_TYPE_IPV4 = IPAddrType(C.VIR_IP_ADDR_TYPE_IPV4) + IP_ADDR_TYPE_IPV6 = IPAddrType(C.VIR_IP_ADDR_TYPE_IPV6) +) + +type NetworkXMLFlags int + +const ( + NETWORK_XML_INACTIVE = NetworkXMLFlags(C.VIR_NETWORK_XML_INACTIVE) +) + +type NetworkUpdateCommand int + +const ( + NETWORK_UPDATE_COMMAND_NONE = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_NONE) + NETWORK_UPDATE_COMMAND_MODIFY = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_MODIFY) + NETWORK_UPDATE_COMMAND_DELETE = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_DELETE) + NETWORK_UPDATE_COMMAND_ADD_LAST = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_ADD_LAST) + NETWORK_UPDATE_COMMAND_ADD_FIRST = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) +) + +type NetworkUpdateSection int + +const ( + NETWORK_SECTION_NONE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_NONE) + NETWORK_SECTION_BRIDGE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_BRIDGE) + NETWORK_SECTION_DOMAIN = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DOMAIN) + NETWORK_SECTION_IP = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP) + NETWORK_SECTION_IP_DHCP_HOST = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP_DHCP_HOST) + NETWORK_SECTION_IP_DHCP_RANGE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP_DHCP_RANGE) + NETWORK_SECTION_FORWARD = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD) + NETWORK_SECTION_FORWARD_INTERFACE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD_INTERFACE) + NETWORK_SECTION_FORWARD_PF = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD_PF) + NETWORK_SECTION_PORTGROUP = NetworkUpdateSection(C.VIR_NETWORK_SECTION_PORTGROUP) + NETWORK_SECTION_DNS_HOST = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_HOST) + NETWORK_SECTION_DNS_TXT = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_TXT) + NETWORK_SECTION_DNS_SRV = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_SRV) +) + +type NetworkUpdateFlags int + +const ( + NETWORK_UPDATE_AFFECT_CURRENT = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_CURRENT) + NETWORK_UPDATE_AFFECT_LIVE = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_LIVE) + NETWORK_UPDATE_AFFECT_CONFIG = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_CONFIG) +) + +type NetworkEventLifecycleType int + +const ( + NETWORK_EVENT_DEFINED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_DEFINED) + NETWORK_EVENT_UNDEFINED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_UNDEFINED) + NETWORK_EVENT_STARTED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_STARTED) + NETWORK_EVENT_STOPPED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_STOPPED) +) + +type NetworkEventID int + +const ( + NETWORK_EVENT_ID_LIFECYCLE = NetworkEventID(C.VIR_NETWORK_EVENT_ID_LIFECYCLE) +) + +type Network struct { + ptr C.virNetworkPtr +} + +type NetworkDHCPLease struct { + Iface string + ExpiryTime time.Time + Type IPAddrType + Mac string + Iaid string + IPaddr string + Prefix uint + Hostname string + Clientid string +} + +func (n *Network) Free() error { + ret := C.virNetworkFree(n.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Network) Ref() error { + ret := C.virNetworkRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) Create() error { + result := C.virNetworkCreate(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) Destroy() error { + result := C.virNetworkDestroy(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) IsActive() (bool, error) { + result := C.virNetworkIsActive(n.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (n *Network) IsPersistent() (bool, error) { + result := C.virNetworkIsPersistent(n.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (n *Network) GetAutostart() (bool, error) { + var out C.int + result := C.virNetworkGetAutostart(n.ptr, (*C.int)(unsafe.Pointer(&out))) + if result == -1 { + return false, GetLastError() + } + switch out { + case 1: + return true, nil + default: + return false, nil + } +} + +func (n *Network) SetAutostart(autostart bool) error { + var cAutostart C.int + switch autostart { + case true: + cAutostart = 1 + default: + cAutostart = 0 + } + result := C.virNetworkSetAutostart(n.ptr, cAutostart) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) GetName() (string, error) { + name := C.virNetworkGetName(n.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (n *Network) GetUUID() ([]byte, error) { + var cUuid [C.VIR_UUID_BUFLEN](byte) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virNetworkGetUUID(n.ptr, (*C.uchar)(cuidPtr)) + if result != 0 { + return []byte{}, GetLastError() + } + return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil +} + +func (n *Network) GetUUIDString() (string, error) { + var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virNetworkGetUUIDString(n.ptr, (*C.char)(cuidPtr)) + if result != 0 { + return "", GetLastError() + } + return C.GoString((*C.char)(cuidPtr)), nil +} + +func (n *Network) GetBridgeName() (string, error) { + result := C.virNetworkGetBridgeName(n.ptr) + if result == nil { + return "", GetLastError() + } + bridge := C.GoString(result) + C.free(unsafe.Pointer(result)) + return bridge, nil +} + +func (n *Network) GetXMLDesc(flags NetworkXMLFlags) (string, error) { + result := C.virNetworkGetXMLDesc(n.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (n *Network) Undefine() error { + result := C.virNetworkUndefine(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) Update(cmd NetworkUpdateCommand, section NetworkUpdateSection, parentIndex int, xml string, flags NetworkUpdateFlags) error { + cxml := C.CString(xml) + defer C.free(unsafe.Pointer(cxml)) + result := C.virNetworkUpdate(n.ptr, C.uint(cmd), C.uint(section), C.int(parentIndex), cxml, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease, error) { + if C.LIBVIR_VERSION_NUMBER < 1002006 { + return []NetworkDHCPLease{}, GetNotImplementedError("virNetworkGetDHCPLeases") + } + var cLeases *C.virNetworkDHCPLeasePtr + numLeases := C.virNetworkGetDHCPLeasesCompat(n.ptr, nil, (**C.virNetworkDHCPLeasePtr)(&cLeases), C.uint(0)) + if numLeases == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cLeases)), + Len: int(numLeases), + Cap: int(numLeases), + } + var leases []NetworkDHCPLease + slice := *(*[]C.virNetworkDHCPLeasePtr)(unsafe.Pointer(&hdr)) + for _, clease := range slice { + leases = append(leases, NetworkDHCPLease{ + Iface: C.GoString(clease.iface), + ExpiryTime: time.Unix(int64(clease.expirytime), 0), + Type: IPAddrType(clease._type), + Mac: C.GoString(clease.mac), + Iaid: C.GoString(clease.iaid), + IPaddr: C.GoString(clease.ipaddr), + Prefix: uint(clease.prefix), + Hostname: C.GoString(clease.hostname), + Clientid: C.GoString(clease.clientid), + }) + C.virNetworkDHCPLeaseFreeCompat(clease) + } + C.free(unsafe.Pointer(cLeases)) + return leases, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/network_compat.go b/vendor/github.com/libvirt/libvirt-go/network_compat.go new file mode 100644 index 000000000000..744b41aa3c51 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network_compat.go @@ -0,0 +1,62 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "network_compat.h" + +int virConnectNetworkEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID) +{ +#if LIBVIR_VERSION_NUMBER < 1002001 + assert(0); // Caller should have checked version +#else + return virConnectNetworkEventDeregisterAny(conn, callbackID); +#endif +} + +void virNetworkDHCPLeaseFreeCompat(virNetworkDHCPLeasePtr lease) +{ +} + +int virNetworkGetDHCPLeasesCompat(virNetworkPtr network, + const char *mac, + virNetworkDHCPLeasePtr **leases, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 1002006 + assert(0); // Caller should have checked version +#else + return virNetworkGetDHCPLeases(network, mac, leases, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/network_compat.h b/vendor/github.com/libvirt/libvirt-go/network_compat.h new file mode 100644 index 000000000000..fea9e3740af4 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network_compat.h @@ -0,0 +1,96 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_NETWORK_COMPAT_H__ +#define LIBVIRT_GO_NETWORK_COMPAT_H__ + +/* 1.2.1 */ + +#ifndef VIR_NETWORK_EVENT_DEFINED +#define VIR_NETWORK_EVENT_DEFINED 0 +#endif + +#ifndef VIR_NETWORK_EVENT_UNDEFINED +#define VIR_NETWORK_EVENT_UNDEFINED 1 +#endif + +#ifndef VIR_NETWORK_EVENT_STARTED +#define VIR_NETWORK_EVENT_STARTED 2 +#endif + +#ifndef VIR_NETWORK_EVENT_STOPPED +#define VIR_NETWORK_EVENT_STOPPED 3 +#endif + +#ifndef VIR_NETWORK_EVENT_ID_LIFECYCLE +#define VIR_NETWORK_EVENT_ID_LIFECYCLE 0 +#endif + + +#if LIBVIR_VERSION_NUMBER < 1002001 +typedef void (*virConnectNetworkEventGenericCallback)(virConnectPtr conn, + virNetworkPtr net, + void *opaque); +#endif + +int virConnectNetworkEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID); + + +/* 1.2.5 */ + +#ifndef VIR_IP_ADDR_TYPE_IPV4 +#define VIR_IP_ADDR_TYPE_IPV4 0 +#endif + +#ifndef VIR_IP_ADDR_TYPE_IPV6 +#define VIR_IP_ADDR_TYPE_IPV6 1 +#endif + +#if LIBVIR_VERSION_NUMBER < 1002006 +typedef struct _virNetworkDHCPLease virNetworkDHCPLease; +typedef virNetworkDHCPLease *virNetworkDHCPLeasePtr; +struct _virNetworkDHCPLease { + char *iface; /* Network interface name */ + long long expirytime; /* Seconds since epoch */ + int type; /* virIPAddrType */ + char *mac; /* MAC address */ + char *iaid; /* IAID */ + char *ipaddr; /* IP address */ + unsigned int prefix; /* IP address prefix */ + char *hostname; /* Hostname */ + char *clientid; /* Client ID or DUID */ +}; +#endif + +void virNetworkDHCPLeaseFreeCompat(virNetworkDHCPLeasePtr lease); + +int virNetworkGetDHCPLeasesCompat(virNetworkPtr network, + const char *mac, + virNetworkDHCPLeasePtr **leases, + unsigned int flags); + +#endif /* LIBVIRT_GO_NETWORK_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/network_events.go b/vendor/github.com/libvirt/libvirt-go/network_events.go new file mode 100644 index 000000000000..6c1423dff266 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network_events.go @@ -0,0 +1,124 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include "network_compat.h" +#include "network_events_cfuncs.h" +*/ +import "C" + +type NetworkEventLifecycle struct { + Event NetworkEventLifecycleType + // TODO: we can make Detail typesafe somehow ? + Detail int +} + +type NetworkEventLifecycleCallback func(c *Connect, n *Network, event *NetworkEventLifecycle) + +//export networkEventLifecycleCallback +func networkEventLifecycleCallback(c C.virConnectPtr, n C.virNetworkPtr, + event int, detail int, + goCallbackId int) { + + network := &Network{ptr: n} + connection := &Connect{ptr: c} + + eventDetails := &NetworkEventLifecycle{ + Event: NetworkEventLifecycleType(event), + Detail: detail, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(NetworkEventLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, network, eventDetails) +} + +func (c *Connect) NetworkEventLifecycleRegister(net *Network, callback NetworkEventLifecycleCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + if C.LIBVIR_VERSION_NUMBER < 1002001 { + return 0, GetNotImplementedError("virConnectNetworkEventRegisterAny") + } + + callbackPtr := unsafe.Pointer(C.networkEventLifecycleCallback_cgo) + var cnet C.virNetworkPtr + if net != nil { + cnet = net.ptr + } + ret := C.virConnectNetworkEventRegisterAny_cgo(c.ptr, cnet, + C.VIR_NETWORK_EVENT_ID_LIFECYCLE, + C.virConnectNetworkEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) NetworkEventDeregister(callbackId int) error { + if C.LIBVIR_VERSION_NUMBER < 1002001 { + return GetNotImplementedError("virConnectNetworkEventDeregisterAny") + } + // Deregister the callback + if i := int(C.virConnectNetworkEventDeregisterAnyCompat(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} + +func (e NetworkEventLifecycle) String() string { + var event string + switch e.Event { + case NETWORK_EVENT_DEFINED: + event = "defined" + + case NETWORK_EVENT_UNDEFINED: + event = "undefined" + + case NETWORK_EVENT_STARTED: + event = "started" + + case NETWORK_EVENT_STOPPED: + event = "stopped" + + default: + event = "unknown" + } + + return fmt.Sprintf("Network event=%q", event) +} diff --git a/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.go new file mode 100644 index 000000000000..c4920ea9adc0 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.go @@ -0,0 +1,58 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "network_compat.h" +#include "network_events_cfuncs.h" +#include "callbacks_cfuncs.h" +#include + +extern void networkEventLifecycleCallback(virConnectPtr, virNetworkPtr, int, int, int); +void networkEventLifecycleCallback_cgo(virConnectPtr c, virNetworkPtr d, + int event, int detail, void *data) +{ + networkEventLifecycleCallback(c, d, event, detail, (int)(intptr_t)data); +} + +int virConnectNetworkEventRegisterAny_cgo(virConnectPtr c, virNetworkPtr d, + int eventID, virConnectNetworkEventGenericCallback cb, + long goCallbackId) { + void* id = (void*)goCallbackId; +#if LIBVIR_VERSION_NUMBER < 1002001 + assert(0); // Caller should have checked version +#else + return virConnectNetworkEventRegisterAny(c, d, eventID, cb, id, freeGoCallback_cgo); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.h new file mode 100644 index 000000000000..58a684a8d7d9 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/network_events_cfuncs.h @@ -0,0 +1,38 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_NETWORK_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_NETWORK_EVENTS_CFUNCS_H__ + +void networkEventLifecycleCallback_cgo(virConnectPtr c, virNetworkPtr d, + int event, int detail, void* data); + +int virConnectNetworkEventRegisterAny_cgo(virConnectPtr c, virNetworkPtr d, + int eventID, virConnectNetworkEventGenericCallback cb, + long goCallbackId); + + +#endif /* LIBVIRT_GO_NETWORK_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/node_device.go b/vendor/github.com/libvirt/libvirt-go/node_device.go new file mode 100644 index 000000000000..a5654f7a87d7 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device.go @@ -0,0 +1,170 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "node_device_compat.h" +*/ +import "C" + +import ( + "unsafe" +) + +type NodeDeviceEventID int + +const ( + NODE_DEVICE_EVENT_ID_LIFECYCLE = NodeDeviceEventID(C.VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE) + NODE_DEVICE_EVENT_ID_UPDATE = NodeDeviceEventID(C.VIR_NODE_DEVICE_EVENT_ID_UPDATE) +) + +type NodeDeviceEventLifecycleType int + +const ( + NODE_DEVICE_EVENT_CREATED = NodeDeviceEventLifecycleType(C.VIR_NODE_DEVICE_EVENT_CREATED) + NODE_DEVICE_EVENT_DELETED = NodeDeviceEventLifecycleType(C.VIR_NODE_DEVICE_EVENT_DELETED) +) + +type NodeDevice struct { + ptr C.virNodeDevicePtr +} + +func (n *NodeDevice) Free() error { + ret := C.virNodeDeviceFree(n.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *NodeDevice) Ref() error { + ret := C.virNodeDeviceRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) Destroy() error { + result := C.virNodeDeviceDestroy(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) Reset() error { + result := C.virNodeDeviceReset(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) Detach() error { + result := C.virNodeDeviceDettach(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) DetachFlags(driverName string, flags uint32) error { + cDriverName := C.CString(driverName) + defer C.free(unsafe.Pointer(cDriverName)) + result := C.virNodeDeviceDetachFlags(n.ptr, cDriverName, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) ReAttach() error { + result := C.virNodeDeviceReAttach(n.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (n *NodeDevice) GetName() (string, error) { + name := C.virNodeDeviceGetName(n.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (n *NodeDevice) GetXMLDesc(flags uint32) (string, error) { + result := C.virNodeDeviceGetXMLDesc(n.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (n *NodeDevice) GetParent() (string, error) { + result := C.virNodeDeviceGetParent(n.ptr) + if result == nil { + return "", GetLastError() + } + defer C.free(unsafe.Pointer(result)) + return C.GoString(result), nil +} + +func (p *NodeDevice) NumOfStorageCaps() (int, error) { + result := int(C.virNodeDeviceNumOfCaps(p.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (p *NodeDevice) ListStorageCaps() ([]string, error) { + const maxCaps = 1024 + var names [maxCaps](*C.char) + namesPtr := unsafe.Pointer(&names) + numCaps := C.virNodeDeviceListCaps( + p.ptr, + (**C.char)(namesPtr), + maxCaps) + if numCaps == -1 { + return nil, GetLastError() + } + goNames := make([]string, numCaps) + for k := 0; k < int(numCaps); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/node_device_compat.go b/vendor/github.com/libvirt/libvirt-go/node_device_compat.go new file mode 100644 index 000000000000..1f69c7e33b16 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device_compat.go @@ -0,0 +1,46 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "node_device_compat.h" + +int virConnectNodeDeviceEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID) +{ +#if LIBVIR_VERSION_NUMBER < 2002000 + assert(0); // Caller should have checked version +#else + return virConnectNodeDeviceEventDeregisterAny(conn, callbackID); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/node_device_compat.h b/vendor/github.com/libvirt/libvirt-go/node_device_compat.h new file mode 100644 index 000000000000..ca849da4c360 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device_compat.h @@ -0,0 +1,58 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_NODE_DEVICE_COMPAT_H__ +#define LIBVIRT_GO_NODE_DEVICE_COMPAT_H__ + +/* 2.2.0 */ + +#ifndef VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE +#define VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE 0 +#endif + +#ifndef VIR_NODE_DEVICE_EVENT_ID_UPDATE +#define VIR_NODE_DEVICE_EVENT_ID_UPDATE 1 +#endif + +#ifndef VIR_NODE_DEVICE_EVENT_CREATED +#define VIR_NODE_DEVICE_EVENT_CREATED 0 +#endif + +#ifndef VIR_NODE_DEVICE_EVENT_DELETED +#define VIR_NODE_DEVICE_EVENT_DELETED 1 +#endif + +#if LIBVIR_VERSION_NUMBER < 2002000 +typedef void (*virConnectNodeDeviceEventGenericCallback)(virConnectPtr conn, + virNodeDevicePtr dev, + void *opaque); +#endif + +int virConnectNodeDeviceEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID); + + +#endif /* LIBVIRT_GO_NODE_DEVICE_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/node_device_events.go b/vendor/github.com/libvirt/libvirt-go/node_device_events.go new file mode 100644 index 000000000000..a43d9f217c22 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device_events.go @@ -0,0 +1,154 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include "node_device_compat.h" +#include "node_device_events_cfuncs.h" +*/ +import "C" + +type NodeDeviceEventGenericCallback func(c *Connect, d *NodeDevice) + +type NodeDeviceEventLifecycle struct { + Event NodeDeviceEventLifecycleType + // TODO: we can make Detail typesafe somehow ? + Detail int +} + +type NodeDeviceEventLifecycleCallback func(c *Connect, n *NodeDevice, event *NodeDeviceEventLifecycle) + +//export nodeDeviceEventLifecycleCallback +func nodeDeviceEventLifecycleCallback(c C.virConnectPtr, s C.virNodeDevicePtr, + event int, detail int, + goCallbackId int) { + + node_device := &NodeDevice{ptr: s} + connection := &Connect{ptr: c} + + eventDetails := &NodeDeviceEventLifecycle{ + Event: NodeDeviceEventLifecycleType(event), + Detail: detail, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(NodeDeviceEventLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, node_device, eventDetails) +} + +//export nodeDeviceEventGenericCallback +func nodeDeviceEventGenericCallback(c C.virConnectPtr, d C.virNodeDevicePtr, + goCallbackId int) { + + node_device := &NodeDevice{ptr: d} + connection := &Connect{ptr: c} + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(NodeDeviceEventGenericCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, node_device) +} + +func (c *Connect) NodeDeviceEventLifecycleRegister(device *NodeDevice, callback NodeDeviceEventLifecycleCallback) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 2002000 { + return 0, GetNotImplementedError("virConnectNodeDeviceEventRegisterAny") + } + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.nodeDeviceEventLifecycleCallback_cgo) + var cdevice C.virNodeDevicePtr + if device != nil { + cdevice = device.ptr + } + ret := C.virConnectNodeDeviceEventRegisterAny_cgo(c.ptr, cdevice, + C.VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE, + C.virConnectNodeDeviceEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) NodeDeviceEventUpdateRegister(device *NodeDevice, callback NodeDeviceEventGenericCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.nodeDeviceEventGenericCallback_cgo) + var cdevice C.virNodeDevicePtr + if device != nil { + cdevice = device.ptr + } + ret := C.virConnectNodeDeviceEventRegisterAny_cgo(c.ptr, cdevice, + C.VIR_NODE_DEVICE_EVENT_ID_UPDATE, + C.virConnectNodeDeviceEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) NodeDeviceEventDeregister(callbackId int) error { + if C.LIBVIR_VERSION_NUMBER < 2002000 { + return GetNotImplementedError("virConnectNodeDeviceEventDeregisterAny") + } + // Deregister the callback + if i := int(C.virConnectNodeDeviceEventDeregisterAnyCompat(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} + +func (e NodeDeviceEventLifecycle) String() string { + var event string + switch e.Event { + case NODE_DEVICE_EVENT_CREATED: + event = "created" + + case NODE_DEVICE_EVENT_DELETED: + event = "deleted" + + default: + event = "unknown" + } + + return fmt.Sprintf("NodeDevice event=%q", event) +} diff --git a/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.go new file mode 100644 index 000000000000..12aaf6064bf1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.go @@ -0,0 +1,64 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "node_device_compat.h" +#include "node_device_events_cfuncs.h" +#include "callbacks_cfuncs.h" +#include + +extern void nodeDeviceEventLifecycleCallback(virConnectPtr, virNodeDevicePtr, int, int, int); +void nodeDeviceEventLifecycleCallback_cgo(virConnectPtr c, virNodeDevicePtr d, + int event, int detail, void *data) +{ + nodeDeviceEventLifecycleCallback(c, d, event, detail, (int)(intptr_t)data); +} + +extern void nodeDeviceEventGenericCallback(virConnectPtr, virNodeDevicePtr, int); +void nodeDeviceEventGenericCallback_cgo(virConnectPtr c, virNodeDevicePtr d, void *data) +{ + nodeDeviceEventGenericCallback(c, d, (int)(intptr_t)data); +} + +int virConnectNodeDeviceEventRegisterAny_cgo(virConnectPtr c, virNodeDevicePtr d, + int eventID, virConnectNodeDeviceEventGenericCallback cb, + long goCallbackId) { + void* id = (void*)goCallbackId; +#if LIBVIR_VERSION_NUMBER < 2002000 + assert(0); // Caller should have checked version +#else + return virConnectNodeDeviceEventRegisterAny(c, d, eventID, cb, id, freeGoCallback_cgo); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.h new file mode 100644 index 000000000000..0d010750ed2d --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/node_device_events_cfuncs.h @@ -0,0 +1,40 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_NODE_DEVICE_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_NODE_DEVICE_EVENTS_CFUNCS_H__ + +void nodeDeviceEventLifecycleCallback_cgo(virConnectPtr c, virNodeDevicePtr d, + int event, int detail, void* data); + +void nodeDeviceEventGenericCallback_cgo(virConnectPtr c, virNodeDevicePtr d, void* data); + +int virConnectNodeDeviceEventRegisterAny_cgo(virConnectPtr c, virNodeDevicePtr d, + int eventID, virConnectNodeDeviceEventGenericCallback cb, + long goCallbackId); + + +#endif /* LIBVIRT_GO_NODE_DEVICE_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/nwfilter.go b/vendor/github.com/libvirt/libvirt-go/nwfilter.go new file mode 100644 index 000000000000..4dba03fb0353 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/nwfilter.go @@ -0,0 +1,105 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +*/ +import "C" + +import ( + "unsafe" +) + +type NWFilter struct { + ptr C.virNWFilterPtr +} + +func (f *NWFilter) Free() error { + ret := C.virNWFilterFree(f.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *NWFilter) Ref() error { + ret := C.virNWFilterRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (f *NWFilter) GetName() (string, error) { + name := C.virNWFilterGetName(f.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (f *NWFilter) Undefine() error { + result := C.virNWFilterUndefine(f.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (f *NWFilter) GetUUID() ([]byte, error) { + var cUuid [C.VIR_UUID_BUFLEN](byte) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virNWFilterGetUUID(f.ptr, (*C.uchar)(cuidPtr)) + if result != 0 { + return []byte{}, GetLastError() + } + return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil +} + +func (f *NWFilter) GetUUIDString() (string, error) { + var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virNWFilterGetUUIDString(f.ptr, (*C.char)(cuidPtr)) + if result != 0 { + return "", GetLastError() + } + return C.GoString((*C.char)(cuidPtr)), nil +} + +func (f *NWFilter) GetXMLDesc(flags uint32) (string, error) { + result := C.virNWFilterGetXMLDesc(f.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/qemu.go b/vendor/github.com/libvirt/libvirt-go/qemu.go new file mode 100644 index 000000000000..86e62642679a --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/qemu.go @@ -0,0 +1,190 @@ +// +build !without_qemu + +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +// Can't rely on pkg-config for libvirt-qemu since it was not +// installed until 2.6.0 onwards +#cgo LDFLAGS: -lvirt-qemu +#include +#include +#include +#include +#include "qemu_compat.h" +#include "qemu_cfuncs.h" +*/ +import "C" + +import ( + "unsafe" +) + +/* + * QMP has two different kinds of ways to talk to QEMU. One is legacy (HMP, + * or 'human' monitor protocol. The default is QMP, which is all-JSON. + * + * QMP json commands are of the format: + * {"execute" : "query-cpus"} + * + * whereas the same command in 'HMP' would be: + * 'info cpus' + */ + +type DomainQemuMonitorCommandFlags int + +const ( + DOMAIN_QEMU_MONITOR_COMMAND_DEFAULT = DomainQemuMonitorCommandFlags(C.VIR_DOMAIN_QEMU_MONITOR_COMMAND_DEFAULT) + DOMAIN_QEMU_MONITOR_COMMAND_HMP = DomainQemuMonitorCommandFlags(C.VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP) +) + +type DomainQemuAgentCommandTimeout int + +const ( + DOMAIN_QEMU_AGENT_COMMAND_MIN = DomainQemuAgentCommandTimeout(C.VIR_DOMAIN_QEMU_AGENT_COMMAND_MIN) + DOMAIN_QEMU_AGENT_COMMAND_BLOCK = DomainQemuAgentCommandTimeout(C.VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) + DOMAIN_QEMU_AGENT_COMMAND_DEFAULT = DomainQemuAgentCommandTimeout(C.VIR_DOMAIN_QEMU_AGENT_COMMAND_DEFAULT) + DOMAIN_QEMU_AGENT_COMMAND_NOWAIT = DomainQemuAgentCommandTimeout(C.VIR_DOMAIN_QEMU_AGENT_COMMAND_NOWAIT) + DOMAIN_QEMU_AGENT_COMMAND_SHUTDOWN = DomainQemuAgentCommandTimeout(C.VIR_DOMAIN_QEMU_AGENT_COMMAND_SHUTDOWN) +) + +type DomainQemuMonitorEventFlags int + +const ( + CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX = DomainQemuMonitorEventFlags(C.VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX) + CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE = DomainQemuMonitorEventFlags(C.VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE) +) + +func (d *Domain) QemuMonitorCommand(command string, flags DomainQemuMonitorCommandFlags) (string, error) { + var cResult *C.char + cCommand := C.CString(command) + defer C.free(unsafe.Pointer(cCommand)) + result := C.virDomainQemuMonitorCommand(d.ptr, cCommand, &cResult, C.uint(flags)) + + if result != 0 { + return "", GetLastError() + } + + rstring := C.GoString(cResult) + C.free(unsafe.Pointer(cResult)) + return rstring, nil +} + +func (d *Domain) QemuAgentCommand(command string, timeout DomainQemuAgentCommandTimeout, flags uint32) (string, error) { + cCommand := C.CString(command) + defer C.free(unsafe.Pointer(cCommand)) + result := C.virDomainQemuAgentCommand(d.ptr, cCommand, C.int(timeout), C.uint(flags)) + + if result == nil { + return "", GetLastError() + } + + rstring := C.GoString(result) + C.free(unsafe.Pointer(result)) + return rstring, nil +} + +func (c *Connect) DomainQemuAttach(pid uint32, flags uint32) (*Domain, error) { + + ptr := C.virDomainQemuAttach(c.ptr, C.uint(pid), C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &Domain{ptr: ptr}, nil +} + +type DomainQemuMonitorEvent struct { + Event string + Seconds int64 + Micros uint + Details string +} + +type DomainQemuMonitorEventCallback func(c *Connect, d *Domain, event *DomainQemuMonitorEvent) + +//export domainQemuMonitorEventCallback +func domainQemuMonitorEventCallback(c C.virConnectPtr, d C.virDomainPtr, + event *C.char, seconds C.longlong, micros C.uint, details *C.char, goCallbackId int) { + + domain := &Domain{ptr: d} + connection := &Connect{ptr: c} + + eventDetails := &DomainQemuMonitorEvent{ + Event: C.GoString(event), + Seconds: int64(seconds), + Micros: uint(micros), + Details: C.GoString(details), + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(DomainQemuMonitorEventCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, domain, eventDetails) + +} + +func (c *Connect) DomainQemuMonitorEventRegister(dom *Domain, event string, callback DomainQemuMonitorEventCallback, flags DomainQemuMonitorEventFlags) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 1002003 { + return 0, GetNotImplementedError("virConnectDomainQemuMonitorEventRegister") + } + + cEvent := C.CString(event) + defer C.free(unsafe.Pointer(cEvent)) + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.domainQemuMonitorEventCallback_cgo) + var cdom C.virDomainPtr + if dom != nil { + cdom = dom.ptr + } + ret := C.virConnectDomainQemuMonitorEventRegister_cgo(c.ptr, cdom, + cEvent, + C.virConnectDomainEventGenericCallback(callbackPtr), + C.long(goCallBackId), + C.uint(flags)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) DomainQemuEventDeregister(callbackId int) error { + if C.LIBVIR_VERSION_NUMBER < 1002003 { + return GetNotImplementedError("virConnectDomainQemuMonitorEventDeregister") + } + + // Deregister the callback + if i := int(C.virConnectDomainQemuMonitorEventDeregisterCompat(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.go new file mode 100644 index 000000000000..83bb67a271c1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.go @@ -0,0 +1,64 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +// Can't rely on pkg-config for libvirt-qemu since it was not +// installed until 2.6.0 onwards +#cgo LDFLAGS: -lvirt-qemu +#include +#include +#include +#include "qemu_compat.h" +#include "qemu_cfuncs.h" +#include "callbacks_cfuncs.h" +#include +#include + + +extern void domainQemuMonitorEventCallback(virConnectPtr, virDomainPtr, const char *, long long, unsigned int, const char *, int); +void domainQemuMonitorEventCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *event, long long secs, + unsigned int micros, const char *details, void *data) +{ + domainQemuMonitorEventCallback(c, d, event, secs, micros, details, (int)(intptr_t)data); +} + +int virConnectDomainQemuMonitorEventRegister_cgo(virConnectPtr c, virDomainPtr d, + const char *event, virConnectDomainQemuMonitorEventCallback cb, + long goCallbackId, unsigned int flags) { +#if LIBVIR_VERSION_NUMBER < 1002003 + assert(0); // Caller should have checked version +#else + void* id = (void*)goCallbackId; + return virConnectDomainQemuMonitorEventRegister(c, d, event, cb, id, freeGoCallback_cgo, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.h new file mode 100644 index 000000000000..f1f48b0d2607 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/qemu_cfuncs.h @@ -0,0 +1,39 @@ + /* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ + +void domainQemuMonitorEventCallback_cgo(virConnectPtr c, virDomainPtr d, + const char *event, long long secs, + unsigned int micros, const char *details, void *data); + +int virConnectDomainQemuMonitorEventRegister_cgo(virConnectPtr c, virDomainPtr d, + const char *event, virConnectDomainQemuMonitorEventCallback cb, + long goCallbackId, unsigned int flags); + + +#endif /* LIBVIRT_GO_DOMAIN_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/qemu_compat.go b/vendor/github.com/libvirt/libvirt-go/qemu_compat.go new file mode 100644 index 000000000000..a24abf3c8bbf --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/qemu_compat.go @@ -0,0 +1,48 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "qemu_compat.h" + + +int virConnectDomainQemuMonitorEventDeregisterCompat(virConnectPtr conn, + int callbackID) +{ +#if LIBVIR_VERSION_NUMBER < 1002003 + assert(0); // Caller should have checked version +#else + return virConnectDomainQemuMonitorEventDeregister(conn, callbackID); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/qemu_compat.h b/vendor/github.com/libvirt/libvirt-go/qemu_compat.h new file mode 100644 index 000000000000..f88939172fd4 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/qemu_compat.h @@ -0,0 +1,60 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_QEMU_COMPAT_H__ +#define LIBVIRT_GO_QEMU_COMPAT_H__ + +/* 1.2.3 */ + +#if LIBVIR_VERSION_NUMBER < 1002003 +typedef void (*virConnectDomainQemuMonitorEventCallback)(virConnectPtr conn, + virDomainPtr dom, + const char *event, + long long seconds, + unsigned int micros, + const char *details, + void *opaque); +#endif + +int virConnectDomainQemuMonitorEventDeregisterCompat(virConnectPtr conn, + int callbackID); + +#ifndef VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX +#define VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_REGEX (1 << 0) +#endif + +#ifndef VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE +#define VIR_CONNECT_DOMAIN_QEMU_MONITOR_EVENT_REGISTER_NOCASE (1 << 1) +#endif + +/* 1.2.15 */ + +#ifndef VIR_DOMAIN_QEMU_AGENT_COMMAND_SHUTDOWN +#define VIR_DOMAIN_QEMU_AGENT_COMMAND_SHUTDOWN 60 +#endif + + +#endif /* LIBVIRT_GO_QEMU_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/secret.go b/vendor/github.com/libvirt/libvirt-go/secret.go new file mode 100644 index 000000000000..1e35f7e95bb7 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret.go @@ -0,0 +1,166 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "secret_compat.h" +*/ +import "C" + +import ( + "unsafe" +) + +type SecretUsageType int + +const ( + SECRET_USAGE_TYPE_NONE = SecretUsageType(C.VIR_SECRET_USAGE_TYPE_NONE) + SECRET_USAGE_TYPE_VOLUME = SecretUsageType(C.VIR_SECRET_USAGE_TYPE_VOLUME) + SECRET_USAGE_TYPE_CEPH = SecretUsageType(C.VIR_SECRET_USAGE_TYPE_CEPH) + SECRET_USAGE_TYPE_ISCSI = SecretUsageType(C.VIR_SECRET_USAGE_TYPE_ISCSI) + SECRET_USAGE_TYPE_TLS = SecretUsageType(C.VIR_SECRET_USAGE_TYPE_TLS) +) + +type SecretEventLifecycleType int + +const ( + SECRET_EVENT_DEFINED = SecretEventLifecycleType(C.VIR_SECRET_EVENT_DEFINED) + SECRET_EVENT_UNDEFINED = SecretEventLifecycleType(C.VIR_SECRET_EVENT_UNDEFINED) +) + +type SecretEventID int + +const ( + SECRET_EVENT_ID_LIFECYCLE = SecretEventID(C.VIR_SECRET_EVENT_ID_LIFECYCLE) + SECRET_EVENT_ID_VALUE_CHANGED = SecretEventID(C.VIR_SECRET_EVENT_ID_VALUE_CHANGED) +) + +type Secret struct { + ptr C.virSecretPtr +} + +func (s *Secret) Free() error { + ret := C.virSecretFree(s.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Secret) Ref() error { + ret := C.virSecretRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (s *Secret) Undefine() error { + result := C.virSecretUndefine(s.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (s *Secret) GetUUID() ([]byte, error) { + var cUuid [C.VIR_UUID_BUFLEN](byte) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virSecretGetUUID(s.ptr, (*C.uchar)(cuidPtr)) + if result != 0 { + return []byte{}, GetLastError() + } + return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil +} + +func (s *Secret) GetUUIDString() (string, error) { + var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virSecretGetUUIDString(s.ptr, (*C.char)(cuidPtr)) + if result != 0 { + return "", GetLastError() + } + return C.GoString((*C.char)(cuidPtr)), nil +} + +func (s *Secret) GetUsageID() (string, error) { + result := C.virSecretGetUsageID(s.ptr) + if result == nil { + return "", GetLastError() + } + return C.GoString(result), nil +} + +func (s *Secret) GetUsageType() (SecretUsageType, error) { + result := SecretUsageType(C.virSecretGetUsageType(s.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (s *Secret) GetXMLDesc(flags uint32) (string, error) { + result := C.virSecretGetXMLDesc(s.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (s *Secret) GetValue(flags uint32) ([]byte, error) { + var cvalue_size C.size_t + + cvalue := C.virSecretGetValue(s.ptr, &cvalue_size, C.uint(flags)) + if cvalue == nil { + return nil, GetLastError() + } + defer C.free(unsafe.Pointer(cvalue)) + ret := C.GoBytes(unsafe.Pointer(cvalue), C.int(cvalue_size)) + return ret, nil +} + +func (s *Secret) SetValue(value []byte, flags uint32) error { + cvalue := make([]C.uchar, len(value)) + + for i := 0; i < len(value); i++ { + cvalue[i] = C.uchar(value[i]) + } + + result := C.virSecretSetValue(s.ptr, &cvalue[0], C.size_t(len(value)), C.uint(flags)) + + if result == -1 { + return GetLastError() + } + + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/secret_compat.go b/vendor/github.com/libvirt/libvirt-go/secret_compat.go new file mode 100644 index 000000000000..b68b9d1a3634 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret_compat.go @@ -0,0 +1,47 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "secret_compat.h" + +int virConnectSecretEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID) +{ +#if LIBVIR_VERSION_NUMBER < 3000000 + assert(0); // Caller should have checked version +#else + return virConnectSecretEventDeregisterAny(conn, callbackID); +#endif +} + + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/secret_compat.h b/vendor/github.com/libvirt/libvirt-go/secret_compat.h new file mode 100644 index 000000000000..745e672ba4b5 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret_compat.h @@ -0,0 +1,64 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_SECRET_COMPAT_H__ +#define LIBVIRT_GO_SECRET_COMPAT_H__ + +/* 3.0.0 */ + +#ifndef VIR_SECRET_EVENT_DEFINED +#define VIR_SECRET_EVENT_DEFINED 0 +#endif + +#ifndef VIR_SECRET_EVENT_UNDEFINED +#define VIR_SECRET_EVENT_UNDEFINED 1 +#endif + +#ifndef VIR_SECRET_EVENT_ID_LIFECYCLE +#define VIR_SECRET_EVENT_ID_LIFECYCLE 0 +#endif + +#ifndef VIR_SECRET_EVENT_ID_VALUE_CHANGED +#define VIR_SECRET_EVENT_ID_VALUE_CHANGED 1 +#endif + + +#if LIBVIR_VERSION_NUMBER < 3000000 +typedef void (*virConnectSecretEventGenericCallback)(virConnectPtr conn, + virSecretPtr secret, + void *opaque); +#endif + +int virConnectSecretEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID); + +/* 2.2.1 */ + +#ifndef VIR_SECRET_USAGE_TYPE_TLS +#define VIR_SECRET_USAGE_TYPE_TLS 4 +#endif + +#endif /* LIBVIRT_GO_SECRET_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/secret_events.go b/vendor/github.com/libvirt/libvirt-go/secret_events.go new file mode 100644 index 000000000000..7da94282c71a --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret_events.go @@ -0,0 +1,157 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include "secret_compat.h" +#include "secret_events_cfuncs.h" +*/ +import "C" + +type SecretEventLifecycle struct { + Event SecretEventLifecycleType + // TODO: we can make Detail typesafe somehow ? + Detail int +} + +type SecretEventLifecycleCallback func(c *Connect, n *Secret, event *SecretEventLifecycle) + +type SecretEventGenericCallback func(c *Connect, n *Secret) + +//export secretEventLifecycleCallback +func secretEventLifecycleCallback(c C.virConnectPtr, n C.virSecretPtr, + event int, detail int, + goCallbackId int) { + + secret := &Secret{ptr: n} + connection := &Connect{ptr: c} + + eventDetails := &SecretEventLifecycle{ + Event: SecretEventLifecycleType(event), + Detail: detail, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(SecretEventLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, secret, eventDetails) +} + +//export secretEventGenericCallback +func secretEventGenericCallback(c C.virConnectPtr, n C.virSecretPtr, + goCallbackId int) { + + secret := &Secret{ptr: n} + connection := &Connect{ptr: c} + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(SecretEventGenericCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, secret) +} + +func (c *Connect) SecretEventLifecycleRegister(secret *Secret, callback SecretEventLifecycleCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + if C.LIBVIR_VERSION_NUMBER < 3000000 { + return 0, GetNotImplementedError("virConnectSecretEventRegisterAny") + } + + callbackPtr := unsafe.Pointer(C.secretEventLifecycleCallback_cgo) + var csecret C.virSecretPtr + if secret != nil { + csecret = secret.ptr + } + ret := C.virConnectSecretEventRegisterAny_cgo(c.ptr, csecret, + C.VIR_SECRET_EVENT_ID_LIFECYCLE, + C.virConnectSecretEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) SecretEventValueChangedRegister(secret *Secret, callback SecretEventGenericCallback) (int, error) { + goCallBackId := registerCallbackId(callback) + if C.LIBVIR_VERSION_NUMBER < 3000000 { + return 0, GetNotImplementedError("virConnectSecretEventRegisterAny") + } + + callbackPtr := unsafe.Pointer(C.secretEventGenericCallback_cgo) + var csecret C.virSecretPtr + if secret != nil { + csecret = secret.ptr + } + ret := C.virConnectSecretEventRegisterAny_cgo(c.ptr, csecret, + C.VIR_SECRET_EVENT_ID_VALUE_CHANGED, + C.virConnectSecretEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) SecretEventDeregister(callbackId int) error { + if C.LIBVIR_VERSION_NUMBER < 3000000 { + return GetNotImplementedError("virConnectSecretEventDeregisterAny") + } + // Deregister the callback + if i := int(C.virConnectSecretEventDeregisterAnyCompat(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} + +func (e SecretEventLifecycle) String() string { + var event string + switch e.Event { + case SECRET_EVENT_DEFINED: + event = "defined" + + case SECRET_EVENT_UNDEFINED: + event = "undefined" + + default: + event = "unknown" + } + + return fmt.Sprintf("Secret event=%q", event) +} diff --git a/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.go new file mode 100644 index 000000000000..158008bc05fe --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.go @@ -0,0 +1,65 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "secret_compat.h" +#include "secret_events_cfuncs.h" +#include "callbacks_cfuncs.h" +#include + +extern void secretEventLifecycleCallback(virConnectPtr, virSecretPtr, int, int, int); +void secretEventLifecycleCallback_cgo(virConnectPtr c, virSecretPtr d, + int event, int detail, void *data) +{ + secretEventLifecycleCallback(c, d, event, detail, (int)(intptr_t)data); +} + +extern void secretEventGenericCallback(virConnectPtr, virSecretPtr, int); +void secretEventGenericCallback_cgo(virConnectPtr c, virSecretPtr d, + void *data) +{ + secretEventGenericCallback(c, d, (int)(intptr_t)data); +} + +int virConnectSecretEventRegisterAny_cgo(virConnectPtr c, virSecretPtr d, + int eventID, virConnectSecretEventGenericCallback cb, + long goCallbackId) { + void* id = (void*)goCallbackId; +#if LIBVIR_VERSION_NUMBER < 3000000 + assert(0); // Caller should have checked version +#else + return virConnectSecretEventRegisterAny(c, d, eventID, cb, id, freeGoCallback_cgo); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.h new file mode 100644 index 000000000000..96401d59c897 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/secret_events_cfuncs.h @@ -0,0 +1,40 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_SECRET_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_SECRET_EVENTS_CFUNCS_H__ + +void secretEventLifecycleCallback_cgo(virConnectPtr c, virSecretPtr d, + int event, int detail, void* data); +void secretEventGenericCallback_cgo(virConnectPtr c, virSecretPtr d, + void* data); + +int virConnectSecretEventRegisterAny_cgo(virConnectPtr c, virSecretPtr d, + int eventID, virConnectSecretEventGenericCallback cb, + long goCallbackId); + + +#endif /* LIBVIRT_GO_SECRET_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool.go b/vendor/github.com/libvirt/libvirt-go/storage_pool.go new file mode 100644 index 000000000000..7044aa5f7a35 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool.go @@ -0,0 +1,348 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "storage_pool_compat.h" +*/ +import "C" + +import ( + "reflect" + "unsafe" +) + +type StoragePoolState int + +const ( + STORAGE_POOL_INACTIVE = StoragePoolState(C.VIR_STORAGE_POOL_INACTIVE) // Not running + STORAGE_POOL_BUILDING = StoragePoolState(C.VIR_STORAGE_POOL_BUILDING) // Initializing pool,not available + STORAGE_POOL_RUNNING = StoragePoolState(C.VIR_STORAGE_POOL_RUNNING) // Running normally + STORAGE_POOL_DEGRADED = StoragePoolState(C.VIR_STORAGE_POOL_DEGRADED) // Running degraded + STORAGE_POOL_INACCESSIBLE = StoragePoolState(C.VIR_STORAGE_POOL_INACCESSIBLE) // Running,but not accessible +) + +type StoragePoolBuildFlags int + +const ( + STORAGE_POOL_BUILD_NEW = StoragePoolBuildFlags(C.VIR_STORAGE_POOL_BUILD_NEW) // Regular build from scratch + STORAGE_POOL_BUILD_REPAIR = StoragePoolBuildFlags(C.VIR_STORAGE_POOL_BUILD_REPAIR) // Repair / reinitialize + STORAGE_POOL_BUILD_RESIZE = StoragePoolBuildFlags(C.VIR_STORAGE_POOL_BUILD_RESIZE) // Extend existing pool + STORAGE_POOL_BUILD_NO_OVERWRITE = StoragePoolBuildFlags(C.VIR_STORAGE_POOL_BUILD_NO_OVERWRITE) // Do not overwrite existing pool + STORAGE_POOL_BUILD_OVERWRITE = StoragePoolBuildFlags(C.VIR_STORAGE_POOL_BUILD_OVERWRITE) // Overwrite data +) + +type StoragePoolCreateFlags int + +const ( + STORAGE_POOL_CREATE_NORMAL = StoragePoolCreateFlags(C.VIR_STORAGE_POOL_CREATE_NORMAL) + STORAGE_POOL_CREATE_WITH_BUILD = StoragePoolCreateFlags(C.VIR_STORAGE_POOL_CREATE_WITH_BUILD) + STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE = StoragePoolCreateFlags(C.VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE) + STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE = StoragePoolCreateFlags(C.VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE) +) + +type StoragePoolDeleteFlags int + +const ( + STORAGE_POOL_DELETE_NORMAL = StoragePoolDeleteFlags(C.VIR_STORAGE_POOL_DELETE_NORMAL) + STORAGE_POOL_DELETE_ZEROED = StoragePoolDeleteFlags(C.VIR_STORAGE_POOL_DELETE_ZEROED) +) + +type StoragePoolEventID int + +const ( + STORAGE_POOL_EVENT_ID_LIFECYCLE = StoragePoolEventID(C.VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE) + STORAGE_POOL_EVENT_ID_REFRESH = StoragePoolEventID(C.VIR_STORAGE_POOL_EVENT_ID_REFRESH) +) + +type StoragePoolEventLifecycleType int + +const ( + STORAGE_POOL_EVENT_DEFINED = StoragePoolEventLifecycleType(C.VIR_STORAGE_POOL_EVENT_DEFINED) + STORAGE_POOL_EVENT_UNDEFINED = StoragePoolEventLifecycleType(C.VIR_STORAGE_POOL_EVENT_UNDEFINED) + STORAGE_POOL_EVENT_STARTED = StoragePoolEventLifecycleType(C.VIR_STORAGE_POOL_EVENT_STARTED) + STORAGE_POOL_EVENT_STOPPED = StoragePoolEventLifecycleType(C.VIR_STORAGE_POOL_EVENT_STOPPED) +) + +type StoragePool struct { + ptr C.virStoragePoolPtr +} + +type StoragePoolInfo struct { + State StoragePoolState + Capacity uint64 + Allocation uint64 + Available uint64 +} + +func (p *StoragePool) Build(flags StoragePoolBuildFlags) error { + result := C.virStoragePoolBuild(p.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Create(flags StoragePoolCreateFlags) error { + result := C.virStoragePoolCreate(p.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Delete(flags StoragePoolDeleteFlags) error { + result := C.virStoragePoolDelete(p.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Destroy() error { + result := C.virStoragePoolDestroy(p.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Free() error { + ret := C.virStoragePoolFree(p.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *StoragePool) Ref() error { + ret := C.virStoragePoolRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) GetAutostart() (bool, error) { + var out C.int + result := C.virStoragePoolGetAutostart(p.ptr, (*C.int)(unsafe.Pointer(&out))) + if result == -1 { + return false, GetLastError() + } + switch out { + case 1: + return true, nil + default: + return false, nil + } +} + +func (p *StoragePool) GetInfo() (*StoragePoolInfo, error) { + var cinfo C.virStoragePoolInfo + result := C.virStoragePoolGetInfo(p.ptr, &cinfo) + if result == -1 { + return nil, GetLastError() + } + return &StoragePoolInfo{ + State: StoragePoolState(cinfo.state), + Capacity: uint64(cinfo.capacity), + Allocation: uint64(cinfo.allocation), + Available: uint64(cinfo.available), + }, nil +} + +func (p *StoragePool) GetName() (string, error) { + name := C.virStoragePoolGetName(p.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (p *StoragePool) GetUUID() ([]byte, error) { + var cUuid [C.VIR_UUID_BUFLEN](byte) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virStoragePoolGetUUID(p.ptr, (*C.uchar)(cuidPtr)) + if result != 0 { + return []byte{}, GetLastError() + } + return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil +} + +func (p *StoragePool) GetUUIDString() (string, error) { + var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) + cuidPtr := unsafe.Pointer(&cUuid) + result := C.virStoragePoolGetUUIDString(p.ptr, (*C.char)(cuidPtr)) + if result != 0 { + return "", GetLastError() + } + return C.GoString((*C.char)(cuidPtr)), nil +} + +func (p *StoragePool) GetXMLDesc(flags StorageXMLFlags) (string, error) { + result := C.virStoragePoolGetXMLDesc(p.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (p *StoragePool) IsActive() (bool, error) { + result := C.virStoragePoolIsActive(p.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (p *StoragePool) IsPersistent() (bool, error) { + result := C.virStoragePoolIsPersistent(p.ptr) + if result == -1 { + return false, GetLastError() + } + if result == 1 { + return true, nil + } + return false, nil +} + +func (p *StoragePool) SetAutostart(autostart bool) error { + var cAutostart C.int + switch autostart { + case true: + cAutostart = 1 + default: + cAutostart = 0 + } + result := C.virStoragePoolSetAutostart(p.ptr, cAutostart) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Refresh(flags uint32) error { + result := C.virStoragePoolRefresh(p.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) Undefine() error { + result := C.virStoragePoolUndefine(p.ptr) + if result == -1 { + return GetLastError() + } + return nil +} + +func (p *StoragePool) StorageVolCreateXML(xmlConfig string, flags StorageVolCreateFlags) (*StorageVol, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virStorageVolCreateXML(p.ptr, cXml, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &StorageVol{ptr: ptr}, nil +} + +func (p *StoragePool) StorageVolCreateXMLFrom(xmlConfig string, clonevol *StorageVol, flags StorageVolCreateFlags) (*StorageVol, error) { + cXml := C.CString(string(xmlConfig)) + defer C.free(unsafe.Pointer(cXml)) + ptr := C.virStorageVolCreateXMLFrom(p.ptr, cXml, clonevol.ptr, C.uint(flags)) + if ptr == nil { + return nil, GetLastError() + } + return &StorageVol{ptr: ptr}, nil +} + +func (p *StoragePool) LookupStorageVolByName(name string) (*StorageVol, error) { + cName := C.CString(name) + defer C.free(unsafe.Pointer(cName)) + ptr := C.virStorageVolLookupByName(p.ptr, cName) + if ptr == nil { + return nil, GetLastError() + } + return &StorageVol{ptr: ptr}, nil +} + +func (p *StoragePool) NumOfStorageVolumes() (int, error) { + result := int(C.virStoragePoolNumOfVolumes(p.ptr)) + if result == -1 { + return 0, GetLastError() + } + return result, nil +} + +func (p *StoragePool) ListStorageVolumes() ([]string, error) { + const maxVols = 1024 + var names [maxVols](*C.char) + namesPtr := unsafe.Pointer(&names) + numStorageVols := C.virStoragePoolListVolumes( + p.ptr, + (**C.char)(namesPtr), + maxVols) + if numStorageVols == -1 { + return nil, GetLastError() + } + goNames := make([]string, numStorageVols) + for k := 0; k < int(numStorageVols); k++ { + goNames[k] = C.GoString(names[k]) + C.free(unsafe.Pointer(names[k])) + } + return goNames, nil +} + +func (p *StoragePool) ListAllStorageVolumes(flags uint32) ([]StorageVol, error) { + var cList *C.virStorageVolPtr + numVols := C.virStoragePoolListAllVolumes(p.ptr, (**C.virStorageVolPtr)(&cList), C.uint(flags)) + if numVols == -1 { + return nil, GetLastError() + } + hdr := reflect.SliceHeader{ + Data: uintptr(unsafe.Pointer(cList)), + Len: int(numVols), + Cap: int(numVols), + } + var pools []StorageVol + slice := *(*[]C.virStorageVolPtr)(unsafe.Pointer(&hdr)) + for _, ptr := range slice { + pools = append(pools, StorageVol{ptr}) + } + C.free(unsafe.Pointer(cList)) + return pools, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.go b/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.go new file mode 100644 index 000000000000..04ad85a581d7 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.go @@ -0,0 +1,46 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "storage_pool_compat.h" + +int virConnectStoragePoolEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID) +{ +#if LIBVIR_VERSION_NUMBER < 2000000 + assert(0); // Caller shouuld have checked version +#else + return virConnectStoragePoolEventDeregisterAny(conn, callbackID); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.h b/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.h new file mode 100644 index 000000000000..23caf94006da --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool_compat.h @@ -0,0 +1,85 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_STORAGE_POOL_COMPAT_H__ +#define LIBVIRT_GO_STORAGE_POOL_COMPAT_H__ + +/* 1.3.1 */ + +#ifndef VIR_STORAGE_POOL_CREATE_NORMAL +#define VIR_STORAGE_POOL_CREATE_NORMAL 0 +#endif + +#ifndef VIR_STORAGE_POOL_CREATE_WITH_BUILD +#define VIR_STORAGE_POOL_CREATE_WITH_BUILD 1 << 0 +#endif + +#ifndef VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE +#define VIR_STORAGE_POOL_CREATE_WITH_BUILD_OVERWRITE 1 << 1 +#endif + +#ifndef VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE +#define VIR_STORAGE_POOL_CREATE_WITH_BUILD_NO_OVERWRITE 1 << 2 +#endif + + +/* 2.0.0 */ + +#ifndef VIVIR_STORAGE_POOL_EVENT_DEFINED +#define VIR_STORAGE_POOL_EVENT_DEFINED 0 +#endif + +#ifndef VIR_STORAGE_POOL_EVENT_UNDEFINED +#define VIR_STORAGE_POOL_EVENT_UNDEFINED 1 +#endif + +#ifndef VIR_STORAGE_POOL_EVENT_STARTED +#define VIR_STORAGE_POOL_EVENT_STARTED 2 +#endif + +#ifndef VIR_STORAGE_POOL_EVENT_STOPPED +#define VIR_STORAGE_POOL_EVENT_STOPPED 3 +#endif + +#ifndef VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE +#define VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE 0 +#endif + +#ifndef VIR_STORAGE_POOL_EVENT_ID_REFRESH +#define VIR_STORAGE_POOL_EVENT_ID_REFRESH 1 +#endif + +#if LIBVIR_VERSION_NUMBER < 2000000 +typedef void (*virConnectStoragePoolEventGenericCallback)(virConnectPtr conn, + virStoragePoolPtr pool, + void *opaque); +#endif + +int virConnectStoragePoolEventDeregisterAnyCompat(virConnectPtr conn, + int callbackID); + + +#endif /* LIBVIRT_GO_STORAGE_POOL_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool_events.go b/vendor/github.com/libvirt/libvirt-go/storage_pool_events.go new file mode 100644 index 000000000000..9eb5dfcffe8b --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool_events.go @@ -0,0 +1,166 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +import ( + "fmt" + "unsafe" +) + +/* +#cgo pkg-config: libvirt +#include +#include "storage_pool_compat.h" +#include "storage_pool_events_cfuncs.h" +*/ +import "C" + +type StoragePoolEventLifecycle struct { + Event StoragePoolEventLifecycleType + // TODO: we can make Detail typesafe somehow ? + Detail int +} + +type StoragePoolEventLifecycleCallback func(c *Connect, n *StoragePool, event *StoragePoolEventLifecycle) + +type StoragePoolEventGenericCallback func(c *Connect, n *StoragePool) + +//export storagePoolEventLifecycleCallback +func storagePoolEventLifecycleCallback(c C.virConnectPtr, s C.virStoragePoolPtr, + event int, detail int, + goCallbackId int) { + + storage_pool := &StoragePool{ptr: s} + connection := &Connect{ptr: c} + + eventDetails := &StoragePoolEventLifecycle{ + Event: StoragePoolEventLifecycleType(event), + Detail: detail, + } + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(StoragePoolEventLifecycleCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, storage_pool, eventDetails) +} + +//export storagePoolEventGenericCallback +func storagePoolEventGenericCallback(c C.virConnectPtr, s C.virStoragePoolPtr, + goCallbackId int) { + + storage_pool := &StoragePool{ptr: s} + connection := &Connect{ptr: c} + + callbackFunc := getCallbackId(goCallbackId) + callback, ok := callbackFunc.(StoragePoolEventGenericCallback) + if !ok { + panic("Inappropriate callback type called") + } + callback(connection, storage_pool) +} + +func (c *Connect) StoragePoolEventLifecycleRegister(pool *StoragePool, callback StoragePoolEventLifecycleCallback) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return 0, GetNotImplementedError("virConnectStoragePoolEventRegisterAny") + } + + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.storagePoolEventLifecycleCallback_cgo) + var cpool C.virStoragePoolPtr + if pool != nil { + cpool = pool.ptr + } + ret := C.virConnectStoragePoolEventRegisterAny_cgo(c.ptr, cpool, + C.VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE, + C.virConnectStoragePoolEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) StoragePoolEventRefreshRegister(pool *StoragePool, callback StoragePoolEventGenericCallback) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return 0, GetNotImplementedError("virConnectStoragePoolEventRegisterAny") + } + + goCallBackId := registerCallbackId(callback) + + callbackPtr := unsafe.Pointer(C.storagePoolEventGenericCallback_cgo) + var cpool C.virStoragePoolPtr + if pool != nil { + cpool = pool.ptr + } + ret := C.virConnectStoragePoolEventRegisterAny_cgo(c.ptr, cpool, + C.VIR_STORAGE_POOL_EVENT_ID_REFRESH, + C.virConnectStoragePoolEventGenericCallback(callbackPtr), + C.long(goCallBackId)) + if ret == -1 { + freeCallbackId(goCallBackId) + return 0, GetLastError() + } + return int(ret), nil +} + +func (c *Connect) StoragePoolEventDeregister(callbackId int) error { + if C.LIBVIR_VERSION_NUMBER < 2000000 { + return GetNotImplementedError("virConnectStoragePoolEventDeregisterAny") + } + + // Deregister the callback + if i := int(C.virConnectStoragePoolEventDeregisterAnyCompat(c.ptr, C.int(callbackId))); i != 0 { + return GetLastError() + } + return nil +} + +func (e StoragePoolEventLifecycle) String() string { + var event string + switch e.Event { + case STORAGE_POOL_EVENT_DEFINED: + event = "defined" + + case STORAGE_POOL_EVENT_UNDEFINED: + event = "undefined" + + case STORAGE_POOL_EVENT_STARTED: + event = "started" + + case STORAGE_POOL_EVENT_STOPPED: + event = "stopped" + + default: + event = "unknown" + } + + return fmt.Sprintf("StoragePool event=%q", event) +} diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.go new file mode 100644 index 000000000000..52ec553fdf39 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.go @@ -0,0 +1,65 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "storage_pool_compat.h" +#include "storage_pool_events_cfuncs.h" +#include "callbacks_cfuncs.h" +#include + +extern void storagePoolEventLifecycleCallback(virConnectPtr, virStoragePoolPtr, int, int, int); +void storagePoolEventLifecycleCallback_cgo(virConnectPtr c, virStoragePoolPtr d, + int event, int detail, void *data) +{ + storagePoolEventLifecycleCallback(c, d, event, detail, (int)(intptr_t)data); +} + +extern void storagePoolEventGenericCallback(virConnectPtr, virStoragePoolPtr, int); +void storagePoolEventGenericCallback_cgo(virConnectPtr c, virStoragePoolPtr d, + void *data) +{ + storagePoolEventGenericCallback(c, d, (int)(intptr_t)data); +} + +int virConnectStoragePoolEventRegisterAny_cgo(virConnectPtr c, virStoragePoolPtr d, + int eventID, virConnectStoragePoolEventGenericCallback cb, + long goCallbackId) { +#if LIBVIR_VERSION_NUMBER < 2000000 + assert(0); // Caller should have checked version +#else + void* id = (void*)goCallbackId; + return virConnectStoragePoolEventRegisterAny(c, d, eventID, cb, id, freeGoCallback_cgo); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.h new file mode 100644 index 000000000000..0087d6f13aec --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_pool_events_cfuncs.h @@ -0,0 +1,40 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_STORAGE_POOL_EVENTS_CFUNCS_H__ +#define LIBVIRT_GO_STORAGE_POOL_EVENTS_CFUNCS_H__ + +void storagePoolEventLifecycleCallback_cgo(virConnectPtr c, virStoragePoolPtr d, + int event, int detail, void* data); +void storagePoolEventGenericCallback_cgo(virConnectPtr c, virStoragePoolPtr d, + void* data); + +int virConnectStoragePoolEventRegisterAny_cgo(virConnectPtr c, virStoragePoolPtr d, + int eventID, virConnectStoragePoolEventGenericCallback cb, + long goCallbackId); + + +#endif /* LIBVIRT_GO_STORAGE_POOL_EVENTS_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/storage_volume.go b/vendor/github.com/libvirt/libvirt-go/storage_volume.go new file mode 100644 index 000000000000..04fc16b26bf4 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_volume.go @@ -0,0 +1,261 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "storage_volume_compat.h" +*/ +import "C" + +import ( + "unsafe" +) + +type StorageVolCreateFlags int + +const ( + STORAGE_VOL_CREATE_PREALLOC_METADATA = StorageVolCreateFlags(C.VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA) + STORAGE_VOL_CREATE_REFLINK = StorageVolCreateFlags(C.VIR_STORAGE_VOL_CREATE_REFLINK) +) + +type StorageVolDeleteFlags int + +const ( + STORAGE_VOL_DELETE_NORMAL = StorageVolDeleteFlags(C.VIR_STORAGE_VOL_DELETE_NORMAL) // Delete metadata only (fast) + STORAGE_VOL_DELETE_ZEROED = StorageVolDeleteFlags(C.VIR_STORAGE_VOL_DELETE_ZEROED) // Clear all data to zeros (slow) + STORAGE_VOL_DELETE_WITH_SNAPSHOTS = StorageVolDeleteFlags(C.VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS) // Force removal of volume, even if in use +) + +type StorageVolResizeFlags int + +const ( + STORAGE_VOL_RESIZE_ALLOCATE = StorageVolResizeFlags(C.VIR_STORAGE_VOL_RESIZE_ALLOCATE) // force allocation of new size + STORAGE_VOL_RESIZE_DELTA = StorageVolResizeFlags(C.VIR_STORAGE_VOL_RESIZE_DELTA) // size is relative to current + STORAGE_VOL_RESIZE_SHRINK = StorageVolResizeFlags(C.VIR_STORAGE_VOL_RESIZE_SHRINK) // allow decrease in capacity +) + +type StorageVolType int + +const ( + STORAGE_VOL_FILE = StorageVolType(C.VIR_STORAGE_VOL_FILE) // Regular file based volumes + STORAGE_VOL_BLOCK = StorageVolType(C.VIR_STORAGE_VOL_BLOCK) // Block based volumes + STORAGE_VOL_DIR = StorageVolType(C.VIR_STORAGE_VOL_DIR) // Directory-passthrough based volume + STORAGE_VOL_NETWORK = StorageVolType(C.VIR_STORAGE_VOL_NETWORK) //Network volumes like RBD (RADOS Block Device) + STORAGE_VOL_NETDIR = StorageVolType(C.VIR_STORAGE_VOL_NETDIR) // Network accessible directory that can contain other network volumes + STORAGE_VOL_PLOOP = StorageVolType(C.VIR_STORAGE_VOL_PLOOP) // Ploop directory based volumes +) + +type StorageVolWipeAlgorithm int + +const ( + STORAGE_VOL_WIPE_ALG_ZERO = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_ZERO) // 1-pass, all zeroes + STORAGE_VOL_WIPE_ALG_NNSA = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_NNSA) // 4-pass NNSA Policy Letter NAP-14.1-C (XVI-8) + STORAGE_VOL_WIPE_ALG_DOD = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_DOD) // 4-pass DoD 5220.22-M section 8-306 procedure + STORAGE_VOL_WIPE_ALG_BSI = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_BSI) // 9-pass method recommended by the German Center of Security in Information Technologies + STORAGE_VOL_WIPE_ALG_GUTMANN = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_GUTMANN) // The canonical 35-pass sequence + STORAGE_VOL_WIPE_ALG_SCHNEIER = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_SCHNEIER) // 7-pass method described by Bruce Schneier in "Applied Cryptography" (1996) + STORAGE_VOL_WIPE_ALG_PFITZNER7 = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_PFITZNER7) // 7-pass random + STORAGE_VOL_WIPE_ALG_PFITZNER33 = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_PFITZNER33) // 33-pass random + STORAGE_VOL_WIPE_ALG_RANDOM = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_RANDOM) // 1-pass random + STORAGE_VOL_WIPE_ALG_TRIM = StorageVolWipeAlgorithm(C.VIR_STORAGE_VOL_WIPE_ALG_TRIM) // Trim the underlying storage +) + +type StorageXMLFlags int + +const ( + STORAGE_XML_INACTIVE = StorageXMLFlags(C.VIR_STORAGE_XML_INACTIVE) +) + +type StorageVolInfoFlags int + +const ( + STORAGE_VOL_USE_ALLOCATION = StorageVolInfoFlags(C.VIR_STORAGE_VOL_USE_ALLOCATION) + STORAGE_VOL_GET_PHYSICAL = StorageVolInfoFlags(C.VIR_STORAGE_VOL_GET_PHYSICAL) +) + +type StorageVolUploadFlags int + +const ( + STORAGE_VOL_UPLOAD_SPARSE_STREAM = StorageVolUploadFlags(C.VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM) +) + +type StorageVolDownloadFlags int + +const ( + STORAGE_VOL_DOWNLOAD_SPARSE_STREAM = StorageVolDownloadFlags(C.VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM) +) + +type StorageVol struct { + ptr C.virStorageVolPtr +} + +type StorageVolInfo struct { + Type StorageVolType + Capacity uint64 + Allocation uint64 +} + +func (v *StorageVol) Delete(flags StorageVolDeleteFlags) error { + result := C.virStorageVolDelete(v.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) Free() error { + ret := C.virStorageVolFree(v.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *StorageVol) Ref() error { + ret := C.virStorageVolRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) GetInfo() (*StorageVolInfo, error) { + var cinfo C.virStorageVolInfo + result := C.virStorageVolGetInfo(v.ptr, &cinfo) + if result == -1 { + return nil, GetLastError() + } + return &StorageVolInfo{ + Type: StorageVolType(cinfo._type), + Capacity: uint64(cinfo.capacity), + Allocation: uint64(cinfo.allocation), + }, nil +} + +func (v *StorageVol) GetInfoFlags(flags StorageVolInfoFlags) (*StorageVolInfo, error) { + if C.LIBVIR_VERSION_NUMBER < 3000000 { + return nil, GetNotImplementedError("virStorageVolGetInfoFlags") + } + + var cinfo C.virStorageVolInfo + result := C.virStorageVolGetInfoFlagsCompat(v.ptr, &cinfo, C.uint(flags)) + if result == -1 { + return nil, GetLastError() + } + return &StorageVolInfo{ + Type: StorageVolType(cinfo._type), + Capacity: uint64(cinfo.capacity), + Allocation: uint64(cinfo.allocation), + }, nil +} + +func (v *StorageVol) GetKey() (string, error) { + key := C.virStorageVolGetKey(v.ptr) + if key == nil { + return "", GetLastError() + } + return C.GoString(key), nil +} + +func (v *StorageVol) GetName() (string, error) { + name := C.virStorageVolGetName(v.ptr) + if name == nil { + return "", GetLastError() + } + return C.GoString(name), nil +} + +func (v *StorageVol) GetPath() (string, error) { + result := C.virStorageVolGetPath(v.ptr) + if result == nil { + return "", GetLastError() + } + path := C.GoString(result) + C.free(unsafe.Pointer(result)) + return path, nil +} + +func (v *StorageVol) GetXMLDesc(flags uint32) (string, error) { + result := C.virStorageVolGetXMLDesc(v.ptr, C.uint(flags)) + if result == nil { + return "", GetLastError() + } + xml := C.GoString(result) + C.free(unsafe.Pointer(result)) + return xml, nil +} + +func (v *StorageVol) Resize(capacity uint64, flags StorageVolResizeFlags) error { + result := C.virStorageVolResize(v.ptr, C.ulonglong(capacity), C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) Wipe(flags uint32) error { + result := C.virStorageVolWipe(v.ptr, C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} +func (v *StorageVol) WipePattern(algorithm StorageVolWipeAlgorithm, flags uint32) error { + result := C.virStorageVolWipePattern(v.ptr, C.uint(algorithm), C.uint(flags)) + if result == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) Upload(stream *Stream, offset, length uint64, flags StorageVolUploadFlags) error { + if C.virStorageVolUpload(v.ptr, stream.ptr, C.ulonglong(offset), + C.ulonglong(length), C.uint(flags)) == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) Download(stream *Stream, offset, length uint64, flags StorageVolDownloadFlags) error { + if C.virStorageVolDownload(v.ptr, stream.ptr, C.ulonglong(offset), + C.ulonglong(length), C.uint(flags)) == -1 { + return GetLastError() + } + return nil +} + +func (v *StorageVol) LookupPoolByVolume() (*StoragePool, error) { + poolPtr := C.virStoragePoolLookupByVolume(v.ptr) + if poolPtr == nil { + return nil, GetLastError() + } + return &StoragePool{ptr: poolPtr}, nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.go b/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.go new file mode 100644 index 000000000000..46f0e0b18b59 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.go @@ -0,0 +1,47 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "storage_volume_compat.h" + +int virStorageVolGetInfoFlagsCompat(virStorageVolPtr vol, + virStorageVolInfoPtr info, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3000000 + assert(0); // Caller should have checked version +#else + return virStorageVolGetInfoFlags(vol, info, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.h b/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.h new file mode 100644 index 000000000000..a20d04aca3b1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/storage_volume_compat.h @@ -0,0 +1,82 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_STORAGE_VOLUME_COMPAT_H__ +#define LIBVIRT_GO_STORAGE_VOLUME_COMPAT_H__ + +/* 3.0.0 */ + +int virStorageVolGetInfoFlagsCompat(virStorageVolPtr vol, + virStorageVolInfoPtr info, + unsigned int flags); + +#ifndef VIR_STORAGE_VOL_USE_ALLOCATION +#define VIR_STORAGE_VOL_USE_ALLOCATION 0 +#endif + +#ifndef VIR_STORAGE_VOL_GET_PHYSICAL +#define VIR_STORAGE_VOL_GET_PHYSICAL 1 << 0 +#endif + + +/* 1.2.13 */ + +#ifndef VIR_STORAGE_VOL_CREATE_REFLINK +#define VIR_STORAGE_VOL_CREATE_REFLINK 1<< 1 +#endif + + +/* 1.2.21 */ + +#ifndef VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS +#define VIR_STORAGE_VOL_DELETE_WITH_SNAPSHOTS 1 << 1 +#endif + + +/* 1.3.2 */ + +#ifndef VIR_STORAGE_VOL_WIPE_ALG_TRIM +#define VIR_STORAGE_VOL_WIPE_ALG_TRIM 9 +#endif + + +/* 1.3.4 */ + +#ifndef VIR_STORAGE_VOL_PLOOP +#define VIR_STORAGE_VOL_PLOOP 5 +#endif + +/* 3.4.0 */ + +#ifndef VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM +#define VIR_STORAGE_VOL_UPLOAD_SPARSE_STREAM (1 << 0) +#endif + +#ifndef VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM +#define VIR_STORAGE_VOL_DOWNLOAD_SPARSE_STREAM (1 << 0) +#endif + +#endif /* LIBVIRT_GO_STORAGE_VOLUME_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/stream.go b/vendor/github.com/libvirt/libvirt-go/stream.go new file mode 100644 index 000000000000..c6cdd06305aa --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/stream.go @@ -0,0 +1,389 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include "stream_cfuncs.h" +#include "stream_compat.h" +*/ +import "C" +import ( + "io" + "unsafe" +) + +type StreamFlags int + +const ( + STREAM_NONBLOCK = StreamFlags(C.VIR_STREAM_NONBLOCK) +) + +type StreamEventType int + +const ( + STREAM_EVENT_READABLE = StreamEventType(C.VIR_STREAM_EVENT_READABLE) + STREAM_EVENT_WRITABLE = StreamEventType(C.VIR_STREAM_EVENT_WRITABLE) + STREAM_EVENT_ERROR = StreamEventType(C.VIR_STREAM_EVENT_ERROR) + STREAM_EVENT_HANGUP = StreamEventType(C.VIR_STREAM_EVENT_HANGUP) +) + +type StreamRecvFlagsValues int + +const ( + STREAM_RECV_STOP_AT_HOLE = StreamRecvFlagsValues(C.VIR_STREAM_RECV_STOP_AT_HOLE) +) + +type Stream struct { + ptr C.virStreamPtr +} + +func (v *Stream) Abort() error { + result := C.virStreamAbort(v.ptr) + if result == -1 { + return GetLastError() + } + + return nil +} + +func (v *Stream) Finish() error { + result := C.virStreamFinish(v.ptr) + if result == -1 { + return GetLastError() + } + + return nil +} + +func (v *Stream) Free() error { + ret := C.virStreamFree(v.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (c *Stream) Ref() error { + ret := C.virStreamRef(c.ptr) + if ret == -1 { + return GetLastError() + } + return nil +} + +func (v *Stream) Recv(p []byte) (int, error) { + n := C.virStreamRecv(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p))) + if n < 0 { + return 0, GetLastError() + } + if n == 0 { + return 0, io.EOF + } + + return int(n), nil +} + +func (v *Stream) RecvFlags(p []byte, flags StreamRecvFlagsValues) (int, error) { + if C.LIBVIR_VERSION_NUMBER < 3004000 { + return 0, GetNotImplementedError("virStreamRecvFlags") + } + + n := C.virStreamRecvFlagsCompat(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p)), C.uint(flags)) + if n < 0 { + return 0, GetLastError() + } + if n == 0 { + return 0, io.EOF + } + + return int(n), nil +} + +func (v *Stream) RecvHole(flags uint) (int64, error) { + if C.LIBVIR_VERSION_NUMBER < 3004000 { + return 0, GetNotImplementedError("virStreamSparseRecvHole") + } + + var len C.longlong + ret := C.virStreamRecvHoleCompat(v.ptr, &len, C.uint(flags)) + if ret < 0 { + return 0, GetLastError() + } + + return int64(len), nil +} + +func (v *Stream) Send(p []byte) (int, error) { + n := C.virStreamSend(v.ptr, (*C.char)(unsafe.Pointer(&p[0])), C.size_t(len(p))) + if n < 0 { + return 0, GetLastError() + } + if n == 0 { + return 0, io.EOF + } + + return int(n), nil +} + +func (v *Stream) SendHole(len int64, flags uint32) error { + if C.LIBVIR_VERSION_NUMBER < 3004000 { + return GetNotImplementedError("virStreamSendHole") + } + + ret := C.virStreamSendHoleCompat(v.ptr, C.longlong(len), C.uint(flags)) + if ret < 0 { + return GetLastError() + } + + return nil +} + +type StreamSinkFunc func(*Stream, []byte) (int, error) +type StreamSinkHoleFunc func(*Stream, int64) error + +//export streamSinkCallback +func streamSinkCallback(stream C.virStreamPtr, cdata *C.char, nbytes C.size_t, callbackID int) int { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamSinkFunc) + if !ok { + panic("Incorrect stream sink func callback") + } + + data := make([]byte, int(nbytes)) + for i := 0; i < int(nbytes); i++ { + cdatabyte := (*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cdata)) + (unsafe.Sizeof(*cdata) * uintptr(i)))) + data[i] = (byte)(*cdatabyte) + } + + retnbytes, err := callback(&Stream{ptr: stream}, data) + if err != nil { + return -1 + } + + return retnbytes +} + +//export streamSinkHoleCallback +func streamSinkHoleCallback(stream C.virStreamPtr, length C.longlong, callbackID int) int { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamSinkHoleFunc) + if !ok { + panic("Incorrect stream sink hole func callback") + } + + err := callback(&Stream{ptr: stream}, int64(length)) + if err != nil { + return -1 + } + + return 0 +} + +func (v *Stream) RecvAll(handler StreamSinkFunc) error { + + callbackID := registerCallbackId(handler) + + ret := C.virStreamRecvAll_cgo(v.ptr, (C.int)(callbackID)) + freeCallbackId(callbackID) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (v *Stream) SparseRecvAll(handler StreamSinkFunc, holeHandler StreamSinkHoleFunc) error { + if C.LIBVIR_VERSION_NUMBER < 3004000 { + return GetNotImplementedError("virStreamSparseSendAll") + } + + callbackID := registerCallbackId(handler) + holeCallbackID := registerCallbackId(holeHandler) + + ret := C.virStreamSparseRecvAll_cgo(v.ptr, (C.int)(callbackID), (C.int)(holeCallbackID)) + freeCallbackId(callbackID) + freeCallbackId(holeCallbackID) + if ret == -1 { + return GetLastError() + } + + return nil +} + +type StreamSourceFunc func(*Stream, int) ([]byte, error) +type StreamSourceHoleFunc func(*Stream) (bool, int64, error) +type StreamSourceSkipFunc func(*Stream, int64) error + +//export streamSourceCallback +func streamSourceCallback(stream C.virStreamPtr, cdata *C.char, nbytes C.size_t, callbackID int) int { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamSourceFunc) + if !ok { + panic("Incorrect stream sink func callback") + } + + data, err := callback(&Stream{ptr: stream}, (int)(nbytes)) + if err != nil { + return -1 + } + + nretbytes := int(nbytes) + if len(data) < nretbytes { + nretbytes = len(data) + } + + for i := 0; i < nretbytes; i++ { + cdatabyte := (*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(cdata)) + (unsafe.Sizeof(*cdata) * uintptr(i)))) + *cdatabyte = (C.char)(data[i]) + } + + return nretbytes +} + +//export streamSourceHoleCallback +func streamSourceHoleCallback(stream C.virStreamPtr, cinData *C.int, clength *C.longlong, callbackID int) int { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamSourceHoleFunc) + if !ok { + panic("Incorrect stream sink hole func callback") + } + + inData, length, err := callback(&Stream{ptr: stream}) + if err != nil { + return -1 + } + + if inData { + *cinData = 1 + } else { + *cinData = 0 + } + *clength = C.longlong(length) + + return 0 +} + +//export streamSourceSkipCallback +func streamSourceSkipCallback(stream C.virStreamPtr, length C.longlong, callbackID int) int { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamSourceSkipFunc) + if !ok { + panic("Incorrect stream sink skip func callback") + } + + err := callback(&Stream{ptr: stream}, int64(length)) + if err != nil { + return -1 + } + + return 0 +} + +func (v *Stream) SendAll(handler StreamSourceFunc) error { + + callbackID := registerCallbackId(handler) + + ret := C.virStreamSendAll_cgo(v.ptr, (C.int)(callbackID)) + freeCallbackId(callbackID) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (v *Stream) SparseSendAll(handler StreamSourceFunc, holeHandler StreamSourceHoleFunc, skipHandler StreamSourceSkipFunc) error { + if C.LIBVIR_VERSION_NUMBER < 3004000 { + return GetNotImplementedError("virStreamSparseSendAll") + } + + callbackID := registerCallbackId(handler) + holeCallbackID := registerCallbackId(holeHandler) + skipCallbackID := registerCallbackId(skipHandler) + + ret := C.virStreamSparseSendAll_cgo(v.ptr, (C.int)(callbackID), (C.int)(holeCallbackID), (C.int)(skipCallbackID)) + freeCallbackId(callbackID) + freeCallbackId(holeCallbackID) + freeCallbackId(skipCallbackID) + if ret == -1 { + return GetLastError() + } + + return nil +} + +type StreamEventCallback func(*Stream, StreamEventType) + +func (v *Stream) EventAddCallback(events StreamEventType, callback StreamEventCallback) error { + callbackID := registerCallbackId(callback) + + ret := C.virStreamEventAddCallback_cgo(v.ptr, (C.int)(events), (C.int)(callbackID)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +//export streamEventCallback +func streamEventCallback(st C.virStreamPtr, events int, callbackID int) { + callbackFunc := getCallbackId(callbackID) + + callback, ok := callbackFunc.(StreamEventCallback) + if !ok { + panic("Incorrect stream event func callback") + } + + callback(&Stream{ptr: st}, StreamEventType(events)) +} + +func (v *Stream) EventUpdateCallback(events StreamEventType) error { + ret := C.virStreamEventUpdateCallback(v.ptr, (C.int)(events)) + if ret == -1 { + return GetLastError() + } + + return nil +} + +func (v *Stream) EventRemoveCallback() error { + ret := C.virStreamEventRemoveCallback(v.ptr) + if ret == -1 { + return GetLastError() + } + + return nil +} diff --git a/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.go b/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.go new file mode 100644 index 000000000000..99cde0e976f3 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.go @@ -0,0 +1,132 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include +#include +#include "stream_cfuncs.h" + +int streamSourceCallback(virStreamPtr st, char *cdata, size_t nbytes, int callbackID); +int streamSourceHoleCallback(virStreamPtr st, int *inData, long long *length, int callbackID); +int streamSourceSkipCallback(virStreamPtr st, long long length, int callbackID); + +int streamSinkCallback(virStreamPtr st, const char *cdata, size_t nbytes, int callbackID); +int streamSinkHoleCallback(virStreamPtr st, long long length, int callbackID); + +struct CallbackData { + int callbackID; + int holeCallbackID; + int skipCallbackID; +}; + +static int streamSourceCallbackHelper(virStreamPtr st, char *data, size_t nbytes, void *opaque) +{ + struct CallbackData *cbdata = opaque; + + return streamSourceCallback(st, data, nbytes, cbdata->callbackID); +} + +static int streamSourceHoleCallbackHelper(virStreamPtr st, int *inData, long long *length, void *opaque) +{ + struct CallbackData *cbdata = opaque; + + return streamSourceHoleCallback(st, inData, length, cbdata->holeCallbackID); +} + +static int streamSourceSkipCallbackHelper(virStreamPtr st, long long length, void *opaque) +{ + struct CallbackData *cbdata = opaque; + + return streamSourceSkipCallback(st, length, cbdata->skipCallbackID); +} + +static int streamSinkCallbackHelper(virStreamPtr st, const char *data, size_t nbytes, void *opaque) +{ + struct CallbackData *cbdata = opaque; + + return streamSinkCallback(st, data, nbytes, cbdata->callbackID); +} + +static int streamSinkHoleCallbackHelper(virStreamPtr st, long long length, void *opaque) +{ + struct CallbackData *cbdata = opaque; + + return streamSinkHoleCallback(st, length, cbdata->holeCallbackID); +} + +int virStreamSendAll_cgo(virStreamPtr st, int callbackID) +{ + struct CallbackData cbdata = { .callbackID = callbackID }; + return virStreamSendAll(st, streamSourceCallbackHelper, &cbdata); +} + +int virStreamSparseSendAll_cgo(virStreamPtr st, int callbackID, int holeCallbackID, int skipCallbackID) +{ + struct CallbackData cbdata = { .callbackID = callbackID, .holeCallbackID = holeCallbackID, .skipCallbackID = skipCallbackID }; +#if LIBVIR_VERSION_NUMBER < 3004000 + assert(0); // Caller should have checked version +#else + return virStreamSparseSendAll(st, streamSourceCallbackHelper, streamSourceHoleCallbackHelper, streamSourceSkipCallbackHelper, &cbdata); +#endif +} + + +int virStreamRecvAll_cgo(virStreamPtr st, int callbackID) +{ + struct CallbackData cbdata = { .callbackID = callbackID }; + return virStreamRecvAll(st, streamSinkCallbackHelper, &cbdata); +} + +int virStreamSparseRecvAll_cgo(virStreamPtr st, int callbackID, int holeCallbackID) +{ + struct CallbackData cbdata = { .callbackID = callbackID, .holeCallbackID = holeCallbackID }; +#if LIBVIR_VERSION_NUMBER < 3004000 + assert(0); // Caller should have checked version +#else + return virStreamSparseRecvAll(st, streamSinkCallbackHelper, streamSinkHoleCallbackHelper, &cbdata); +#endif +} + +void streamEventCallback(virStreamPtr st, int events, int callbackID); + +static void streamEventCallbackHelper(virStreamPtr st, int events, void *opaque) +{ + streamEventCallback(st, events, (int)(intptr_t)opaque); +} + +int virStreamEventAddCallback_cgo(virStreamPtr st, int events, int callbackID) +{ + return virStreamEventAddCallback(st, events, streamEventCallbackHelper, (void *)(intptr_t)callbackID, NULL); +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.h b/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.h new file mode 100644 index 000000000000..d5696eced854 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/stream_cfuncs.h @@ -0,0 +1,37 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_STREAM_CFUNCS_H__ +#define LIBVIRT_GO_STREAM_CFUNCS_H__ + +int virStreamSendAll_cgo(virStreamPtr st, int callbackID); +int virStreamRecvAll_cgo(virStreamPtr st, int callbackID); +int virStreamSparseSendAll_cgo(virStreamPtr st, int callbackID, int holeCallbackID, int skipCallbackID); +int virStreamSparseRecvAll_cgo(virStreamPtr st, int callbackID, int holeCallbackID); + +int virStreamEventAddCallback_cgo(virStreamPtr st, int events, int callbackID); + +#endif /* LIBVIRT_GO_STREAM_CFUNCS_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/stream_compat.go b/vendor/github.com/libvirt/libvirt-go/stream_compat.go new file mode 100644 index 000000000000..c5a3f2f73e8a --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/stream_compat.go @@ -0,0 +1,69 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (C) 2017 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include "stream_compat.h" + +int virStreamRecvFlagsCompat(virStreamPtr st, + char *data, + size_t nbytes, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3004000 + assert(0); // Caller should have checked version +#else + return virStreamRecvFlags(st, data, nbytes, flags); +#endif +} + +int virStreamSendHoleCompat(virStreamPtr st, + long long length, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3004000 + assert(0); // Caller should have checked version +#else + return virStreamSendHole(st, length, flags); +#endif +} + +int virStreamRecvHoleCompat(virStreamPtr st, + long long *length, + unsigned int flags) +{ +#if LIBVIR_VERSION_NUMBER < 3004000 + assert(0); // Caller should have checked version +#else + return virStreamRecvHole(st, length, flags); +#endif +} + +*/ +import "C" diff --git a/vendor/github.com/libvirt/libvirt-go/stream_compat.h b/vendor/github.com/libvirt/libvirt-go/stream_compat.h new file mode 100644 index 000000000000..1488d8f398c4 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/stream_compat.h @@ -0,0 +1,49 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +#ifndef LIBVIRT_GO_STREAM_COMPAT_H__ +#define LIBVIRT_GO_STREAM_COMPAT_H__ + +/* 3.4.0 */ + +#ifndef VIR_STREAM_RECV_STOP_AT_HOLE +#define VIR_STREAM_RECV_STOP_AT_HOLE (1 << 0) +#endif + +int virStreamRecvFlagsCompat(virStreamPtr st, + char *data, + size_t nbytes, + unsigned int flags); + +int virStreamSendHoleCompat(virStreamPtr st, + long long length, + unsigned int flags); + +int virStreamRecvHoleCompat(virStreamPtr, + long long *length, + unsigned int flags); + +#endif /* LIBVIRT_GO_STREAM_COMPAT_H__ */ diff --git a/vendor/github.com/libvirt/libvirt-go/typedparams.go b/vendor/github.com/libvirt/libvirt-go/typedparams.go new file mode 100644 index 000000000000..e8ceae07e1e1 --- /dev/null +++ b/vendor/github.com/libvirt/libvirt-go/typedparams.go @@ -0,0 +1,262 @@ +/* + * This file is part of the libvirt-go project + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Copyright (c) 2013 Alex Zorin + * Copyright (C) 2016 Red Hat, Inc. + * + */ + +package libvirt + +/* +#cgo pkg-config: libvirt +#include +#include +#include +#include +*/ +import "C" + +import ( + "fmt" + "unsafe" +) + +type typedParamsFieldInfo struct { + set *bool + i *int + ui *uint + l *int64 + ul *uint64 + b *bool + d *float64 + s *string + sl *[]string +} + +func typedParamsUnpackLen(cparams *C.virTypedParameter, nparams int, infomap map[string]typedParamsFieldInfo) (uint, error) { + count := uint(0) + for i := 0; i < nparams; i++ { + var cparam *C.virTypedParameter + cparam = (*C.virTypedParameter)(unsafe.Pointer(uintptr(unsafe.Pointer(cparams)) + unsafe.Sizeof(*cparam)*uintptr(i))) + name := C.GoString((*C.char)(unsafe.Pointer(&cparam.field))) + info, ok := infomap[name] + if !ok { + // Ignore unknown keys so that we don't break if + // run against a newer libvirt that returns more + // parameters than we currently have code to + // consume + continue + } + switch cparam._type { + case C.VIR_TYPED_PARAM_INT: + if info.i == nil { + return 0, fmt.Errorf("field %s expects an int", name) + } + *info.i = int(*(*C.int)(unsafe.Pointer(&cparam.value))) + *info.set = true + case C.VIR_TYPED_PARAM_UINT: + if info.ui == nil { + return 0, fmt.Errorf("field %s expects a uint", name) + } + *info.ui = uint(*(*C.uint)(unsafe.Pointer(&cparam.value))) + *info.set = true + case C.VIR_TYPED_PARAM_LLONG: + if info.l == nil { + return 0, fmt.Errorf("field %s expects an int64", name) + } + *info.l = int64(*(*C.longlong)(unsafe.Pointer(&cparam.value))) + *info.set = true + case C.VIR_TYPED_PARAM_ULLONG: + if info.ul == nil { + return 0, fmt.Errorf("field %s expects a uint64", name) + } + *info.ul = uint64(*(*C.ulonglong)(unsafe.Pointer(&cparam.value))) + *info.set = true + case C.VIR_TYPED_PARAM_DOUBLE: + if info.d == nil { + return 0, fmt.Errorf("field %s expects a float64", name) + } + *info.d = float64(*(*C.double)(unsafe.Pointer(&cparam.value))) + *info.set = true + case C.VIR_TYPED_PARAM_BOOLEAN: + if info.b == nil { + return 0, fmt.Errorf("field %s expects a bool", name) + } + *info.b = *(*C.char)(unsafe.Pointer(&cparam.value)) == 1 + *info.set = true + case C.VIR_TYPED_PARAM_STRING: + if info.s != nil { + *info.s = C.GoString(*(**C.char)(unsafe.Pointer(&cparam.value))) + *info.set = true + } else if info.sl != nil { + *info.sl = append(*info.sl, C.GoString(*(**C.char)(unsafe.Pointer(&cparam.value)))) + *info.set = true + } else { + return 0, fmt.Errorf("field %s expects a string/string list", name) + } + } + count++ + } + + return count, nil +} + +func typedParamsUnpack(cparams []C.virTypedParameter, infomap map[string]typedParamsFieldInfo) (uint, error) { + return typedParamsUnpackLen(&cparams[0], len(cparams), infomap) +} + +func typedParamsPackLen(cparams *C.virTypedParameter, nparams int, infomap map[string]typedParamsFieldInfo) error { + stringOffsets := make(map[string]uint) + + for i := 0; i < nparams; i++ { + var cparam *C.virTypedParameter + cparam = (*C.virTypedParameter)(unsafe.Pointer(uintptr(unsafe.Pointer(cparams)) + unsafe.Sizeof(*cparam)*uintptr(i))) + name := C.GoString((*C.char)(unsafe.Pointer(&cparam.field))) + info, ok := infomap[name] + if !ok { + // Ignore unknown keys so that we don't break if + // run against a newer libvirt that returns more + // parameters than we currently have code to + // consume + continue + } + if !*info.set { + continue + } + switch cparam._type { + case C.VIR_TYPED_PARAM_INT: + if info.i == nil { + return fmt.Errorf("field %s expects an int", name) + } + *(*C.int)(unsafe.Pointer(&cparam.value)) = C.int(*info.i) + case C.VIR_TYPED_PARAM_UINT: + if info.ui == nil { + return fmt.Errorf("field %s expects a uint", name) + } + *(*C.uint)(unsafe.Pointer(&cparam.value)) = C.uint(*info.ui) + case C.VIR_TYPED_PARAM_LLONG: + if info.l == nil { + return fmt.Errorf("field %s expects an int64", name) + } + *(*C.longlong)(unsafe.Pointer(&cparam.value)) = C.longlong(*info.l) + case C.VIR_TYPED_PARAM_ULLONG: + if info.ul == nil { + return fmt.Errorf("field %s expects a uint64", name) + } + *(*C.ulonglong)(unsafe.Pointer(&cparam.value)) = C.ulonglong(*info.ul) + case C.VIR_TYPED_PARAM_DOUBLE: + if info.d == nil { + return fmt.Errorf("field %s expects a float64", name) + } + *(*C.double)(unsafe.Pointer(&cparam.value)) = C.double(*info.d) + case C.VIR_TYPED_PARAM_BOOLEAN: + if info.b == nil { + return fmt.Errorf("field %s expects a bool", name) + } + if *info.b { + *(*C.char)(unsafe.Pointer(&cparam.value)) = 1 + } else { + *(*C.char)(unsafe.Pointer(&cparam.value)) = 0 + } + case C.VIR_TYPED_PARAM_STRING: + if info.s != nil { + *(**C.char)(unsafe.Pointer(&cparam.value)) = C.CString(*info.s) + } else if info.sl != nil { + count := stringOffsets[name] + *(**C.char)(unsafe.Pointer(&cparam.value)) = C.CString((*info.sl)[count]) + stringOffsets[name] = count + 1 + } else { + return fmt.Errorf("field %s expects a string", name) + } + } + } + + return nil +} + +func typedParamsPack(cparams []C.virTypedParameter, infomap map[string]typedParamsFieldInfo) error { + return typedParamsPackLen(&cparams[0], len(cparams), infomap) +} + +func typedParamsPackNew(infomap map[string]typedParamsFieldInfo) (*[]C.virTypedParameter, error) { + nparams := 0 + for _, value := range infomap { + if !*value.set { + continue + } + + if value.sl != nil { + nparams += len(*value.sl) + } else { + nparams++ + } + } + + cparams := make([]C.virTypedParameter, nparams) + nparams = 0 + for key, value := range infomap { + if !*value.set { + continue + } + + cfield := C.CString(key) + defer C.free(unsafe.Pointer(cfield)) + clen := len(key) + 1 + if clen > C.VIR_TYPED_PARAM_FIELD_LENGTH { + clen = C.VIR_TYPED_PARAM_FIELD_LENGTH + } + if value.sl != nil { + for i := 0; i < len(*value.sl); i++ { + cparam := &cparams[nparams] + cparam._type = C.VIR_TYPED_PARAM_STRING + C.memcpy(unsafe.Pointer(&cparam.field[0]), unsafe.Pointer(cfield), C.size_t(clen)) + nparams++ + } + } else { + cparam := &cparams[nparams] + if value.i != nil { + cparam._type = C.VIR_TYPED_PARAM_INT + } else if value.ui != nil { + cparam._type = C.VIR_TYPED_PARAM_UINT + } else if value.l != nil { + cparam._type = C.VIR_TYPED_PARAM_LLONG + } else if value.ul != nil { + cparam._type = C.VIR_TYPED_PARAM_ULLONG + } else if value.b != nil { + cparam._type = C.VIR_TYPED_PARAM_BOOLEAN + } else if value.d != nil { + cparam._type = C.VIR_TYPED_PARAM_DOUBLE + } else if value.s != nil { + cparam._type = C.VIR_TYPED_PARAM_STRING + } + C.memcpy(unsafe.Pointer(&cparam.field[0]), unsafe.Pointer(cfield), C.size_t(clen)) + nparams++ + } + } + + err := typedParamsPack(cparams, infomap) + if err != nil { + C.virTypedParamsClear((*C.virTypedParameter)(unsafe.Pointer(&cparams[0])), C.int(nparams)) + return nil, err + } + return &cparams, nil +}