[libvirt] [libvirt-qpid PATCH 3/3] Make libvirt-qpid a matahari agent

Zane Bitter zbitter at redhat.com
Tue Jul 12 16:29:18 UTC 2011


---
 AUTHORS              |    2 
 configure.ac         |    1 
 libvirt-qpid.spec    |    2 
 src/LibvirtAgent.cpp |   97 ++++++++++++++++++++++++
 src/LibvirtAgent.h   |   36 +++++++++
 src/Makefile.am      |    7 +-
 src/NodeWrap.cpp     |  203 +++++---------------------------------------------
 src/NodeWrap.h       |   22 +----
 8 files changed, 169 insertions(+), 201 deletions(-)
 create mode 100644 src/LibvirtAgent.cpp
 create mode 100644 src/LibvirtAgent.h

diff --git a/AUTHORS b/AUTHORS
index 367ea49..8af5aba 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -9,6 +9,6 @@ Patches have also been contributed by:
 
   Ted Ross              <tross at redhat.com>
 
-Conversion to QMFv2 API by:
+Conversion to matahari agent and QMFv2 API by:
 
   Zane Bitter           <zbitter at redhat.com>
diff --git a/configure.ac b/configure.ac
index 3896d9d..03bbb80 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,6 +21,7 @@ dnl Required minimum versions of all libs we depend on
 LIBVIRT_REQUIRED="4.4.0"
 
 PKG_CHECK_MODULES(XML, libxml-2.0)
+PKG_CHECK_MODULES([DEPS], [glib-2.0])
 
 AC_OUTPUT(Makefile src/Makefile doc/Makefile)
 
diff --git a/libvirt-qpid.spec b/libvirt-qpid.spec
index d64552d..c8a88fd 100644
--- a/libvirt-qpid.spec
+++ b/libvirt-qpid.spec
@@ -10,6 +10,7 @@ Requires: libxml2 >= 2.7.1
 Requires: qmf >= 0.5.790661
 Requires: qpid-cpp-client >= 0.10
 Requires: libvirt >= 0.4.4
+Requires: matahari-lib >= 0.4.1
 Requires(post):  /sbin/chkconfig
 Requires(preun): /sbin/chkconfig
 Requires(preun): initscripts
@@ -17,6 +18,7 @@ BuildRequires: qpid-cpp-client-devel >= 0.10
 BuildRequires: libxml2-devel >= 2.7.1
 BuildRequires: libvirt-devel >= 0.5.0
 BuildRequires: qmf-devel >= 0.5.790661
+BuildRequires: matahari-devel >= 0.4.1
 Url: http://libvirt.org/qpid
 
 %description
diff --git a/src/LibvirtAgent.cpp b/src/LibvirtAgent.cpp
new file mode 100644
index 0000000..deb77ca
--- /dev/null
+++ b/src/LibvirtAgent.cpp
@@ -0,0 +1,97 @@
+#include "LibvirtAgent.h"
+#include "NodeWrap.h"
+#include "Exception.h"
+
+#include <syslog.h>
+
+
+#define POLL_TIME_s 3
+
+
+static gboolean handleTimer(gpointer user_data)
+{
+    LibvirtAgent *agent = (LibvirtAgent *)user_data;
+    if (agent) {
+        agent->updateData();
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+int
+LibvirtAgent::setup(qmf::AgentSession session)
+{
+    _package.configure(session);
+    initErrorSchema(session);
+
+    _node = new NodeWrap(this);
+
+    _timer = g_timeout_add_seconds(POLL_TIME_s, &handleTimer, this);
+
+    return 0;
+}
+
+LibvirtAgent::~LibvirtAgent()
+{
+    if (_timer) {
+        g_source_remove(_timer);
+    }
+    delete _node;
+}
+
+void
+LibvirtAgent::addData(qmf::Data& data)
+{
+    _agent_session.addData(data);
+}
+
+void
+LibvirtAgent::delData(qmf::Data& data)
+{
+    _agent_session.delData(data.getAddr());
+}
+
+gboolean
+LibvirtAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event,
+                     gpointer user_data)
+{
+    if (event.getType() != qmf::AGENT_METHOD) {
+        return TRUE;
+    }
+
+    bool handled = _node->handleMethod(session, event);
+    if (!handled) {
+        raiseException(session, event,
+                       ERROR_UNKNOWN_OBJECT, STATUS_UNKNOWN_OBJECT);
+    }
+
+    return TRUE;
+}
+
+void
+LibvirtAgent::updateData(void)
+{
+    if (_node) {
+        _node->poll();
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    LibvirtAgent agent;
+
+    int rc = agent.init(argc, argv, "libvirt");
+
+    openlog("libvirt-qpid", 0, LOG_DAEMON);
+
+    // This prevents us from dying if libvirt disconnects.
+    signal(SIGPIPE, SIG_IGN);
+
+    if (rc == 0) {
+        agent.run();
+    }
+    return rc;
+}
+
diff --git a/src/LibvirtAgent.h b/src/LibvirtAgent.h
new file mode 100644
index 0000000..3b2a940
--- /dev/null
+++ b/src/LibvirtAgent.h
@@ -0,0 +1,36 @@
+#ifndef LIBVIRT_AGENT_H
+#define LIBVIRT_AGENT_H
+
+#include <matahari/mh_agent.h>
+#include "QmfPackage.h"
+#include "ManagedObject.h"
+
+
+class NodeWrap;
+
+
+class LibvirtAgent:
+    public MatahariAgent,
+    public PackageOwner<qmf::com::redhat::libvirt::PackageDefinition>
+{
+public:
+    ~LibvirtAgent();
+
+    int setup(qmf::AgentSession session);
+    gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event,
+		    gpointer user_data);
+
+    PackageDefinition& package(void) { return _package; }
+    void addData(qmf::Data& data);
+    void delData(qmf::Data& data);
+
+    void updateData(void);
+
+private:
+    PackageDefinition _package;
+    NodeWrap *_node;
+    int _timer;
+};
+
+#endif
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 4bb27b2..40d9371 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
 ## Process this file with automake to produce Makefile.in
 
-INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/libvirt $(XML_CFLAGS)
+INCLUDES = -I$(top_srcdir)/src/qmf/com/redhat/libvirt
 
 sbin_PROGRAMS = libvirt-qpid
 
@@ -11,6 +11,7 @@ generated_file_list = \
 nodist_libvirt_qpid_SOURCES = $(generated_file_list)
 
 libvirt_qpid_SOURCES = \
+	LibvirtAgent.cpp \
 	DomainWrap.cpp \
 	Error.cpp \
 	Exception.cpp \
@@ -18,6 +19,7 @@ libvirt_qpid_SOURCES = \
 	PoolWrap.cpp \
 	VolumeWrap.cpp \
 	ManagedObject.h \
+	LibvirtAgent.h \
 	DomainWrap.h \
 	Error.h \
 	Exception.h \
@@ -33,7 +35,8 @@ $(generated_file_list): .libvirt-schema.xml.tstamp
 BUILT_SOURCES = $(generated_file_list)
 CLEANFILES = $(generated_file_list) .libvirt-schema.xml.tstamp
 
-libvirt_qpid_LDADD = -lqmf2 -lqpidtypes -lqpidcommon -lqpidmessaging -lvirt $(XML_LIBS)
+libvirt_qpid_CXXFLAGS = $(XML_CFLAGS) $(DEPS_CFLAGS)
+libvirt_qpid_LDADD = -lqmf2 -lqpidtypes -lqpidcommon -lqpidmessaging -lmcommon -lmcommon_qmf -lvirt $(XML_LIBS) $(DEPS_LIBS)
 
 dist_pkgdata_DATA = libvirt-schema.xml
 
diff --git a/src/NodeWrap.cpp b/src/NodeWrap.cpp
index 40c4339..f68e666 100644
--- a/src/NodeWrap.cpp
+++ b/src/NodeWrap.cpp
@@ -4,7 +4,6 @@
 #include <errno.h>
 #include <unistd.h>
 #include <getopt.h>
-#include <syslog.h>
 #include <signal.h>
 #include <cstdio>
 
@@ -15,10 +14,10 @@
 #include "Exception.h"
 
 
-NodeWrap::NodeWrap(qmf::AgentSession& agent_session, PackageDefinition& package):
-    ManagedObject(package.data_node),
-    _session(agent_session),
-    _package(package)
+NodeWrap::NodeWrap(LibvirtAgent *agent):
+    PackageOwner<LibvirtAgent::PackageDefinition>(agent),
+    ManagedObject(package().data_node),
+    _agent(agent)
 {
     virNodeInfo info;
     char *hostname;
@@ -354,46 +353,27 @@ void NodeWrap::syncPools(void)
     }
 }
 
-void NodeWrap::doLoop()
+void
+NodeWrap::poll(void)
 {
-    fd_set fds;
-    struct timeval tv;
-    int retval;
-
-    /* Go through all domains and call update() for each, letting them update
-     * information and statistics. */
-    while (1) {
-        // We're using this to check to see if our connection is still good.
-        // I don't see any reason this call should fail unless there is some
-        // connection problem..
-        int maxname = virConnectNumOfDefinedDomains(_conn);
-        if (maxname < 0) {
-            return;
-        }
+    // We're using this to check to see if our connection is still good.
+    // I don't see any reason this call should fail unless there is some
+    // connection problem..
+    int maxname = virConnectNumOfDefinedDomains(_conn);
+    if (maxname < 0) {
+        return;
+    }
 
-        syncDomains();
-        syncPools();
-
-        for (DomainList::iterator iter = _domains.begin();
-                iter != _domains.end(); iter++) {
-            (*iter)->update();
-        }
-        for (PoolList::iterator iter = _pools.begin();
-                iter != _pools.end(); iter++) {
-            (*iter)->update();
-        }
-
-        qmf::AgentEvent event;
-        if (_session.nextEvent(event, qpid::messaging::Duration(3000))) {
-            if (event.getType() == qmf::AGENT_METHOD) {
-                bool handled = handleMethod(_session, event);
-                if (!handled) {
-                    raiseException(_session, event,
-                                   ERROR_UNKNOWN_OBJECT, STATUS_UNKNOWN_OBJECT);
-                }
-            }
-        }
+    syncDomains();
+    syncPools();
 
+    for (DomainList::iterator iter = _domains.begin();
+            iter != _domains.end(); iter++) {
+        (*iter)->update();
+    }
+    for (PoolList::iterator iter = _pools.begin();
+            iter != _pools.end(); iter++) {
+        (*iter)->update();
     }
 }
 
@@ -570,142 +550,3 @@ NodeWrap::handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event)
     }
 }
 
-static void
-print_usage()
-{
-    printf("Usage:\tlibvirt-qpid <options>\n");
-    printf("\t-d | --daemon     run as a daemon.\n");
-    printf("\t-h | --help       print this help message.\n");
-    printf("\t-b | --broker     specify broker host name..\n");
-    printf("\t-u | --username   username to use for authentication purproses.\n");
-    printf("\t-s | --service    service name to use for authentication purproses.\n");
-    printf("\t-p | --port       specify broker port.\n");
-}
-
-
-//==============================================================
-// Main program
-//==============================================================
-int main(int argc, char** argv) {
-    int arg;
-    int idx = 0;
-    bool verbose = false;
-    bool daemonize = false;
-    const char *host = NULL;
-    char *username = NULL;
-    char *service = NULL;
-    int port = 5672;
-
-    struct option opt[] = {
-        {"help", 0, 0, 'h'},
-        {"daemon", 0, 0, 'd'},
-        {"broker", 1, 0, 'b'},
-        {"username", 1, 0, 'u'},
-        {"service", 1, 0, 's'},
-        {"port", 1, 0, 'p'},
-        {0, 0, 0, 0}
-    };
-
-    while ((arg = getopt_long(argc, argv, "hdb:u:s:p:", opt, &idx)) != -1) {
-        switch (arg) {
-            case 'h':
-            case '?':
-                print_usage();
-                exit(0);
-                break;
-            case 'd':
-                daemonize = true;
-                break;
-            case 'v':
-                verbose = true;
-                break;
-            case 's':
-                if (optarg) {
-                    service = strdup(optarg);
-                } else {
-                    print_usage();
-                    exit(1);
-                }
-                break;
-            case 'u':
-                if (optarg) {
-                    username = strdup(optarg);
-                } else {
-                    print_usage();
-                    exit(1);
-                }
-                break;
-            case 'p':
-                if (optarg) {
-                    port = atoi(optarg);
-                } else {
-                    print_usage();
-                    exit(1);
-                }
-                break;
-            case 'b':
-                if (optarg) {
-                    host = strdup(optarg);
-                } else {
-                    print_usage();
-                    exit(1);
-                }
-                break;
-            default:
-                fprintf(stderr, "unsupported option '-%c'.  See --help.\n", arg);
-                print_usage();
-                exit(0);
-            break;
-        }
-    }
-
-    if (daemonize == true) {
-        if (daemon(0, 0) < 0) {
-            fprintf(stderr, "Error daemonizing: %s\n", strerror(errno));
-            exit(1);
-        }
-    }
-    openlog("libvirt-qpid", 0, LOG_DAEMON);
-
-    // This prevents us from dying if libvirt disconnects.
-    signal(SIGPIPE, SIG_IGN);
-
-    qpid::types::Variant::Map options;
-
-    if (username != NULL) {
-        options["username"] = username;
-    }
-    if (service != NULL) {
-        options["service"] = service;
-    }
-
-    if (host == NULL) {
-        host = "127.0.0.1";
-    }
-
-    std::stringstream url;
-
-    url << "amqp:" << "tcp" << ":" << host << ":" << port;
-
-    qpid::messaging::Connection amqp_connection(url.str(), options);
-    amqp_connection.open();
-
-    qmf::AgentSession session(amqp_connection);
-    session.setVendor("redhat.com");
-    session.setProduct("libvirt-qpid");
-    session.setAttribute("hostname", host);
-
-    session.open();
-    NodeWrap::PackageDefinition package;
-    package.configure(session);
-
-    initErrorSchema(session);
-
-    while (true) {
-        try {
-            NodeWrap node(session, package);
-            node.doLoop();
-        } catch (int err) { }
-        sleep(10);
-    }
-}
diff --git a/src/NodeWrap.h b/src/NodeWrap.h
index 6f55061..b1ee98a 100644
--- a/src/NodeWrap.h
+++ b/src/NodeWrap.h
@@ -1,8 +1,7 @@
 #ifndef NODE_WRAP_H
 #define NODE_WRAP_H
 
-#include "ManagedObject.h"
-#include "QmfPackage.h"
+#include "LibvirtAgent.h"
 
 #include <unistd.h>
 #include <cstdlib>
@@ -19,7 +18,7 @@ class DomainWrap;
 class PoolWrap;
 
 class NodeWrap:
-    public PackageOwner<qmf::com::redhat::libvirt::PackageDefinition>,
+    public PackageOwner<LibvirtAgent::PackageDefinition>,
     public ManagedObject
 {
     typedef std::vector<DomainWrap*> DomainList;
@@ -30,27 +29,16 @@ class NodeWrap:
 
     virConnectPtr _conn;
 
-    qmf::AgentSession& _session;
-    PackageDefinition& _package;
+    LibvirtAgent *_agent;
 
 public:
-    NodeWrap(qmf::AgentSession& agent_session, PackageDefinition& package);
+    NodeWrap(LibvirtAgent *agent);
     ~NodeWrap();
 
-    void doLoop();
+    void poll(void);
 
     bool handleMethod(qmf::AgentSession& session, qmf::AgentEvent& event);
 
-    virtual PackageDefinition& package(void) { return _package; }
-
-    virtual void addData(qmf::Data& data) {
-        _session.addData(data);
-    }
-
-    virtual void delData(qmf::Data& data) {
-        _session.delData(data.getAddr());
-    }
-
 protected:
     void syncDomains(void);
     void syncPools(void);




More information about the libvir-list mailing list