{"id":13500436,"url":"https://github.com/digitalocean/go-libvirt","last_synced_at":"2025-06-11T01:09:00.758Z","repository":{"id":37821692,"uuid":"59240156","full_name":"digitalocean/go-libvirt","owner":"digitalocean","description":"Package libvirt provides a pure Go interface for interacting with Libvirt.  Apache 2.0 Licensed.","archived":false,"fork":false,"pushed_at":"2025-05-12T23:19:07.000Z","size":666,"stargazers_count":988,"open_issues_count":13,"forks_count":136,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-05-13T00:23:56.527Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalocean.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-05-19T20:26:41.000Z","updated_at":"2025-05-12T23:19:07.000Z","dependencies_parsed_at":"2024-09-16T20:29:31.528Z","dependency_job_id":"5288ca1c-5ab1-40e1-9cdb-c02e0a2a8c8b","html_url":"https://github.com/digitalocean/go-libvirt","commit_stats":{"total_commits":174,"total_committers":36,"mean_commits":4.833333333333333,"dds":0.7873563218390804,"last_synced_commit":"2939327a8519c6cffe295bfe2dd2e7b8cd153801"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-libvirt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-libvirt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-libvirt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-libvirt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalocean","download_url":"https://codeload.github.com/digitalocean/go-libvirt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalocean%2Fgo-libvirt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259178492,"owners_count":22817388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T22:01:00.932Z","updated_at":"2025-06-11T01:09:00.731Z","avatar_url":"https://github.com/digitalocean.png","language":"Go","funding_links":[],"categories":["Go","Open source projects"],"sub_categories":[],"readme":"libvirt\n[![GoDoc](http://godoc.org/github.com/digitalocean/go-libvirt?status.svg)](http://godoc.org/github.com/digitalocean/go-libvirt)\n[![Build Status](https://github.com/digitalocean/go-libvirt/actions/workflows/main.yml/badge.svg)](https://github.com/digitalocean/go-libvirt/actions/)\n[![Report Card](https://goreportcard.com/badge/github.com/digitalocean/go-libvirt)](https://goreportcard.com/report/github.com/digitalocean/go-libvirt)\n====\n\nPackage `go-libvirt` provides a pure Go interface for interacting with libvirt.\n\nRather than using libvirt's C bindings, this package makes use of\nlibvirt's RPC interface, as documented [here](https://libvirt.org/kbase/internals/rpc.html).\nConnections to the libvirt server may be local, or remote. RPC packets are encoded\nusing the XDR standard as defined by [RFC 4506](https://tools.ietf.org/html/rfc4506.html).\n\nlibvirt's RPC interface is quite extensive, and changes from one version to the\nnext, so this project uses a pair of code generators to build the go bindings.\nThe code generators should be run whenever you want to build go-libvirt for a\nnew version of libvirt. See the next section for directions on re-generating\ngo-libvirt.\n\n[Pull requests are welcome](https://github.com/digitalocean/go-libvirt/blob/master/CONTRIBUTING.md)!\n\nFeel free to join us in [`#go-libvirt` on libera chat](https://web.libera.chat/)\nif you'd like to discuss the project.\n\nRunning the Code Generators\n---------------------------\n\nThe code generator doesn't run automatically when you build go-libvirt. It's\nmeant to be run manually any time you change the version of libvirt you're\nusing. When you download go-libvirt it will come with generated files\ncorresponding to a particular version of libvirt. You can use the library as-is,\nbut the generated code may be missing libvirt functions, if you're using a newer\nversion of libvirt, or it may have extra functions that will return\n'unimplemented' errors if you try to call them. If this is a problem, you should\nre-run the code generator. To do this, follow these steps:\n\n- First, download a copy of the libvirt sources corresponding to the version you\n  want to use.\n- Change directories into where you've unpacked your distribution of libvirt.\n- The second step depends on the version of libvirt you'd like to build against.\n  It's not necessary to actually build libvirt, but it is necessary to run libvirt's\n  \"configure\" step because it generates required files.\n  - For libvirt \u003c v6.7.0:\n    - `$ mkdir build; cd build`\n    - `$ ../autogen.sh`\n  - For libvirt \u003e= v6.7.0:\n    - `$ meson setup build`\n- Finally, set the environment variable `LIBVIRT_SOURCE` to the directory you\n  put libvirt into, and run `go generate ./...` from the go-libvirt directory.\n  This runs both of the go-libvirt's code generators.\n\nHow to Use This Library\n-----------------------\n\nOnce you've vendored go-libvirt into your project, you'll probably want to call\nsome libvirt functions. There's some example code below showing how to connect\nto libvirt and make one such call, but once you get past the introduction you'll\nnext want to call some other libvirt functions. How do you find them?\n\nStart with the [libvirt API reference](https://libvirt.org/html/index.html).\nLet's say you want to gracefully shutdown a VM, and after reading through the\nlibvirt docs you determine that virDomainShutdown() is the function you want to\ncall to do that. Where's that function in go-libvirt? We transform the names\nslightly when building the go bindings. There's no need for a global prefix like\n\"vir\" in Go, since all our functions are inside the package namespace, so we\ndrop it. That means the Go function for `virDomainShutdown()` is just `DomainShutdown()`,\nand sure enough, you can find the Go function `DomainShutdown()` in libvirt.gen.go,\nwith parameters and return values equivalent to those documented in the API\nreference.\n\nSuppose you then decide you need more control over your shutdown, so you switch\nover to `virDomainShutdownFlags()`. As its name suggests, this function takes a\nflag parameter which has possible values specified in an enum called\n`virDomainShutdownFlagValues`. Flag types like this are a little tricky for the\ncode generator, because the C functions just take an integer type - only the\nlibvirt documentation actually ties the flags to the enum types. In most cases\nthough we're able to generate a wrapper function with a distinct flag type,\nmaking it easier for Go tooling to suggest possible flag values while you're\nworking. Checking the documentation for this function:\n\n`godoc github.com/digitalocean/go-libvirt DomainShutdownFlags`\n\nreturns this:\n\n`func (l *Libvirt) DomainShutdownFlags(Dom Domain, Flags DomainShutdownFlagValues) (err error)`\n\nIf you want to see the possible flag values, `godoc` can help again:\n\n```\n$ godoc github.com/digitalocean/go-libvirt DomainShutdownFlagValues\n\ntype DomainShutdownFlagValues int32\n    DomainShutdownFlagValues as declared in libvirt/libvirt-domain.h:1121\n\nconst (\n    DomainShutdownDefault      DomainShutdownFlagValues = iota\n    DomainShutdownAcpiPowerBtn DomainShutdownFlagValues = 1\n    DomainShutdownGuestAgent   DomainShutdownFlagValues = 2\n    DomainShutdownInitctl      DomainShutdownFlagValues = 4\n    DomainShutdownSignal       DomainShutdownFlagValues = 8\n    DomainShutdownParavirt     DomainShutdownFlagValues = 16\n)\n    DomainShutdownFlagValues enumeration from libvirt/libvirt-domain.h:1121\n```\n\nOne other suggestion: most of the code in go-libvirt is now generated, but a few\nhand-written routines still exist in libvirt.go, and wrap calls to the generated\ncode with slightly different parameters or return values. We suggest avoiding\nthese hand-written routines and calling the generated routines in libvirt.gen.go\ninstead. Over time these handwritten routines will be removed from go-libvirt.\n\nWarning\n-------\n\nWhile these package are reasonably well-tested and have seen some use inside of\nDigitalOcean, there may be subtle bugs which could cause the packages to act\nin unexpected ways.  Use at your own risk!\n\nIn addition, the API is not considered stable at this time.  If you would like\nto include package `libvirt` in a project, we highly recommend vendoring it into\nyour project.\n\nExample\n-------\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/url\"\n\n\t\"github.com/digitalocean/go-libvirt\"\n)\n\nfunc main() {\n\turi, _ := url.Parse(string(libvirt.QEMUSystem))\n\tl, err := libvirt.ConnectToURI(uri)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to connect: %v\", err)\n\t}\n\n\tv, err := l.ConnectGetLibVersion()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to retrieve libvirt version: %v\", err)\n\t}\n\tfmt.Println(\"Version:\", v)\n\n\tflags := libvirt.ConnectListDomainsActive | libvirt.ConnectListDomainsInactive\n\tdomains, _, err := l.ConnectListAllDomains(1, flags)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to retrieve domains: %v\", err)\n\t}\n\n\tfmt.Println(\"ID\\tName\\t\\tUUID\")\n\tfmt.Printf(\"--------------------------------------------------------\\n\")\n\tfor _, d := range domains {\n\t\tfmt.Printf(\"%d\\t%s\\t%x\\n\", d.ID, d.Name, d.UUID)\n\t}\n\n\tif err = l.Disconnect(); err != nil {\n\t\tlog.Fatalf(\"failed to disconnect: %v\", err)\n\t}\n}\n\n\n```\n\n```\nVersion: 1.3.4\nID\tName\t\tUUID\n--------------------------------------------------------\n1\tTest-1\t\tdc329f87d4de47198cfd2e21c6105b01\n2\tTest-2\t\tdc229f87d4de47198cfd2e21c6105b01\n```\n\nExample (Connect to libvirt via TLS over TCP)\n-------\n\n```go\npackage main\n\nimport (\n        \"crypto/tls\"\n        \"crypto/x509\"\n\n        \"fmt\"\n        \"io/ioutil\"\n        \"log\"\n\n        \"github.com/digitalocean/go-libvirt\"\n        \"github.com/digitalocean/go-libvirt/socket/dialers\"\n)\n\nfunc main() {\n        // This dials libvirt on the local machine\n        // It connects to libvirt via TLS over TCP\n        // To connect to a remote machine, you need to have the ca/cert/key of it.\n        // The private key is at ~/.pki/libvirt/clientkey.pem\n        // or /etc/pki/libvirt/private/clientkey.pem\n        // The Client Cert is at ~/.pki/libvirt/clientcert.pem\n        // or /etc/pki/libvirt/clientcert.pem\n        // The CA Cert is at ~/.pki/libvirt/cacert.pem\n        // or /etc/pki/CA/cacert.pem\n\n        // Use host name or IP which is valid in certificate\n        addr := \"10.10.10.10\"\n\n        l := libvirt.NewWithDialer(dialers.NewTLS(addr))\n        if err := l.Connect(); err != nil {\n                log.Fatalf(\"failed to connect: %v\", err)\n        }\n\n        v, err := l.Version()\n        if err != nil {\n                log.Fatalf(\"failed to retrieve libvirt version: %v\", err)\n        }\n        fmt.Println(\"Version:\", v)\n\n        // Return both running and stopped VMs\n        flags := libvirt.ConnectListDomainsActive | libvirt.ConnectListDomainsInactive\n        domains, _, err := l.ConnectListAllDomains(1, flags)\n        if err != nil {\n                log.Fatalf(\"failed to retrieve domains: %v\", err)\n        }\n\n        fmt.Println(\"ID\\tName\\t\\tUUID\")\n        fmt.Println(\"--------------------------------------------------------\")\n        for _, d := range domains {\n                fmt.Printf(\"%d\\t%s\\t%x\\n\", d.ID, d.Name, d.UUID)\n        }\n\n        if err := l.Disconnect(); err != nil {\n                log.Fatalf(\"failed to disconnect: %v\", err)\n        }\n}\n```\n\nRunning the Integration Tests\n-----------------------------\n\nGitHub actions workflows are defined in [.github/workflows](.github/workflows)\nand can be triggered manually in the GitHub UI after pushing a branch. There\nare not currently convenient scripts for setting up and running integration tests\nlocally, but installing libvirt and defining only the artifacts described by the\nfiles in testdata should be sufficient to be able to run the integration test file\nagainst.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-libvirt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalocean%2Fgo-libvirt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalocean%2Fgo-libvirt/lists"}