More coding guidelines
by Radek Novacek
I finally get to reformating the DBus code to match our coding guidelines.
When I was looking on the code I have found some more rules we might add to
the guidelines. This proposal uses the most frequent styles I've found in the
code.
* Control statements (if, else, while, for):
Keyword is followed by one space, then left parenthesis without space,
condition, right parenthesis, space, opening brace on same line. "else" and
"else if" are on same line with ending brace and opening brace, separated by
space.
if (condition1) {
statement1;
} else if (condition2) {
statement2;
} else {
statement3;
}
* Switch statement:
Cases have same indentation as switch. Body of cases is indented. Opening and
ending brace of switch are on separate lines.
switch (expression)
{
case 0:
command0;
break;
case 1:
command1;
break;
default:
command;
}
* Operators have spaces from both sides:
x = a + b * c;
* Classes:
Visibility modifiers have same indentation as the class, methods and
properties are indented. Name of the class should be Upper-CamelCase (first
letter of each word upper cased).
class TestClass : public ParentClass
{
private:
int x;
public:
void test();
};
If these (or some other) modification of the guidelines are accepted, I will
create the patch to adjust the code to match them.
Radek Novacek
13 years
Augeas-based configuration agent
by Radek Novacek
I finally published augeas-based agent. You can find it in my repo on github
[1]. It is now done as standalone agent out of matahari tree, but it should be
easy to integrate it into Matahari.
The agent is now called _conf_, but some better name would be great :)
Now how the agent works. For now it is only augeas API published to QMF/DBus
by Matahari agent. First step in using it is to call method `init` which
return number - handle (ID) of the session. This handle must be then passed to
all methods (it is an index to augeas structure returned by aug_init()).
Finally it must be closed by method `close` to avoid memory leaking.
Since those method aren't stateless there are some security issues. For
example: User creates his session, change some files and saves (after
authorization check by polkit). But all DBus communication is public, so
anyone can use same handle to changed other files before user saves. All
changes will be saved no matter who did them.
To aviod this issue two precautions were made. Init takes name of augeas' lens
as argument and won't load any other lenses. It should minimize the impact of
this issue, but it's a little bit hackish and user unfriendly (need to know
the name of the lens). Second precaution applies only to DBus agent (don't
know if it is doable with QMF). During init method the handle is connected
with DBus object name of the caller and all methods check if the caller is the
same. It might not be an issue for QMF because user must be authorized
_before_ connecting to the QMF.
Any suggestions are welcomed.
Radek Novacek
[1] https://github.com/rnovacek/matahari_conf
13 years
[PATCH] Turn on reconnect by default
by Adam Stokes
From: Adam Stokes <astokes(a)fedoraproject.org>
---
matahari.sysconf.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/matahari.sysconf.in b/matahari.sysconf.in
index 15282c2..b046192 100644
--- a/matahari.sysconf.in
+++ b/matahari.sysconf.in
@@ -1,3 +1,3 @@
-MATAHARI_AGENT_ARGS=""
+MATAHARI_AGENT_ARGS="-r"
MATAHARI_BROKER=@MATAHARI_BROKER@
MATAHARI_PORT=@MATAHARI_PORT@
--
1.7.4.4
13 years
[PATCH] service-qmf: Add a handle IO param to methods with an interval.
by russell@russellbryant.net
This patch adds a handle IO param to the status method for Services and
the monitor and invoke methods of Resources. If a handle is provided,
it is added to the method response as well as all events raised as a
result of this method call in the future.
In passing, add a couple of \todo notes about things that need to be
done to this agent.
Signed-off-by: Russell Bryant <russell(a)russellbryant.net>
---
src/schema.xml | 8 ++++++--
src/service/service-qmf.cpp | 25 ++++++++++++++++++++++---
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/src/schema.xml b/src/schema.xml
index ea82e4f..217fa4c 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -10,6 +10,7 @@
<arg name="name" type="sstr" />
<arg name="action" type="sstr" />
<arg name="interval" type="uint32"/>
+ <arg name="handle" type="sstr"/>
<arg name="rc" type="uint32" />
@@ -104,8 +105,8 @@
<!-- Is sequence needed? How to tie to the async method call seq? -->
<!-- Is timestamp needed? Possibly available for all events already -->
- <event name="service_op" args="name,action,interval,rc,sequence,timestamp" />
- <event name="resource_op" args="name,action,interval,rc,sequence,timestamp,rsc_type,rsc_class,rsc_provider" />
+ <event name="service_op" args="name,action,interval,rc,sequence,timestamp,handle" />
+ <event name="resource_op" args="name,action,interval,rc,sequence,timestamp,rsc_type,rsc_class,rsc_provider,handle" />
<class name="Services">
<property name="uuid" type="sstr" access="RO" desc="Host UUID" />
@@ -135,6 +136,7 @@
<arg name="interval" dir="IO" type="uint32" />
<arg name="timeout" dir="I" type="uint32" />
<arg name="rc" dir="O" type="uint32" />
+ <arg name="handle" dir="IO" type="sstr" />
</method>
<method name="cancel" desc="Cancel a pending or running action on a system service">
<arg name="name" dir="I" type="sstr" />
@@ -204,6 +206,7 @@
<arg name="parameters" dir="I" type="map" />
<arg name="timeout" dir="I" type="uint32" />
<arg name="rc" dir="O" type="uint32" />
+ <arg name="handle" dir="IO" type="sstr" />
</method>
<method name="invoke" desc="Perform a custom action on a resource">
<arg name="name" dir="IO" type="sstr" />
@@ -215,6 +218,7 @@
<arg name="parameters" dir="I" type="map" />
<arg name="timeout" dir="I" type="uint32" />
<arg name="rc" dir="O" type="uint32" />
+ <arg name="handle" dir="IO" type="sstr" />
</method>
<method name="cancel" desc="Cancel a pending or running action on a resource">
<arg name="name" dir="IO" type="sstr" />
diff --git a/src/service/service-qmf.cpp b/src/service/service-qmf.cpp
index 37017c0..a69ceb0 100644
--- a/src/service/service-qmf.cpp
+++ b/src/service/service-qmf.cpp
@@ -16,6 +16,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+/**
+ * \file
+ * \brief Matahari Services Agent
+ *
+ * \todo Add a way to cancel a method that is in progress and has not
+ * yet returned (not just one running periodically).
+ * \todo Add code to ensure that all IO parameters are being copied to
+ * responses.
+ */
+
#ifndef WIN32
#include "config.h"
#endif
@@ -63,7 +73,7 @@ class SrvAgent : public MatahariAgent
virtual int setup(qmf::AgentSession session);
virtual gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event,
gpointer user_data);
- void raiseEvent(svc_action_t *op, enum service_id service);
+ void raiseEvent(svc_action_t *op, enum service_id service, qmf::AgentEvent& method_call);
};
/**
@@ -108,6 +118,10 @@ AsyncCB::mh_async_callback(svc_action_t *op)
mh_trace("Completed: %s = %d\n", op->id, op->rc);
if (cb_data->first_result) {
+ qpid::types::Variant::Map& args = cb_data->event.getArguments();
+ if (args.count("handle") > 0) {
+ cb_data->event.addReturnArgument("handle", args["handle"]);
+ }
if (cb_data->has_rc) {
cb_data->event.addReturnArgument("rc", op->rc);
}
@@ -116,7 +130,7 @@ AsyncCB::mh_async_callback(svc_action_t *op)
} else if (cb_data->last_rc != op->rc) {
mh_trace("Result changed on recurring action: was '%d', now '%d'\n",
cb_data->last_rc, op->rc);
- cb_data->agent->raiseEvent(op, cb_data->service);
+ cb_data->agent->raiseEvent(op, cb_data->service, cb_data->event);
}
if (op->interval) { /* recurring action */
@@ -156,7 +170,7 @@ main(int argc, char **argv)
return rc;
}
-void SrvAgent::raiseEvent(svc_action_t *op, enum service_id service)
+void SrvAgent::raiseEvent(svc_action_t *op, enum service_id service, qmf::AgentEvent& method_call)
{
uint64_t timestamp = 0L;
qmf::Data event;
@@ -171,6 +185,11 @@ void SrvAgent::raiseEvent(svc_action_t *op, enum service_id service)
event = qmf::Data(_package.event_resource_op);
}
+ qpid::types::Variant::Map& args = method_call.getArguments();
+ if (args.count("handle") > 0) {
+ event.setProperty("handle", args["handle"]);
+ }
+
event.setProperty("name", op->rsc);
event.setProperty("action", op->action);
event.setProperty("interval", op->interval);
--
1.7.4.4
13 years
A console event monitor in Python
by russell@russellbryant.net
I know Adam already has some code that does this. I wrote this for fun
as an excuse to try out QMF in Python. I figured I'd share in case
anyone else found it useful.
---
src/utils/qmfeventmon.py | 96 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 96 insertions(+), 0 deletions(-)
create mode 100755 src/utils/qmfeventmon.py
diff --git a/src/utils/qmfeventmon.py b/src/utils/qmfeventmon.py
new file mode 100755
index 0000000..cdee2c5
--- /dev/null
+++ b/src/utils/qmfeventmon.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+'''QMF event monitor
+
+Copyright (C) 2011, Russell Bryant <russell(a)russellbryant.net>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This software is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+'''
+
+import sys
+import time
+from optparse import OptionParser
+import cqpid
+from qmf2 import ConsoleSession, ConsoleHandler
+
+
+SEVERITY_MAP = {
+ 0 : "EMERGENCY",
+ 1 : "ALERT",
+ 2 : "CRITICAL",
+ 3 : "ERROR",
+ 4 : "WARNING",
+ 5 : "NOTICE",
+ 6 : "INFO",
+ 7 : "DEBUG"
+}
+
+
+def severity_str(severity):
+ if severity in SEVERITY_MAP:
+ return SEVERITY_MAP[severity]
+ else:
+ return "UNKNOWN(%d)" % severity
+
+
+class EventConsole(ConsoleHandler):
+ def __init__(self, options):
+ self.options = options
+ self.conn = cqpid.Connection("%s:%d" % (self.options.broker,
+ self.options.port))
+ self.conn.open()
+ self.session = ConsoleSession(self.conn)
+ self.session.open()
+ ConsoleHandler.__init__(self, self.session)
+
+ def agentAdded(self, agent):
+ print "Agent added: %s\n" % agent
+
+ def agentDeleted(self, agent):
+ print "Agent deleted: %s\n" % agent
+
+ def eventRaised(self, agent, data, timestamp, severity):
+ print "Event [%s]:" % severity_str(severity)
+ print " ==> Agent: %s" % agent
+ print " ==> Timestamp: %s" % timestamp
+ print " ==> Data: %s\n" % data.getProperties()
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
+
+ parser = OptionParser()
+
+ parser.add_option("-b", "--broker", action="store", type="string",
+ dest="broker", default="127.0.0.1",
+ help="broker hostname or IP address")
+ parser.add_option("-p", "--port", action="store", type="int",
+ dest="port", default=49000,
+ help="broker port number")
+
+ (options, args) = parser.parse_args(argv)
+
+ console = EventConsole(options)
+
+ try:
+ console.run()
+ except (KeyboardInterrupt, SystemExit):
+ pass
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
--
1.7.4.4
13 years
[PATCH 1/2] Installation of dbus-to-c.xsl and verbose macro
by Radek Novacek
dbus-to-c.xsl is now installed so it can be used by external agents.
generate_dbus_headers macro is verbatim to made any errors visible.
Signed-off-by: Radek Novacek <rnovacek(a)redhat.com>
---
src/CMakeLists.txt | 1 +
src/cmake/modules/MatahariMacros.cmake | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ed379c0..4b3857c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -158,6 +158,7 @@ endif(WITH-QMF)
if(WITH-DBUS)
install(FILES schema-to-dbus.xsl DESTINATION share/matahari)
+ install(FILES dbus-to-c.xsl DESTINATION share/matahari)
install(FILES include/matahari/mh_dbus_common.h DESTINATION include/matahari)
install(FILES include/matahari/mh_gobject_class.h DESTINATION include/matahari)
endif(WITH-DBUS)
diff --git a/src/cmake/modules/MatahariMacros.cmake b/src/cmake/modules/MatahariMacros.cmake
index 3c5a428..2cd2232 100644
--- a/src/cmake/modules/MatahariMacros.cmake
+++ b/src/cmake/modules/MatahariMacros.cmake
@@ -7,6 +7,9 @@
macro(generate_dbus_headers API XML)
find_file(XSLTPROC xsltproc)
find_file(BIND_TOOL dbus-binding-tool)
+ find_file(DBUS_TO_C dbus-to-c.xsl
+ ${CMAKE_CURRENT_SOURCE_DIR}/..
+ /usr/share/matahari)
# Convert dbus interface to glue and properties files
add_custom_command(
@@ -15,14 +18,16 @@ macro(generate_dbus_headers API XML)
--output=${API}-dbus-glue.h
${XML}
COMMENT "Generating ${API}-dbus-glue.h"
+ VERBATIM
)
add_custom_command(
OUTPUT ${API}-dbus-properties.h
COMMAND ${XSLTPROC} --output ${API}-dbus-properties.h
- ${CMAKE_CURRENT_SOURCE_DIR}/../dbus-to-c.xsl
+ ${DBUS_TO_C}
${XML}
COMMENT "Generating ${API}-dbus-properties.h"
+ VERBATIM
)
endmacro(generate_dbus_headers)
--
1.7.5.1
13 years
[PATCH] Config Agent and Console Agent v2
by Adam Stokes
From: Adam Stokes <astokes(a)fedoraproject.org>
Sigh... this actually contains the rest of the code I didn't add during the merge
- Config agent will provide a method for telling the Console agent if it was configured or not. At this time it creates a file /tmp/.mh_configured and tests if this file exists and responds accordingly.
- Console agent monitors when an Agent connects and will query that agent to make sure it is of class: Config under package:org.matahariproject. If that is the case it will then invoke the method configure on the agent which provides the above response.
Pretty straight forward and we can expand on arguements or other methods if needed.
Signed-off-by: Adam Stokes <astokes(a)fedoraproject.org>
---
src/CMakeLists.txt | 2 +
src/config/CMakeLists.txt | 20 +++++++
src/config/config-qmf.cpp | 99 ++++++++++++++++++++++++++++++++
src/console/CMakeLists.txt | 18 ++++++
src/console/matahari-console.cpp | 84 +++++++++++++++++++++++++++
src/include/matahari/mh_agent_config.h | 33 +++++++++++
src/lib/CMakeLists.txt | 6 ++-
src/lib/mh_agent_config.c | 48 +++++++++++++++
src/schema.xml | 12 +++-
9 files changed, 319 insertions(+), 3 deletions(-)
create mode 100644 src/config/CMakeLists.txt
create mode 100644 src/config/config-qmf.cpp
create mode 100644 src/console/CMakeLists.txt
create mode 100644 src/console/matahari-console.cpp
create mode 100644 src/include/matahari/mh_agent_config.h
create mode 100644 src/lib/mh_agent_config.c
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b55f339..dfc2fa6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -117,6 +117,8 @@ add_subdirectory(lib)
add_subdirectory(host)
add_subdirectory(network)
add_subdirectory(service)
+add_subdirectory(console)
+add_subdirectory(config)
### Installation
install(FILES ${SCHEMAS} DESTINATION share/matahari)
diff --git a/src/config/CMakeLists.txt b/src/config/CMakeLists.txt
new file mode 100644
index 0000000..8e4f810
--- /dev/null
+++ b/src/config/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(BASE "config")
+set(BASE_LIB "m${BASE}")
+set(QMF_AGENT "matahari-qmf-${BASE}d")
+
+# QMF daemon
+if(WITH-QMF)
+ add_executable(${QMF_AGENT} ${BASE}-qmf.cpp ${SCHEMA_SOURCES})
+ target_link_libraries(${QMF_AGENT} ${BASE_LIB} mcommon mcommon_qmf)
+
+ target_link_libraries(${QMF_AGENT} ${QPIDCOMMON_LIBRARY} ${QPIDCLIENT_LIBRARY} ${QPIDMESSAGING_LIBRARY} ${QMF2_LIBRARY})
+ if(QPIDTYPES_LIBRARY)
+ target_link_libraries(${QMF_AGENT} ${QPIDTYPES_LIBRARY})
+ endif(QPIDTYPES_LIBRARY)
+
+ if(WIN32)
+ target_link_libraries(${QMF_AGENT} wsock32)
+ endif(WIN32)
+
+ install(TARGETS ${QMF_AGENT} DESTINATION sbin)
+endif(WITH-QMF)
diff --git a/src/config/config-qmf.cpp b/src/config/config-qmf.cpp
new file mode 100644
index 0000000..bf8963c
--- /dev/null
+++ b/src/config/config-qmf.cpp
@@ -0,0 +1,99 @@
+/* config-qmf.cpp - Copyright (C) 2011 Red Hat, Inc.
+ * Written by Adam Stokes <astokes(a)fedoraproject.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef WIN32
+#include "config.h"
+#endif
+
+#include "matahari/mh_agent.h"
+
+#include "qmf/org/matahariproject/QmfPackage.h"
+
+#include <qpid/agent/ManagementAgent.h>
+
+extern "C" {
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "matahari/mh_agent_config.h"
+#include "matahari/logging.h"
+#include "matahari/network.h"
+#include "matahari/host.h"
+#include <sigar.h>
+#include <sigar_format.h>
+};
+
+class ConfigAgent : public MatahariAgent
+{
+private:
+ qmf::org::matahariproject::PackageDefinition _package;
+public:
+ virtual int setup(qmf::AgentSession session);
+ virtual gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event,
+ gpointer user_data);
+};
+
+int
+main(int argc, char **argv)
+{
+ ConfigAgent agent;
+ int rc = agent.init(argc, argv, "Config");
+ if (rc == 0) {
+ agent.run();
+ }
+ return rc;
+}
+
+int
+ConfigAgent::setup(qmf::AgentSession session)
+{
+ _package.configure(session);
+ _instance = qmf::Data(_package.data_Config);
+
+ _instance.setProperty("hostname", mh_hostname());
+ _instance.setProperty("uuid", mh_uuid());
+ _instance.setProperty("configured", mh_is_configured());
+
+ _agent_session.addData(_instance);
+ return 0;
+}
+
+gboolean
+ConfigAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event, gpointer user_data)
+{
+ if (event.getType() != qmf::AGENT_METHOD) {
+ session.methodSuccess(event);
+ return TRUE;
+ }
+
+ const std::string& methodName(event.getMethodName());
+
+ if (methodName == "configure") {
+ int rc = mh_is_configured();
+ event.addReturnArgument("configured", rc);
+ } else {
+ session.raiseException(event, MH_NOT_IMPLEMENTED);
+ goto bail;
+ }
+
+ session.methodSuccess(event);
+
+bail:
+ return TRUE;
+}
diff --git a/src/console/CMakeLists.txt b/src/console/CMakeLists.txt
new file mode 100644
index 0000000..31645ff
--- /dev/null
+++ b/src/console/CMakeLists.txt
@@ -0,0 +1,18 @@
+set(CONSOLE_QMF "matahari-qmf-consoled")
+
+# QMF daemon
+if(WITH-QMF)
+ add_executable(${CONSOLE_QMF} matahari-console.cpp)
+ target_link_libraries(${CONSOLE_QMF} mcommon mcommon_qmf)
+
+ target_link_libraries(${CONSOLE_QMF} ${QPIDCOMMON_LIBRARY} ${QPIDCLIENT_LIBRARY} ${QPIDMESSAGING_LIBRARY} ${QMF2_LIBRARY})
+ if(QPIDTYPES_LIBRARY)
+ target_link_libraries(${CONSOLE_QMF} ${QPIDTYPES_LIBRARY})
+ endif(QPIDTYPES_LIBRARY)
+
+ if(WIN32)
+ target_link_libraries(${CONSOLE_QMF} wsock32)
+ endif(WIN32)
+
+ install(TARGETS ${CONSOLE_QMF} DESTINATION sbin)
+endif(WITH-QMF)
diff --git a/src/console/matahari-console.cpp b/src/console/matahari-console.cpp
new file mode 100644
index 0000000..5b0cf15
--- /dev/null
+++ b/src/console/matahari-console.cpp
@@ -0,0 +1,84 @@
+/* matahari-console.cpp - Copyright (c) 2011 Red Hat, Inc.
+ * Written by Adam Stokes <astokes(a)fedoraproject.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef WIN32
+#include "config.h"
+#endif
+
+#include <qpid/messaging/Connection.h>
+#include <qpid/messaging/Duration.h>
+#include <qmf/ConsoleSession.h>
+#include <qmf/ConsoleEvent.h>
+#include <qmf/Agent.h>
+#include <qmf/Data.h>
+#include <qmf/DataAddr.h>
+#include <qmf/Query.h>
+#include <qpid/types/Variant.h>
+
+#include "qmf/org/matahariproject/QmfPackage.h"
+
+#include <string>
+#include <iostream>
+
+using namespace std;
+using namespace qmf;
+using qpid::types::Variant;
+using qpid::messaging::Duration;
+
+int main(int argc, char** argv)
+{
+ string url("amqp:tcp:127.0.0.1:49000");
+ const string methodName("configure");
+ qpid::types::Variant::Map connectionOptions;
+ qpid::types::Variant::Map dataProperties;
+ string sessionOptions;
+
+ connectionOptions["reconnect"] = false;
+
+ qpid::messaging::Connection connection(url, connectionOptions);
+ connection.open();
+
+ ConsoleSession session(connection, sessionOptions);
+ session.open();
+
+ Agent agent;
+ while (true) {
+ ConsoleEvent event;
+ if(session.nextEvent(event)) {
+ switch(event.getType()) {
+ case CONSOLE_AGENT_ADD:
+ {
+ cout << "Agent added : " << event.getAgent().getName() << endl;
+ agent = event.getAgent();
+ ConsoleEvent result(agent.query("{class:Config, package:'org.matahariproject'}"));
+ if(result.getDataCount() == 1) {
+ const Data& data(result.getData(0));
+ dataProperties = data.getProperties();
+ cout << "data : " << dataProperties << endl;
+ ConsoleEvent result(agent.callMethod(methodName, dataProperties, data.getAddr(), qpid::messaging::Duration(4000)));
+ } else {
+ cout << "No objects in query" << endl;
+ }
+ }
+ break;
+ default: {}
+ }
+ }
+ }
+ return 0;
+}
diff --git a/src/include/matahari/mh_agent_config.h b/src/include/matahari/mh_agent_config.h
new file mode 100644
index 0000000..2e21fe7
--- /dev/null
+++ b/src/include/matahari/mh_agent_config.h
@@ -0,0 +1,33 @@
+/* host.h - Copyright (C) 2009 Red Hat, Inc.
+ * Written by Arjun Roy <arroy(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/**
+ * \file
+ * \brief Config API
+ * \ingroup coreapi
+ */
+
+#ifndef __MH_CONFIG_H__
+#define __MH_CONFIG_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+extern uint32_t mh_is_configured(void);
+
+#endif // __MH_CONFIG_H__
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 2538517..38485d3 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -1,6 +1,6 @@
# Library
-set(LIBS mcommon mhost mnetwork mservice)
+set(LIBS mcommon mhost mnetwork mservice mconfig)
include_directories(${pcre_INCLUDE_DIRS})
add_library (mcommon SHARED utilities.c mainloop.c)
@@ -19,6 +19,10 @@ add_library (mservice SHARED services.c services_${VARIANT}.c)
set_target_properties(mservice PROPERTIES SOVERSION 0.0.1)
target_link_libraries(mservice ${pcre_LIBRARIES} mcommon ${SIGAR} ${glib_LIBRARIES})
+add_library (mconfig SHARED mh_agent_config.c)
+set_target_properties(mconfig PROPERTIES SOVERSION 0.0.1)
+target_link_libraries(mconfig ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES})
+
if(WIN32)
foreach (lib ${LIBS})
target_link_libraries(${lib} wsock32)
diff --git a/src/lib/mh_agent_config.c b/src/lib/mh_agent_config.c
new file mode 100644
index 0000000..a38b5c0
--- /dev/null
+++ b/src/lib/mh_agent_config.c
@@ -0,0 +1,48 @@
+/* mh_agent_config.c - Copyright (C) 2011 Red Hat, Inc.
+ * Written by Adam Stokes <astokes(a)fedoraproject.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef WIN32
+#include "config.h"
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <glib.h>
+#include <glib/gprintf.h>
+#include "matahari/mh_agent_config.h"
+#include "matahari/logging.h"
+
+MH_TRACE_INIT_DATA(mh_config);
+
+uint32_t mh_is_configured(void)
+{
+ int config_file_exist = 0;
+ const char *filename = "/tmp/.mh_configured";
+ const char *contents = "I've been configured.";
+
+ if(!g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ if(!g_file_set_contents(filename, contents, -1, NULL)) {
+ mh_log(LOG_DEBUG, "Unable to create file.");
+ }
+ config_file_exist = 1;
+ } else {
+ config_file_exist = 1;
+ }
+ return config_file_exist;
+}
diff --git a/src/schema.xml b/src/schema.xml
index ea82e4f..8446490 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -90,7 +90,7 @@
<arg name="iface" dir="I" type="sstr" />
<arg name="status" dir="O" type="uint32" />
</method>
- <method name="get_ip_address" desc="Obtain ip addressof a network interface">
+ <method name="get_ip_address" desc="Obtain ip address of a network interface">
<arg name="iface" dir="I" type="sstr" />
<arg name="ip" dir="O" type="sstr" />
</method>
@@ -243,5 +243,13 @@
<arg name="timeout" dir="O" type="uint32" />
</method-->
</class>
-
+
+ <event name="configure_me" args="ip,sequence,timestamp" />
+
+ <class name="Config">
+ <property name="uuid" type="sstr" access="RO" desc="Host UUID" />
+ <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y"/>
+ <property name="configured" type="uint32" access="RO" desc="Am I configured?" />
+ <method name="configure" desc="Send configure method" />
+ </class>
</schema>
--
1.7.4.4
13 years
[PATCH] service-qmf: Process more methods asynchronously.
by russell@russellbryant.net
Process more methods asynchronously. Specifically:
Services - enable, disable, start, stop, status
Resources - start, stop, monitor, invoke
Signed-off-by: Russell Bryant <russell(a)russellbryant.net>
---
src/service/service-qmf.cpp | 95 +++++++++++++++++++++----------------------
1 files changed, 47 insertions(+), 48 deletions(-)
diff --git a/src/service/service-qmf.cpp b/src/service/service-qmf.cpp
index 05a74c7..06c670f 100644
--- a/src/service/service-qmf.cpp
+++ b/src/service/service-qmf.cpp
@@ -37,11 +37,17 @@ extern "C" {
#include "matahari/services.h"
}
-enum service_id { SRV_RESOURCES, SRV_SERVICES };
+enum service_id {
+ SRV_RESOURCES,
+ SRV_SERVICES
+};
class SrvAgent : public MatahariAgent
{
private:
+ void action_async(enum service_id service, qmf::AgentSession& session,
+ qmf::AgentEvent& event, svc_action_t *op, bool has_rc);
+
qmf::Data _services;
qmf::DataAddr _services_addr;
@@ -69,9 +75,10 @@ class SrvAgent : public MatahariAgent
class AsyncCB {
public:
AsyncCB(SrvAgent *_agent, enum service_id _service,
- qmf::AgentSession& _session, qmf::AgentEvent& _event) :
+ qmf::AgentSession& _session, qmf::AgentEvent& _event,
+ bool _has_rc) :
agent(_agent), service(_service), session(_session), event(_event),
- last_rc(0), first_result(true) {};
+ has_rc(_has_rc), last_rc(0), first_result(true) {};
~AsyncCB() {};
static void mh_async_callback(svc_action_t *op);
@@ -84,6 +91,9 @@ public:
qmf::AgentSession session;
/** The method call that initiated this async action */
qmf::AgentEvent event;
+ /** Whether or not this method has an rc output param. */
+ bool has_rc;
+
/** The last result code for recurring actions */
int last_rc;
/** true if this is the first callback. */
@@ -98,7 +108,9 @@ AsyncCB::mh_async_callback(svc_action_t *op)
mh_trace("Completed: %s = %d\n", op->id, op->rc);
if (cb_data->first_result) {
- cb_data->event.addReturnArgument("rc", op->rc);
+ if (cb_data->has_rc) {
+ cb_data->event.addReturnArgument("rc", op->rc);
+ }
cb_data->session.methodSuccess(cb_data->event);
cb_data->first_result = false;
} else if (cb_data->last_rc != op->rc) {
@@ -213,6 +225,13 @@ SrvAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event, gpointer user
return TRUE;
}
+void
+SrvAgent::action_async(enum service_id service, qmf::AgentSession& session,
+ qmf::AgentEvent& event, svc_action_t *op, bool has_rc)
+{
+ op->cb_data = new AsyncCB(this, SRV_SERVICES, session, event, has_rc);
+ services_action_async(op, AsyncCB::mh_async_callback);
+}
gboolean
SrvAgent::invoke_services(qmf::AgentSession session, qmf::AgentEvent event, gpointer user_data)
@@ -241,45 +260,39 @@ SrvAgent::invoke_services(qmf::AgentSession session, qmf::AgentEvent event, gpoi
svc_action_t * op = services_action_create(
args["name"].asString().c_str(), "enable", 0,
default_timeout_ms);
- services_action_sync(op);
- services_action_free(op);
+
+ action_async(SRV_SERVICES, session, event, op, false);
+ async = true;
} else if (methodName == "disable") {
svc_action_t * op = services_action_create(
args["name"].asString().c_str(), "disable", 0,
default_timeout_ms);
- services_action_sync(op);
- services_action_free(op);
+
+ action_async(SRV_SERVICES, session, event, op, false);
+ async = true;
} else if (methodName == "start") {
svc_action_t *op = services_action_create(
args["name"].asString().c_str(), "start", 0, args["timeout"]);
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
+
+ action_async(SRV_SERVICES, session, event, op, true);
+ async = true;
} else if (methodName == "stop") {
svc_action_t * op = services_action_create(
args["name"].asString().c_str(), "stop", 0, args["timeout"]);
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
+
+ action_async(SRV_SERVICES, session, event, op, true);
+ async = true;
} else if (methodName == "status") {
svc_action_t *op = services_action_create(
args["name"].asString().c_str(), "status", args["interval"],
args["timeout"]);
- if(args["interval"]) {
- op->cb_data = new AsyncCB(this, SRV_SERVICES, session, event);
- services_action_async(op, AsyncCB::mh_async_callback);
- async = true;
-
- } else {
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
- }
+ action_async(SRV_SERVICES, session, event, op, true);
+ async = true;
} else if (methodName == "cancel") {
services_action_cancel(
@@ -344,9 +357,9 @@ SrvAgent::invoke_resources(qmf::AgentSession session, qmf::AgentEvent event, gpo
args["provider"].asString().c_str(),
args["type"].asString().c_str(),
"start", 0, args["timeout"], params);
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
+
+ action_async(SRV_RESOURCES, session, event, op, true);
+ async = true;
} else if (methodName == "stop") {
GHashTable *params = qmf_map_to_hash(args["parameters"].asMap());
@@ -355,9 +368,9 @@ SrvAgent::invoke_resources(qmf::AgentSession session, qmf::AgentEvent event, gpo
args["provider"].asString().c_str(),
args["type"].asString().c_str(),
"stop", 0, args["timeout"], params);
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
+
+ action_async(SRV_RESOURCES, session, event, op, true);
+ async = true;
} else if (methodName == "monitor") {
GHashTable *params = qmf_map_to_hash(args["parameters"].asMap());
@@ -367,16 +380,9 @@ SrvAgent::invoke_resources(qmf::AgentSession session, qmf::AgentEvent event, gpo
args["type"].asString().c_str(),
"monitor", args["interval"], args["timeout"], params);
- if(op->interval) {
- op->cb_data = new AsyncCB(this, SRV_RESOURCES, session, event);
- services_action_async(op, AsyncCB::mh_async_callback);
- async = true;
+ action_async(SRV_RESOURCES, session, event, op, true);
+ async = true;
- } else {
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
- }
} else if (methodName == "invoke") {
GHashTable *params = qmf_map_to_hash(args["parameters"].asMap());
svc_action_t *op = resources_action_create(
@@ -386,16 +392,9 @@ SrvAgent::invoke_resources(qmf::AgentSession session, qmf::AgentEvent event, gpo
args["action"].asString().c_str(),
args["interval"], args["timeout"], params);
- if(op->interval) {
- op->cb_data = new AsyncCB(this, SRV_RESOURCES, session, event);
- services_action_async(op, AsyncCB::mh_async_callback);
- async = true;
+ action_async(SRV_RESOURCES, session, event, op, true);
+ async = true;
- } else {
- services_action_sync(op);
- event.addReturnArgument("rc", op->rc);
- services_action_free(op);
- }
} else if (methodName == "cancel") {
services_action_cancel(
args["name"].asString().c_str(),
--
1.7.4.4
13 years
[PATCH] Config Agent and Console Agent
by Adam Stokes
From: Adam Stokes <astokes(a)fedoraproject.org>
- Config agent will provide a method for telling the Console agent if it was configured or not. At this time it creates a file /tmp/.mh_configured and tests if this file exists and responds accordingly.
- Console agent monitors when an Agent connects and will query that agent to make sure it is of class: Config under package:org.matahariproject. If that is the case it will then invoke the method configure on the agent which provides the above response.
Pretty straight forward and we can expand on arguements or other methods if needed.
---
src/CMakeLists.txt | 2 ++
src/lib/CMakeLists.txt | 6 +++++-
src/schema.xml | 12 ++++++++++--
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b55f339..dfc2fa6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -117,6 +117,8 @@ add_subdirectory(lib)
add_subdirectory(host)
add_subdirectory(network)
add_subdirectory(service)
+add_subdirectory(console)
+add_subdirectory(config)
### Installation
install(FILES ${SCHEMAS} DESTINATION share/matahari)
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 2538517..38485d3 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -1,6 +1,6 @@
# Library
-set(LIBS mcommon mhost mnetwork mservice)
+set(LIBS mcommon mhost mnetwork mservice mconfig)
include_directories(${pcre_INCLUDE_DIRS})
add_library (mcommon SHARED utilities.c mainloop.c)
@@ -19,6 +19,10 @@ add_library (mservice SHARED services.c services_${VARIANT}.c)
set_target_properties(mservice PROPERTIES SOVERSION 0.0.1)
target_link_libraries(mservice ${pcre_LIBRARIES} mcommon ${SIGAR} ${glib_LIBRARIES})
+add_library (mconfig SHARED mh_agent_config.c)
+set_target_properties(mconfig PROPERTIES SOVERSION 0.0.1)
+target_link_libraries(mconfig ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES})
+
if(WIN32)
foreach (lib ${LIBS})
target_link_libraries(${lib} wsock32)
diff --git a/src/schema.xml b/src/schema.xml
index ea82e4f..8446490 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -90,7 +90,7 @@
<arg name="iface" dir="I" type="sstr" />
<arg name="status" dir="O" type="uint32" />
</method>
- <method name="get_ip_address" desc="Obtain ip addressof a network interface">
+ <method name="get_ip_address" desc="Obtain ip address of a network interface">
<arg name="iface" dir="I" type="sstr" />
<arg name="ip" dir="O" type="sstr" />
</method>
@@ -243,5 +243,13 @@
<arg name="timeout" dir="O" type="uint32" />
</method-->
</class>
-
+
+ <event name="configure_me" args="ip,sequence,timestamp" />
+
+ <class name="Config">
+ <property name="uuid" type="sstr" access="RO" desc="Host UUID" />
+ <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y"/>
+ <property name="configured" type="uint32" access="RO" desc="Am I configured?" />
+ <method name="configure" desc="Send configure method" />
+ </class>
</schema>
--
1.7.4.4
13 years
[PATCH] Config Agent and Console Agent
by Adam Stokes
From: Adam Stokes <astokes(a)fedoraproject.org>
- Config agent will provide a method for telling the Console agent if it was configured or not. At this time it creates a file /tmp/.mh_configured and tests if this file exists and responds accordingly.
- Console agent monitors when an Agent connects and will query that agent to make sure it is of class: Config under package:org.matahariproject. If that is the case it will then invoke the method configure on the agent which provides the above response.
Pretty straight forward and we can expand on arguements or other methods if needed.
---
src/CMakeLists.txt | 2 ++
src/lib/CMakeLists.txt | 6 +++++-
src/schema.xml | 12 ++++++++++--
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b55f339..dfc2fa6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -117,6 +117,8 @@ add_subdirectory(lib)
add_subdirectory(host)
add_subdirectory(network)
add_subdirectory(service)
+add_subdirectory(console)
+add_subdirectory(config)
### Installation
install(FILES ${SCHEMAS} DESTINATION share/matahari)
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 2538517..38485d3 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -1,6 +1,6 @@
# Library
-set(LIBS mcommon mhost mnetwork mservice)
+set(LIBS mcommon mhost mnetwork mservice mconfig)
include_directories(${pcre_INCLUDE_DIRS})
add_library (mcommon SHARED utilities.c mainloop.c)
@@ -19,6 +19,10 @@ add_library (mservice SHARED services.c services_${VARIANT}.c)
set_target_properties(mservice PROPERTIES SOVERSION 0.0.1)
target_link_libraries(mservice ${pcre_LIBRARIES} mcommon ${SIGAR} ${glib_LIBRARIES})
+add_library (mconfig SHARED mh_agent_config.c)
+set_target_properties(mconfig PROPERTIES SOVERSION 0.0.1)
+target_link_libraries(mconfig ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES})
+
if(WIN32)
foreach (lib ${LIBS})
target_link_libraries(${lib} wsock32)
diff --git a/src/schema.xml b/src/schema.xml
index ea82e4f..8446490 100644
--- a/src/schema.xml
+++ b/src/schema.xml
@@ -90,7 +90,7 @@
<arg name="iface" dir="I" type="sstr" />
<arg name="status" dir="O" type="uint32" />
</method>
- <method name="get_ip_address" desc="Obtain ip addressof a network interface">
+ <method name="get_ip_address" desc="Obtain ip address of a network interface">
<arg name="iface" dir="I" type="sstr" />
<arg name="ip" dir="O" type="sstr" />
</method>
@@ -243,5 +243,13 @@
<arg name="timeout" dir="O" type="uint32" />
</method-->
</class>
-
+
+ <event name="configure_me" args="ip,sequence,timestamp" />
+
+ <class name="Config">
+ <property name="uuid" type="sstr" access="RO" desc="Host UUID" />
+ <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y"/>
+ <property name="configured" type="uint32" access="RO" desc="Am I configured?" />
+ <method name="configure" desc="Send configure method" />
+ </class>
</schema>
--
1.7.4.4
13 years