dmacvicar / terraform-provider-libvirt

Terraform provider to provision infrastructure with Linux's KVM using libvirt
Apache License 2.0
1.54k stars 457 forks source link

Default connection to qemu://system instead of session #906

Open bestrocker221 opened 2 years ago

bestrocker221 commented 2 years ago

Linux distribution

Manjaro 5.13.19

Terraform version

terraform -v

Terraform v1.0.10
on linux_amd64
+ provider registry.terraform.io/dmacvicar/libvirt v0.6.11

Description of Issue/Question

I am re-reporting the issue already present at https://issueexplorer.com/issue/dmacvicar/terraform-provider-libvirt/883

The provider tries to connect to the system session instead of the user session, thus provoking permissions issues, as expected.

The Terraform file explicitly set the

provider "libvirt" {
  uri = "qemu:///session"
}

but the terraform plan and terraform apply request to authenticate, and then proceed in the system session.

This will break the user configuration in terms of file and folders permissions.

This seems to be the same in version 0.6.10 as well.

crivetimihai commented 2 years ago

I was able to reproduce in 0.6.11 and 0.6.10 it seems it connects to qemu:///system when looking for the storage pool. 0.6.9 fails with "Error: failed to connect: authentication required"

What are you getting when using

export TF_LOG="DEBUG" export TF_LOG_PATH="terraform.log"

grep qemu terraform.log

Probably related to: https://github.com/dmacvicar/terraform-provider-libvirt/commit/1a86985cac99cc623a0a123f36df475f9b861991

Other things to try:

virsh -c qemu:///session list # user is in libvirt group and can use it just fine virsh -c "qemu+unix:///session" list

https://registry.terraform.io/providers/dmacvicar/libvirt/latest/docs

freedomfury commented 2 years ago

I believe the issue here is that unless specified the code is using the same socket for both system and session. The code uses connection uri to parse the query string checking for socket variable. If socket is not found the code sets it to the default file for system socket file incorrectly.

Defaults: session = /run/user/$(id -u)/libvirt/libvirt-sock vs system = /var/run/libvirt/libvirt-sock

# libvirt/uri/unix.go
const (
    defaultUnixSock = "/var/run/libvirt/libvirt-sock"
)

func (u *ConnectionURI) dialUNIX() (net.aConn, error) {

    q := u.Query()
    address := q.Get("socket")
    if address == "" {
        address = defaultUnixSock
    }

    return net.DialTimeout("unix", address, 2*time.Second)
}

The solution I settled on is listed below.

provider "libvirt" {
  uri = "qemu:///session?socket=/run/user/1000/libvirt/libvirt-sock"
}

resource "libvirt_pool" "cloud_images" {
  name = "cloud_images"
  type = "dir"
  path = "/home/user_name/.cloud"
}

This worked for me with one caveat, the libvirt daemon must be running on the user during the time of terraform execution. Running virsh connect without specifying the socket file starts the daemon and creates the default socket file.

bestrocker221 commented 2 years ago

The issue persists also with the version 0.6.12

I tried to manually set the default qemu connection to session within /etc/libvirt/ config files, but does not seem to help.

more specifically I changed the uri_default = "qemu:///session" within /etc/libvirt/libvirt.conf, with no luck yet.

Anyway, I'd like to thank the devs for the awesome work in this project.

bestrocker221 commented 2 years ago

Update:

I noticed, by following @freedomfury comment, that the libvirt-sock was not present on my system, not even on a newly installed clean virtual machine (of course when connected to the virt-manager / virsh).

So with the libvirt daemon not running i tried to connect and received the error that virtqemud-sock was not found.

Consequently I used virtqemud-sock instead of libvirt-sock in the user session and it worked.

provider "libvirt" {
  uri = "qemu:///session?socket=/run/user/1000/libvirt/virtqemud-sock"
}

This one let me use again terraform and libvirt in user mode. Note: not sure if this is how it is supposed to work, and why exactly, but I wanted to report that this temporary fix seems to work for me.

rafutek commented 1 year ago

Hello,

Is there any updates here ? Having the issue on v0.7.1. I needed to set the socket parameter as explained above to make it work in session mode.

Thank you

AlexandreFournier commented 8 months ago

Hello,

I've been facing the same problem. One way to make it work:

provider "libvirt" {
  uri = "whatever:///?name=qemu:///session&socket=/run/user/1000/libvirt/virtqemud-sock"
}

Yeah I know this does not look right...

Change the UID parameter (1000) according to your own UID if needed.