[libvirt] [dbus PATCH v2 00/17] StorageVolume APIs

Changes from v1: - Fixes from reviews - And more: * tests: Moved all xml definitions for tests in separate file. * tests: Renamed all functions that are not supposed to be run as tests, so that they don't have test prefix. I found out that these were running as tests, when I added the new function for listing the volumes from the test driver. test driver doesn't offer any volumes, and the function failed. * tests: To get a test volume I created a pytest fixture, which I add in the setup of the tests that are manipulating with volumes. In this way, the get_test_storage_volume function remained same to the similar purpose functions as suggested in the previous review. Katerina Koukiou (17): Introduce StorageVol Interface Implement ListStorageVolumes for StoragePool Interface test: move XML definition of entities to seperate file tests: rename test_* functions which are not tests Implement StorageVolCreateXML method for StoragePool Interface Implement Name property for StorageVol Interface Implement Key property for StorageVol Interface Implement Path property for StorageVol Interface Implement GetXMLDesc method for StorageVol Interface Implement StorageVolLookupByKey method for Connect Interface Implement StorageVolLookupByName method for StoragePool Interface Implement StorageVolLookupByPath method for Connect Interface Implement Resize method for StorageVol Interface Implement Wipe method for StorageVol Interface Implement GetInfo method for StorageVol Interface Implement Delete method for StorageVol Interface Implement StorageVolCreateXMLFrom method for StoragePool Interface data/Makefile.am | 4 +- data/org.libvirt.Connect.xml | 12 ++ data/org.libvirt.StoragePool.xml | 28 ++++ data/org.libvirt.StorageVol.xml | 51 +++++++ src/Makefile.am | 4 +- src/connect.c | 66 +++++++++ src/connect.h | 1 + src/storagepool.c | 152 ++++++++++++++++++++ src/storagevol.c | 302 +++++++++++++++++++++++++++++++++++++++ src/storagevol.h | 9 ++ src/util.c | 35 +++++ src/util.h | 16 +++ tests/libvirttest.py | 37 ++++- tests/test_connect.py | 69 ++++----- tests/test_domain.py | 20 +-- tests/test_network.py | 14 +- tests/test_storage.py | 79 ++++++++-- tests/xmldata.py | 47 ++++++ 18 files changed, 871 insertions(+), 75 deletions(-) create mode 100644 data/org.libvirt.StorageVol.xml create mode 100644 src/storagevol.c create mode 100644 src/storagevol.h create mode 100644 tests/xmldata.py -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/Makefile.am | 4 ++- data/org.libvirt.StorageVol.xml | 7 ++++ src/Makefile.am | 4 ++- src/connect.c | 6 ++++ src/connect.h | 1 + src/storagevol.c | 77 +++++++++++++++++++++++++++++++++++++++++ src/storagevol.h | 9 +++++ src/util.c | 35 +++++++++++++++++++ src/util.h | 16 +++++++++ 9 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 data/org.libvirt.StorageVol.xml create mode 100644 src/storagevol.c create mode 100644 src/storagevol.h diff --git a/data/Makefile.am b/data/Makefile.am index fdec857..721b874 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -24,7 +24,9 @@ interfaces_files = \ org.libvirt.Network.xml \ org.libvirt.NWFilter.xml \ org.libvirt.Secret.xml \ - org.libvirt.StoragePool.xml + org.libvirt.StoragePool.xml \ + org.libvirt.StorageVol.xml \ + $(NULL) interfacesdir = $(DBUS_INTERFACES_DIR) interfaces_DATA = $(interfaces_files) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml new file mode 100644 index 0000000..c72c847 --- /dev/null +++ b/data/org.libvirt.StorageVol.xml @@ -0,0 +1,7 @@ +<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" +"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> + +<node name="/org/libvirt/storagevol"> + <interface name="org.libvirt.StorageVol"> + </interface> +</node> diff --git a/src/Makefile.am b/src/Makefile.am index 22128c2..53d1a23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,9 @@ DAEMON_SOURCES = \ network.c network.h \ nwfilter.c nwfilter.h \ secret.c secret.h \ - storagepool.c storagepool.h + storagepool.c storagepool.h \ + storagevol.c storagevol.h \ + $(NULL) EXTRA_DIST = \ $(DAEMON_SOURCES) diff --git a/src/connect.c b/src/connect.c index 75ae1cd..1090e3e 100644 --- a/src/connect.c +++ b/src/connect.c @@ -5,6 +5,7 @@ #include "nwfilter.h" #include "secret.h" #include "storagepool.h" +#include "storagevol.h" #include "util.h" #include <gio/gunixfdlist.h> @@ -1612,6 +1613,7 @@ virtDBusConnectFree(virtDBusConnect *connect) g_free(connect->nwfilterPath); g_free(connect->secretPath); g_free(connect->storagePoolPath); + g_free(connect->storageVolPath); g_free(connect); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(virtDBusConnect, virtDBusConnectFree); @@ -1679,6 +1681,10 @@ virtDBusConnectNew(virtDBusConnect **connectp, if (error && *error) return; + virtDBusStorageVolRegister(connect, error); + if (error && *error) + return; + *connectp = connect; connect = NULL; } diff --git a/src/connect.h b/src/connect.h index fe672ed..341dfc4 100644 --- a/src/connect.h +++ b/src/connect.h @@ -17,6 +17,7 @@ struct virtDBusConnect { gchar *nwfilterPath; gchar *secretPath; gchar *storagePoolPath; + gchar *storageVolPath; virConnectPtr connection; GMutex lock; diff --git a/src/storagevol.c b/src/storagevol.c new file mode 100644 index 0000000..0097a7f --- /dev/null +++ b/src/storagevol.c @@ -0,0 +1,77 @@ +#include "storagevol.h" +#include "util.h" + +#include <libvirt/libvirt.h> + +static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { + { 0 } +}; + +static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { + { 0 } +}; + +static gchar ** +virtDBusStorageVolEnumerate(gpointer userData) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePoolPtr) storagePools = NULL; + gint numPools = 0; + GPtrArray *list = NULL; + + if (!virtDBusConnectOpen(connect, NULL)) + return NULL; + + numPools = virConnectListAllStoragePools(connect->connection, + &storagePools, 0); + if (numPools <= 0) + return NULL; + + list = g_ptr_array_new(); + + for (gint i = 0; i < numPools; i++) { + g_autoptr(virStorageVolPtr) storageVols = NULL; + gint numVols; + + numVols = virStoragePoolListAllVolumes(storagePools[i], + &storageVols, 0); + if (numVols <= 0) + continue; + + for (gint j = 0; j < numVols; j++) { + gchar *volPath = virtDBusUtilBusPathForVirStorageVol(storageVols[j], + connect->storageVolPath); + g_ptr_array_add(list, volPath); + } + } + + if (list->len > 0) + g_ptr_array_add(list, NULL); + + return (gchar **)g_ptr_array_free(list, FALSE); +} + +static GDBusInterfaceInfo *interfaceInfo; + +void +virtDBusStorageVolRegister(virtDBusConnect *connect, + GError **error) +{ + connect->storageVolPath = g_strdup_printf("%s/storagevol", + connect->connectPath); + + if (!interfaceInfo) { + interfaceInfo = virtDBusGDBusLoadIntrospectData(VIRT_DBUS_STORAGEVOL_INTERFACE, + error); + if (!interfaceInfo) + return; + } + + virtDBusGDBusRegisterSubtree(connect->bus, + connect->storageVolPath, + interfaceInfo, + virtDBusStorageVolEnumerate, + virtDBusStorageVolMethodTable, + virtDBusStorageVolPropertyTable, + connect); +} diff --git a/src/storagevol.h b/src/storagevol.h new file mode 100644 index 0000000..e2a893b --- /dev/null +++ b/src/storagevol.h @@ -0,0 +1,9 @@ +#pragma once + +#include "connect.h" + +#define VIRT_DBUS_STORAGEVOL_INTERFACE "org.libvirt.StorageVol" + +void +virtDBusStorageVolRegister(virtDBusConnect *connect, + GError **error); diff --git a/src/util.c b/src/util.c index 1268736..ac6d11b 100644 --- a/src/util.c +++ b/src/util.c @@ -417,3 +417,38 @@ virtDBusUtilVirStoragePoolListFree(virStoragePoolPtr *storagePools) g_free(storagePools); } + +virStorageVolPtr +virtDBusUtilVirStorageVolFromBusPath(virConnectPtr connection, + const gchar *path, + const gchar *storageVolPath) +{ + g_autofree gchar *key = NULL; + gsize prefixLen = strlen(storageVolPath) + 1; + + key = virtDBusUtilDecodeStr(path + prefixLen); + + return virStorageVolLookupByKey(connection, key); +} + +gchar * +virtDBusUtilBusPathForVirStorageVol(virStorageVolPtr storageVol, + const gchar *storageVolPath) +{ + const gchar *key = NULL; + g_autofree const gchar *encodedKey = NULL; + + key = virStorageVolGetKey(storageVol); + encodedKey = virtDBusUtilEncodeStr(key); + + return g_strdup_printf("%s/%s", storageVolPath, encodedKey); +} + +void +virtDBusUtilVirStorageVolListFree(virStorageVolPtr *storageVols) +{ + for (gint i = 0; storageVols[i] != NULL; i++) + virStorageVolFree(storageVols[i]); + + g_free(storageVols); +} diff --git a/src/util.h b/src/util.h index 56e0409..bf08d5d 100644 --- a/src/util.h +++ b/src/util.h @@ -133,3 +133,19 @@ virtDBusUtilVirStoragePoolListFree(virStoragePoolPtr *storagePools); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStoragePool, virStoragePoolFree); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStoragePoolPtr, virtDBusUtilVirStoragePoolListFree); + +virStorageVolPtr +virtDBusUtilVirStorageVolFromBusPath(virConnectPtr connection, + const gchar *path, + const gchar *storageVolPath); + +gchar * +virtDBusUtilBusPathForVirStorageVol(virStorageVolPtr storageVol, + const gchar *storageVolPath); + +void +virtDBusUtilVirStorageVolListFree(virStorageVolPtr *storageVols); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageVol, virStorageVolFree); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virStorageVolPtr, + virtDBusUtilVirStorageVolListFree); -- 2.15.0

On Thu, Jun 14, 2018 at 05:59:37PM +0200, Katerina Koukiou wrote:
Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/Makefile.am | 4 ++- data/org.libvirt.StorageVol.xml | 7 ++++ src/Makefile.am | 4 ++- src/connect.c | 6 ++++ src/connect.h | 1 + src/storagevol.c | 77 +++++++++++++++++++++++++++++++++++++++++ src/storagevol.h | 9 +++++ src/util.c | 35 +++++++++++++++++++ src/util.h | 16 +++++++++ 9 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 data/org.libvirt.StorageVol.xml create mode 100644 src/storagevol.c create mode 100644 src/storagevol.h
[...]
diff --git a/src/storagevol.c b/src/storagevol.c new file mode 100644 index 0000000..0097a7f --- /dev/null +++ b/src/storagevol.c @@ -0,0 +1,77 @@ +#include "storagevol.h" +#include "util.h" + +#include <libvirt/libvirt.h> + +static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { + { 0 } +}; + +static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { + { 0 } +}; + +static gchar ** +virtDBusStorageVolEnumerate(gpointer userData) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePoolPtr) storagePools = NULL; + gint numPools = 0; + GPtrArray *list = NULL; + + if (!virtDBusConnectOpen(connect, NULL)) + return NULL; + + numPools = virConnectListAllStoragePools(connect->connection, + &storagePools, 0); + if (numPools <= 0) + return NULL; + + list = g_ptr_array_new(); + + for (gint i = 0; i < numPools; i++) { + g_autoptr(virStorageVolPtr) storageVols = NULL; + gint numVols; + + numVols = virStoragePoolListAllVolumes(storagePools[i], + &storageVols, 0); + if (numVols <= 0) + continue; + + for (gint j = 0; j < numVols; j++) { + gchar *volPath = virtDBusUtilBusPathForVirStorageVol(storageVols[j], + connect->storageVolPath); + g_ptr_array_add(list, volPath); + } + } + + if (list->len > 0) + g_ptr_array_add(list, NULL); + + return (gchar **)g_ptr_array_free(list, FALSE);
Indentation is off by +1. Reviewed-by: Pavel Hrdina <phrdina@redhat.com>

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StoragePool.xml | 6 ++++++ src/storagepool.c | 43 ++++++++++++++++++++++++++++++++++++++++ tests/test_storage.py | 8 ++++++++ 3 files changed, 57 insertions(+) diff --git a/data/org.libvirt.StoragePool.xml b/data/org.libvirt.StoragePool.xml index e9d6b0e..764c9c1 100644 --- a/data/org.libvirt.StoragePool.xml +++ b/data/org.libvirt.StoragePool.xml @@ -57,6 +57,12 @@ <arg name="flags" type="u" direction="in"/> <arg name="xml" type="s" direction="out"/> </method> + <method name="ListStorageVolumes"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolListAllVolumes"/> + <arg name="flags" type="u" direction="in"/> + <arg name="storageVols" type="ao" direction="out"/> + </method> <method name="Refresh"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolRefresh"/> diff --git a/src/storagepool.c b/src/storagepool.c index 0da732f..4f83ee2 100644 --- a/src/storagepool.c +++ b/src/storagepool.c @@ -301,6 +301,48 @@ virtDBusStoragePoolGetXMLDesc(GVariant *inArgs, *outArgs = g_variant_new("(s)", xml); } +static void +virtDBusStoragePoolListStorageVolumes(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePool) storagePool = NULL; + g_autoptr(virStorageVolPtr) storageVols = NULL; + guint flags; + gint nVols; + GVariantBuilder builder; + GVariant *gstorageVols; + + g_variant_get(inArgs, "(u)", &flags); + + storagePool = virtDBusStoragePoolGetVirStoragePool(connect, objectPath, + error); + if (!storagePool) + return; + + nVols = virStoragePoolListAllVolumes(storagePool, &storageVols, flags); + if (nVols < 0) + return virtDBusUtilSetLastVirtError(error); + + g_variant_builder_init(&builder, G_VARIANT_TYPE("ao")); + + for (gint i = 0; i < nVols; i++) { + g_autofree gchar *path = NULL; + path = virtDBusUtilBusPathForVirStorageVol(storageVols[i], + connect->storageVolPath); + + g_variant_builder_add(&builder, "o", path); + } + + gstorageVols = g_variant_builder_end(&builder); + *outArgs = g_variant_new_tuple(&gstorageVols, 1); +} + static void virtDBusStoragePoolRefresh(GVariant *inArgs, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -363,6 +405,7 @@ static virtDBusGDBusMethodTable virtDBusStoragePoolMethodTable[] = { { "Destroy", virtDBusStoragePoolDestroy }, { "GetInfo", virtDBusStoragePoolGetInfo }, { "GetXMLDesc", virtDBusStoragePoolGetXMLDesc }, + { "ListStorageVolumes", virtDBusStoragePoolListStorageVolumes }, { "Refresh", virtDBusStoragePoolRefresh }, { "Undefine", virtDBusStoragePoolUndefine }, { 0 } diff --git a/tests/test_storage.py b/tests/test_storage.py index b9e7090..79e0c16 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -79,6 +79,14 @@ class TestStoragePool(libvirttest.BaseTestClass): info = interface_obj.GetXMLDesc(0) assert isinstance(info, dbus.String) + def test_storage_pool_list_storage_volumes(self): + _, test_storage_pool = self.test_storage_pool() + interface_obj = dbus.Interface(test_storage_pool, + 'org.libvirt.StoragePool') + storage_vols = interface_obj.ListStorageVolumes(0) + assert isinstance(storage_vols, dbus.Array) + assert len(storage_vols) == 0 + def test_storage_pool_properties_type(self): _, obj = self.test_storage_pool() -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- tests/test_connect.py | 47 +++++++---------------------------------------- tests/xmldata.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 tests/xmldata.py diff --git a/tests/test_connect.py b/tests/test_connect.py index da146a4..01b6bd1 100755 --- a/tests/test_connect.py +++ b/tests/test_connect.py @@ -3,43 +3,10 @@ import dbus import libvirttest import pytest +import xmldata class TestConnect(libvirttest.BaseTestClass): - minimal_domain_xml = ''' - <domain type="test"> - <name>foo</name> - <memory>1024</memory> - <os> - <type>hvm</type> - </os> - </domain> - ''' - - minimal_network_xml = ''' - <network> - <name>bar</name> - <uuid>004b96e12d78c30f5aa5f03c87d21e69</uuid> - <bridge name='brdefault'/> - <forward dev='eth0'/> - <ip address='192.168.122.1' netmask='255.255.255.0'> - <dhcp> - <range start='192.168.122.128' end='192.168.122.253'/> - </dhcp> - </ip> - </network> - ''' - - minimal_storage_pool_xml = ''' - <pool type='dir'> - <name>foo</name> - <uuid>35bb2ad9-388a-cdfe-461a-b8907f6e53fe</uuid> - <target> - <path>/foo</path> - </target> - </pool> - ''' - def test_connect_domain_create_xml(self): def domain_started(path, event, detail): if event != libvirttest.DomainEvent.STARTED: @@ -50,7 +17,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_started) - path = self.connect.DomainCreateXML(self.minimal_domain_xml, 0) + path = self.connect.DomainCreateXML(xmldata.minimal_domain_xml, 0) assert isinstance(path, dbus.ObjectPath) self.main_loop() @@ -65,7 +32,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_defined) - path = self.connect.DomainDefineXML(self.minimal_domain_xml) + path = self.connect.DomainDefineXML(xmldata.minimal_domain_xml) assert isinstance(path, dbus.ObjectPath) self.main_loop() @@ -157,7 +124,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('NetworkEvent', network_started) - path = self.connect.NetworkCreateXML(self.minimal_network_xml) + path = self.connect.NetworkCreateXML(xmldata.minimal_network_xml) assert isinstance(path, dbus.ObjectPath) self.main_loop() @@ -171,7 +138,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('NetworkEvent', network_defined) - path = self.connect.NetworkDefineXML(self.minimal_network_xml) + path = self.connect.NetworkDefineXML(xmldata.minimal_network_xml) assert isinstance(path, dbus.ObjectPath) self.main_loop() @@ -210,7 +177,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('StoragePoolEvent', storage_pool_started) path = self.connect.StoragePoolCreateXML( - self.minimal_storage_pool_xml, 0) + xmldata.minimal_storage_pool_xml, 0) assert isinstance(path, dbus.ObjectPath) self.main_loop() @@ -225,7 +192,7 @@ class TestConnect(libvirttest.BaseTestClass): self.connect.connect_to_signal('StoragePoolEvent', storage_pool_defined) path = self.connect.StoragePoolDefineXML( - self.minimal_storage_pool_xml, 0) + xmldata.minimal_storage_pool_xml, 0) assert isinstance(path, dbus.ObjectPath) self.main_loop() diff --git a/tests/xmldata.py b/tests/xmldata.py new file mode 100644 index 0000000..e42b6aa --- /dev/null +++ b/tests/xmldata.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +"""Minimal libvirt XML definition of entities to be used in the test suite. +""" + +minimal_domain_xml = ''' +<domain type="test"> + <name>foo</name> + <memory>1024</memory> + <os> + <type>hvm</type> + </os> +</domain> +''' + +minimal_network_xml = ''' +<network> + <name>bar</name> + <uuid>004b96e12d78c30f5aa5f03c87d21e69</uuid> + <bridge name='brdefault'/> + <forward dev='eth0'/> + <ip address='192.168.122.1' netmask='255.255.255.0'> + <dhcp> + <range start='192.168.122.128' end='192.168.122.253'/> + </dhcp> + </ip> +</network> +''' + +minimal_storage_pool_xml = ''' +<pool type='dir'> + <name>foo</name> + <uuid>35bb2ad9-388a-cdfe-461a-b8907f6e53fe</uuid> + <target> + <path>/foo</path> + </target> +</pool> +''' -- 2.15.0

On Thu, Jun 14, 2018 at 05:59:39PM +0200, Katerina Koukiou wrote:
Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- tests/test_connect.py | 47 +++++++---------------------------------------- tests/xmldata.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 40 deletions(-) create mode 100644 tests/xmldata.py
s/test/tests/ in subject Reviewed-by: Pavel Hrdina <phrdina@redhat.com>

pytest collects functions starting with test prefix to run them as tests by default. Rename functions that are not supposed to be run as tests, to avoid unexpected failures. Note: this commit also renames domain function to follow the naming convention for same purpose functions. Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- tests/libvirttest.py | 6 +++--- tests/test_connect.py | 6 +++--- tests/test_domain.py | 20 ++++++++++---------- tests/test_network.py | 14 +++++++------- tests/test_storage.py | 22 +++++++++++----------- 5 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/libvirttest.py b/tests/libvirttest.py index 3cd02ef..23a597f 100644 --- a/tests/libvirttest.py +++ b/tests/libvirttest.py @@ -70,12 +70,12 @@ class BaseTestClass(): if self.timeout: raise TimeoutError() - def domain(self): + def get_test_domain(self): path = self.connect.ListDomains(0)[0] obj = self.bus.get_object('org.libvirt', path) return obj, dbus.Interface(obj, 'org.libvirt.Domain') - def test_network(self): + def get_test_network(self): """Fetch information for the test network from test driver Returns: @@ -87,7 +87,7 @@ class BaseTestClass(): obj = self.bus.get_object('org.libvirt', path) return path, obj - def test_storage_pool(self): + def get_test_storage_pool(self): """Fetch information for the test storage pool from test driver Returns: diff --git a/tests/test_connect.py b/tests/test_connect.py index 01b6bd1..ec3f551 100755 --- a/tests/test_connect.py +++ b/tests/test_connect.py @@ -46,7 +46,7 @@ class TestConnect(libvirttest.BaseTestClass): """Parameterized test for all DomainLookupBy* API calls of Connect interface """ original_path = self.connect.ListDomains(0)[0] - obj, _ = self.domain() + obj, _ = self.get_test_domain() props = obj.GetAll('org.libvirt.Domain', dbus_interface=dbus.PROPERTIES_IFACE) path = getattr(self.connect, lookup_method_name)(props[lookup_item]) assert original_path == path @@ -150,7 +150,7 @@ class TestConnect(libvirttest.BaseTestClass): def test_connect_network_lookup_by_property(self, lookup_method_name, lookup_item): """Parameterized test for all NetworkLookupBy* API calls of Connect interface """ - original_path, obj = self.test_network() + original_path, obj = self.get_test_network() prop = obj.Get('org.libvirt.Network', lookup_item, dbus_interface=dbus.PROPERTIES_IFACE) path = getattr(self.connect, lookup_method_name)(prop) assert original_path == path @@ -206,7 +206,7 @@ class TestConnect(libvirttest.BaseTestClass): lookup_item): """Parameterized test for all StoragePoolLookupBy* API calls of Connect interface """ - original_path, obj = self.test_storage_pool() + original_path, obj = self.get_test_storage_pool() prop = obj.Get('org.libvirt.StoragePool', lookup_item, dbus_interface=dbus.PROPERTIES_IFACE) path = getattr(self.connect, lookup_method_name)(prop) diff --git a/tests/test_domain.py b/tests/test_domain.py index dbb1e3d..b9a6d33 100755 --- a/tests/test_domain.py +++ b/tests/test_domain.py @@ -7,7 +7,7 @@ DBUS_EXCEPTION_MISSING_FUNCTION = 'this function is not supported by the connect class TestDomain(libvirttest.BaseTestClass): def test_api(self): - obj, domain = self.domain() + obj, domain = self.get_test_domain() props = obj.GetAll('org.libvirt.Domain', dbus_interface=dbus.PROPERTIES_IFACE) assert isinstance(props['Active'], dbus.Boolean) @@ -39,7 +39,7 @@ class TestDomain(libvirttest.BaseTestClass): domain.Undefine(0) def test_domain_autostart(self): - _, domain = self.domain() + _, domain = self.get_test_domain() autostart_expected = True domain.Set('org.libvirt.Domain', 'Autostart', autostart_expected, dbus_interface=dbus.PROPERTIES_IFACE) autostart_current = domain.Get('org.libvirt.Domain', 'Autostart', dbus_interface=dbus.PROPERTIES_IFACE) @@ -55,7 +55,7 @@ class TestDomain(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_stopped) - obj, domain = self.domain() + obj, domain = self.get_test_domain() domain.ManagedSave(0) assert domain.HasManagedSaveImage(0) == dbus.Boolean(True) state, _ = domain.GetState(0) @@ -67,7 +67,7 @@ class TestDomain(libvirttest.BaseTestClass): def test_domain_metadata(self): metadata_description = 0 - obj, domain = self.domain() + obj, domain = self.get_test_domain() description_expected = "This is the Test domain" domain.SetMetadata(metadata_description, description_expected, "", "", 0) @@ -83,7 +83,7 @@ class TestDomain(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_resumed) - obj, domain = self.domain() + obj, domain = self.get_test_domain() domain.Suspend() domain.Resume() @@ -102,7 +102,7 @@ class TestDomain(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_stopped) - obj, domain = self.domain() + obj, domain = self.get_test_domain() domain.Shutdown(0) state, _ = domain.GetState(0) @@ -120,7 +120,7 @@ class TestDomain(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_suspended) - obj, domain = self.domain() + obj, domain = self.get_test_domain() domain.Suspend() state, _ = domain.GetState(0) @@ -138,20 +138,20 @@ class TestDomain(libvirttest.BaseTestClass): self.connect.connect_to_signal('DomainEvent', domain_undefined) - _, domain = self.domain() + _, domain = self.get_test_domain() domain.Shutdown(0) domain.Undefine(0) self.main_loop() def test_domain_vcpus(self): - obj, domain = self.domain() + obj, domain = self.get_test_domain() vcpus_expected = 2 domain.SetVcpus(vcpus_expected, 0) assert domain.GetVcpus(0) == dbus.Int32(vcpus_expected) def test_domain_vcpu_pin_info(self): - obj, domain = self.domain() + obj, domain = self.get_test_domain() pinInfo_expected = [ [ True, True, True, True, True, True, True, True ], [ True, True, True, True, True, True, True, True ] diff --git a/tests/test_network.py b/tests/test_network.py index 1a71536..11418cb 100755 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -16,7 +16,7 @@ class TestNetwork(libvirttest.BaseTestClass): def test_network_properties_type(self): """ Ensure correct return type for Network properties """ - _, obj = self.test_network() + _, obj = self.get_test_network() props = obj.GetAll('org.libvirt.Network', dbus_interface=dbus.PROPERTIES_IFACE) assert isinstance(props['Active'], dbus.Boolean) assert isinstance(props['Autostart'], dbus.Boolean) @@ -25,7 +25,7 @@ class TestNetwork(libvirttest.BaseTestClass): assert isinstance(props['UUID'], dbus.String) def test_network_autostart(self): - _,test_network = self.test_network() + _,test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') autostart_expected = True interface_obj.Set('org.libvirt.Network', 'Autostart', autostart_expected, dbus_interface=dbus.PROPERTIES_IFACE) @@ -41,7 +41,7 @@ class TestNetwork(libvirttest.BaseTestClass): self.connect.connect_to_signal('NetworkEvent', domain_started) - _,test_network = self.test_network() + _,test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') interface_obj.Destroy() interface_obj.Create() @@ -57,14 +57,14 @@ class TestNetwork(libvirttest.BaseTestClass): self.connect.connect_to_signal('NetworkEvent', network_stopped) - _, test_network = self.test_network() + _, test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') interface_obj.Destroy() self.main_loop() def test_network_get_xml_description(self): - _,test_network = self.test_network() + _,test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') assert isinstance(interface_obj.GetXMLDesc(0), dbus.String) @@ -77,7 +77,7 @@ class TestNetwork(libvirttest.BaseTestClass): self.connect.connect_to_signal('NetworkEvent', domain_undefined) - _,test_network = self.test_network() + _,test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') interface_obj.Destroy() interface_obj.Undefine() @@ -88,7 +88,7 @@ class TestNetwork(libvirttest.BaseTestClass): ('4', '4', 0, ip_dhcp_host_xml, 0), # add-first, ip-dhcp-host ]) def test_network_update(self, command, section, parentIndex, xml_str, flags): - _, test_network = self.test_network() + _, test_network = self.get_test_network() interface_obj = dbus.Interface(test_network, 'org.libvirt.Network') interface_obj.Update(command, section, parentIndex, xml_str, flags) updated_netxml = interface_obj.GetXMLDesc(0) diff --git a/tests/test_storage.py b/tests/test_storage.py index 79e0c16..10bcea3 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -5,7 +5,7 @@ import libvirttest class TestStoragePool(libvirttest.BaseTestClass): def test_storage_pool_autostart(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') autostart_expected = True @@ -18,7 +18,7 @@ class TestStoragePool(libvirttest.BaseTestClass): assert autostart_current == dbus.Boolean(autostart_expected) def test_storage_pool_build(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.Destroy() @@ -33,7 +33,7 @@ class TestStoragePool(libvirttest.BaseTestClass): self.connect.connect_to_signal('StoragePoolEvent', storage_pool_started) - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.Destroy() @@ -42,7 +42,7 @@ class TestStoragePool(libvirttest.BaseTestClass): self.main_loop() def test_storage_pool_delete(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.Destroy() @@ -58,7 +58,7 @@ class TestStoragePool(libvirttest.BaseTestClass): self.connect.connect_to_signal('StoragePoolEvent', storage_pool_destroyed) - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.Destroy() @@ -66,21 +66,21 @@ class TestStoragePool(libvirttest.BaseTestClass): self.main_loop() def test_storage_pool_get_info(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') info = interface_obj.GetInfo() assert isinstance(info, dbus.Struct) def test_storage_pool_get_xml_description(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') info = interface_obj.GetXMLDesc(0) assert isinstance(info, dbus.String) def test_storage_pool_list_storage_volumes(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') storage_vols = interface_obj.ListStorageVolumes(0) @@ -88,7 +88,7 @@ class TestStoragePool(libvirttest.BaseTestClass): assert len(storage_vols) == 0 def test_storage_pool_properties_type(self): - _, obj = self.test_storage_pool() + _, obj = self.get_test_storage_pool() props = obj.GetAll('org.libvirt.StoragePool', dbus_interface=dbus.PROPERTIES_IFACE) @@ -108,7 +108,7 @@ class TestStoragePool(libvirttest.BaseTestClass): self.connect.connect_to_signal('StoragePoolEvent', storage_pool_undefined) - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.Destroy() @@ -117,7 +117,7 @@ class TestStoragePool(libvirttest.BaseTestClass): self.main_loop() def test_storage_pool_refresh(self): - _, test_storage_pool = self.test_storage_pool() + _, test_storage_pool = self.get_test_storage_pool() interface_obj = dbus.Interface(test_storage_pool, 'org.libvirt.StoragePool') interface_obj.connect_to_signal('Refresh', -- 2.15.0

On Thu, Jun 14, 2018 at 05:59:40PM +0200, Katerina Koukiou wrote:
pytest collects functions starting with test prefix to run them as tests by default.
Rename functions that are not supposed to be run as tests, to avoid unexpected failures.
Note: this commit also renames domain function to follow the naming convention for same purpose functions.
Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- tests/libvirttest.py | 6 +++--- tests/test_connect.py | 6 +++--- tests/test_domain.py | 20 ++++++++++---------- tests/test_network.py | 14 +++++++------- tests/test_storage.py | 22 +++++++++++----------- 5 files changed, 34 insertions(+), 34 deletions(-)
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/org.libvirt.StoragePool.xml | 7 +++++++ src/storagepool.c | 34 ++++++++++++++++++++++++++++++++++ tests/libvirttest.py | 31 +++++++++++++++++++++++++++++++ tests/test_storage.py | 3 +++ tests/xmldata.py | 10 ++++++++++ 5 files changed, 85 insertions(+) diff --git a/data/org.libvirt.StoragePool.xml b/data/org.libvirt.StoragePool.xml index 764c9c1..51d65ab 100644 --- a/data/org.libvirt.StoragePool.xml +++ b/data/org.libvirt.StoragePool.xml @@ -68,6 +68,13 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolRefresh"/> <arg name="flags" type="u" direction="in"/> </method> + <method name="StorageVolCreateXML"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolCreateXML"/> + <arg name="xml" type="s" direction="in"/> + <arg name="flags" type="u" direction="in"/> + <arg name="storageVol" type="o" direction="out"/> + </method> <method name="Undefine"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolUndefine"/> diff --git a/src/storagepool.c b/src/storagepool.c index 4f83ee2..cde9ec3 100644 --- a/src/storagepool.c +++ b/src/storagepool.c @@ -367,6 +367,39 @@ virtDBusStoragePoolRefresh(GVariant *inArgs, virtDBusUtilSetLastVirtError(error); } +static void +virtDBusStoragePoolStorageVolCreateXML(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePool) storagePool = NULL; + g_autoptr(virStorageVol) storageVol = NULL; + gchar *xml; + guint flags; + g_autofree gchar *path = NULL; + + g_variant_get(inArgs, "(&su)", &xml, &flags); + + storagePool = virtDBusStoragePoolGetVirStoragePool(connect, objectPath, + error); + if (!storagePool) + return; + + storageVol = virStorageVolCreateXML(storagePool, xml, flags); + if (!storageVol) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirStorageVol(storageVol, + connect->storageVolPath); + + *outArgs = g_variant_new("(o)", path); +} + static void virtDBusStoragePoolUndefine(GVariant *inArgs G_GNUC_UNUSED, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -407,6 +440,7 @@ static virtDBusGDBusMethodTable virtDBusStoragePoolMethodTable[] = { { "GetXMLDesc", virtDBusStoragePoolGetXMLDesc }, { "ListStorageVolumes", virtDBusStoragePoolListStorageVolumes }, { "Refresh", virtDBusStoragePoolRefresh }, + { "StorageVolCreateXML", virtDBusStoragePoolStorageVolCreateXML }, { "Undefine", virtDBusStoragePoolUndefine }, { 0 } }; diff --git a/tests/libvirttest.py b/tests/libvirttest.py index 23a597f..6d1a9d0 100644 --- a/tests/libvirttest.py +++ b/tests/libvirttest.py @@ -7,6 +7,7 @@ import pytest import subprocess import sys import time +import xmldata root = os.environ.get('abs_top_builddir', os.path.dirname(os.path.dirname(__file__))) @@ -70,6 +71,20 @@ class BaseTestClass(): if self.timeout: raise TimeoutError() + @pytest.fixture + def storage_volume_create(self): + """ Fixture to create dummy storage volume on the test driver + + This fixture should be used in the setup of every test manipulating + with test volume. + """ + _, test_storage_pool = self.get_test_storage_pool() + interface_obj = dbus.Interface(test_storage_pool, + 'org.libvirt.StoragePool') + path = interface_obj.StorageVolCreateXML(xmldata.minimal_storage_vol_xml, 0) + yield path + + def get_test_domain(self): path = self.connect.ListDomains(0)[0] obj = self.bus.get_object('org.libvirt', path) @@ -100,6 +115,22 @@ class BaseTestClass(): obj = self.bus.get_object('org.libvirt', path) return path, obj + def get_test_storage_volume(self): + """Fetch information for the test storage vol from test driver + + Returns: + (dbus.proxies.ProxyObject, dbus.proxies.ProxyObject): + Test StorageVol Object, Local proxy for the test StorageVol + Object. + + """ + _, test_storage_pool = self.get_test_storage_pool() + pool_iface = dbus.Interface(test_storage_pool, + 'org.libvirt.StoragePool') + path = pool_iface.ListStorageVolumes(0)[0] + obj = self.bus.get_object('org.libvirt', path) + return path, obj + class DomainEvent(IntEnum): DEFINED = 0 diff --git a/tests/test_storage.py b/tests/test_storage.py index 10bcea3..2aefd74 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -126,6 +126,9 @@ class TestStoragePool(libvirttest.BaseTestClass): self.main_loop() + def test_storage_pool_volume_create(self, storage_volume_create): + assert isinstance(storage_volume_create, dbus.ObjectPath) + if __name__ == '__main__': libvirttest.run() diff --git a/tests/xmldata.py b/tests/xmldata.py index e42b6aa..926bd2c 100644 --- a/tests/xmldata.py +++ b/tests/xmldata.py @@ -35,3 +35,13 @@ minimal_storage_pool_xml = ''' </target> </pool> ''' + +minimal_storage_vol_xml = ''' +<volume> + <name>sparse.img</name> + <capacity unit="G">2</capacity> + <target> + <path>/var/lib/virt/images/sparse.img</path> + </target> +</volume> +''' -- 2.15.0

On Thu, Jun 14, 2018 at 05:59:41PM +0200, Katerina Koukiou wrote:
Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/org.libvirt.StoragePool.xml | 7 +++++++ src/storagepool.c | 34 ++++++++++++++++++++++++++++++++++ tests/libvirttest.py | 31 +++++++++++++++++++++++++++++++ tests/test_storage.py | 3 +++ tests/xmldata.py | 10 ++++++++++ 5 files changed, 85 insertions(+)
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 5 +++++ src/storagevol.c | 44 +++++++++++++++++++++++++++++++++++++++++ tests/test_storage.py | 11 +++++++++++ 3 files changed, 60 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index c72c847..3110b4f 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -3,5 +3,10 @@ <node name="/org/libvirt/storagevol"> <interface name="org.libvirt.StorageVol"> + <property name="Name" type="s" access="read"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetName"/> + <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> + </property> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index 0097a7f..12ebef1 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -3,7 +3,51 @@ #include <libvirt/libvirt.h> +static virStorageVolPtr +virtDBusStorageVolGetVirStorageVol(virtDBusConnect *connect, + const gchar *objectPath, + GError **error) +{ + virStorageVolPtr storageVol; + + if (virtDBusConnectOpen(connect, error) < 0) + return NULL; + + storageVol = virtDBusUtilVirStorageVolFromBusPath(connect->connection, + objectPath, + connect->storageVolPath); + if (!storageVol) { + virtDBusUtilSetLastVirtError(error); + return NULL; + } + + return storageVol; +} + +static void +virtDBusStorageVolGetName(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + const gchar *name; + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + name = virStorageVolGetName(storageVol); + if (!name) + return virtDBusUtilSetLastVirtError(error); + + *value = g_variant_new("s", name); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { + { "Name", virtDBusStorageVolGetName, NULL }, { 0 } }; diff --git a/tests/test_storage.py b/tests/test_storage.py index 2aefd74..c93b800 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -2,6 +2,7 @@ import dbus import libvirttest +import pytest class TestStoragePool(libvirttest.BaseTestClass): def test_storage_pool_autostart(self): @@ -130,5 +131,15 @@ class TestStoragePool(libvirttest.BaseTestClass): assert isinstance(storage_volume_create, dbus.ObjectPath) +@pytest.mark.usefixtures('storage_volume_create') +class TestStorageVolume(libvirttest.BaseTestClass): + def test_storage_vol_properties_type(self): + _, obj = self.get_test_storage_volume() + + props = obj.GetAll('org.libvirt.StorageVol', + dbus_interface=dbus.PROPERTIES_IFACE) + assert isinstance(props['Name'], dbus.String) + + if __name__ == '__main__': libvirttest.run() -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 5 +++++ src/storagevol.c | 23 +++++++++++++++++++++++ tests/test_storage.py | 1 + 3 files changed, 29 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index 3110b4f..3b36f3b 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -8,5 +8,10 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetName"/> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> + <property name="Key" type="s" access="read"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetKey"/> + <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> + </property> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index 12ebef1..b979b82 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -46,8 +46,31 @@ virtDBusStorageVolGetName(const gchar *objectPath, *value = g_variant_new("s", name); } +static void +virtDBusStorageVolGetKey(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + const gchar *key; + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + key = virStorageVolGetKey(storageVol); + if (!key) + return virtDBusUtilSetLastVirtError(error); + + *value = g_variant_new("s", key); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { { "Name", virtDBusStorageVolGetName, NULL }, + { "Key", virtDBusStorageVolGetKey, NULL }, { 0 } }; diff --git a/tests/test_storage.py b/tests/test_storage.py index c93b800..91b2597 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -138,6 +138,7 @@ class TestStorageVolume(libvirttest.BaseTestClass): props = obj.GetAll('org.libvirt.StorageVol', dbus_interface=dbus.PROPERTIES_IFACE) + assert isinstance(props['Key'], dbus.String) assert isinstance(props['Name'], dbus.String) -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 5 +++++ src/storagevol.c | 23 +++++++++++++++++++++++ tests/test_storage.py | 1 + 3 files changed, 29 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index 3b36f3b..03c15c2 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -13,5 +13,10 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetKey"/> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> + <property name="Path" type="s" access="read"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetPath"/> + <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> + </property> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index b979b82..7f33de8 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -68,9 +68,32 @@ virtDBusStorageVolGetKey(const gchar *objectPath, *value = g_variant_new("s", key); } +static void +virtDBusStorageVolGetPath(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + g_autofree gchar *path = NULL; + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + path = virStorageVolGetPath(storageVol); + if (!path) + return virtDBusUtilSetLastVirtError(error); + + *value = g_variant_new("s", path); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { { "Name", virtDBusStorageVolGetName, NULL }, { "Key", virtDBusStorageVolGetKey, NULL }, + { "Path", virtDBusStorageVolGetPath, NULL }, { 0 } }; diff --git a/tests/test_storage.py b/tests/test_storage.py index 91b2597..d3a8701 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -140,6 +140,7 @@ class TestStorageVolume(libvirttest.BaseTestClass): dbus_interface=dbus.PROPERTIES_IFACE) assert isinstance(props['Key'], dbus.String) assert isinstance(props['Name'], dbus.String) + assert isinstance(props['Path'], dbus.String) if __name__ == '__main__': -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 6 ++++++ src/storagevol.c | 29 +++++++++++++++++++++++++++++ tests/test_storage.py | 7 +++++++ 3 files changed, 42 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index 03c15c2..c1fecf3 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -18,5 +18,11 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetPath"/> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> + <method name="GetXMLDesc"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetXMLDesc"/> + <arg name="flags" type="u" direction="in"/> + <arg name="xml" type="s" direction="out"/> + </method> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index 7f33de8..fb66dd0 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -90,6 +90,34 @@ virtDBusStorageVolGetPath(const gchar *objectPath, *value = g_variant_new("s", path); } +static void +virtDBusStorageVolGetXMLDesc(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + g_autofree gchar *xml = NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + xml = virStorageVolGetXMLDesc(storageVol, flags); + if (!xml) + return virtDBusUtilSetLastVirtError(error); + + *outArgs = g_variant_new("(s)", xml); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { { "Name", virtDBusStorageVolGetName, NULL }, { "Key", virtDBusStorageVolGetKey, NULL }, @@ -98,6 +126,7 @@ static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { }; static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { + { "GetXMLDesc", virtDBusStorageVolGetXMLDesc }, { 0 } }; diff --git a/tests/test_storage.py b/tests/test_storage.py index d3a8701..3f15fe0 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -142,6 +142,13 @@ class TestStorageVolume(libvirttest.BaseTestClass): assert isinstance(props['Name'], dbus.String) assert isinstance(props['Path'], dbus.String) + def test_storage_vol_get_xml_description(self): + _, test_storage_vol = self.get_test_storage_volume() + interface_obj = dbus.Interface(test_storage_vol, + 'org.libvirt.StorageVol') + xml = interface_obj.GetXMLDesc(0) + assert isinstance(xml, dbus.String) + if __name__ == '__main__': libvirttest.run() -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.Connect.xml | 6 ++++++ src/connect.c | 30 ++++++++++++++++++++++++++++++ tests/test_connect.py | 15 +++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml index f41acd2..d3871b3 100644 --- a/data/org.libvirt.Connect.xml +++ b/data/org.libvirt.Connect.xml @@ -308,6 +308,12 @@ <arg name="uuid" type="s" direction="in"/> <arg name="storagePool" type="o" direction="out"/> </method> + <method name="StorageVolLookupByKey"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolLookupByKey"/> + <arg name="key" type="s" direction="in"/> + <arg name="storageVol" type="o" direction="out"/> + </method> <signal name="DomainEvent"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectDomainEventCallback"/> diff --git a/src/connect.c b/src/connect.c index 1090e3e..ff9d91a 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1544,6 +1544,35 @@ virtDBusConnectStoragePoolLookupByUUID(GVariant *inArgs, *outArgs = g_variant_new("(o)", path); } +static void +virtDBusConnectStorageVolLookupByKey(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + g_autofree gchar *path = NULL; + const gchar *key; + + g_variant_get(inArgs, "(&s)", &key); + + if (!virtDBusConnectOpen(connect, error)) + return; + + storageVol = virStorageVolLookupByKey(connect->connection, key); + if (!storageVol) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirStorageVol(storageVol, + connect->storageVolPath); + + *outArgs = g_variant_new("(o)", path); +} + static virtDBusGDBusPropertyTable virtDBusConnectPropertyTable[] = { { "Encrypted", virtDBusConnectGetEncrypted, NULL }, { "Hostname", virtDBusConnectGetHostname, NULL }, @@ -1597,6 +1626,7 @@ static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = { { "StoragePoolDefineXML", virtDBusConnectStoragePoolDefineXML }, { "StoragePoolLookupByName", virtDBusConnectStoragePoolLookupByName }, { "StoragePoolLookupByUUID", virtDBusConnectStoragePoolLookupByUUID }, + { "StorageVolLookupByKey", virtDBusConnectStorageVolLookupByKey }, { 0 } }; diff --git a/tests/test_connect.py b/tests/test_connect.py index ec3f551..5182769 100755 --- a/tests/test_connect.py +++ b/tests/test_connect.py @@ -212,6 +212,21 @@ class TestConnect(libvirttest.BaseTestClass): path = getattr(self.connect, lookup_method_name)(prop) assert original_path == path + @pytest.mark.usefixtures("storage_volume_create") + @pytest.mark.parametrize("lookup_method_name,lookup_item", [ + ("StorageVolLookupByKey", 'Key'), + ]) + def test_connect_storage_vol_lookup_by_property(self, + lookup_method_name, + lookup_item): + """Parameterized test for all StorageVolLookupBy* API calls of Connect interface + """ + original_path, obj = self.get_test_storage_volume() + prop = obj.Get('org.libvirt.StorageVol', lookup_item, + dbus_interface=dbus.PROPERTIES_IFACE) + path = getattr(self.connect, lookup_method_name)(prop) + assert original_path == path + if __name__ == '__main__': libvirttest.run() -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StoragePool.xml | 6 ++++++ src/storagepool.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/data/org.libvirt.StoragePool.xml b/data/org.libvirt.StoragePool.xml index 51d65ab..161ade5 100644 --- a/data/org.libvirt.StoragePool.xml +++ b/data/org.libvirt.StoragePool.xml @@ -75,6 +75,12 @@ <arg name="flags" type="u" direction="in"/> <arg name="storageVol" type="o" direction="out"/> </method> + <method name="StorageVolLookupByName"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolLookupByName"/> + <arg name="name" type="s" direction="in"/> + <arg name="storageVol" type="o" direction="out"/> + </method> <method name="Undefine"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStoragePoolUndefine"/> diff --git a/src/storagepool.c b/src/storagepool.c index cde9ec3..ee2862b 100644 --- a/src/storagepool.c +++ b/src/storagepool.c @@ -400,6 +400,39 @@ virtDBusStoragePoolStorageVolCreateXML(GVariant *inArgs, *outArgs = g_variant_new("(o)", path); } +static void +virtDBusStoragePoolStorageVolLookupByName(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePool) storagePool = NULL; + g_autoptr(virStorageVol) storageVol = NULL; + g_autofree gchar *path = NULL; + const gchar *name; + + g_variant_get(inArgs, "(&s)", &name); + + storagePool = virtDBusStoragePoolGetVirStoragePool(connect, objectPath, + error); + if (!storagePool) + return; + + storageVol = virStorageVolLookupByName(storagePool, name); + + if (!storageVol) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirStorageVol(storageVol, + connect->storageVolPath); + + *outArgs = g_variant_new("(o)", path); +} + static void virtDBusStoragePoolUndefine(GVariant *inArgs G_GNUC_UNUSED, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -441,6 +474,7 @@ static virtDBusGDBusMethodTable virtDBusStoragePoolMethodTable[] = { { "ListStorageVolumes", virtDBusStoragePoolListStorageVolumes }, { "Refresh", virtDBusStoragePoolRefresh }, { "StorageVolCreateXML", virtDBusStoragePoolStorageVolCreateXML }, + { "StorageVolLookupByName", virtDBusStoragePoolStorageVolLookupByName }, { "Undefine", virtDBusStoragePoolUndefine }, { 0 } }; -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.Connect.xml | 6 ++++++ src/connect.c | 30 ++++++++++++++++++++++++++++++ tests/test_connect.py | 1 + 3 files changed, 37 insertions(+) diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml index d3871b3..37daed0 100644 --- a/data/org.libvirt.Connect.xml +++ b/data/org.libvirt.Connect.xml @@ -314,6 +314,12 @@ <arg name="key" type="s" direction="in"/> <arg name="storageVol" type="o" direction="out"/> </method> + <method name="StorageVolLookupByPath"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolLookupByPath"/> + <arg name="path" type="s" direction="in"/> + <arg name="storageVol" type="o" direction="out"/> + </method> <signal name="DomainEvent"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-domain.html#virConnectDomainEventCallback"/> diff --git a/src/connect.c b/src/connect.c index ff9d91a..4f2bdb6 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1573,6 +1573,35 @@ virtDBusConnectStorageVolLookupByKey(GVariant *inArgs, *outArgs = g_variant_new("(o)", path); } +static void +virtDBusConnectStorageVolLookupByPath(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath G_GNUC_UNUSED, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + const gchar *inPath; + g_autofree gchar *path = NULL; + + g_variant_get(inArgs, "(&s)", &inPath); + + if (!virtDBusConnectOpen(connect, error)) + return; + + storageVol = virStorageVolLookupByPath(connect->connection, inPath); + if (!storageVol) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirStorageVol(storageVol, + connect->storageVolPath); + + *outArgs = g_variant_new("(o)", path); +} + static virtDBusGDBusPropertyTable virtDBusConnectPropertyTable[] = { { "Encrypted", virtDBusConnectGetEncrypted, NULL }, { "Hostname", virtDBusConnectGetHostname, NULL }, @@ -1627,6 +1656,7 @@ static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = { { "StoragePoolLookupByName", virtDBusConnectStoragePoolLookupByName }, { "StoragePoolLookupByUUID", virtDBusConnectStoragePoolLookupByUUID }, { "StorageVolLookupByKey", virtDBusConnectStorageVolLookupByKey }, + { "StorageVolLookupByPath", virtDBusConnectStorageVolLookupByPath }, { 0 } }; diff --git a/tests/test_connect.py b/tests/test_connect.py index 5182769..57b385e 100755 --- a/tests/test_connect.py +++ b/tests/test_connect.py @@ -215,6 +215,7 @@ class TestConnect(libvirttest.BaseTestClass): @pytest.mark.usefixtures("storage_volume_create") @pytest.mark.parametrize("lookup_method_name,lookup_item", [ ("StorageVolLookupByKey", 'Key'), + ("StorageVolLookupByPath", 'Path'), ]) def test_connect_storage_vol_lookup_by_property(self, lookup_method_name, -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 6 ++++++ src/storagevol.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index c1fecf3..fdde430 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -24,5 +24,11 @@ <arg name="flags" type="u" direction="in"/> <arg name="xml" type="s" direction="out"/> </method> + <method name="Resize"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolResize"/> + <arg name="capacity" type="t" direction="in"/> + <arg name="flags" type="u" direction="in"/> + </method> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index fb66dd0..44965a9 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -118,6 +118,31 @@ virtDBusStorageVolGetXMLDesc(GVariant *inArgs, *outArgs = g_variant_new("(s)", xml); } +static void +virtDBusStorageVolResize(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + guint64 capacity; + guint flags; + + g_variant_get(inArgs, "(tu)", &capacity, &flags); + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + if (virStorageVolResize(storageVol, capacity, flags) < 0) + virtDBusUtilSetLastVirtError(error); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { { "Name", virtDBusStorageVolGetName, NULL }, { "Key", virtDBusStorageVolGetKey, NULL }, @@ -127,6 +152,7 @@ static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { { "GetXMLDesc", virtDBusStorageVolGetXMLDesc }, + { "Resize", virtDBusStorageVolResize }, { 0 } }; -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 6 ++++++ src/storagevol.c | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index fdde430..aed3f7a 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -30,5 +30,11 @@ <arg name="capacity" type="t" direction="in"/> <arg name="flags" type="u" direction="in"/> </method> + <method name="Wipe"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolWipePattern"/> + <arg name="pattern" type="u" direction="in"/> + <arg name="flags" type="u" direction="in"/> + </method> </interface> </node> diff --git a/src/storagevol.c b/src/storagevol.c index 44965a9..7bfe39e 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -143,6 +143,31 @@ virtDBusStorageVolResize(GVariant *inArgs, virtDBusUtilSetLastVirtError(error); } +static void +virtDBusStorageVolWipe(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + guint pattern; + guint flags; + + g_variant_get(inArgs, "(uu)", &pattern, &flags); + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + if (virStorageVolWipePattern(storageVol, pattern, flags) < 0) + virtDBusUtilSetLastVirtError(error); +} + static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { { "Name", virtDBusStorageVolGetName, NULL }, { "Key", virtDBusStorageVolGetKey, NULL }, @@ -153,6 +178,7 @@ static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { { "GetXMLDesc", virtDBusStorageVolGetXMLDesc }, { "Resize", virtDBusStorageVolResize }, + { "Wipe", virtDBusStorageVolWipe }, { 0 } }; -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 6 ++++++ src/storagevol.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index aed3f7a..8a4eab2 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -18,6 +18,12 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetPath"/> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> + <method name="GetInfo"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetInfoFlags"/> + <arg name="flags" type="u" direction="in"/> + <arg name="info" type="(itt)" direction="out"/> + </method> <method name="GetXMLDesc"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetXMLDesc"/> diff --git a/src/storagevol.c b/src/storagevol.c index 7bfe39e..022ce37 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -90,6 +90,34 @@ virtDBusStorageVolGetPath(const gchar *objectPath, *value = g_variant_new("s", path); } +static void +virtDBusStorageVolGetInfo(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + virStorageVolInfo info; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + if (virStorageVolGetInfoFlags(storageVol, &info, flags) < 0) + return virtDBusUtilSetLastVirtError(error); + + *outArgs = g_variant_new("((itt))", info.type, info.capacity, + info.allocation); +} + static void virtDBusStorageVolGetXMLDesc(GVariant *inArgs, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -176,6 +204,7 @@ static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { }; static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { + { "GetInfo", virtDBusStorageVolGetInfo }, { "GetXMLDesc", virtDBusStorageVolGetXMLDesc }, { "Resize", virtDBusStorageVolResize }, { "Wipe", virtDBusStorageVolWipe }, -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StorageVol.xml | 5 +++++ src/storagevol.c | 25 +++++++++++++++++++++++++ tests/test_storage.py | 6 ++++++ 3 files changed, 36 insertions(+) diff --git a/data/org.libvirt.StorageVol.xml b/data/org.libvirt.StorageVol.xml index 8a4eab2..7ad9459 100644 --- a/data/org.libvirt.StorageVol.xml +++ b/data/org.libvirt.StorageVol.xml @@ -18,6 +18,11 @@ value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetPath"/> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> + <method name="Delete"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolDelete"/> + <arg name="flags" type="u" direction="in"/> + </method> <method name="GetInfo"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolGetInfoFlags"/> diff --git a/src/storagevol.c b/src/storagevol.c index 022ce37..489749d 100644 --- a/src/storagevol.c +++ b/src/storagevol.c @@ -90,6 +90,30 @@ virtDBusStorageVolGetPath(const gchar *objectPath, *value = g_variant_new("s", path); } +static void +virtDBusStorageVolDelete(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs G_GNUC_UNUSED, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStorageVol) storageVol = NULL; + guint flags; + + g_variant_get(inArgs, "(u)", &flags); + + storageVol = virtDBusStorageVolGetVirStorageVol(connect, objectPath, + error); + if (!storageVol) + return; + + if (virStorageVolDelete(storageVol, flags) < 0) + virtDBusUtilSetLastVirtError(error); +} + static void virtDBusStorageVolGetInfo(GVariant *inArgs, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -204,6 +228,7 @@ static virtDBusGDBusPropertyTable virtDBusStorageVolPropertyTable[] = { }; static virtDBusGDBusMethodTable virtDBusStorageVolMethodTable[] = { + { "Delete", virtDBusStorageVolDelete }, { "GetInfo", virtDBusStorageVolGetInfo }, { "GetXMLDesc", virtDBusStorageVolGetXMLDesc }, { "Resize", virtDBusStorageVolResize }, diff --git a/tests/test_storage.py b/tests/test_storage.py index 3f15fe0..ae06007 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -133,6 +133,12 @@ class TestStoragePool(libvirttest.BaseTestClass): @pytest.mark.usefixtures('storage_volume_create') class TestStorageVolume(libvirttest.BaseTestClass): + def test_storage_vol_delete(self): + test_storage_vol_path, test_storage_vol = self.get_test_storage_volume() + interface_obj = dbus.Interface(test_storage_vol, + 'org.libvirt.StorageVol') + interface_obj.Delete(0) + def test_storage_vol_properties_type(self): _, obj = self.get_test_storage_volume() -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com> --- data/org.libvirt.StoragePool.xml | 9 +++++++++ src/storagepool.c | 41 ++++++++++++++++++++++++++++++++++++++++ tests/test_storage.py | 22 +++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/data/org.libvirt.StoragePool.xml b/data/org.libvirt.StoragePool.xml index 161ade5..0a324e6 100644 --- a/data/org.libvirt.StoragePool.xml +++ b/data/org.libvirt.StoragePool.xml @@ -75,6 +75,15 @@ <arg name="flags" type="u" direction="in"/> <arg name="storageVol" type="o" direction="out"/> </method> + <method name="StorageVolCreateXMLFrom"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolCreateXML... + Call with @key argument set to the key of the storage volume to be cloned."/> + <arg name="xml" type="s" direction="in"/> + <arg name="key" type="s" direction="in"/> + <arg name="flags" type="u" direction="in"/> + <arg name="storageVol" type="o" direction="out"/> + </method> <method name="StorageVolLookupByName"> <annotation name="org.gtk.GDBus.DocString" value="See https://libvirt.org/html/libvirt-libvirt-storage.html#virStorageVolLookupByName"/> diff --git a/src/storagepool.c b/src/storagepool.c index ee2862b..6eb6f27 100644 --- a/src/storagepool.c +++ b/src/storagepool.c @@ -400,6 +400,46 @@ virtDBusStoragePoolStorageVolCreateXML(GVariant *inArgs, *outArgs = g_variant_new("(o)", path); } +static void +virtDBusStoragePoolStorageVolCreateXMLFrom(GVariant *inArgs, + GUnixFDList *inFDs G_GNUC_UNUSED, + const gchar *objectPath, + gpointer userData, + GVariant **outArgs, + GUnixFDList **outFDs G_GNUC_UNUSED, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virStoragePool) storagePool = NULL; + g_autoptr(virStorageVol) storageVol = NULL; + g_autoptr(virStorageVol) storageVolOld = NULL; + const gchar *key; + const gchar *xml; + guint flags; + g_autofree gchar *path = NULL; + + g_variant_get(inArgs, "(&s&su)", &xml, &key, &flags); + + storagePool = virtDBusStoragePoolGetVirStoragePool(connect, objectPath, + error); + if (!storagePool) + return; + + storageVolOld = virStorageVolLookupByKey(connect->connection, key); + if (!storageVolOld) + return virtDBusUtilSetLastVirtError(error); + + storageVol = virStorageVolCreateXMLFrom(storagePool, xml, storageVolOld, + flags); + if (!storageVol) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirStorageVol(storageVol, + connect->storageVolPath); + + *outArgs = g_variant_new("(o)", path); +} + static void virtDBusStoragePoolStorageVolLookupByName(GVariant *inArgs, GUnixFDList *inFDs G_GNUC_UNUSED, @@ -474,6 +514,7 @@ static virtDBusGDBusMethodTable virtDBusStoragePoolMethodTable[] = { { "ListStorageVolumes", virtDBusStoragePoolListStorageVolumes }, { "Refresh", virtDBusStoragePoolRefresh }, { "StorageVolCreateXML", virtDBusStoragePoolStorageVolCreateXML }, + { "StorageVolCreateXMLFrom", virtDBusStoragePoolStorageVolCreateXMLFrom }, { "StorageVolLookupByName", virtDBusStoragePoolStorageVolLookupByName }, { "Undefine", virtDBusStoragePoolUndefine }, { 0 } diff --git a/tests/test_storage.py b/tests/test_storage.py index ae06007..63ecf91 100755 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -130,6 +130,28 @@ class TestStoragePool(libvirttest.BaseTestClass): def test_storage_pool_volume_create(self, storage_volume_create): assert isinstance(storage_volume_create, dbus.ObjectPath) + @pytest.mark.usefixtures('storage_volume_create') + def test_storage_pool_volume_create_xml_from(self): + minimal_storage_vol_clone_xml = ''' + <volume> + <name>clone.img</name> + <capacity unit="G">1</capacity> + </volume> + ''' + _, test_storage_vol = self.get_test_storage_volume() + props = test_storage_vol.GetAll('org.libvirt.StorageVol', + dbus_interface=dbus.PROPERTIES_IFACE) + test_storage_vol_key = str(props['Key']) + + _, test_storage_pool = self.get_test_storage_pool() + storage_pool_iface = dbus.Interface(test_storage_pool, + 'org.libvirt.StoragePool') + + new_vol_path = storage_pool_iface.StorageVolCreateXMLFrom(minimal_storage_vol_clone_xml, + test_storage_vol_key, + 0) + assert isinstance(new_vol_path, dbus.ObjectPath) + @pytest.mark.usefixtures('storage_volume_create') class TestStorageVolume(libvirttest.BaseTestClass): -- 2.15.0
participants (2)
-
Katerina Koukiou
-
Pavel Hrdina