mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-08 11:16:47 +00:00
fix(storages): a new NFS pool starts when its mount point does not exist
create_storage_netfs started the pool without a build, so a netfs pool
whose target directory was missing failed to mount ("mount point ... does
not exist"): the page showed the error and the pool stayed defined and
inactive. It now starts with VIR_STORAGE_POOL_CREATE_WITH_BUILD, as the
dir and logical pools do, which makes the mount point.
The Vagrant computes export /srv/wvcnfs to 127.0.0.1, and the live pool
test creates an NFS pool on it at a missing mount point when
TEST_LIBVIRT_NFS_EXPORT is set.
This commit is contained in:
parent
f13a90c047
commit
baeb023da2
4 changed files with 40 additions and 19 deletions
|
|
@ -703,19 +703,20 @@ export TEST_LIBVIRT_LOGIN=root TEST_LIBVIRT_PASSWORD= # login/password for TCP
|
|||
export TEST_LIBVIRT_GUEST_IMAGE=/var/lib/libvirt/images/linux.qcow2 # optional, see below
|
||||
export TEST_LIBVIRT_LVM_DEVICE=/dev/vdb # optional: an empty disk of 4 GiB or more on the host, wiped by the LVM tests
|
||||
export TEST_LIBVIRT_ISCSI_TARGET=iqn.2026-10.test.wvc:lun # optional: a target on the host's 127.0.0.1, open to any initiator, with a LUN
|
||||
export TEST_LIBVIRT_NFS_EXPORT=/srv/wvcnfs # optional: a directory the host exports to its 127.0.0.1 over NFS
|
||||
python manage.py test
|
||||
```
|
||||
|
||||
`TEST_LIBVIRT_GUEST_IMAGE` enables the tests that need a guest OS (disk and NIC hot-unplug, vCPU hotplug, guest agent, ACPI power off). It must be an installed, BIOS-bootable Linux qcow2 image with qemu-guest-agent, in a storage pool of the host other than `wvc-test`; the tests boot copies of it from overlays and only read the image. Shut down any VM using it first.
|
||||
|
||||
Two disposable compute nodes for these tests come from the `Vagrantfile`: AlmaLinux 10 with nested KVM, set up by `dev/libvirt-bootstrap.sh` (with this checkout's gstfsd), a SASL user for TCP (`wvc`, password `wvc-test`) and your `~/.ssh/id_ed25519.pub` for root; migration runs between them, and each has an empty second disk (`/dev/vdb`) for the LVM tests and serves a 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI test. They accept TLS logins (SASL) with certificates from a throwaway CA that `vagrant up` makes in `.vagrant/tls`; the TLS run takes its client certificate from there through `HOME`. It needs Vagrant with the `vagrant-libvirt` plugin, a KVM host with `qemu-kvm` and `cyrus-sasl-md5`, and a user in the `libvirt` group. On a host that also runs Docker, let the VMs' network (the bridge of `virsh net-info vagrant-libvirt`, `virbr1` here) through Docker's forward rules (`sudo iptables -I DOCKER-USER -i virbr1 -j ACCEPT` and `sudo iptables -I DOCKER-USER -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT`).
|
||||
Two disposable compute nodes for these tests come from the `Vagrantfile`: AlmaLinux 10 with nested KVM, set up by `dev/libvirt-bootstrap.sh` (with this checkout's gstfsd), a SASL user for TCP (`wvc`, password `wvc-test`) and your `~/.ssh/id_ed25519.pub` for root; migration runs between them, and each has an empty second disk (`/dev/vdb`) for the LVM tests and serves a 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI test and an NFS export (`/srv/wvcnfs`) to 127.0.0.1 for the NFS pool test. They accept TLS logins (SASL) with certificates from a throwaway CA that `vagrant up` makes in `.vagrant/tls`; the TLS run takes its client certificate from there through `HOME`. It needs Vagrant with the `vagrant-libvirt` plugin, a KVM host with `qemu-kvm` and `cyrus-sasl-md5`, and a user in the `libvirt` group. On a host that also runs Docker, let the VMs' network (the bridge of `virsh net-info vagrant-libvirt`, `virbr1` here) through Docker's forward rules (`sudo iptables -I DOCKER-USER -i virbr1 -j ACCEPT` and `sudo iptables -I DOCKER-USER -o virbr1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT`).
|
||||
|
||||
```bash
|
||||
vagrant up --provider=libvirt
|
||||
C1=$(vagrant ssh compute1 -c "hostname -I" | awk '{print $1}') C2=$(vagrant ssh compute2 -c "hostname -I" | awk '{print $1}')
|
||||
for h in $C1 $C2; do ssh-keygen -R $h; ssh -o StrictHostKeyChecking=accept-new root@$h true; done # new VMs, new host keys
|
||||
export TEST_LIBVIRT_HOST=$C1 TEST_LIBVIRT_TYPE=1 TEST_LIBVIRT_LOGIN=wvc TEST_LIBVIRT_PASSWORD=wvc-test
|
||||
export TEST_LIBVIRT_SSH_HOST=$C2 TEST_LIBVIRT_SSH_LOGIN=root TEST_LIBVIRT_MIGRATE_ADDRESS=$C2 TEST_LIBVIRT_LVM_DEVICE=/dev/vdb TEST_LIBVIRT_ISCSI_TARGET=iqn.2026-10.test.wvc:lun
|
||||
export TEST_LIBVIRT_SSH_HOST=$C2 TEST_LIBVIRT_SSH_LOGIN=root TEST_LIBVIRT_MIGRATE_ADDRESS=$C2 TEST_LIBVIRT_LVM_DEVICE=/dev/vdb TEST_LIBVIRT_ISCSI_TARGET=iqn.2026-10.test.wvc:lun TEST_LIBVIRT_NFS_EXPORT=/srv/wvcnfs
|
||||
python manage.py test
|
||||
HOME=$PWD/.vagrant/tls TEST_LIBVIRT_TYPE=3 TEST_LIBVIRT_SSH_HOST= python manage.py test # compute1 again, over TLS
|
||||
vagrant destroy -f
|
||||
|
|
|
|||
6
Vagrantfile
vendored
6
Vagrantfile
vendored
|
|
@ -4,6 +4,7 @@
|
|||
# key for root (SASL user wvc, password wvc-test). The empty second disk
|
||||
# /dev/vdb is for the LVM tests (TEST_LIBVIRT_LVM_DEVICE); each also serves a
|
||||
# 1 GiB iSCSI LUN on 127.0.0.1 for the iSCSI tests (TEST_LIBVIRT_ISCSI_TARGET),
|
||||
# exports /srv/wvcnfs to 127.0.0.1 for the NFS pool test (TEST_LIBVIRT_NFS_EXPORT),
|
||||
# and accepts TLS logins (SASL) with a certificate from a throwaway CA.
|
||||
|
||||
# The CA is made here once; each compute signs its own certificate with it.
|
||||
|
|
@ -60,6 +61,11 @@ Vagrant.configure(2) do |config|
|
|||
targetcli /iscsi/$T/tpg1 set attribute generate_node_acls=1 demo_mode_write_protect=0
|
||||
targetcli saveconfig
|
||||
}
|
||||
dnf -y install nfs-utils
|
||||
install -d /srv/wvcnfs
|
||||
echo "/srv/wvcnfs 127.0.0.1(rw,no_root_squash)" > /etc/exports.d/wvc.exports
|
||||
systemctl enable --now nfs-server
|
||||
exportfs -r
|
||||
install -D -m 644 /tmp/wvc/cacert.pem /etc/pki/CA/cacert.pem
|
||||
install -d /etc/pki/libvirt/private
|
||||
echo "subjectAltName=IP:$(hostname -I | cut -d' ' -f1)" > /tmp/wvc/ext
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
"""Live check that a directory pool created on the storages page starts
|
||||
when its directory does not exist yet: libvirt builds it. Runs only with
|
||||
TEST_LIBVIRT_HOST set."""
|
||||
"""Live check that a directory or NFS pool created on the storages page
|
||||
starts when its directory does not exist yet: libvirt builds it. Runs only
|
||||
with TEST_LIBVIRT_HOST set; the NFS case needs TEST_LIBVIRT_NFS_EXPORT, a
|
||||
directory the host exports to its 127.0.0.1 (the Vagrant computes do)."""
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
|
@ -13,8 +14,7 @@ from django.urls import reverse
|
|||
from instances.tests import livetest
|
||||
from vrtManager.connection import connection_manager
|
||||
|
||||
POOL = livetest.PREFIX + "dir"
|
||||
PATH = f"/var/lib/libvirt/{POOL}"
|
||||
P = livetest.PREFIX
|
||||
|
||||
|
||||
@unittest.skipUnless(livetest.enabled(), "Set TEST_LIBVIRT_HOST to run the live libvirt tests")
|
||||
|
|
@ -27,27 +27,40 @@ class LivePoolsTestCase(TestCase):
|
|||
type=int(os.environ.get("TEST_LIBVIRT_TYPE", 1)),
|
||||
)
|
||||
self.conn = connection_manager.get_connection(*args.values())
|
||||
self.remove_pool()
|
||||
self.addCleanup(self.remove_pool)
|
||||
self.compute = Compute.objects.create(name="live-pools", **args)
|
||||
self.client.force_login(get_user_model().objects.create_superuser("live-pools", "lp@example.com", "x"))
|
||||
|
||||
def remove_pool(self):
|
||||
def remove_pool(self, name):
|
||||
try:
|
||||
pool = self.conn.storagePoolLookupByName(POOL)
|
||||
pool = self.conn.storagePoolLookupByName(name)
|
||||
except libvirt.libvirtError:
|
||||
return
|
||||
if pool.isActive():
|
||||
pool.destroy()
|
||||
pool.destroy() # unmounts an NFS pool
|
||||
pool.delete(0) # removes the directory
|
||||
pool.undefine()
|
||||
|
||||
def test_a_missing_directory_is_built(self):
|
||||
response = self.client.post(
|
||||
reverse("storages", args=[self.compute.id]),
|
||||
{"create": "", "name": POOL, "stg_type": "dir", "target": PATH},
|
||||
def assert_created(self, data):
|
||||
self.remove_pool(data["name"])
|
||||
self.addCleanup(self.remove_pool, data["name"])
|
||||
response = self.client.post(reverse("storages", args=[self.compute.id]), {"create": "", **data})
|
||||
self.assertRedirects(
|
||||
response, reverse("storage", args=[self.compute.id, data["name"]]), fetch_redirect_response=False
|
||||
)
|
||||
self.assertRedirects(response, reverse("storage", args=[self.compute.id, POOL]), fetch_redirect_response=False)
|
||||
pool = self.conn.storagePoolLookupByName(POOL)
|
||||
pool = self.conn.storagePoolLookupByName(data["name"])
|
||||
self.assertTrue(pool.isActive())
|
||||
self.assertTrue(pool.autostart())
|
||||
|
||||
def test_a_missing_directory_is_built(self):
|
||||
self.assert_created({"name": P + "dir", "stg_type": "dir", "target": f"/var/lib/libvirt/{P}dir"})
|
||||
|
||||
@unittest.skipUnless(os.environ.get("TEST_LIBVIRT_NFS_EXPORT"), "Set TEST_LIBVIRT_NFS_EXPORT to run the NFS pool test")
|
||||
def test_a_missing_mount_point_is_built(self):
|
||||
self.assert_created({
|
||||
"name": P + "nfs",
|
||||
"stg_type": "netfs",
|
||||
"netfs_host": "127.0.0.1",
|
||||
"source": os.environ["TEST_LIBVIRT_NFS_EXPORT"],
|
||||
"source_format": "nfs",
|
||||
"target": f"/var/lib/libvirt/{P}nfs",
|
||||
})
|
||||
|
|
|
|||
|
|
@ -101,7 +101,8 @@ class wvmStorages(wvmConnect):
|
|||
"""
|
||||
self.define_storage(xml, 0)
|
||||
stg = self.get_storage(name)
|
||||
stg.create(0)
|
||||
# builds the mount point
|
||||
stg.create(libvirt.VIR_STORAGE_POOL_CREATE_WITH_BUILD)
|
||||
stg.setAutostart(1)
|
||||
|
||||
return stg
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue