Closed n-able-consulting closed 10 months ago
This also seems to break usage of user session URIs
provider "libvirt" { uri = "qemu:///session?socket=/run/user/1000/libvirt/virtqemud-sock" }
same issue with bhyve+ssh://
The issue is that the connectionURI is modified by the call to RemoteName() done during the call to Dial by go-libvirt. As it seems, the copy of the URI is shallow and thus, calling Dial during a ConnectToURI on the RemoteName() causes the Dial call to contact the RemoteName instead of the configured URI.
I managed to fix the bug by replacing the copy with the following initialization:
newURI := url.URL{
Scheme: u.driver(),
Path: u.Path,
}
The issue was not present before because the dial was done prior to passing the connection to go-libvirt and prior to the call of the RemoteName() function.
@X-Cli Good catch. It feels to me like the real fix is not having a pointer to a URL inside ConnectionURI, which is what makes the shallow copy useless.
type ConnectionURI struct {
url.URL
}
Can you try that out/open a PR?
Could be related to what @X-Cli is mentioning. I'm having issues connecting using qemu+tls.
main.tf
:
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.7.4"
}
}
}
provider "libvirt" {
uri = "qemu+tls://libvirt.example.tld/system"
}
resource "libvirt_domain" "test" {
name = "Test"
}
$ TF_LOG=DEBUG terraform plan
2023-11-03T12:37:30.115+0100 [INFO] Terraform version: 1.6.2
2023-11-03T12:37:30.115+0100 [DEBUG] using github.com/hashicorp/go-tfe v1.36.0
2023-11-03T12:37:30.115+0100 [DEBUG] using github.com/hashicorp/hcl/v2 v2.19.1
2023-11-03T12:37:30.115+0100 [DEBUG] using github.com/hashicorp/terraform-svchost v0.1.1
2023-11-03T12:37:30.115+0100 [DEBUG] using github.com/zclconf/go-cty v1.14.1
2023-11-03T12:37:30.115+0100 [INFO] Go runtime version: go1.21.1
2023-11-03T12:37:30.115+0100 [INFO] CLI args: []string{"terraform", "plan"}
2023-11-03T12:37:30.115+0100 [DEBUG] Attempting to open CLI config file: /home/user/.terraformrc
2023-11-03T12:37:30.115+0100 [DEBUG] File doesn't exist, but doesn't need to. Ignoring.
2023-11-03T12:37:30.116+0100 [DEBUG] ignoring non-existing provider search directory terraform.d/plugins
2023-11-03T12:37:30.116+0100 [DEBUG] ignoring non-existing provider search directory /home/user/.terraform.d/plugins
2023-11-03T12:37:30.116+0100 [DEBUG] ignoring non-existing provider search directory /home/user/.local/share/terraform/plugins
2023-11-03T12:37:30.116+0100 [DEBUG] ignoring non-existing provider search directory /usr/local/share/terraform/plugins
2023-11-03T12:37:30.116+0100 [DEBUG] ignoring non-existing provider search directory /usr/share/terraform/plugins
2023-11-03T12:37:30.116+0100 [INFO] CLI command args: []string{"plan"}
2023-11-03T12:37:30.117+0100 [DEBUG] New state was assigned lineage "180c2c10-411f-61f4-2b91-0112ae838318"
2023-11-03T12:37:30.128+0100 [DEBUG] checking for provisioner in "."
2023-11-03T12:37:30.129+0100 [DEBUG] checking for provisioner in "/usr/bin"
2023-11-03T12:37:30.130+0100 [INFO] backend/local: starting Plan operation
2023-11-03T12:37:30.131+0100 [DEBUG] created provider logger: level=debug
2023-11-03T12:37:30.131+0100 [INFO] provider: configuring client automatic mTLS
2023-11-03T12:37:30.136+0100 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 args=[".terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4"]
2023-11-03T12:37:30.136+0100 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18656
2023-11-03T12:37:30.136+0100 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4
2023-11-03T12:37:30.142+0100 [INFO] provider.terraform-provider-libvirt_v0.7.4: configuring server automatic mTLS: timestamp="2023-11-03T12:37:30.142+0100"
2023-11-03T12:37:30.155+0100 [DEBUG] provider: using plugin: version=5
2023-11-03T12:37:30.155+0100 [DEBUG] provider.terraform-provider-libvirt_v0.7.4: plugin address: address=/tmp/plugin2606746144 network=unix timestamp="2023-11-03T12:37:30.155+0100"
2023-11-03T12:37:30.175+0100 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-11-03T12:37:30.179+0100 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18656
2023-11-03T12:37:30.179+0100 [DEBUG] provider: plugin exited
2023-11-03T12:37:30.179+0100 [DEBUG] Building and walking validate graph
2023-11-03T12:37:30.180+0100 [DEBUG] ProviderTransformer: "libvirt_domain.test" (*terraform.NodeValidatableResource) needs provider["registry.terraform.io/dmacvicar/libvirt"]
2023-11-03T12:37:30.180+0100 [DEBUG] ReferenceTransformer: "libvirt_domain.test" references: []
2023-11-03T12:37:30.180+0100 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/dmacvicar/libvirt\"]" references: []
2023-11-03T12:37:30.181+0100 [DEBUG] Starting graph walk: walkValidate
2023-11-03T12:37:30.181+0100 [DEBUG] created provider logger: level=debug
2023-11-03T12:37:30.181+0100 [INFO] provider: configuring client automatic mTLS
2023-11-03T12:37:30.185+0100 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 args=[".terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4"]
2023-11-03T12:37:30.186+0100 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18670
2023-11-03T12:37:30.186+0100 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4
2023-11-03T12:37:30.191+0100 [INFO] provider.terraform-provider-libvirt_v0.7.4: configuring server automatic mTLS: timestamp="2023-11-03T12:37:30.191+0100"
2023-11-03T12:37:30.201+0100 [DEBUG] provider: using plugin: version=5
2023-11-03T12:37:30.201+0100 [DEBUG] provider.terraform-provider-libvirt_v0.7.4: plugin address: address=/tmp/plugin181566249 network=unix timestamp="2023-11-03T12:37:30.200+0100"
2023-11-03T12:37:30.217+0100 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-11-03T12:37:30.217+0100 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18670
2023-11-03T12:37:30.217+0100 [DEBUG] provider: plugin exited
2023-11-03T12:37:30.218+0100 [INFO] backend/local: plan calling Plan
2023-11-03T12:37:30.218+0100 [DEBUG] Building and walking plan graph for NormalMode
2023-11-03T12:37:30.218+0100 [DEBUG] ProviderTransformer: "libvirt_domain.test (expand)" (*terraform.nodeExpandPlannableResource) needs provider["registry.terraform.io/dmacvicar/libvirt"]
2023-11-03T12:37:30.218+0100 [DEBUG] ReferenceTransformer: "libvirt_domain.test (expand)" references: []
2023-11-03T12:37:30.218+0100 [DEBUG] ReferenceTransformer: "provider[\"registry.terraform.io/dmacvicar/libvirt\"]" references: []
2023-11-03T12:37:30.218+0100 [DEBUG] Starting graph walk: walkPlan
2023-11-03T12:37:30.218+0100 [DEBUG] created provider logger: level=debug
2023-11-03T12:37:30.218+0100 [INFO] provider: configuring client automatic mTLS
2023-11-03T12:37:30.221+0100 [DEBUG] provider: starting plugin: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 args=[".terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4"]
2023-11-03T12:37:30.222+0100 [DEBUG] provider: plugin started: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18684
2023-11-03T12:37:30.222+0100 [DEBUG] provider: waiting for RPC address: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4
2023-11-03T12:37:30.226+0100 [INFO] provider.terraform-provider-libvirt_v0.7.4: configuring server automatic mTLS: timestamp="2023-11-03T12:37:30.226+0100"
2023-11-03T12:37:30.234+0100 [DEBUG] provider: using plugin: version=5
2023-11-03T12:37:30.234+0100 [DEBUG] provider.terraform-provider-libvirt_v0.7.4: plugin address: address=/tmp/plugin1548367601 network=unix timestamp="2023-11-03T12:37:30.234+0100"
2023-11-03T12:37:30.253+0100 [INFO] provider.terraform-provider-libvirt_v0.7.4: 2023/11/03 12:37:30 [DEBUG] Configuring provider for 'qemu+tls://libvirt.example.tld/system': &{map[uri:0xc0003ea500] <nil> <nil> 0xc00034c680 map[] <nil> {{<nil>} <nil>} 0xc000120160 0xc000132450 0xc000291ad0 false {1 {0 0}} false false}: timestamp="2023-11-03T12:37:30.252+0100"
2023-11-03T12:37:30.253+0100 [ERROR] provider.terraform-provider-libvirt_v0.7.4: Response contains error diagnostic: @caller=github.com/hashicorp/terraform-plugin-go@v0.14.2/tfprotov5/internal/diag/diagnostics.go:55 diagnostic_detail="" diagnostic_severity=ERROR tf_proto_version=5.3 tf_req_id=c3645f64-4cbb-70af-f2d3-8256215c7cc2 @module=sdk.proto diagnostic_summary="failed to connect: dial unix /var/run/libvirt/libvirt-sock: connect: no such file or directory" tf_provider_addr=provider tf_rpc=Configure timestamp="2023-11-03T12:37:30.253+0100"
2023-11-03T12:37:30.253+0100 [ERROR] vertex "provider[\"registry.terraform.io/dmacvicar/libvirt\"]" error: failed to connect: dial unix /var/run/libvirt/libvirt-sock: connect: no such file or directory
2023-11-03T12:37:30.253+0100 [INFO] backend/local: plan operation completed
Planning failed. Terraform encountered an error while generating this plan.
╷
│ Error: failed to connect: dial unix /var/run/libvirt/libvirt-sock: connect: no such file or directory
│
│ with provider["registry.terraform.io/dmacvicar/libvirt"],
│ on main.tf line 10, in provider "libvirt":
│ 10: provider "libvirt" {
│
╵
2023-11-03T12:37:30.254+0100 [DEBUG] provider.stdio: received EOF, stopping recv loop: err="rpc error: code = Unavailable desc = error reading from server: EOF"
2023-11-03T12:37:30.255+0100 [DEBUG] provider: plugin process exited: path=.terraform/providers/registry.terraform.io/dmacvicar/libvirt/0.7.4/linux_amd64/terraform-provider-libvirt_v0.7.4 pid=18684
2023-11-03T12:37:30.255+0100 [DEBUG] provider: plugin exited
@X-Cli Good catch. It feels to me like the real fix is not having a pointer to a URL inside ConnectionURI, which is what makes the shallow copy useless.
type ConnectionURI struct { url.URL }
As far as I know Go, this syntax is not exactly a pointer; it is a syntactic sugar for ConnectionURI to have the same attributes, current and future, as a url.URL. The type is only used as a proxy for url.URL augmented with the Dialer implementation, and a few private functions. However, you are correct that if RemoteName receiver was not a pointer, the ConnectionURI instance would not have been modified either.
I have modified my code to do both, just in case :)
As far as I know Go, this syntax is not exactly a pointer;
In fact that's what *url.URL
ensures. There's implicitly a URL: *url.URL
field, so that on a shallow copy of ConnectionURI
, the pointer itself is copied, not the value pointed to by the pointer. And so the subsequent statements like newURI.User = nil
modify the original value u.URL.User
via the newURI.URL *url.URL
via the pointer receiver u *ConnectionURI
when we call u.RemoteName()
.
The change from:
type ConnectionURI struct {
*url.URL
}
to
type ConnectionURI struct {
url.URL
}
would make it so that ConnectionURI
wraps a value, not a pointer. Preventing unintentional mutation of the URL
contained in ConnectionURI
. It seems to me very unlikely that a shallow copy of a ConnectionURI
is meant to preserve mutability of the contained URL
, though I can't be sure without a deeper look at the code.
So the pointer receiver change is actually unnecessary, since the shallow copy of ConnectionURI
still points to the same URL
.
System Information
amd64
Linux distribution
Ubuntu22.04
Terraform version
v1.6.1
Provider and libvirt versions
0.7.4
Description of Issue/Question
I use the plugin to provision vm's on rack within my network. I always implement an install with the latest Terraform and plugin versions. With version 0.7.4. I get the following error when executing my code: Error: failed to connect: dial unix /var/run/libvirt/libvirt-sock: connect: permission denied │ │ with provider["registry.terraform.io/dmacvicar/libvirt"], │ on connection.tf line 14, in provider "libvirt": │ 14: provider "libvirt" {
Falling back to version 0.7.1 (since it is the latest version that is useable): it works again.
Setup
my connection.tf not working
my connection.tf working