From 91d0e457d01090bc4de45f5ccfd8aeb87d1cc05f Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Thu, 11 Oct 2018 15:34:08 -0700 Subject: [PATCH] main: Add -version Give callers an easy way to extract both the plugin version and the dependency versions. With this commit: $ ./terraform-provider-libvirt -version ./terraform-provider-libvirt 48adac309dc181faad7ccd87d52d5e004d5798ec-dirty Compiled against library: libvirt 3.9.0 Using library: libvirt 3.9.0 Running hypervisor: QEMU 2.9.0 Running against daemon: 3.9.0 The details are very similar to: $ virsh version --daemon Compiled against library: libvirt 3.9.0 Using library: libvirt 3.9.0 Using API: QEMU 3.9.0 Running hypervisor: QEMU 2.9.0 Running against daemon: 3.9.0 except the Go bindings do not currently expose the API version [1]. I've submitted a patch to libvirt-go adding ParseVersion there. But until then, carrying our own parseVersion shouldn't be too much trouble. Passing an empty string to NewConnect ends up passing a nil pointer through to virConnect [2], which will give us libvirt's internal default URI logic [3,4]. I hunted around for a way to expose the version information in Terraform. Currently: $ cat main.tf provider "libvirt" { uri = "qemu:///system" } $ terraform version Terraform v0.11.8 + provider.libvirt (unversioned) but the RPC API is not particularly clear to me, and the versions there may be extracted from plugin filenames and not from RPC calls. [1]: https://libvirt.org/git/?p=libvirt-go.git;a=blob;f=connect.go;h=8cc7cc771f7d258400175df47fcc8b3779ef4930;hb=9c5bdce3c18faad94cb383e7ec42f5122a8c7fa1#l313 [2]: https://libvirt.org/git/?p=libvirt-go.git;a=blob;f=connect.go;h=8cc7cc771f7d258400175df47fcc8b3779ef4930;hb=9c5bdce3c18faad94cb383e7ec42f5122a8c7fa1#l322 [3]: https://libvirt.org/html/libvirt-libvirt-host.html#virConnectOpen [4]: https://libvirt.org/uri.html#URI_default --- .github/ISSUE_TEMPLATE.md | 17 +++++++--- Makefile | 6 ++-- main.go | 67 +++++++++++++++++++++++++++++++++++++-- main_test.go | 21 ++++++++++++ 4 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 main_test.go diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 558930d6c..86da35c34 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,15 +5,22 @@ ``` openSUSE 42.2/ Centos7/ Ubuntu.. ``` ### Terraform Version Report -(Provided by running `terraform -v`.) -### Libvirt version +```sh +terraform -v +``` -```virsh --version``` +### Provider and libvirt versions -### terraform-provider-libvirt plugin version (git-hash) +```sh +terraform-provider-libvirt -version +``` -``` git log``` +If that gives you "was not built correctly", get the Git commit hash from your local provider repository: + +```sh +git describe --always --abbrev=40 --dirty +``` ___ # Description of Issue/Question diff --git a/Makefile b/Makefile index 172a354a4..3c7fa272a 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,15 @@ +LDFLAGS += -X main.version=$$(git describe --always --abbrev=40 --dirty) + default: build build: gofmtcheck golint vet - go build + go build -ldflags "${LDFLAGS}" install: go install test: - go test -v -covermode=count -coverprofile=profile.cov ./libvirt + go test -v -covermode=count -coverprofile=profile.cov . ./libvirt testacc: ./travis/run-tests-acceptance diff --git a/main.go b/main.go index ff25e89e5..7fee0a959 100644 --- a/main.go +++ b/main.go @@ -1,13 +1,32 @@ package main import ( - "github.com/dmacvicar/terraform-provider-libvirt/libvirt" - "github.com/hashicorp/terraform/plugin" + "flag" + "fmt" + "io" + "log" "math/rand" + "os" "time" + + "github.com/dmacvicar/terraform-provider-libvirt/libvirt" + "github.com/hashicorp/terraform/plugin" + libvirtgo "github.com/libvirt/libvirt-go" ) +var version = "was not built correctly" // set via the Makefile + func main() { + versionFlag := flag.Bool("version", false, "print version information and exit") + flag.Parse() + if *versionFlag { + err := printVersion(os.Stdout) + if err != nil { + log.Fatal(err) + } + os.Exit(0) + } + defer libvirt.CleanupLibvirtConnections() plugin.Serve(&plugin.ServeOpts{ @@ -15,6 +34,50 @@ func main() { }) } +func printVersion(writer io.Writer) error { + fmt.Fprintf(writer, "%s %s\n", os.Args[0], version) + + fmt.Fprintf(writer, "Compiled against library: libvirt %s\n", parseVersion(libvirtgo.VERSION_NUMBER)) + + libvirtVersion, err := libvirtgo.GetVersion() + if err != nil { + return err + } + fmt.Fprintf(writer, "Using library: libvirt %s\n", parseVersion(libvirtVersion)) + + conn, err := libvirtgo.NewConnect("") + if err != nil { + return err + } + defer conn.Close() + + hvType, err := conn.GetType() + if err != nil { + return err + } + libvirtVersion, err = conn.GetVersion() + if err != nil { + return err + } + fmt.Fprintf(writer, "Running hypervisor: %s %s\n", hvType, parseVersion(libvirtVersion)) + + libvirtVersion, err = conn.GetLibVersion() + if err != nil { + return err + } + fmt.Fprintf(writer, "Running against daemon: %s\n", parseVersion(libvirtVersion)) + + return nil +} + +func parseVersion(version uint32) string { + release := version % 1000 + version /= 1000 + minor := version % 1000 + major := version / 1000 + return fmt.Sprintf("%d.%d.%d", major, minor, release) +} + func init() { rand.Seed(time.Now().UTC().UnixNano()) } diff --git a/main_test.go b/main_test.go new file mode 100644 index 000000000..c4162025f --- /dev/null +++ b/main_test.go @@ -0,0 +1,21 @@ +package main + +import ( + "bytes" + "regexp" + "testing" +) + +func TestPrintVersion(t *testing.T) { + buf := &bytes.Buffer{} + err := printVersion(buf) + if err != nil { + t.Fatal(err) + } + output := buf.Bytes() + + re := regexp.MustCompile("^.*terraform-provider-libvirt.test was not built correctly\\nCompiled against library: libvirt [0-9.]*\\nUsing library: libvirt [0-9.]*\\nRunning hypervisor: .* [0-9.]*\\nRunning against daemon: [0-9.]*\\n$") + if !re.Match(output) { + t.Fatalf("unexpected output:\n%q", string(output)) + } +}