[PATCH] Broker: rhbz#735425 - Implement broker federation
by Zane Bitter
Replace the broker wrapper script with a C wrapper that calls execve() on
qpidd. Implement parsing of the MATAHARI_PORT environment variable and the
Broker Federation options in the C wrapper.
Broker federation is configured using the BROKER_FEDERATION environment
variable set in /etc/sysconfig/matahari-broker. The contents of the
variable should be a list of hosts or DNS SRV queries separated by any
combinations of spaces, commas and/or semicolons.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
CMakeLists.txt | 12 +++--
matahari-broker.init.in | 9 +++-
matahari-broker.service | 19 --------
matahari-broker.service.in | 22 +++++++++
matahari-broker.sysconf.in | 23 +++++-----
matahari-brokerd.in | 8 ---
src/CMakeLists.txt | 1
src/broker/CMakeLists.txt | 16 +++++++
src/broker/broker.c | 74 ++++++++++++++++++++++++++++++++
src/broker/broker.h | 12 +++++
src/broker/broker_federation.c | 93 ++++++++++++++++++++++++++++++++++++++++
src/broker/broker_federation.h | 6 +++
src/broker/broker_linux.c | 53 +++++++++++++++++++++++
src/broker/broker_os.h | 15 ++++++
src/include/config.h.in | 2 +
15 files changed, 319 insertions(+), 46 deletions(-)
delete mode 100644 matahari-broker.service
create mode 100644 matahari-broker.service.in
delete mode 100644 matahari-brokerd.in
create mode 100644 src/broker/CMakeLists.txt
create mode 100644 src/broker/broker.c
create mode 100644 src/broker/broker.h
create mode 100644 src/broker/broker_federation.c
create mode 100644 src/broker/broker_federation.h
create mode 100644 src/broker/broker_linux.c
create mode 100644 src/broker/broker_os.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7555b4..4ec2d1e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -109,9 +109,6 @@ else(WIN32)
set (CPACK_GENERATOR "TGZ")
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari-brokerd.in
- ${CMAKE_CURRENT_BINARY_DIR}/matahari-brokerd)
-
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari.init.in
${CMAKE_CURRENT_BINARY_DIR}/matahari.init)
@@ -126,8 +123,6 @@ else(WIN32)
GROUP_READ GROUP_WRITE GROUP_EXECUTE)
install(CODE "execute_process(COMMAND chown root:qpidd ${localstatedir}/lib/matahari)")
- install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-brokerd DESTINATION sbin)
-
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker DESTINATION ${initdir})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/matahari.sysconf DESTINATION ${sysconfdir}/sysconfig RENAME matahari)
@@ -142,8 +137,13 @@ else(WIN32)
if(systemd_FOUND)
set(systemdunitdir "/lib/systemd/system")
- install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/matahari-broker.service DESTINATION ${systemdunitdir})
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari-broker.service.in
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker.service)
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker.service DESTINATION ${systemdunitdir})
endif(systemd_FOUND)
+
endif(WIN32)
INCLUDE(InstallRequiredSystemLibraries)
diff --git a/matahari-broker.init.in b/matahari-broker.init.in
index e74926c..d9ca4ee 100755
--- a/matahari-broker.init.in
+++ b/matahari-broker.init.in
@@ -46,12 +46,19 @@ pidfile=@localstatedir(a)/run/matahari-broker.pid
# Source function library.
. @sysconfdir(a)/rc.d/init.d/functions
+if [ -f @sysconfdir@/sysconfig/matahari ]; then
+ . @sysconfdir@/sysconfig/matahari
+fi
+if [ -f @sysconfdir@/sysconfig/matahari-broker ]; then
+ . @sysconfdir@/sysconfig/matahari-broker
+fi
+
RETVAL=0
start() {
echo -n $"Starting Matahari broker daemon: "
install -o root -g qpidd -m 775 -d @localstatedir@/run/matahari
- daemon --pidfile $pidfile --check $proc --user qpidd /usr/sbin/$prog --daemon
+ daemon --pidfile $pidfile --check $proc --user qpidd /usr/sbin/$prog $QPIDD_OPTIONS --daemon
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch $lockfile
diff --git a/matahari-broker.service b/matahari-broker.service
deleted file mode 100644
index 7e6e9f7..0000000
--- a/matahari-broker.service
+++ /dev/null
@@ -1,19 +0,0 @@
-[Unit]
-Description=Matahari Broker is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protcol.
-After=syslog.target network.target
-Requires=syslog.target network.target
-
-[Install]
-WantedBy=multi-user.target
-
-[Service]
-Type=simple
-NotifyAccess=all
-SysVStartPriority=85
-User=qpidd
-Group=qpidd
-
-ExecStart=/usr/sbin/matahari-brokerd
-
-# Restart options include: no, on-success, on-failure, on-abort or always
-Restart=on-failure
diff --git a/matahari-broker.service.in b/matahari-broker.service.in
new file mode 100644
index 0000000..62898fb
--- /dev/null
+++ b/matahari-broker.service.in
@@ -0,0 +1,22 @@
+[Unit]
+Description=Matahari Broker is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protcol.
+After=syslog.target network.target
+Requires=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+[Service]
+Type=simple
+NotifyAccess=all
+SysVStartPriority=85
+User=qpidd
+Group=qpidd
+
+EnvironmentFile=-@sysconfdir@/sysconfig/matahari
+EnvironmentFile=-@sysconfdir@/sysconfig/matahari-broker
+
+ExecStart=/usr/sbin/matahari-brokerd $QPIDD_OPTIONS
+
+# Restart options include: no, on-success, on-failure, on-abort or always
+Restart=on-failure
diff --git a/matahari-broker.sysconf.in b/matahari-broker.sysconf.in
index 9b1c2b5..367e00c 100644
--- a/matahari-broker.sysconf.in
+++ b/matahari-broker.sysconf.in
@@ -1,13 +1,12 @@
-# Try to use the centrally defined port (also used by the agents)
-# Otherwise, use the default port specified at build-time
-
-if [ -f @sysconfdir@/sysconfig/matahari ] ; then
- . @sysconfdir@/sysconfig/matahari
-fi
-
-if [ -z $MATAHARI_PORT ]; then
- MATAHARI_PORT=@MATAHARI_PORT@
-fi
-
-QPIDD_OPTIONS="--config @sysconfdir(a)/matahari-broker.conf --port $MATAHARI_PORT"
+QPIDD_OPTIONS="--config @sysconfdir(a)/matahari-broker.conf"
+
+# Federated Broker configuration - list the brokers to federate with
+# The following formats are allowed:
+# Hostname and port
+# <fqdn>:<port>
+# DNS SRV record format ("_matahari._tcp" is REQUIRED)
+# _matahari._tcp.<fqdn>
+#
+# Addresses need not all be in the same format
+#FEDERATED_BROKERS="broker1.example.com:49000, _matahari._tcp.example.com"
diff --git a/matahari-brokerd.in b/matahari-brokerd.in
deleted file mode 100644
index 0bab652..0000000
--- a/matahari-brokerd.in
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-if [ -f @sysconfdir@/sysconfig/matahari-broker ]; then
- . @sysconfdir@/sysconfig/matahari-broker
-fi
-
-/usr/sbin/qpidd --data-dir @localstatedir@/lib/matahari $QPIDD_OPTIONS $*
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index cb47956..58ba8a2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -161,6 +161,7 @@ endif(WITH-QMF)
### Subdirectories
+add_subdirectory(broker)
add_subdirectory(lib)
add_subdirectory(host)
add_subdirectory(network)
diff --git a/src/broker/CMakeLists.txt b/src/broker/CMakeLists.txt
new file mode 100644
index 0000000..7b48387
--- /dev/null
+++ b/src/broker/CMakeLists.txt
@@ -0,0 +1,16 @@
+SET(BROKER_DAEMON "matahari-brokerd")
+
+if(WITH-QMF)
+if(NOT WIN32)
+ add_executable(${BROKER_DAEMON} broker.c broker_federation.c broker_${VARIANT}.c)
+
+ if(HAVE_RESOLV_H)
+ target_link_libraries(${BROKER_DAEMON} mcommon)
+ target_link_libraries(${BROKER_DAEMON} resolv)
+ endif(HAVE_RESOLV_H)
+
+ install(TARGETS ${BROKER_DAEMON} DESTINATION sbin)
+
+endif(NOT WIN32)
+endif(WITH-QMF)
+
diff --git a/src/broker/broker.c b/src/broker/broker.c
new file mode 100644
index 0000000..ffb2587
--- /dev/null
+++ b/src/broker/broker.c
@@ -0,0 +1,74 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "broker_os.h"
+#include "broker.h"
+
+
+uint16_t broker_get_port(void)
+{
+ static uint16_t port = 0;
+
+ if (!port) {
+ char *end;
+ char *port_env = getenv("MATAHARI_PORT");
+ if (port_env) {
+ unsigned long port_l = strtoul(port_env, &end, 10);
+ if (port_env != end && port_l < (1 << 16)) {
+ port = port_l;
+ }
+ }
+ }
+
+ return port ? port : MATAHARI_PORT;
+}
+
+static char **broker_args(int argc, char * const argv[])
+{
+ int i = 0, o = 0;
+ char portarg[13];
+ char **newargs = malloc(sizeof(char *) * (argc + 2 + 1));
+
+ if (argc) {
+ newargs[o++] = strdup(argv[i++]);
+ }
+
+ snprintf(portarg, sizeof(portarg), "--port=%hu", broker_get_port());
+ newargs[o++] = strdup(portarg);
+ newargs[o++] = strdup("--data-dir=" LOCAL_STATE_DIR "/lib/matahari");
+
+ while (i < argc) {
+ newargs[o++] = strdup(argv[i++]);
+ }
+
+ newargs[o] = NULL;
+
+ return newargs;
+}
+
+static void broker_args_free(char **args)
+{
+ char **p = args;
+
+ while (*args) {
+ free(*args++);
+ }
+
+ free(p);
+}
+
+int main(int argc, char *argv[])
+{
+ char **arglist = broker_args(argc, argv);
+
+ int ret = broker_os_start_broker(arglist);
+
+ broker_args_free(arglist);
+
+ return ret;
+}
+
diff --git a/src/broker/broker.h b/src/broker/broker.h
new file mode 100644
index 0000000..4c7340d
--- /dev/null
+++ b/src/broker/broker.h
@@ -0,0 +1,12 @@
+#ifndef MH_BROKER_H
+#define MH_BROKER_H
+
+#include <stdint.h>
+
+
+#define MATAHARI_PORT 49000
+
+
+uint16_t broker_get_port(void);
+
+#endif
diff --git a/src/broker/broker_federation.c b/src/broker/broker_federation.c
new file mode 100644
index 0000000..ae8dccf
--- /dev/null
+++ b/src/broker/broker_federation.c
@@ -0,0 +1,93 @@
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <matahari/dnssrv.h>
+#include <matahari/logging.h>
+
+#include "broker.h"
+#include "broker_os.h"
+#include "broker_federation.h"
+
+
+#define DNS_SRV_PREFIX "_matahari._tcp."
+
+#define ROUTE_LIST(LOCAL, REMOTE) { \
+ {REMOTE, LOCAL, "amq.direct"}, \
+ {LOCAL, REMOTE, "amq.direct"}, \
+ {REMOTE, LOCAL, "qmf.default.direct"}, \
+ {LOCAL, REMOTE, "qmf.default.direct"}, \
+ {REMOTE, LOCAL, "qmf.default.topic"}, \
+ {LOCAL, REMOTE, "qmf.default.topic"} \
+}
+
+
+static int broker_federate(const char *local, const char *remote)
+{
+ int i;
+ struct mh_qpid_route routes[] = ROUTE_LIST(local, remote);
+
+ mh_trace("Adding routes for federated broker \"%s\"", remote);
+
+ for (i = 0; i < (sizeof(routes) / sizeof(*routes)); i++) {
+ int ret = broker_os_add_qpid_route(&routes[i]);
+ if (ret) {
+ mh_err("Failed to add federated broker \"%s\"", remote);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static char *broker_lookup(const char *query)
+{
+#ifdef HAVE_RESOLV_H
+ static char broker[1025 + 6];
+ char *host;
+ mh_trace("Looking up DNS SRV record for \"%s\"", query);
+
+ host = mh_dnssrv_lookup(query);
+
+ if (host) {
+ snprintf(broker, sizeof(broker), "%s:%hu", host, MATAHARI_PORT);
+ return broker;
+ }
+ mh_warn("Failed to find DNS SRV record for \"%s\"", query);
+#else
+ mh_warn("DNS SRV lookups are not supported");
+#endif
+
+ return NULL;
+}
+
+void broker_federation_configure(void)
+{
+ const char *brokers = getenv("FEDERATED_BROKERS");
+ char local[16];
+ char peers[1024];
+ char *p = NULL;
+ char *peer;
+
+ if (!brokers) {
+ return;
+ }
+
+ snprintf(local, sizeof(local), "localhost:%hu", broker_get_port());
+
+ strncpy(peers, brokers, sizeof(peers) - 1);
+ peers[sizeof(peers) - 1] = '\0';
+
+ while ((peer = strtok_r(p ? NULL : peers, ",; ", &p)) != NULL) {
+ if (strncmp(peer, DNS_SRV_PREFIX, strlen(DNS_SRV_PREFIX)) == 0) {
+ peer = broker_lookup(peer);
+ }
+
+ if (peer) {
+ broker_federate(local, peer);
+ }
+ }
+}
+
diff --git a/src/broker/broker_federation.h b/src/broker/broker_federation.h
new file mode 100644
index 0000000..12cfe61
--- /dev/null
+++ b/src/broker/broker_federation.h
@@ -0,0 +1,6 @@
+#ifndef MH_BROKER_FEDERATION_H
+#define MH_BROKER_FEDERATION_H
+
+void broker_federation_configure(void);
+
+#endif
diff --git a/src/broker/broker_linux.c b/src/broker/broker_linux.c
new file mode 100644
index 0000000..54e3bff
--- /dev/null
+++ b/src/broker/broker_linux.c
@@ -0,0 +1,53 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "broker_federation.h"
+#include "broker_os.h"
+
+
+int broker_os_start_broker(char * const args[])
+{
+ pid_t pid = fork();
+
+ if (pid < 0) {
+ perror("fork()");
+ return errno;
+ }
+
+ if (pid) {
+ // exec() in parent process so that qpidd keeps the initial pid.
+ // Note that this means the child will become a zombie. That's just the
+ // way it goes.
+
+ // execvp() will find the path to qpidd from $PATH.
+ execvp("qpidd", args);
+
+ // It's an error if we get here
+ perror("exec()");
+ return errno;
+ } else {
+ // Configure federated brokers in the child process
+ broker_federation_configure();
+ return 0;
+ }
+}
+
+int broker_os_add_qpid_route(const struct mh_qpid_route *route)
+{
+ char cmd[1024];
+ int ret;
+
+ snprintf(cmd, sizeof(cmd), "qpid-route --timeout=5 dynamic add %s %s %s",
+ route->dest, route->src, route->exchange);
+
+ ret = system(cmd);
+
+ if (ret < 0) {
+ perror("system()");
+ }
+ return ret;
+}
+
diff --git a/src/broker/broker_os.h b/src/broker/broker_os.h
new file mode 100644
index 0000000..a961625
--- /dev/null
+++ b/src/broker/broker_os.h
@@ -0,0 +1,15 @@
+#ifndef MH_OS_BROKER_H
+#define MH_OS_BROKER_H
+
+struct mh_qpid_route {
+ const char *dest;
+ const char *src;
+ const char *exchange;
+};
+
+
+int broker_os_start_broker(char * const args[]);
+
+int broker_os_add_qpid_route(const struct mh_qpid_route *route);
+
+#endif
diff --git a/src/include/config.h.in b/src/include/config.h.in
index 6231970..64a64db 100644
--- a/src/include/config.h.in
+++ b/src/include/config.h.in
@@ -5,3 +5,5 @@
#cmakedefine HAVE_TIME 1
#cmakedefine HAVE_G_LIST_FREE_FULL 1
#cmakedefine HAVE_PK_GET_SYNC 1
+
+#define LOCAL_STATE_DIR "@localstatedir@"
12 years, 8 months
[PATCH v2] Broker: rhbz#735425 - Implement broker federation
by Zane Bitter
Replace the broker wrapper script with a C wrapper that calls execve() on
qpidd. Implement parsing of the MATAHARI_PORT environment variable and the
Broker Federation options in the C wrapper.
Broker federation is configured using the BROKER_FEDERATION environment
variable set in /etc/sysconfig/matahari-broker. The contents of the
variable should be a list of hosts or DNS SRV queries separated by any
combinations of spaces, commas and/or semicolons.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
CMakeLists.txt | 12 ++--
matahari-broker.init.in | 9 +++
matahari-broker.service | 19 -------
matahari-broker.service.in | 22 ++++++++
matahari-broker.sysconf.in | 23 ++++----
matahari-brokerd.in | 8 ---
src/CMakeLists.txt | 1
src/broker/CMakeLists.txt | 16 ++++++
src/broker/broker.c | 88 +++++++++++++++++++++++++++++++
src/broker/broker.h | 35 +++++++++++++
src/broker/broker_federation.c | 112 ++++++++++++++++++++++++++++++++++++++++
src/broker/broker_federation.h | 33 ++++++++++++
src/broker/broker_linux.c | 71 +++++++++++++++++++++++++
src/broker/broker_os.h | 51 ++++++++++++++++++
src/include/config.h.in | 9 +++
15 files changed, 463 insertions(+), 46 deletions(-)
delete mode 100644 matahari-broker.service
create mode 100644 matahari-broker.service.in
delete mode 100644 matahari-brokerd.in
create mode 100644 src/broker/CMakeLists.txt
create mode 100644 src/broker/broker.c
create mode 100644 src/broker/broker.h
create mode 100644 src/broker/broker_federation.c
create mode 100644 src/broker/broker_federation.h
create mode 100644 src/broker/broker_linux.c
create mode 100644 src/broker/broker_os.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f7555b4..4ec2d1e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -109,9 +109,6 @@ else(WIN32)
set (CPACK_GENERATOR "TGZ")
- configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari-brokerd.in
- ${CMAKE_CURRENT_BINARY_DIR}/matahari-brokerd)
-
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari.init.in
${CMAKE_CURRENT_BINARY_DIR}/matahari.init)
@@ -126,8 +123,6 @@ else(WIN32)
GROUP_READ GROUP_WRITE GROUP_EXECUTE)
install(CODE "execute_process(COMMAND chown root:qpidd ${localstatedir}/lib/matahari)")
- install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-brokerd DESTINATION sbin)
-
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker DESTINATION ${initdir})
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/matahari.sysconf DESTINATION ${sysconfdir}/sysconfig RENAME matahari)
@@ -142,8 +137,13 @@ else(WIN32)
if(systemd_FOUND)
set(systemdunitdir "/lib/systemd/system")
- install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/matahari-broker.service DESTINATION ${systemdunitdir})
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/matahari-broker.service.in
+ ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker.service)
+
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/matahari-broker.service DESTINATION ${systemdunitdir})
endif(systemd_FOUND)
+
endif(WIN32)
INCLUDE(InstallRequiredSystemLibraries)
diff --git a/matahari-broker.init.in b/matahari-broker.init.in
index e74926c..d9ca4ee 100755
--- a/matahari-broker.init.in
+++ b/matahari-broker.init.in
@@ -46,12 +46,19 @@ pidfile=@localstatedir(a)/run/matahari-broker.pid
# Source function library.
. @sysconfdir(a)/rc.d/init.d/functions
+if [ -f @sysconfdir@/sysconfig/matahari ]; then
+ . @sysconfdir@/sysconfig/matahari
+fi
+if [ -f @sysconfdir@/sysconfig/matahari-broker ]; then
+ . @sysconfdir@/sysconfig/matahari-broker
+fi
+
RETVAL=0
start() {
echo -n $"Starting Matahari broker daemon: "
install -o root -g qpidd -m 775 -d @localstatedir@/run/matahari
- daemon --pidfile $pidfile --check $proc --user qpidd /usr/sbin/$prog --daemon
+ daemon --pidfile $pidfile --check $proc --user qpidd /usr/sbin/$prog $QPIDD_OPTIONS --daemon
RETVAL=$?
echo
[ $RETVAL = 0 ] && touch $lockfile
diff --git a/matahari-broker.service b/matahari-broker.service
deleted file mode 100644
index 7e6e9f7..0000000
--- a/matahari-broker.service
+++ /dev/null
@@ -1,19 +0,0 @@
-[Unit]
-Description=Matahari Broker is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protcol.
-After=syslog.target network.target
-Requires=syslog.target network.target
-
-[Install]
-WantedBy=multi-user.target
-
-[Service]
-Type=simple
-NotifyAccess=all
-SysVStartPriority=85
-User=qpidd
-Group=qpidd
-
-ExecStart=/usr/sbin/matahari-brokerd
-
-# Restart options include: no, on-success, on-failure, on-abort or always
-Restart=on-failure
diff --git a/matahari-broker.service.in b/matahari-broker.service.in
new file mode 100644
index 0000000..62898fb
--- /dev/null
+++ b/matahari-broker.service.in
@@ -0,0 +1,22 @@
+[Unit]
+Description=Matahari Broker is an AMQP broker. It receives, stores, routes and forwards messages using the AMQP protcol.
+After=syslog.target network.target
+Requires=syslog.target network.target
+
+[Install]
+WantedBy=multi-user.target
+
+[Service]
+Type=simple
+NotifyAccess=all
+SysVStartPriority=85
+User=qpidd
+Group=qpidd
+
+EnvironmentFile=-@sysconfdir@/sysconfig/matahari
+EnvironmentFile=-@sysconfdir@/sysconfig/matahari-broker
+
+ExecStart=/usr/sbin/matahari-brokerd $QPIDD_OPTIONS
+
+# Restart options include: no, on-success, on-failure, on-abort or always
+Restart=on-failure
diff --git a/matahari-broker.sysconf.in b/matahari-broker.sysconf.in
index 9b1c2b5..367e00c 100644
--- a/matahari-broker.sysconf.in
+++ b/matahari-broker.sysconf.in
@@ -1,13 +1,12 @@
-# Try to use the centrally defined port (also used by the agents)
-# Otherwise, use the default port specified at build-time
-
-if [ -f @sysconfdir@/sysconfig/matahari ] ; then
- . @sysconfdir@/sysconfig/matahari
-fi
-
-if [ -z $MATAHARI_PORT ]; then
- MATAHARI_PORT=@MATAHARI_PORT@
-fi
-
-QPIDD_OPTIONS="--config @sysconfdir(a)/matahari-broker.conf --port $MATAHARI_PORT"
+QPIDD_OPTIONS="--config @sysconfdir(a)/matahari-broker.conf"
+
+# Federated Broker configuration - list the brokers to federate with
+# The following formats are allowed:
+# Hostname and port
+# <fqdn>:<port>
+# DNS SRV record format ("_matahari._tcp" is REQUIRED)
+# _matahari._tcp.<fqdn>
+#
+# Addresses need not all be in the same format
+#FEDERATED_BROKERS="broker1.example.com:49000, _matahari._tcp.example.com"
diff --git a/matahari-brokerd.in b/matahari-brokerd.in
deleted file mode 100644
index 0bab652..0000000
--- a/matahari-brokerd.in
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-if [ -f @sysconfdir@/sysconfig/matahari-broker ]; then
- . @sysconfdir@/sysconfig/matahari-broker
-fi
-
-/usr/sbin/qpidd --data-dir @localstatedir@/lib/matahari $QPIDD_OPTIONS $*
-
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f045887..e3a7e38 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -162,6 +162,7 @@ endif(WITH-QMF)
### Subdirectories
+add_subdirectory(broker)
add_subdirectory(lib)
add_subdirectory(host)
add_subdirectory(network)
diff --git a/src/broker/CMakeLists.txt b/src/broker/CMakeLists.txt
new file mode 100644
index 0000000..7b48387
--- /dev/null
+++ b/src/broker/CMakeLists.txt
@@ -0,0 +1,16 @@
+SET(BROKER_DAEMON "matahari-brokerd")
+
+if(WITH-QMF)
+if(NOT WIN32)
+ add_executable(${BROKER_DAEMON} broker.c broker_federation.c broker_${VARIANT}.c)
+
+ if(HAVE_RESOLV_H)
+ target_link_libraries(${BROKER_DAEMON} mcommon)
+ target_link_libraries(${BROKER_DAEMON} resolv)
+ endif(HAVE_RESOLV_H)
+
+ install(TARGETS ${BROKER_DAEMON} DESTINATION sbin)
+
+endif(NOT WIN32)
+endif(WITH-QMF)
+
diff --git a/src/broker/broker.c b/src/broker/broker.c
new file mode 100644
index 0000000..f6d7d73
--- /dev/null
+++ b/src/broker/broker.c
@@ -0,0 +1,88 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "broker_os.h"
+#include "broker.h"
+
+
+uint16_t broker_get_port(void)
+{
+ static uint16_t port = 0;
+
+ if (!port) {
+ char *port_env = getenv("MATAHARI_PORT");
+ if (port_env) {
+ sscanf(port_env, "%hu", &port);
+ }
+ }
+
+ return port ? port : MATAHARI_PORT;
+}
+
+static char **broker_args(int argc, char * const argv[])
+{
+ int i = 0, o = 0;
+ char portarg[13];
+ char **newargs = malloc(sizeof(char *) * (argc + 2 + 1));
+
+ if (argc) {
+ newargs[o++] = strdup(argv[i++]);
+ }
+
+ snprintf(portarg, sizeof(portarg), "--port=%hu", broker_get_port());
+ newargs[o++] = strdup(portarg);
+ newargs[o++] = strdup("--data-dir=" LOCAL_STATE_DIR "/lib/matahari");
+
+ while (i < argc) {
+ newargs[o++] = strdup(argv[i++]);
+ }
+
+ newargs[o] = NULL;
+
+ return newargs;
+}
+
+static void broker_args_free(char **args)
+{
+ char **p = args;
+
+ while (*args) {
+ free(*args++);
+ }
+
+ free(p);
+}
+
+int main(int argc, char *argv[])
+{
+ char **arglist = broker_args(argc, argv);
+
+ int ret = broker_os_start_broker(arglist);
+
+ broker_args_free(arglist);
+
+ return ret;
+}
+
diff --git a/src/broker/broker.h b/src/broker/broker.h
new file mode 100644
index 0000000..3aff4d3
--- /dev/null
+++ b/src/broker/broker.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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 broker.h
+ * Interface to the broker configuration code.
+ */
+
+#ifndef MH_BROKER_H
+#define MH_BROKER_H
+
+#include <stdint.h>
+
+/**
+ * Get the port for the broker to listen on.
+ * @return the TCP port for the local broker
+ */
+uint16_t broker_get_port(void);
+
+#endif
diff --git a/src/broker/broker_federation.c b/src/broker/broker_federation.c
new file mode 100644
index 0000000..5140657
--- /dev/null
+++ b/src/broker/broker_federation.c
@@ -0,0 +1,112 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <matahari/dnssrv.h>
+#include <matahari/utilities.h>
+#include <matahari/logging.h>
+
+#include "broker.h"
+#include "broker_os.h"
+#include "broker_federation.h"
+
+
+#define DNS_SRV_PREFIX "_matahari._tcp."
+
+#define ROUTE_LIST(LOCAL, REMOTE) { \
+ {REMOTE, LOCAL, "amq.direct"}, \
+ {LOCAL, REMOTE, "amq.direct"}, \
+ {REMOTE, LOCAL, "qmf.default.direct"}, \
+ {LOCAL, REMOTE, "qmf.default.direct"}, \
+ {REMOTE, LOCAL, "qmf.default.topic"}, \
+ {LOCAL, REMOTE, "qmf.default.topic"} \
+}
+
+
+static int broker_federate(const char *local, const char *remote)
+{
+ int i;
+ struct mh_qpid_route routes[] = ROUTE_LIST(local, remote);
+
+ mh_trace("Adding routes for federated broker \"%s\"", remote);
+
+ for (i = 0; i < DIMOF(routes); i++) {
+ int ret = broker_os_add_qpid_route(&routes[i]);
+ if (ret) {
+ mh_err("Failed to add federated broker \"%s\"", remote);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static char *broker_lookup(const char *query)
+{
+#ifdef HAVE_RESOLV_H
+ static char broker[1025 + 6];
+ char *host;
+ mh_trace("Looking up DNS SRV record for \"%s\"", query);
+
+ host = mh_dnssrv_lookup(query);
+
+ if (host) {
+ snprintf(broker, sizeof(broker), "%s:%hu", host, MATAHARI_PORT);
+ return broker;
+ }
+ mh_warn("Failed to find DNS SRV record for \"%s\"", query);
+#else
+ mh_warn("DNS SRV lookups are not supported");
+#endif
+
+ return NULL;
+}
+
+void broker_federation_configure(void)
+{
+ const char *brokers = getenv("FEDERATED_BROKERS");
+ char local[16];
+ char peers[1024];
+ char *p = NULL;
+ char *peer;
+
+ if (!brokers) {
+ return;
+ }
+
+ snprintf(local, sizeof(local), "localhost:%hu", broker_get_port());
+
+ strncpy(peers, brokers, sizeof(peers) - 1);
+ peers[sizeof(peers) - 1] = '\0';
+
+ while ((peer = strtok_r(p ? NULL : peers, ",; ", &p)) != NULL) {
+ if (strncmp(peer, DNS_SRV_PREFIX, strlen(DNS_SRV_PREFIX)) == 0) {
+ peer = broker_lookup(peer);
+ }
+
+ if (peer) {
+ broker_federate(local, peer);
+ }
+ }
+}
+
diff --git a/src/broker/broker_federation.h b/src/broker/broker_federation.h
new file mode 100644
index 0000000..0cacaef
--- /dev/null
+++ b/src/broker/broker_federation.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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 broker_federation.h
+ * Interface to the broker federation configuration code.
+ */
+
+#ifndef MH_BROKER_FEDERATION_H
+#define MH_BROKER_FEDERATION_H
+
+/**
+ * Read the broker federation settings from the environment and set up broker
+ * federation.
+ */
+void broker_federation_configure(void);
+
+#endif
diff --git a/src/broker/broker_linux.c b/src/broker/broker_linux.c
new file mode 100644
index 0000000..6dd98e8
--- /dev/null
+++ b/src/broker/broker_linux.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "broker_federation.h"
+#include "broker_os.h"
+
+
+int broker_os_start_broker(char * const args[])
+{
+ pid_t pid = fork();
+
+ if (pid < 0) {
+ perror("fork()");
+ return errno;
+ }
+
+ if (pid) {
+ // exec() in parent process so that qpidd keeps the initial pid.
+ // Note that this means the child will become a zombie. That's just the
+ // way it goes.
+
+ // execvp() will find the path to qpidd from $PATH.
+ execvp("qpidd", args);
+
+ // It's an error if we get here
+ perror("exec()");
+ return errno;
+ } else {
+ // Configure federated brokers in the child process
+ broker_federation_configure();
+ return 0;
+ }
+}
+
+int broker_os_add_qpid_route(const struct mh_qpid_route *route)
+{
+ char cmd[1024];
+ int ret;
+
+ snprintf(cmd, sizeof(cmd), "qpid-route --timeout=5 dynamic add %s %s %s",
+ route->dest, route->src, route->exchange);
+
+ ret = system(cmd);
+
+ if (ret < 0) {
+ perror("system()");
+ }
+ return ret;
+}
+
diff --git a/src/broker/broker_os.h b/src/broker/broker_os.h
new file mode 100644
index 0000000..788fe78
--- /dev/null
+++ b/src/broker/broker_os.h
@@ -0,0 +1,51 @@
+/* Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter <zbitter(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 broker_os.h
+ * Interface to the OS-specific broker configuration code.
+ */
+
+#ifndef MH_BROKER_OS_H
+#define MH_BROKER_OS_H
+
+/**
+ * A route between two Qpid brokers.
+ */
+struct mh_qpid_route {
+ const char *dest; /**< The route destination */
+ const char *src; /**< The route source */
+ const char *exchange; /**< The exchange */
+};
+
+
+/**
+ * Start the broker with the supplied argument list.
+ * @param args a list of args to pass to the broker. The last item in the list
+ * must be NULL.
+ */
+int broker_os_start_broker(char * const args[]);
+
+/**
+ * Add a route between two Qpid brokers.
+ * @param route pointer to the route to add
+ * @return -1 on error, otherwise the result of the external route add command.
+ */
+int broker_os_add_qpid_route(const struct mh_qpid_route *route);
+
+#endif
diff --git a/src/include/config.h.in b/src/include/config.h.in
index 6231970..fd248ad 100644
--- a/src/include/config.h.in
+++ b/src/include/config.h.in
@@ -1,3 +1,6 @@
+#ifndef MH_CONFIG_H
+#define MH_CONFIG_H
+
#cmakedefine HAVE_STRING_H 1
#cmakedefine HAVE_SYS_IOCTL_H 1
#cmakedefine HAVE_ASPRINTF 1
@@ -5,3 +8,9 @@
#cmakedefine HAVE_TIME 1
#cmakedefine HAVE_G_LIST_FREE_FULL 1
#cmakedefine HAVE_PK_GET_SYNC 1
+
+#define LOCAL_STATE_DIR "@localstatedir@"
+
+#define MATAHARI_PORT @MATAHARI_PORT@
+
+#endif
12 years, 8 months
[PATCH] - Win32 uuid support
by Adam Stokes
- Fixes rhbz#733483 as a result
- Add support for generating UUIDs in Windows
Signed-off-by: Adam Stokes <astokes(a)fedoraproject.org>
---
src/lib/CMakeLists.txt | 2 +-
src/lib/utilities.c | 31 ++++++++++---------------------
src/lib/utilities_linux.c | 19 +++++++++++++++++++
src/lib/utilities_private.h | 14 ++++++++++++++
src/lib/utilities_windows.c | 24 ++++++++++++++++++++++++
5 files changed, 68 insertions(+), 22 deletions(-)
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 1cd41d4..610040f 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -32,7 +32,7 @@ target_link_libraries(msysconfig ${pcre_LIBRARIES} mcommon ${glib_LIBRARIES})
if(WIN32)
foreach (lib ${LIBS})
- target_link_libraries(${lib} wsock32 dnsapi)
+ target_link_libraries(${lib} wsock32 dnsapi rpcrt4)
install(TARGETS ${lib} DESTINATION sbin)
endforeach (lib ${LIBS})
else(WIN32)
diff --git a/src/lib/utilities.c b/src/lib/utilities.c
index 9d60de8..30720a4 100644
--- a/src/lib/utilities.c
+++ b/src/lib/utilities.c
@@ -382,6 +382,16 @@ mh_dnsdomainname(void)
}
const char *
+mh_uuid(void)
+{
+ const char *res;
+
+ res = mh_os_uuid();
+
+ return res;
+}
+
+const char *
mh_hostname(void)
{
static char *hostname = NULL;
@@ -437,27 +447,6 @@ char *mh_file_first_line(const char *file)
return buffer;
}
-const char *
-mh_uuid(void)
-{
- static char *uuid = NULL;
-
-#ifdef __linux__
- if (uuid == NULL && g_file_test("/etc/machine-id", G_FILE_TEST_EXISTS)) {
- uuid = mh_file_first_line("/etc/machine-id");
- }
- if (uuid == NULL && g_file_test("/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS)) {
- /* For pre-systemd machines */
- uuid = mh_file_first_line("/var/lib/dbus/machine-id");
- }
-#endif
-
- if(uuid) {
- mh_trace("Got uuid: %s", uuid);
- }
- return uuid;
-}
-
#ifdef WIN32
wchar_t *
char2wide(const char *str)
diff --git a/src/lib/utilities_linux.c b/src/lib/utilities_linux.c
index c848802..f0aae14 100644
--- a/src/lib/utilities_linux.c
+++ b/src/lib/utilities_linux.c
@@ -63,3 +63,22 @@ mh_os_dnsdomainname(void)
return dnsdomainname ? dnsdomainname : "";
}
+
+const char *
+mh_os_uuid(void)
+{
+ static char *uuid = NULL;
+
+ if (uuid == NULL && g_file_test("/etc/machine-id", G_FILE_TEST_EXISTS)) {
+ uuid = mh_file_first_line("/etc/machine-id");
+ }
+ if (uuid == NULL && g_file_test("/var/lib/dbus/machine-id", G_FILE_TEST_EXISTS)) {
+ /* For pre-systemd machines */
+ uuid = mh_file_first_line("/var/lib/dbus/machine-id");
+ }
+
+ if(uuid) {
+ mh_trace("Got uuid: %s", uuid);
+ }
+ return uuid;
+}
diff --git a/src/lib/utilities_private.h b/src/lib/utilities_private.h
index e39d22c..41f074d 100644
--- a/src/lib/utilities_private.h
+++ b/src/lib/utilities_private.h
@@ -30,10 +30,24 @@
#ifndef __MH_UTILITIES_PRIVATE_H__
#define __MH_UTILITIES_PRIVATE_H__
+#include <windows.h>
+#include <rpc.h>
+
+#ifdef uuid_t
+#undef uuid_t
+#endif
+typedef UUID uuid_t[1];
+
/**
* Get the local dnsdomainname.
*/
const char *
mh_os_dnsdomainname(void);
+/**
+ * Generate UUID
+ */
+const char *
+mh_os_uuid(void);
+
#endif /* __MH_UTILITIES_PRIVATE_H__ */
diff --git a/src/lib/utilities_windows.c b/src/lib/utilities_windows.c
index 26a3679..583b544 100644
--- a/src/lib/utilities_windows.c
+++ b/src/lib/utilities_windows.c
@@ -18,9 +18,15 @@
#include "config.h"
+#include <windows.h>
+#include <rpc.h>
+
#include "matahari/utilities.h"
+#include "matahari/logging.h"
#include "utilities_private.h"
+#define MAXUUIDLEN 37
+
const char *
mh_os_dnsdomainname(void)
{
@@ -32,3 +38,21 @@ mh_os_dnsdomainname(void)
return mh_domainname();
}
+
+const char *
+mh_os_uuid(void)
+{
+ uuid_t u;
+ static char s[MAXUUIDLEN];
+ unsigned char __RPC_FAR *rs;
+
+ UuidCreate(u);
+
+ if (UuidToStringA((UUID *)u, &rs) == RPC_S_OK) {
+ strncpy(s,(char __RPC_FAR *)rs, MAXUUIDLEN);
+ RpcStringFree(&rs);
+ mh_trace("Got uuid: %s", s);
+ return s;
+ }
+ return "";
+}
--
1.7.6.1
12 years, 8 months
[PATCH] doc: rhbz#733468 Include OCF return codes in docs.
by Russell Bryant
Include a table of the OCF return codes for handy reference purposes.
Signed-off-by: Russell Bryant <rbryant(a)redhat.com>
---
src/service/schema.xml | 78 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 78 insertions(+), 0 deletions(-)
diff --git a/src/service/schema.xml b/src/service/schema.xml
index 5d57a49..0790eb8 100644
--- a/src/service/schema.xml
+++ b/src/service/schema.xml
@@ -99,6 +99,84 @@
<arg name="agent" dir="I" type="sstr" />
<arg name="xml" dir="O" type="sstr" />
</method>
+ <!--
+ <para>The <literal>rc</literal> output parameter warrants some additional discussion.
+ The potential return values depends on which <literal>standard</literal> is being
+ used. In the case of <literal>OCF</literal>, these values are defined by the
+ <ulink url="http://www.opencf.org/cgi-bin/viewcvs.cgi/specs/ra/resource-agent-api.txt...">OCF
+ resource agent specification</ulink>. However, see <xref linkend="ocf_return_vals"/>
+ for an overview of the OCF resource agent return codes.</para>
+
+ <table id="ocf_return_vals">
+ <title>OCF Resource Agent Exit Codes</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Value(s)</entry>
+ <entry>OCF Name</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><literal>0</literal></entry>
+ <entry><literal>OCF_SUCCESS</literal></entry>
+ <entry>Success. The command complete successfully. This is the expected result for all start, stop, promote and demote commands.</entry>
+ </row>
+ <row>
+ <entry><literal>1</literal></entry>
+ <entry><literal>OCF_ERR_GENERIC</literal></entry>
+ <entry>Generic "there was a problem" error code.</entry>
+ </row>
+ <row>
+ <entry><literal>2</literal></entry>
+ <entry><literal>OCF_ERR_ARGS</literal></entry>
+ <entry>The resource's configuration is not valid on this machine. Eg. Refers to a location/tool not found on the node.</entry>
+ </row>
+ <row>
+ <entry><literal>3</literal></entry>
+ <entry><literal>OCF_ERR_UNIMPLEMENTED</literal></entry>
+ <entry>The requested action is not implemented.</entry>
+ </row>
+ <row>
+ <entry><literal>4</literal></entry>
+ <entry><literal>OCF_ERR_PERM</literal></entry>
+ <entry>The resource agent does not have sufficient privileges to complete the task.</entry>
+ </row>
+ <row>
+ <entry><literal>5</literal></entry>
+ <entry><literal>OCF_ERR_INSTALLED</literal></entry>
+ <entry>The tools required by the resource are not installed on this machine.</entry>
+ </row>
+ <row>
+ <entry><literal>6</literal></entry>
+ <entry><literal>OCF_ERR_CONFIGURED</literal></entry>
+ <entry>The resource's configuration is invalid. Eg. A required parameters are missing.</entry>
+ </row>
+ <row>
+ <entry><literal>7</literal></entry>
+ <entry><literal>OCF_NOT_RUNNING</literal></entry>
+ <entry>The resource is safely stopped.</entry>
+ </row>
+ <row>
+ <entry><literal>8</literal></entry>
+ <entry><literal>OCF_RUNNING_MASTER</literal></entry>
+ <entry>The resource is running in Master mode.</entry>
+ </row>
+ <row>
+ <entry><literal>9</literal></entry>
+ <entry><literal>OCF_FAILED_MASTER</literal></entry>
+ <entry>The resource is in Master mode but has failed. The resource will be demoted, stopped and then started (and possibly promoted) again.</entry>
+ </row>
+ <row>
+ <entry>other</entry>
+ <entry>N/A</entry>
+ <entry>Custom error code.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ -->
<method name="invoke" desc="Perform a custom action on a resource">
<arg name="name" dir="I" type="sstr" />
<arg name="standard" dir="I" type="sstr" />
--
1.7.6
12 years, 8 months
[PATCH] Config: rhbz#735429 - Make localhost default broker on Linux
by Zane Bitter
When started with no options, DNS SRV is used (if available) to look up a
broker. In the most common configuration, agents should connect to the
local broker on Linux. The user may then optionally configure broker
federation (when support for that arrives) using the DNS SRV lookup to find
the federated broker.
Therefore, change the default configuration to force connection to
localhost on Linux. The logic remains the same, in that if the broker
option is not defined the DNS SRV will still be queried.
On Windows, where there is no broker installed by default, the behaviour
remains the same as before.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
matahari.sysconf.in | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/matahari.sysconf.in b/matahari.sysconf.in
index a89e50d..bc25e73 100644
--- a/matahari.sysconf.in
+++ b/matahari.sysconf.in
@@ -1,7 +1,7 @@
# Connect to a broker on the named host
-# If this is not defined, agents will attempt to connect to localhost
-# and/or the contents of a _matahari._tcp SRV record if it exists
-#MATAHARI_BROKER=@MATAHARI_BROKER@
+# If this is not defined, agents will attempt to connect to the server specified
+# by the _matahari._tcp SRV record in DNS if that exists, otherwise to localhost
+MATAHARI_BROKER=@MATAHARI_BROKER@
# Connect to a broker on a non-standard port
#MATAHARI_PORT=@MATAHARI_PORT@
@@ -29,4 +29,4 @@ MATAHARI_AGENT_ARGS="--reconnect=yes"
# KRB_RENEW_ARGS="-f /etc/krb5.keytab -K 10 -l 10h"
# Kerberos REALM
-# KRB_REALM="qpidd/EXAMPLE.COM"
\ No newline at end of file
+# KRB_REALM="qpidd/EXAMPLE.COM"
12 years, 8 months
[PATCH] service-console: rhbz#734536 Use ms resolution for timeout and interval.
by Russell Bryant
The services API takes milliseconds, so just expose that via the service
console in case anyone wants it (and for the sake of consistency).
Signed-off-by: Russell Bryant <rbryant(a)redhat.com>
---
src/service/service-qmf-console.cpp | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/service/service-qmf-console.cpp b/src/service/service-qmf-console.cpp
index ac20fe6..e312d73 100644
--- a/src/service/service-qmf-console.cpp
+++ b/src/service/service-qmf-console.cpp
@@ -49,7 +49,7 @@ call_arg(int code, const char *name, const char *arg, void *userdata)
qpid::types::Variant::Map *options = static_cast<qpid::types::Variant::Map*>(userdata);
mh_debug("Found call option: '%s' = '%s'", name, arg);
if(strcmp(name, "timeout") == 0 || strcmp(name, "interval") == 0) {
- uint32_t number = 1000 * atoi(arg);
+ uint32_t number = atoi(arg);
(*options)[name] = number;
} else {
(*options)[name] = arg;
@@ -107,8 +107,8 @@ int main(int argc, char** argv)
mh_add_option('A', required_argument, "agent", "(Resources API only)", &options, call_arg);
mh_add_option('a', required_argument, "action", "Action to perform", &options, call_arg);
- mh_add_option('i', required_argument, "interval", "(Resources API only)", &options, call_arg);
- mh_add_option('t', required_argument, "timeout", "Time to wait, in seconds, for the action to complete", &options, call_arg);
+ mh_add_option('i', required_argument, "interval", "(Resources API only) Time, in milliseconds, in between recurring executions of this action.", &options, call_arg);
+ mh_add_option('t', required_argument, "timeout", "Time to wait, in milliseconds, for the action to complete", &options, call_arg);
mh_add_option('o', required_argument, "option", "Option to pass to the resource script (Resources API only)", &agent_options, agent_arg);
--
1.7.6
12 years, 8 months
[PATCH] services: rhbz#734522 sanity check sevices action parameters.
by Russell Bryant
The bug that was reported showed that if the Resources invoke method was
executed with an empty argument that should be required, it could start
up a recurring action that would fail every time and could never be
cancelled.
Address this by adding some sanity checking on the arguments in the
core services API. If a parameter is determined to be invalid, don't
attempt the action at all and return an error back to the agent code.
In the QMF agent, if this happens, raise an exception that indicates
that the arguments were invalid.
Signed-off-by: Russell Bryant <rbryant(a)redhat.com>
---
src/include/matahari/agent.h | 1 +
src/include/matahari/services.h | 17 ++++++++++++++++-
src/lib/services.c | 34 ++++++++++++++++++++++++++++++++++
src/service/service-qmf.cpp | 19 +++++++++++++++++--
4 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/src/include/matahari/agent.h b/src/include/matahari/agent.h
index 84e9aaf..8345841 100644
--- a/src/include/matahari/agent.h
+++ b/src/include/matahari/agent.h
@@ -45,6 +45,7 @@ int required_argument = 1;
}
#define MH_NOT_IMPLEMENTED "Not implemented"
+#define MH_INVALID_ARGS "Invalid Arguments"
#ifndef NS_MAXDNAME
# define NS_MAXDNAME 1025
diff --git a/src/include/matahari/services.h b/src/include/matahari/services.h
index 86341b2..54d826b 100644
--- a/src/include/matahari/services.h
+++ b/src/include/matahari/services.h
@@ -218,4 +218,19 @@ services_get_ocf_exitcode(char *action, int lsb_exitcode)
* for rc <= 7 */
return (enum ocf_exitcode)lsb_exitcode;
}
-#endif
+
+/**
+ * Check if a string is empty.
+ *
+ * \param[in] s the string to check
+ *
+ * \retval 0 not empty
+ * \retval non-zero empty
+ */
+static inline int
+mh_strlen_zero(const char *s)
+{
+ return !s || *s == '\0';
+}
+
+#endif /* __MH_SERVICES__ */
diff --git a/src/lib/services.c b/src/lib/services.c
index 5768a5e..a62fff2 100644
--- a/src/lib/services.c
+++ b/src/lib/services.c
@@ -49,6 +49,40 @@ svc_action_t *resources_action_create(
{
svc_action_t *op;
+ /*
+ * Do some up front sanity checks before we go off and
+ * build the svc_action_t instance.
+ */
+
+ if (mh_strlen_zero(name)) {
+ mh_err("A service or resource action must have a name.");
+ return NULL;
+ }
+
+ if (mh_strlen_zero(standard)) {
+ mh_err("A service action must have a valid standard.");
+ return NULL;
+ }
+
+ if (!strcasecmp(standard, "ocf") && mh_strlen_zero(provider)) {
+ mh_err("An OCF resource action must have a provider.");
+ return NULL;
+ }
+
+ if (mh_strlen_zero(agent)) {
+ mh_err("A service or resource action must have an agent.");
+ return NULL;
+ }
+
+ if (mh_strlen_zero(action)) {
+ mh_err("A service or resource action must specify an action.");
+ return NULL;
+ }
+
+ /*
+ * Sanity checks passed, proceed!
+ */
+
op = calloc(1, sizeof(svc_action_t));
op->opaque = calloc(1, sizeof(svc_action_private_t));
op->rsc = strdup(name);
diff --git a/src/service/service-qmf.cpp b/src/service/service-qmf.cpp
index a2df2e3..2ad2a75 100644
--- a/src/service/service-qmf.cpp
+++ b/src/service/service-qmf.cpp
@@ -305,7 +305,12 @@ SrvAgent::invoke_services(qmf::AgentSession session, qmf::AgentEvent event,
args["name"].asString().c_str(), methodName.c_str(), 0,
default_timeout_ms);
- action_async(SRV_SERVICES, session, event, op, true);
+ if (!op) {
+ session.raiseException(event, MH_INVALID_ARGS);
+ } else {
+ action_async(SRV_SERVICES, session, event, op, true);
+ }
+
return TRUE;
} else if (methodName == "start"
@@ -314,7 +319,12 @@ SrvAgent::invoke_services(qmf::AgentSession session, qmf::AgentEvent event,
svc_action_t *op = services_action_create(
args["name"].asString().c_str(), methodName.c_str(), 0, args["timeout"].asInt32());
- action_async(SRV_SERVICES, session, event, op, true);
+ if (!op) {
+ session.raiseException(event, MH_INVALID_ARGS);
+ } else {
+ action_async(SRV_SERVICES, session, event, op, true);
+ }
+
return TRUE;
} else {
@@ -432,6 +442,11 @@ SrvAgent::invoke_resources(qmf::AgentSession session, qmf::AgentEvent event,
args["action"].asString().c_str(),
interval, timeout, params);
+ if (!op) {
+ session.raiseException(event, MH_INVALID_ARGS);
+ return TRUE;
+ }
+
if(args.count("expected-rc") == 1) {
op->expected_rc = args["expected-rc"].asInt32();
}
--
1.7.6
12 years, 8 months
[PATCH 1/2] - Allow for kerberos credential re-ticketing
by Adam Stokes
- Setup some config options to allow the use
of k5start when re-ticketing
Signed-off-by: Adam Stokes <astokes(a)fedoraproject.org>
---
matahari.init.in | 5 +++++
matahari.spec.in | 1 +
matahari.sysconf.in | 14 +++++++++++++-
3 files changed, 19 insertions(+), 1 deletions(-)
diff --git a/matahari.init.in b/matahari.init.in
index 75f9739..cb215de 100644
--- a/matahari.init.in
+++ b/matahari.init.in
@@ -42,6 +42,11 @@ start() {
MATAHARI_ARGS="--broker $MATAHARI_BROKER $MATAHARI_ARGS"
fi
+ # Setup kerberos ticket renewal
+ if [ -n "$KRB_RENEW" ]; then
+ k5start $KRB_RENEW_ARGS $KRB_REALM
+ fi
+
daemon $PROCESS $MATAHARI_ARGS --daemon
RETVAL=$?
echo
diff --git a/matahari.spec.in b/matahari.spec.in
index 6a0c5db..e405a9e 100644
--- a/matahari.spec.in
+++ b/matahari.spec.in
@@ -99,6 +99,7 @@ Group: Applications/System
Requires: %{name}-lib = %{version}-%{release}
Requires: qpid-cpp-client-ssl > 0.7
Requires(pre): shadow-utils
+Requires: kstart
%description agent-lib
C++ library containing the base class for Matahari agents
diff --git a/matahari.sysconf.in b/matahari.sysconf.in
index 4d69015..a89e50d 100644
--- a/matahari.sysconf.in
+++ b/matahari.sysconf.in
@@ -17,4 +17,16 @@ MATAHARI_AGENT_ARGS="--reconnect=yes"
# network_AGENT_ARGS=...
# Per console options
-# sysconfig_CONSOLE_ARGS=...
\ No newline at end of file
+# sysconfig_CONSOLE_ARGS=...
+
+# Security
+# Kerberos
+
+# Uncomment to enable auto-renew credentials
+# KRB_RENEW=yes
+
+# Set custom application and arguments for renew process
+# KRB_RENEW_ARGS="-f /etc/krb5.keytab -K 10 -l 10h"
+
+# Kerberos REALM
+# KRB_REALM="qpidd/EXAMPLE.COM"
\ No newline at end of file
--
1.7.6.1
12 years, 8 months
[PATCH] Doc: Link to Agent Example for developer docs
by Zane Bitter
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
doc/.gitignore | 1
doc/Matahari/en-US/AddingNewAgent.xml | 467 ---------------------------------
2 files changed, 4 insertions(+), 464 deletions(-)
diff --git a/doc/.gitignore b/doc/.gitignore
index 4b64350..b9138c1 100644
--- a/doc/.gitignore
+++ b/doc/.gitignore
@@ -1,2 +1,3 @@
Doxyfile
api/
+tmp
diff --git a/doc/Matahari/en-US/AddingNewAgent.xml b/doc/Matahari/en-US/AddingNewAgent.xml
index 7d6f755..e413bb8 100644
--- a/doc/Matahari/en-US/AddingNewAgent.xml
+++ b/doc/Matahari/en-US/AddingNewAgent.xml
@@ -7,471 +7,10 @@
<chapter id="Matahari-Adding_New_Agent">
<title>Adding a New Agent</title>
- <section id="Matahari-Getting_Started">
- <title>Getting Started</title>
+ <para>The easiest way to begin developing your own Matahari agent is to start with the example agent code. You can fork the <ulink url="http://github.com/matahari/matahari-agent-example">matahari-example-agent repository on GitHub</ulink>, or by cloning the repository directly:</para>
- <para>Getting Started with Matahari development</para>
+ <screen><prompt>$</prompt> <userinput>git clone git://github.com/matahari/matahari-agent-example.git</userinput></screen>
- <section>
- <title>Setting up the environment</title>
+ <para>Full instructions for customising the example are in the <ulink url="https://github.com/matahari/matahari-agent-example/blob/master/README.md">README.md file</ulink> in the repository</para>
- <section>
- <title>Install required packages</title>
-
- <screen><prompt>#</prompt> <userinput>yum groupinstall "Fedora Packager" "Development Libraries" "Development Tools" "MinGW cross-compiler"</userinput></screen>
- </section>
-
- <section>
- <title>Checkout source code</title>
-
- <screen><prompt>$</prompt> <userinput>git clone git://github.com/matahari/matahari.git</userinput></screen>
- </section>
-
- <section>
- <title>Verify Matahari Build</title>
-
- <para>It's always a good idea to build and test the existing code to
- make sure no problems crop up before attempting to develop an agent.
- There are 2 commands provided for cross compilation.</para>
-
- <para>Once building is complete our unittest's should run
- automatically on the Linux platform. Before beginning the journey to
- create an agent make sure that these core unit test never fail. <note>
- <para>Windows builds will need their unittests run on a Windows
- host.</para>
- </note></para>
-
- <section>
- <title>Building for Linux</title>
-
- <screen><prompt>$</prompt> <userinput>make</userinput></screen>
- </section>
-
- <section>
- <title>Building for Windows</title>
-
- <screen><prompt>$</prompt> <userinput>make windows.build</userinput></screen>
- </section>
- </section>
- </section>
- </section>
-
- <section id="Matahari-Prepare_Agent">
- <title>Preparing the Agent</title>
-
- <section>
- <title>Directory Structure</title>
-
- <para>Below is a diagram of how the directory should look with an agent
- named <application>test</application>. <programlisting language="Bash">matahari/
-|
-|--src/
- |--include/
- |--matahari/
- |--test.h # agent library
- |--lib/
- |--test.c # agent library
- |--test/
- |--test-dbus.c # dbus agent
- |--test-qmf.cpp # qmf agent
- |--schema.xml # qmf schema definition
- |--CMakeLists.txt # build instructions
- |--org.matahariproject.Test.conf # dbus xml configuration
- |--org.matahariproject.Test.policy # policykit xml configuration
- |--org.matahariproject.Test.service # dbus service configuration
-
-</programlisting></para>
- </section>
-
- <section>
- <title>Define the API</title>
-
- <para>This library's routine is pretty self explanatory and it what is
- used as our agent's api. <programlisting language="C">int
-mh_plus(int x, int y)
-{
- return x + y;
-}
-</programlisting> <note>
- <para>All Matahari related public api's are prefixed with
- <application>mh_</application></para>
- </note></para>
- </section>
-
- <section>
- <title>The schema definition</title>
-
- <para>A schema describes the structure of management data. Each agent
- provides a schema that describes its management model including the
- object classes, methods, events, etc. that it provides. In the current
- QMF distribution, the agent's schema is codified in an XML document. In
- the near future, there will also be ways to programatically create QMF
- schemata. <footnote>
- <para><ulink
- url="https://cwiki.apache.org/qpid/qpid-management-framework.html\#QpidManagem...">Borrowed
- from Apache QPID Wiki</ulink></para>
- </footnote></para>
-
- <para>Creating a <application>schema.xml</application> file requires the
- use of property and method attributes to describe the api.</para>
-
- <note>
- <para>All agents now contain their own
- <application>schema.xml</application> file which is found within the
- agents source level directory.</para>
- </note>
-
- <para><programlisting language="XML"><schema package="org.matahariproject">
- <class name="Test">
- <property name="uuid" type="sstr" access="RO" desc="Host UUID" index="y" />
- <property name="hostname" type="sstr" access="RO" desc="Hostname" index="y" />
-
- <method name="plus" desc="Sum of two numbers">
- <arg name="x" dir="I" type="int32" />
- <arg name="y" dir="I" type="int32" />
- <arg name="result" dir="O" type="int32" />
- </method>
- </class>
-</schema>
-</programlisting></para>
- </section>
-
- <section>
- <title>Building with CMake</title>
-
- <para>The build tool of choice is CMake. Setting up our agent to be
- included into the distribution should contain a
- <application>CMakeLists.txt</application> which gives the build process
- the necessary instructions.</para>
-
- <para><programlisting language="CMake">cmake_minimum_required(VERSION 2.8)
-
-add_library(mtest SHARED test.c) # Create shared library libmtest from source test.c
-set_target_properties(mtest PROPERTIES SOVERSION 0.0.1) # Set the version of shared library
-target_link_libraries(mtest SOMELIB_LIBRARIES) # Linkage with some external library
-
-# Link to XML definition of your API
-set(SCHEMA ${CMAKE_CURRENT_SOURCE_DIR}/schema.xml)
-
-include(FindPkgConfig) # needed for pkg_check_modules
-
-find_package(Matahari REQUIRED) # Find matahari
-include(MatahariMacros) # You need to include this to use some macros
-
-# QMF
-
- # Find QPid and test if QMF2 is present
-find_package(QPID REQUIRED)
-if(NOT QMF2_FOUND)
- message(FATAL_ERROR "QPid or QMF2 not found")
-endif(NOT QMF2_FOUND)
-
-# Schema points to autogenerated QMF sources
-set(SCHEMA_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/qmf/org/matahariproject/QmfPackage.cpp)
-
-# Generation of QMF sources
-generate_qmf_schemas(${SCHEMA} ${SCHEMA_SOURCES})
-
-# Create QMF agent executable
-add_executable(matahari-qmf-testd test-qmf.cpp ${SCHEMA_SOURCES})
-# Link required libraries
-target_link_libraries(matahari-qmf-testd mtest ${MATAHARI_LIBRARY} ${MATAHARI_QMF_LIBRARY} ${QPIDCOMMON_LIBRARY} ${QMF2_LIBRARY} ${QPIDTYPES_LIBRARY} ${QPIDMESSAGING_LIBRARY})
-
-# DBus
-
-# dbus-glib is required by DBus
-pkg_check_modules(dbus-glib REQUIRED dbus-glib-1)
-include_directories(${dbus-glib_INCLUDE_DIRS})
-
-# Create DBus interface XML files from schema
-generate_dbus_interface(${SCHEMA})
-
-# Create test-dbus-glue.h and test-dbus-properties.h that are used by DBus agent
-generate_dbus_headers(test ${CMAKE_CURRENT_BINARY_DIR}/org.matahariproject.Test.xml)
-
-# Search for generated files in current binary dir
-include_directories(${CMAKE_CURRENT_BINARY_DIR})
-
-# Create DBus agent executable
-add_executable(matahari-dbus-testd test-dbus.c test-dbus-glue.h)
-# Link required libraries
-target_link_libraries(matahari-dbus-testd mtest ${MATAHARI_LIBRARY} ${MATAHARI_DBUS_LIBRARIES} ${dbus-glib_LIBRARIES})
-
-# Install DBus conf and service files
-install(FILES org.matahariproject.Test.conf DESTINATION /etc/dbus-1/system.d)
-install(FILES org.matahariproject.Test.service DESTINATION share/dbus-1/system-services)
-</programlisting></para>
- </section>
- </section>
-
- <section id="Matahari-Creating_Agent">
- <title>Creating the Agent</title>
-
- <para><note>
- <para>For remote access we'll want to create a QMF agent and for our
- local access a DBUS agent.</para>
- </note></para>
-
- <section>
- <title>QMF Agent</title>
-
- <para>Creating the QMF agent requires an agent file
- <application>test-qmf.cpp</application>. This file should contain the
- following code <programlisting language="C++">// Include header files with base class MatahariAgent
-#include <matahari/mh_agent.h>
-// Include QMF header generated from schema.xml
-#include "qmf/org/matahariproject/QmfPackage.h"
-
-// Include header to library that implements action of the agent
-extern "C" {
-#include "test.h"
-}
-
-// Class for the new agent - inherited from MatahariAgent
-class TestAgent : public MatahariAgent
-{
-private:
- qmf::org::matahariproject::PackageDefinition _package;
-public:
- int setup(qmf::AgentSession session);
- gboolean invoke(qmf::AgentSession session, qmf::AgentEvent event,
- gpointer user_data);
-};
-
-
-int
-main(int argc, char **argv)
-{
- // Create and run the agent
- TestAgent agent;
- int rc = agent.init(argc, argv, "test");
- if (rc == 0) {
- agent.run();
- }
- return rc;
-}
-
-int
-TestAgent::setup(qmf::AgentSession session)
-{
- _package.configure(session);
- _instance = qmf::Data(_package.data_Test);
-
- // Set values for the properties
- _instance.setProperty("answer", get_answer());
-
- _agent_session.addData(_instance);
- return 0;
-}
-
-gboolean
-TestAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event,
- gpointer user_data)
-{
- if(event.getType() == qmf::AGENT_METHOD) {
- // Method handling
- const std::string& methodName(event.getMethodName());
- if (methodName == "plus") {
- int32_t x, y, sum;
- // Get the input parameters
- x = event.getArguments()["x"].asInt32();
- y = event.getArguments()["y"].asInt32();
- // Call method from the library
- // (:: is here because of conflict with STL)
- sum = ::mh_plus(x, y);
- // Set output parameters
- event.addReturnArgument("result", sum);
- } else {
- // Function is not implemented
- session.raiseException(event, MH_NOT_IMPLEMENTED);
- goto bail;
- }
- }
- // Method call succeeded
- session.methodSuccess(event);
- bail:
- return TRUE;
-}
-</programlisting></para>
- </section>
-
- <section>
- <title>DBus Agent</title>
-
- <para>Creating the DBus agent requires a couple of resource files that
- define DBus relevant information. These examples demonstrate policykit
- and automatic activation of the dbus service. <programlisting
- language="C">// Some supporting function for DBus agent
-#include <matahari/mh_dbus_common.h>
-
-// Include header to library that implements action of the agent
-#include "test.h"
-
-// Name of the object on DBus
-#define HOST_BUS_NAME "org.matahariproject.Test"
-// Path to the object
-#define HOST_OBJECT_PATH "/org/matahariproject/Test"
-
-// Every function in your schema must be defined here with following prototype:
-// gboolean className_methodName(Matahari *matahari, IN_argument_1,
-// IN_argument_2, IN_argument_n,
-// DBusGMethodInvocation *context);
-// Return output arguments with dbus_g_method_return(context, OUT_argument_1,
-// OUT_argument_2,
-// OUT_arguemnt_n);
-// Or return error with dbus_g_method_return_error(context, error);
-// where error is GError
-gboolean
-Test_plus(Matahari *matahari, int x, int y, DBusGMethodInvocation *context)
-{
- dbus_g_method_return(context, plus(x, y));
- return TRUE;
-}
-
-// Include autogenerated files AFTER declaration of functions
-#include "test-dbus-glue.h"
-#include "test-dbus-properties.h"
-
-// This function is executed when property is set to some value
-void
-matahari_set_property(GObject *object, guint property_id, const GValue *value,
- GParamSpec *pspec)
-{
-}
-
-// This function is executed when value of some property is requested
-void
-matahari_get_property(GObject *object, guint property_id, GValue *value,
- GParamSpec *pspec)
-{
- switch (property_id)
- {
- case PROP_ANSWER:
- g_value_set_int (value, get_answer());
- break;
- }
-}
-
-// This function must be present. It can be used to define types of dictionaries
-GType matahari_dict_type(int prop)
-{
- g_printerr("Type of property %d is map of unknown types\n", prop);
- return G_TYPE_VALUE;
-}
-
-int main(int argc, char *argv[])
-{
- g_type_init();
- // Run the agent
- return run_dbus_server(HOST_BUS_NAME, HOST_OBJECT_PATH);
-}
-</programlisting></para>
- </section>
-
- <section>
- <title>DBus configuration</title>
-
- <para>The next bit of code is DBus configuration
- <application>org.matahariproject.Test.conf</application> which will be
- installed to <application>/etc/dbus-1/system.d</application>
- <programlisting language="XML"><?xml version="1.0" encoding="UTF-8"?>
-
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
- <!-- Only root can own the service -->
- <policy user="root">
- <allow own="org.matahariproject.Test"/>
- </policy>
-
- <!-- Allow anyone to invoke methods on the interfaces -->
- <policy context="default">
- <allow send_destination="org.matahariproject.Test"/>
- </policy>
-</busconfig>
-</programlisting></para>
- </section>
-
- <section>
- <title>Configuration of on demand activation</title>
-
- <para>Finally, the on demand activation configuration
- <application>org.matahariproject.Test.service</application> which is to
- be installed in
- <application>/usr/share/dbus-1/system-services/</application>
- <programlisting language="INI Files">[D-BUS Service]
-Name=org.matahariproject.Test
-Exec=/usr/sbin/matahari-dbus-test
-User=root
-</programlisting></para>
- </section>
- </section>
-
- <section id="chap-Matahari-Testing_Agent">
- <title>We like quality software so please test</title>
-
- <para>For now Cxxtest is the choice of testing platform. It's cross
- platform and for the most part easy to get up to speed on. <important>
- <para><application>mingw32-cxxtest</application> is needed if wanting
- to build test cases for Windows platform. <footnote>
- <para><ulink
- url="https://bugzilla.redhat.com/show_bug.cgi?id=708473">mingw32-cxxtest
- - Red Hat package review</ulink></para>
- </footnote></para>
- </important></para>
-
- <section>
- <title>Defining the Test Suite</title>
-
- <para>Create <application>matahari/src/tests/mh_api_test.h</application>
- and include the following. <programlisting language="C++">#ifndef __MH_API_TEST_UNITTEST_H
-#define __MH_API_TEST_UNITTEST_H
-#include <iostream>
-#include <string>
-#include <sstream>
-#include <utility>
-#include <vector>
-#include <cstdlib>
-#include <cstdio>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <cxxtest/TestSuite.h>
-
-extern "C" {
-#include "matahari/test.h"
-#include <glib.h>
-#include "mh_test_utilities.h"
-};
-
-using namespace std;
-
-class MhApiTestSuite : public CxxTest::TestSuite
-{
- public:
-
- void testAddition(void)
- {
- TS_ASSERT((mh_plus(2,2)) == 4);
- }
-};
-
-#endif
-</programlisting></para>
- </section>
-
- <section>
- <title>Building tests with CMake</title>
-
- <para>CMake provides a macro for CxxTest which enables a seamless
- integration with the build process. <programlisting language="CMake">set(CXXTEST_USE_PYTHON TRUE)
-find_package(CxxTest)
-if(CXXTEST_FOUND)
- include_directories(${CXXTEST_INCLUDE_DIR})
- ENABLE_TESTING()
- CXXTEST_ADD_TEST(mh_test_unittest test_unittest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/mh_api_test.h)
-endif(CXXTEST_FOUND)
-</programlisting></para>
- </section>
- </section>
</chapter>
12 years, 8 months