Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use xslt for pool or volume permissions #1142

Open
5 tasks done
bhundven opened this issue Jan 7, 2025 · 2 comments
Open
5 tasks done

Unable to use xslt for pool or volume permissions #1142

bhundven opened this issue Jan 7, 2025 · 2 comments

Comments

@bhundven
Copy link

bhundven commented Jan 7, 2025

System Information

Linux distribution

Fedora release 41 (Forty One)

Terraform version

terraform -v
Terraform v1.10.3
on linux_amd64
+ provider registry.terraform.io/dmacvicar/libvirt v0.8.1

Provider and libvirt versions

terraform-provider-libvirt -version
v0.8.1

If that gives you "was not built correctly", get the Git commit hash from your local provider repository:

Using the official provider, not from git.


Checklist

  • Is your issue/contribution related with enabling some setting/option exposed by libvirt that the plugin does not yet support, or requires changing/extending the provider terraform schema?

    • Make sure you explain why this option is important to you, why it should be important to everyone. Describe your use-case with detail and provide examples where possible.
    • If it is a very special case, consider using the XSLT support in the provider to tweak the definition instead of opening an issue
    • Maintainers do not have expertise in every libvirt setting, so please, describe the feature and how it is used. Link to the appropriate documentation
  • Is it a bug or something that does not work as expected? Please make sure you fill the version information below:

Description of Issue/Question

With a pretty standard install of Fedora 41 (selinux disabled - for testing, no apparmor), most of my disk is assigned to /home, and a minimal amount assigned to / (root).

So if I want to build out bigger setups, using the default volume pool is kind of out of the question.

I setup a volume pool at "${abspath(path.root)}/pool", but during the terraform apply I get:

Plan: 4 to add, 0 to change, 0 to destroy.
libvirt_pool.local_pool: Creating...
libvirt_pool.local_pool: Creation complete after 0s [id=a175f530-c2ff-4ffc-94b3-1dbe0e40839a]
libvirt_volume.fedora_cloud: Creating...
libvirt_volume.fedora_cloud: Creation complete after 1s [id=/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/fedora_cloud_41]
libvirt_volume.os_disk: Creating...
libvirt_volume.os_disk: Creation complete after 0s [id=/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/os_disk]
libvirt_domain.fedora_vm: Creating...
╷
│ Error: error creating libvirt domain: Cannot access storage file '/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/os_disk' (as uid:107, gid:107): Permission denied
│ 
│   with libvirt_domain.fedora_vm,
│   on main.tf line 37, in resource "libvirt_domain" "fedora_vm":
│   37: resource "libvirt_domain" "fedora_vm" {
│ 
╵

virsh pool-dumpxml --pool local_pool outputs:

<pool type='dir'>
  <name>local_pool</name>
  <uuid>[a uuid]</uuid>
  <capacity unit='bytes'>[lots of storage]</capacity>
  <allocation unit='bytes'>[lots of storage]</allocation>
  <available unit='bytes'>[lots of storage]</available>
  <source>
  </source>
  <target>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool</path>
    <permissions>
      <mode>0711</mode>
      <owner>0</owner>
      <group>0</group>
    </permissions>
  </target>
</pool>

and virsh vol-dumpxml --pool local_pool --vol os_disk outputs:

<volume type='file'>
  <name>os_disk</name>
  <key>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/os_disk</key>
  <capacity unit='bytes'>42949672960</capacity>
  <allocation unit='bytes'>200704</allocation>
  <physical unit='bytes'>197248</physical>
  <target>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/os_disk</path>
    <format type='qcow2'/>
    <permissions>
      <mode>0644</mode>
      <owner>0</owner>
      <group>0</group>
    </permissions>
    <timestamps>
...
      <btime>0</btime>
    </timestamps>
  </target>
  <backingStore>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/fedora_cloud_41</path>
    <format type='qcow2'/>
    <permissions>
      <mode>0644</mode>
      <owner>0</owner>
      <group>0</group>
    </permissions>
    <timestamps>
...
      <btime>0</btime>
    </timestamps>
  </backingStore>
</volume>

The thing I don't understand is that libvirt is creating the pool directory in the same directory as main.tf. It can create the disk, but it can't attach the disk to the domain?

Ok, so let's xslt this (maybe the wrong way?). If I add:
(on fedora uid/gid 107 is qemu)

xml {
  xslt = file("${abspath(path.root)}/pool_permissions.xsl")
}

pool_permissions.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/pool[@type='dir']/target/permissions">
    <xsl:copy>
      <xsl:element name="mode">
        <xsl:text>0755</xsl:text>
      </xsl:element>
      <xsl:element name="owner">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
      <xsl:element name="group">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

to the pool and:

xml {
  xslt = file("${abspath(path.root)}/volume_permissions.xsl")
}

volume_permissions.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/volume[@type='file']/target/permissions">
    <xsl:copy>
      <xsl:element name="mode">
        <xsl:text>0755</xsl:text>
      </xsl:element>
      <xsl:element name="owner">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
      <xsl:element name="group">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/volume[@type='file']/backingStore/permissions">
    <xsl:copy>
      <xsl:element name="mode">
        <xsl:text>0755</xsl:text>
      </xsl:element>
      <xsl:element name="owner">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
      <xsl:element name="group">
        <xsl:text>qemu</xsl:text>
      </xsl:element>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

to the volume(s), then I should be able to change the permissions, right?

If we test those xslt files before we go jumping to conclusions:

$ virsh pool-dumpxml --pool local_pool > testpool.xml
$ virsh vol-dumpxml --pool local_pool --vol os_disk > testvol.xml
$ xsltproc pool_permissions.xsl testpool.xml 
<pool type="dir">
 ...
  <target>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool</path>
    <permissions><mode>0755</mode><owner>qemu</owner><group>qemu</group></permissions>
  </target>
</pool>
$ xsltproc volume_permissions.xsl testvol.xml 
<volume type="file">
  <name>os_disk</name>
...
  <target>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/os_disk</path>
    <format type="qcow2"/>
    <permissions><mode>0755</mode><owner>qemu</owner><group>qemu</group></permissions>
    <timestamps>
...
    </timestamps>
  </target>
  <backingStore>
    <path>/home/bhundven/Projects/github.com/bhundven/libvirt_xslt_bug/pool/fedora_cloud_41</path>
    <format type="qcow2"/>
    <permissions><mode>0755</mode><owner>qemu</owner><group>qemu</group></permissions>
    <timestamps>
...
    </timestamps>
  </backingStore>
</volume>

Looks good to me, but the pool-dumpxml and vol-dumpxml show the same old root permissions, and I get the exact same error as before.

It's possible that something is wrong with my xslt. Or I have something wacky going on? This install has been release upgraded since Fedora 37 Workstation.

Setup

terraform {
  required_version = "~> 1.10"
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.8.1"
    }
  }
}

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

# Most of my disk is partitioned to use /home, so...
resource "libvirt_pool" "local_pool" {
  name = "local_pool"
  type = "dir"
  target {
    path = "${abspath(path.root)}/pool"
  }
  # See above for pool_permissions.xsl
  #xml {
  #  xslt = file("${abspath(path.root)}/pool_permissions.xsl")
  #}
}

resource "libvirt_volume" "fedora_cloud" {
  name   = "fedora_cloud_41"
  source = "/home/bhundven/Downloads/Fedora-Cloud-Base-Generic-41-1.4.x86_64.qcow2"
  pool   = libvirt_pool.local_pool.name
  # See above for volume_permissions.xsl
  #xml {
  #  xslt = file("${abspath(path.root)}/volume_permissions.xsl")
  #}
}

# not using a cloud-init to resize, but this is just an example...
resource "libvirt_volume" "os_disk" {
  name           = "os_disk"
  base_volume_id = libvirt_volume.fedora_cloud.id
  size           = "42949672960" # 40GB
  pool           = libvirt_pool.local_pool.name
  # See above for volume_permissions.xsl
  #xml {
  #  xslt = file("${abspath(path.root)}/volume_permissions.xsl")
  #}
}

resource "libvirt_domain" "fedora_vm" {
  name       = "Fedora VM"
  memory     = "4096"
  vcpu       = 2
  qemu_agent = true
  machine    = "q35"
  autostart  = true

  console {
    type        = "pty"
    target_port = "0"
    target_type = "serial"
  }

  console {
    type        = "pty"
    target_type = "virtio"
    target_port = "1"
  }

  graphics {
    type        = "spice"
    listen_type = "address"
    autoport    = true
  }

  network_interface {
    network_name   = "default"
    hostname       = "fedora41"
    wait_for_lease = true
  }

  disk {
    volume_id = libvirt_volume.os_disk.id
  }
}

Steps to Reproduce Issue

All provided above.


Additional information:

Do you have SELinux or Apparmor/Firewall enabled? Some special configuration?
Have you tried to reproduce the issue without them enabled?

SELinux has been disabled in /etc/selinux/config (and rebooted to take affect), no apparmor. I can't imagine that a firewall is blocking, but:

$ sudo iptables -nvL
[sudo] password for bhundven: 
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
@bhundven
Copy link
Author

bhundven commented Jan 7, 2025

I completely removed all libvirt-daemon* packages and purged configs, re-installed them. Same issue.

@bhundven
Copy link
Author

So if I change the pool path to /srv/vmpool (0755), that works. I assume this is because /home/bhundven is 0700.
I'm still curious why you cannot change the permissions of the pool/volume(s)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant