[libvirt] [dbus PATCH 0/5] Introduce Network Interface

This patchset introduces also some basic methods and properties for Network interface. More functionality will be added in following patchsets. New functions are covered by the test suite. Katerina Koukiou (5): Introduce Network Interface Implement ListNetworks method for Connect interface Implement virtDBusUtilVirNetworkFromBusPath helper function. Implement Name property for Network interface Implement NetworkLookupByName method for Connect interface data/Makefile.am | 3 +- data/org.libvirt.Connect.xml | 12 +++++ data/org.libvirt.Network.xml | 11 +++++ src/Makefile.am | 3 +- src/connect.c | 75 ++++++++++++++++++++++++++++++ src/connect.h | 1 + src/network.c | 107 +++++++++++++++++++++++++++++++++++++++++++ src/network.h | 9 ++++ src/util.c | 33 +++++++++++++ src/util.h | 15 ++++++ test/Makefile.am | 3 +- test/libvirttest.py | 12 +++++ test/test_connect.py | 11 +++++ 13 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 data/org.libvirt.Network.xml create mode 100644 src/network.c create mode 100644 src/network.h -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/Makefile.am | 3 ++- data/org.libvirt.Network.xml | 7 +++++ src/Makefile.am | 3 ++- src/connect.c | 5 ++++ src/connect.h | 1 + src/network.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ src/network.h | 9 +++++++ src/util.c | 20 ++++++++++++++ src/util.h | 10 +++++++ 9 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 data/org.libvirt.Network.xml create mode 100644 src/network.c create mode 100644 src/network.h diff --git a/data/Makefile.am b/data/Makefile.am index dd60713..61702df 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -20,7 +20,8 @@ polkit_DATA = $(polkit_files:.rules.in=.rules) interfaces_files = \ org.libvirt.Connect.xml \ - org.libvirt.Domain.xml + org.libvirt.Domain.xml \ + org.libvirt.Network.xml interfacesdir = $(DBUS_INTERFACES_DIR) interfaces_DATA = $(interfaces_files) diff --git a/data/org.libvirt.Network.xml b/data/org.libvirt.Network.xml new file mode 100644 index 0000000..2b7c4f7 --- /dev/null +++ b/data/org.libvirt.Network.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/network"> + <interface name="org.libvirt.Network"> + </interface> +</node> diff --git a/src/Makefile.am b/src/Makefile.am index 7248561..158398a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,8 @@ DAEMON_SOURCES = \ util.c util.h \ domain.c domain.h \ events.c events.h \ - gdbus.c gdbus.h + gdbus.c gdbus.h \ + network.c network.h EXTRA_DIST = \ $(DAEMON_SOURCES) diff --git a/src/connect.c b/src/connect.c index 2350736..7b3f834 100644 --- a/src/connect.c +++ b/src/connect.c @@ -1,6 +1,7 @@ #include "connect.h" #include "domain.h" #include "events.h" +#include "network.h" #include "util.h" #include <glib/gprintf.h> @@ -345,6 +346,10 @@ virtDBusConnectNew(virtDBusConnect **connectp, if (error && *error) return; + virtDBusNetworkRegister(connect, error); + if (error && *error) + return; + *connectp = connect; connect = NULL; } diff --git a/src/connect.h b/src/connect.h index 9572857..7ed84b8 100644 --- a/src/connect.h +++ b/src/connect.h @@ -13,6 +13,7 @@ struct virtDBusConnect { const gchar *uri; const gchar *connectPath; gchar *domainPath; + gchar *networkPath; virConnectPtr connection; GMutex lock; diff --git a/src/network.c b/src/network.c new file mode 100644 index 0000000..0d0e992 --- /dev/null +++ b/src/network.c @@ -0,0 +1,64 @@ +#include "network.h" +#include "util.h" + +#include <libvirt/libvirt.h> + +static virtDBusGDBusPropertyTable virtDBusNetworkPropertyTable[] = { + { 0 } +}; + +static virtDBusGDBusMethodTable virtDBusNetworkMethodTable[] = { + { 0 } +}; + +static gchar ** +virtDBusNetworkEnumerate(gpointer userData) +{ + virtDBusConnect *connect = userData; + g_autoptr(virNetworkPtr) networks = NULL; + gint num = 0; + gchar **ret = NULL; + + if (!virtDBusConnectOpen(connect, NULL)) + return NULL; + + num = virConnectListAllNetworks(connect->connection, &networks, 0); + if (num < 0) + return NULL; + + if (num == 0) + return NULL; + + ret = g_new0(gchar *, num + 1); + + for (gint i = 0; i < num; i++) { + ret[i] = virtDBusUtilBusPathForVirNetwork(networks[i], + connect->networkPath); + } + + return ret; +} + +static GDBusInterfaceInfo *interfaceInfo = NULL; + +void +virtDBusNetworkRegister(virtDBusConnect *connect, + GError **error) +{ + connect->networkPath = g_strdup_printf("%s/network", connect->connectPath); + + if (!interfaceInfo) { + interfaceInfo = virtDBusGDBusLoadIntrospectData(VIRT_DBUS_NETWORK_INTERFACE, + error); + if (!interfaceInfo) + return; + } + + virtDBusGDBusRegisterSubtree(connect->bus, + connect->networkPath, + interfaceInfo, + virtDBusNetworkEnumerate, + virtDBusNetworkMethodTable, + virtDBusNetworkPropertyTable, + connect); +} diff --git a/src/network.h b/src/network.h new file mode 100644 index 0000000..fc53b28 --- /dev/null +++ b/src/network.h @@ -0,0 +1,9 @@ +#pragma once + +#include "connect.h" + +#define VIRT_DBUS_NETWORK_INTERFACE "org.libvirt.Network" + +void +virtDBusNetworkRegister(virtDBusConnect *connect, + GError **error); diff --git a/src/util.c b/src/util.c index be65172..fe40a96 100644 --- a/src/util.c +++ b/src/util.c @@ -151,3 +151,23 @@ virtDBusUtilEnumFromString(const gchar *const *types, return -1; } + +gchar * +virtDBusUtilBusPathForVirNetwork(virNetworkPtr network, + const gchar *networkPath) +{ + gchar uuid[VIR_UUID_STRING_BUFLEN] = ""; + g_autofree gchar *newUuid = NULL; + virNetworkGetUUIDString(network, uuid); + newUuid = virtDBusUtilEncodeUUID(uuid); + return g_strdup_printf("%s/%s", networkPath, newUuid); +} + +void +virtDBusUtilVirNetworkListFree(virNetworkPtr *networks) +{ + for (gint i = 0; networks[i] != NULL; i += 1) + virNetworkFree(networks[i]); + + g_free(networks); +} diff --git a/src/util.h b/src/util.h index c9d9cfd..fac080c 100644 --- a/src/util.h +++ b/src/util.h @@ -65,3 +65,13 @@ virtDBusUtilEnumToString(const gchar *const *types, #define VIRT_DBUS_ENUM_DECL(name) \ const gchar *name ##TypeToString(gint type) G_GNUC_PURE; \ gint name ##TypeFromString(const gchar *type) G_GNUC_PURE; + +gchar * +virtDBusUtilBusPathForVirNetwork(virNetworkPtr network, + const gchar *networkPath); + +void +virtDBusUtilVirNetworkListFree(virNetworkPtr *networks); + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetwork, virNetworkFree); +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virNetworkPtr, virtDBusUtilVirNetworkListFree); -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/org.libvirt.Connect.xml | 6 ++++++ src/connect.c | 41 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml index 1695100..ac06875 100644 --- a/data/org.libvirt.Connect.xml +++ b/data/org.libvirt.Connect.xml @@ -50,5 +50,11 @@ <arg name="domain" type="o"/> <arg name="event" type="s"/> </signal> + <method name="ListNetworks"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-network.html#virConnectListAllNetworks"/> + <arg name="flags" type="u" direction="in"/> + <arg name="networks" type="ao" direction="out"/> + </method> </interface> </node> diff --git a/src/connect.c b/src/connect.c index 7b3f834..13fdd20 100644 --- a/src/connect.c +++ b/src/connect.c @@ -280,6 +280,46 @@ virtDBusDomainLookupByUUID(GVariant *inArgs, *outArgs = g_variant_new("(o)", path); } +static void +virtDBusConnectListNetworks(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(virNetworkPtr) networks = NULL; + guint flags; + GVariantBuilder builder; + GVariant *gnetworks; + + g_variant_get(inArgs, "(u)", &flags); + + if (!virtDBusConnectOpen(connect, error)) + return; + + if (virConnectListAllNetworks(connect->connection, &networks, flags) < 0) + return virtDBusUtilSetLastVirtError(error); + + if (!*networks) + return; + + g_variant_builder_init(&builder, G_VARIANT_TYPE("ao")); + + for (gint i = 0; networks[i]; i++) { + g_autofree gchar *path = NULL; + path = virtDBusUtilBusPathForVirNetwork(networks[i], + connect->networkPath); + + g_variant_builder_add(&builder, "o", path); + } + + gnetworks = g_variant_builder_end(&builder); + *outArgs = g_variant_new_tuple(&gnetworks, 1); +} + static virtDBusGDBusPropertyTable virtDBusConnectPropertyTable[] = { { "Version", virtDBusConnectGetVersion, NULL }, { 0 } @@ -292,6 +332,7 @@ static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = { { "DomainLookupByID", virtDBusDomainLookupByID }, { "DomainLookupByName", virtDBusDomainLookupByName }, { "DomainLookupByUUID", virtDBusDomainLookupByUUID }, + { "ListNetworks", virtDBusConnectListNetworks }, { 0 } }; -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- src/util.c | 13 +++++++++++++ src/util.h | 5 +++++ 2 files changed, 18 insertions(+) diff --git a/src/util.c b/src/util.c index fe40a96..03a0f10 100644 --- a/src/util.c +++ b/src/util.c @@ -152,6 +152,19 @@ virtDBusUtilEnumFromString(const gchar *const *types, return -1; } +virNetworkPtr +virtDBusUtilVirNetworkFromBusPath(virConnectPtr connection, + const gchar *path, + const gchar *networkPath) +{ + g_autofree gchar *name = NULL; + gsize prefixLen = strlen(networkPath) + 1; + + name = virtDBusUtilDecodeUUID(path+prefixLen); + + return virNetworkLookupByUUIDString(connection, name); +} + gchar * virtDBusUtilBusPathForVirNetwork(virNetworkPtr network, const gchar *networkPath) diff --git a/src/util.h b/src/util.h index fac080c..7bb4ad6 100644 --- a/src/util.h +++ b/src/util.h @@ -66,6 +66,11 @@ virtDBusUtilEnumToString(const gchar *const *types, const gchar *name ##TypeToString(gint type) G_GNUC_PURE; \ gint name ##TypeFromString(const gchar *type) G_GNUC_PURE; +virNetworkPtr +virtDBusUtilVirNetworkFromBusPath(virConnectPtr connection, + const gchar *path, + const gchar *networkPath); + gchar * virtDBusUtilBusPathForVirNetwork(virNetworkPtr network, const gchar *networkPath); -- 2.15.0

This commit also introduces the virtDBusNetworkGetVirNetwork static function which is needed for the virtDBusNetworkGetName. Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/org.libvirt.Network.xml | 4 ++++ src/network.c | 43 +++++++++++++++++++++++++++++++++++++++++++ test/Makefile.am | 3 ++- test/libvirttest.py | 12 ++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/data/org.libvirt.Network.xml b/data/org.libvirt.Network.xml index 2b7c4f7..1215ac3 100644 --- a/data/org.libvirt.Network.xml +++ b/data/org.libvirt.Network.xml @@ -3,5 +3,9 @@ <node name="/org/libvirt/network"> <interface name="org.libvirt.Network"> + <property name="Name" type="s" access="read"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetName"/> + </property> </interface> </node> diff --git a/src/network.c b/src/network.c index 0d0e992..fdfaaa7 100644 --- a/src/network.c +++ b/src/network.c @@ -3,7 +3,50 @@ #include <libvirt/libvirt.h> +static virNetworkPtr +virtDBusNetworkGetVirNetwork(virtDBusConnect *connect, + const gchar *objectPath, + GError **error) +{ + virNetworkPtr network; + + if (virtDBusConnectOpen(connect, error) < 0) + return NULL; + + network = virtDBusUtilVirNetworkFromBusPath(connect->connection, + objectPath, + connect->networkPath); + if (!network) { + virtDBusUtilSetLastVirtError(error); + return NULL; + } + + return network; +} + +static void +virtDBusNetworkGetName(const gchar *objectPath, + gpointer userData, + GVariant **value, + GError **error) +{ + virtDBusConnect *connect = userData; + g_autoptr(virNetwork) network = NULL; + const gchar *name; + + network = virtDBusNetworkGetVirNetwork(connect, objectPath, error); + if (!network) + return; + + name = virNetworkGetName(network); + if (!name) + return virtDBusUtilSetLastVirtError(error); + + *value = g_variant_new("s", name); +} + static virtDBusGDBusPropertyTable virtDBusNetworkPropertyTable[] = { + { "Name", virtDBusNetworkGetName, NULL }, { 0 } }; diff --git a/test/Makefile.am b/test/Makefile.am index acb2d33..089ade5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -4,7 +4,8 @@ test_helpers = \ test_programs = \ test_connect.py \ - test_domain.py + test_domain.py \ + test_network.py EXTRA_DIST = \ $(test_helpers) \ diff --git a/test/libvirttest.py b/test/libvirttest.py index c4dc96f..ecd8aef 100644 --- a/test/libvirttest.py +++ b/test/libvirttest.py @@ -70,3 +70,15 @@ class BaseTestClass(): 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): + """Fetch information for the test network from test driver + + Returns: + (dbus.proxies.ProxyObject, dbus.proxies.ProxyObject): + Test Network Object, Local proxy for the test Network Object. + + """ + path = self.connect.ListNetworks(0)[0] + obj = self.bus.get_object('org.libvirt', path) + return path, obj -- 2.15.0

Signed-off-by: Katerina Koukiou <kkoukiou@redhat.com> --- data/org.libvirt.Connect.xml | 6 ++++++ src/connect.c | 29 +++++++++++++++++++++++++++++ test/test_connect.py | 11 +++++++++++ 3 files changed, 46 insertions(+) diff --git a/data/org.libvirt.Connect.xml b/data/org.libvirt.Connect.xml index ac06875..2901ba5 100644 --- a/data/org.libvirt.Connect.xml +++ b/data/org.libvirt.Connect.xml @@ -56,5 +56,11 @@ <arg name="flags" type="u" direction="in"/> <arg name="networks" type="ao" direction="out"/> </method> + <method name="NetworkLookupByName"> + <annotation name="org.gtk.GDBus.DocString" + value="See https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkLookupByName"/> + <arg name="name" type="s" direction="in"/> + <arg name="network" type="o" direction="out"/> + </method> </interface> </node> diff --git a/src/connect.c b/src/connect.c index 13fdd20..a17e15c 100644 --- a/src/connect.c +++ b/src/connect.c @@ -320,6 +320,34 @@ virtDBusConnectListNetworks(GVariant *inArgs, *outArgs = g_variant_new_tuple(&gnetworks, 1); } +static void +virtDBusNetworkLookupByName(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(virNetwork) network = NULL; + g_autofree gchar *path = NULL; + const gchar *name; + + g_variant_get(inArgs, "(s)", &name); + + if (!virtDBusConnectOpen(connect, NULL)) + return; + + network = virNetworkLookupByName(connect->connection, name); + if (!network) + return virtDBusUtilSetLastVirtError(error); + + path = virtDBusUtilBusPathForVirNetwork(network, connect->networkPath); + + *outArgs = g_variant_new("(o)", path); +} + static virtDBusGDBusPropertyTable virtDBusConnectPropertyTable[] = { { "Version", virtDBusConnectGetVersion, NULL }, { 0 } @@ -333,6 +361,7 @@ static virtDBusGDBusMethodTable virtDBusConnectMethodTable[] = { { "DomainLookupByName", virtDBusDomainLookupByName }, { "DomainLookupByUUID", virtDBusDomainLookupByUUID }, { "ListNetworks", virtDBusConnectListNetworks }, + { "NetworkLookupByName", virtDBusNetworkLookupByName }, { 0 } }; diff --git a/test/test_connect.py b/test/test_connect.py index 5df7a5b..5f82259 100755 --- a/test/test_connect.py +++ b/test/test_connect.py @@ -74,6 +74,17 @@ class TestConnect(libvirttest.BaseTestClass): props = obj.GetAll('org.libvirt.Connect', dbus_interface=dbus.PROPERTIES_IFACE) assert isinstance(props[property_name], expected_type) + @pytest.mark.parametrize("lookup_method_name,lookup_item", [ + ("NetworkLookupByName", 'Name'), + ]) + 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() + 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 + if __name__ == '__main__': libvirttest.run() -- 2.15.0

On Wed, 2018-04-04 at 14:01 +0200, Katerina Koukiou wrote:
This patchset introduces also some basic methods and properties for Network interface. More functionality will be added in following patchsets. New functions are covered by the test suite.
Katerina Koukiou (5): Introduce Network Interface Implement ListNetworks method for Connect interface Implement virtDBusUtilVirNetworkFromBusPath helper function. Implement Name property for Network interface Implement NetworkLookupByName method for Connect interface
data/Makefile.am | 3 +- data/org.libvirt.Connect.xml | 12 +++++ data/org.libvirt.Network.xml | 11 +++++ src/Makefile.am | 3 +- src/connect.c | 75 ++++++++++++++++++++++++++++++ src/connect.h | 1 + src/network.c | 107 +++++++++++++++++++++++++++++++++++++++++++ src/network.h | 9 ++++ src/util.c | 33 +++++++++++++ src/util.h | 15 ++++++ test/Makefile.am | 3 +- test/libvirttest.py | 12 +++++ test/test_connect.py | 11 +++++
I forgot to git add the test_network.py file. I 'll repost.
13 files changed, 292 insertions(+), 3 deletions(-) create mode 100644 data/org.libvirt.Network.xml create mode 100644 src/network.c create mode 100644 src/network.h
participants (1)
-
Katerina Koukiou