[PATCH 0/11] UUIDs on Windows
by Russell Bryant
Greetings,
This adds some UUID support for Windows in the host agent. Specifically,
the "custom" and "agent" UUIDs are now suppoted. I wrote some code for
the "hardware" and "reboot" UUIDs, but had to comment it out in the end
due to funcitons not being available with mingw32.
I implemented the "verbose" option for Windows. Without it, I found it
nearly impossible to do much debugging since I couldn't get debug output
anywhere.
The rest includes some bug fixes and coding style updates that I made
as I made my way through the code.
[PATCH 01/11] host: style updates in uuid related code.
[PATCH 02/11] host: make agent UUID semantics more consistent.
[PATCH 03/11] core: Add missing RegCloseKey() for Windows UUID.
[PATCH 04/11] host: Rewrite custom UUID support for Windows.
[PATCH 05/11] host: Implement agent UUID for Windows.
[PATCH 06/11] host: non-support for SMBIOS UUID on Windows.
[PATCH 07/11] host: add non-support for the reboot UUID.
[PATCH 08/11] core: Add verbose option support on Windows.
[PATCH 09/11] build: Add -v to mock.
[PATCH 10/11] host: Make UUID lifetime case insensitive in set_uuid.
[PATCH 11/11] host: Document which UUIDs are Linux-only.
GNUmakefile | 2
src/host/schema.xml | 6 -
src/lib/host.c | 4
src/lib/host_linux.c | 75 +++++++------
src/lib/host_private.h | 2
src/lib/host_windows.c | 250 +++++++++++++++++++++++++++++++++++++++++---
src/lib/mh_agent.cpp | 17 ++
src/lib/utilities_windows.c | 29 ++---
8 files changed, 312 insertions(+), 73 deletions(-)
Thanks,
--
Russell Bryant
12 years, 7 months
libvirt-qmf selinux and systemd
by Perry Myers
Zane,
You did a bunch of work on matahari to convert to systemd for
F16/rawhide, but did you cover libvirt-qmf in that systemd conversion as
well?
Also... does libvirt-qmf start by default when it is installed or does
the user need to manually enable it after install?
dwalsh will be helping us out with defining a selinux policy for
libvirt-qmf, since it popped up on his radar as a daemon that runs as
initrc_t.
Thanks for chiming in on these things Dan :)
Perry
12 years, 7 months
Qpid SSL multiplexing
by Zane Bitter
I have a working proof-of-concept patch to accept both SSL and non-SSL
connections on the same port in qpidd here:
https://github.com/zaneb/qpid/commit/7ed22e8eda4a106052e16f8a9fe4d2889c50...
I am not submitting this to the Qpid list at this stage, as it is
clearly in an unfit state to be merged upstream. Now that I have scoped
out the issues I am working on a patch that will have less impact on
existing code. However the current basic approach is as follows:
1) After accepting a new connection, peek at the first 4 bytes sent by
the client.
2) If the first 4 bytes are 'A', 'M', 'Q', 'P' then start a regular AMQP
connection.
3) Otherwise, start an AMQPS connection.
If --encryption-required is specified, then AMQP connections are treated
the same as connections to the AMQP port were previously - an error is
returned to the client indicating that encryption is required.
This does actually contravene the AMQP 0-10 spec, which states (in
section 4.3) that "If the server can't parse the protocol header, the
server MUST send a valid protocol header with a supported protocol
version and then close the socket."
Although I consider it unlikely that future versions of AMQP will ever
begin a connection with a different header (version 1.0 still begins
with 'AMQP', although the format of the version number that follows is
different) perhaps a better approach would be to specifically look for
an SSL/TLS header. This has the downside that it may not recognise
future versions of TLS without changes to the code. That approach still
technically breaks the spec, but in a way that I am entirely comfortable
with :)
Open questions:
* How do we enable this option? My current thought is to check for the
existence of an environment variable such as QPID_MULTIPLEX_SSL.
* Which port should we use? The regular port or the ssl-port from the
config file? We need to prevent the non-SSL listener service opening on
the regular port anyway (provided the SSL plugin is actually loaded), so
I'm inclined to just use that.
* When configuring federated brokers, how do we determine whether to
connect over SSL? Options:
- For straight domain names we probably already support the syntax
amqp:ssl:<fqdn>:<port>, so we'd just have to document and test it.
- For DNS SRV lookups, we could get the IANA to assign us the service
name 'matahari-tls' (without an associated port) and lookup
_matahari-tls._tcp.<fqdn> for SSL connections.
- Alternatively, we could lookup _matahari._ssl.<fqdn>, but I'm not
sure how legit that is.
- We could just assume that if SSL is configured locally we should use
it with all other brokers, and if not, not.
- All of this assumes that SSL actually works in the tool we use to
configure broker federation ;)
* It will take a while to get this upstream, if they accept it at all
(especially in version 0.10). What's our short-term plan?
cheers,
Zane.
12 years, 7 months
Small update to matahari BuildRequires
by James Laska
Greetings,
> matahari.spec.in | 2 +-
> mingw32-matahari.spec.in | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
While playing with building matahari RPM packages from the git repo, I noticed
one of the BuildRequires has changed name from qmf-devel to qpid-qmf-devel.
While a %provides is available, and yum resolves this dependency without error,
I decided to include a small patch to update to the current package name. This
patch isn't required for proper packaging, but is a small fix and uses the
current package name, rather than relying on a %provides (which often gets
confusing down the line).
Comments welcome!
Thanks,
James
12 years, 7 months
[PATCH 1/2] Implement augeas support in Sysconfig agent v2
by Radek Novacek
---
src/CMakeLists.txt | 9 +++
src/include/matahari/sysconfig.h | 4 +-
src/lib/CMakeLists.txt | 2 +-
src/lib/sysconfig.c | 2 +-
src/lib/sysconfig_linux.c | 116 +++++++++++++++++++++++++++++++++++---
src/lib/sysconfig_private.h | 2 +-
src/sysconfig/sysconfig-qmf.cpp | 5 +-
7 files changed, 126 insertions(+), 14 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e3a7e38..bd31326 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -109,6 +109,15 @@ if(NOT WIN32)
endif(CURL STREQUAL "CURL-NOTFOUND")
endif(NOT WIN32)
+# Augeas
+# At least version 0.9.0 - we need aug_srun command
+if(NOT WIN32)
+ pkg_check_modules(augeas REQUIRED augeas>=0.9.0)
+ if(NOT augeas_FOUND)
+ message(FATAL_ERROR "Augeas headers/library >= 0.9.0 not found.")
+ endif(NOT augeas_FOUND)
+endif(NOT WIN32)
+
# Include QMF and DBus generation macros
include(MatahariMacros)
diff --git a/src/include/matahari/sysconfig.h b/src/include/matahari/sysconfig.h
index 21a59eb..86998a1 100644
--- a/src/include/matahari/sysconfig.h
+++ b/src/include/matahari/sysconfig.h
@@ -88,9 +88,11 @@ mh_sysconfig_run_string(const char *string, uint32_t flags, const char *scheme,
* \param[in] flags flags used
* \param[in] scheme the type of configuration i.e. puppet
*
+ * \note The return of this routine must be freed with free()
+ *
* \return DATA of returned query result
*/
-const char *
+char *
mh_sysconfig_query(const char *query, uint32_t flags, const char *scheme);
/**
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 4b2326c..260c9b1 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -28,7 +28,7 @@ target_link_libraries(mservice ${pcre_LIBRARIES} mcommon ${SIGAR} ${glib_LIBRARI
add_library (msysconfig SHARED sysconfig.c sysconfig_${VARIANT}.c)
set_target_properties(msysconfig PROPERTIES SOVERSION 1.0.0)
-target_link_libraries(msysconfig ${pcre_LIBRARIES} mcommon mservice ${glib_LIBRARIES})
+target_link_libraries(msysconfig ${pcre_LIBRARIES} mcommon mservice ${glib_LIBRARIES} ${augeas_LIBRARIES})
if(WIN32)
foreach (lib ${LIBS})
diff --git a/src/lib/sysconfig.c b/src/lib/sysconfig.c
index 4e32737..bb58771 100644
--- a/src/lib/sysconfig.c
+++ b/src/lib/sysconfig.c
@@ -146,7 +146,7 @@ mh_sysconfig_run_string(const char *string, uint32_t flags, const char *scheme,
return sysconfig_os_run_string(string, flags, scheme, key, result_cb, cb_data);
}
-const char *
+char *
mh_sysconfig_query(const char *query, uint32_t flags, const char *scheme)
{
return sysconfig_os_query(query, flags, scheme);
diff --git a/src/lib/sysconfig_linux.c b/src/lib/sysconfig_linux.c
index 9a87288..421fb66 100644
--- a/src/lib/sysconfig_linux.c
+++ b/src/lib/sysconfig_linux.c
@@ -25,6 +25,7 @@
#include <unistd.h>
#include <glib.h>
#include <curl/curl.h>
+#include <augeas.h>
#include "matahari/logging.h"
#include "matahari/utilities.h"
@@ -292,18 +293,115 @@ return_failure:
}
static int
-run_augeas(const char *query, const char *data, const char *key,
+run_augeas(const char *uri, const char *data, const char *key,
mh_sysconfig_result_cb result_cb, void *cb_data)
{
- mh_warn("not implemented\n");
- return -1;
+ int fd;
+ FILE *fp;
+ char *text = NULL;
+ char filename[PATH_MAX];
+ GError *err = NULL;
+ augeas *aug;
+ int result;
+ char *value = NULL;
+
+ if (uri) {
+ snprintf(filename, sizeof(filename), "%s", "augeas_conf_XXXXXX");
+
+ fd = mkstemp(filename);
+ if (fd < 0) {
+ mh_err("Unable to create temporary file");
+ return -1;
+ }
+
+ fp = fdopen(fd, "w+b");
+ if (fp == NULL) {
+ close(fd);
+ unlink(filename);
+ mh_err("Unable to open temporary file");
+ return -1;
+ }
+
+ if ((sysconfig_os_download(uri, fp)) != 0) {
+ fclose(fp);
+ unlink(filename);
+ mh_err("Unable to download file from uri %s", uri);
+ return -1;
+ }
+
+ fclose(fp);
+
+ if (!g_file_get_contents(filename, &text, NULL, &err)) {
+ mh_err("Unable to read downloaded file: %s", err ? err->message : "Unknown error");
+ unlink(filename);
+ return -1;
+ }
+
+ unlink(filename);
+
+ } else if (data) {
+ text = g_strdup(data);
+ } else {
+ mh_err("No uri/data provided for augeas");
+ return -1;
+ }
+
+ snprintf(filename, sizeof(filename), "%s", "augeas_conf_XXXXXX");
+
+ fd = mkstemp(filename);
+ if (fd < 0) {
+ mh_err("Unable to create temporary file");
+ return -1;
+ }
+
+ fp = fdopen(fd, "w+b");
+ if (fp == NULL) {
+ close(fd);
+ unlink(filename);
+ mh_err("Unable to open temporary file");
+ return -1;
+ }
+
+ aug = aug_init("", "", AUG_SAVE_BACKUP);
+ result = aug_srun(aug, fp, text);
+
+ mh_info("run_augeas for key \"%s\" exited with status %d and data \"%s\"", key, result, text);
+
+ aug_close(aug);
+
+ g_free(text);
+ fclose(fp);
+
+ if (result < 0) {
+ unlink(filename);
+ mh_err("Augeas command failed");
+ return -1;
+ }
+
+ if (!g_file_get_contents(filename, &value, NULL, &err)) {
+ mh_err("Unable to read augeas results: %s", err->message);
+ unlink(filename);
+ return -1;
+ }
+
+ mh_sysconfig_set_configured(key, value);
+ result_cb(cb_data, result);
+
+ unlink(filename);
+
+ return 0;
}
-static const char *
+static char *
sysconfig_os_query_augeas(const char *query)
{
- const char *data = NULL;
- mh_warn("not implemented\n");
+ char *data = NULL;
+ const char *value = NULL;
+ augeas *aug = aug_init("", "", 0);
+ aug_get(aug, query, &value);
+ if (value)
+ data = strdup(value);
+ aug_close(aug);
return data;
}
@@ -348,6 +446,8 @@ sysconfig_os_run_string(const char *string, uint32_t flags, const char *scheme,
if (!strcasecmp(scheme, "puppet")) {
rc = run_puppet(NULL, string, key, result_cb, cb_data);
+ } else if (strcasecmp(scheme, "augeas") == 0) {
+ rc = run_augeas(NULL, string, key, result_cb, cb_data);
} else {
rc = -1;
}
@@ -355,10 +455,10 @@ sysconfig_os_run_string(const char *string, uint32_t flags, const char *scheme,
return rc;
}
-const char *
+char *
sysconfig_os_query(const char *query, uint32_t flags, const char *scheme)
{
- const char *data = NULL;
+ char *data = NULL;
if (strcasecmp(scheme, "augeas") == 0) {
data = sysconfig_os_query_augeas(query);
diff --git a/src/lib/sysconfig_private.h b/src/lib/sysconfig_private.h
index fb49905..260a459 100644
--- a/src/lib/sysconfig_private.h
+++ b/src/lib/sysconfig_private.h
@@ -29,7 +29,7 @@ sysconfig_os_run_string(const char *string, uint32_t flags, const char *scheme,
const char *key, mh_sysconfig_result_cb result_cb,
void *cb_data);
-const char *
+char *
sysconfig_os_query(const char *query, uint32_t flags, const char *scheme);
#endif /* __MH_SYSCONFIG_PRIVATE_H_ */
diff --git a/src/sysconfig/sysconfig-qmf.cpp b/src/sysconfig/sysconfig-qmf.cpp
index 1ffaa59..840c89e 100644
--- a/src/sysconfig/sysconfig-qmf.cpp
+++ b/src/sysconfig/sysconfig-qmf.cpp
@@ -153,11 +153,12 @@ ConfigAgent::invoke(qmf::AgentSession session, qmf::AgentEvent event, gpointer u
async = true;
}
} else if (methodName == "query") {
- const char *data = NULL;
- data = mh_sysconfig_query(args["query"].asString().c_str(),
+ char *data = NULL;
+ data = mh_sysconfig_query(args["text"].asString().c_str(),
args["flags"].asUint32(),
args["scheme"].asString().c_str());
event.addReturnArgument("data", data ? data : "unknown");
+ free(data);
} else if (methodName == "is_configured") {
status = mh_sysconfig_is_configured(args["key"].asString().c_str());
event.addReturnArgument("status", status ? status : "unknown");
--
1.7.6.2
12 years, 7 months
[PATCH] Fix build failure on windows introduced by augeas patch
by Radek Novacek
---
src/lib/sysconfig_windows.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/lib/sysconfig_windows.c b/src/lib/sysconfig_windows.c
index e87ab52..00b5dce 100644
--- a/src/lib/sysconfig_windows.c
+++ b/src/lib/sysconfig_windows.c
@@ -82,9 +82,8 @@ sysconfig_os_run_string(const char *string, uint32_t flags, const char *scheme,
return -1;
}
-const char *
+char *
sysconfig_os_query(const char *query, uint32_t flags, const char *scheme)
{
- const char *data = NULL;
- return data;
+ return NULL;
}
--
1.7.6.2
12 years, 7 months
[PATCH] Check malloc() return values
by Zane Bitter
This should keep Coverity happy.
Signed-off-by: Zane Bitter <zbitter(a)redhat.com>
---
src/broker/broker.c | 51 ++++++++++++++++++++++++++++++++++----------------
src/lib/host_linux.c | 22 ++++++++++++++++------
2 files changed, 51 insertions(+), 22 deletions(-)
diff --git a/src/broker/broker.c b/src/broker/broker.c
index 63894b7..ead2a61 100644
--- a/src/broker/broker.c
+++ b/src/broker/broker.c
@@ -45,22 +45,48 @@ uint16_t broker_get_port(void)
return port ? port : MATAHARI_PORT;
}
+
+static void broker_args_free(char **args)
+{
+ char **p = args;
+
+ while (*args) {
+ free(*args++);
+ }
+
+ free(p);
+}
+
+#define APPEND_ARG(ARGS, COUNT, NEWARG) do { \
+ const char *_newarg = strdup(NEWARG); \
+ if (((ARGS)[(COUNT)++] = _newarg) == NULL) { \
+ mh_err("Failed to allocate string"); \
+ broker_args_free(ARGS); \
+ return NULL; \
+ } \
+} while (0)
+
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 (!newargs) {
+ mh_err("Failed to allocate argument list");
+ return NULL;
+ }
+
if (argc) {
- newargs[o++] = strdup(argv[i++]);
+ APPEND_ARG(newargs, o, 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");
+ APPEND_ARG(newargs, o, portarg);
+ APPEND_ARG(newargs, o, "--data-dir=" LOCAL_STATE_DIR "/lib/matahari");
while (i < argc) {
- newargs[o++] = strdup(argv[i++]);
+ APPEND_ARG(newargs, o, argv[i++]);
}
newargs[o] = NULL;
@@ -68,24 +94,17 @@ static char **broker_args(int argc, char * const argv[])
return newargs;
}
-static void broker_args_free(char **args)
-{
- char **p = args;
-
- while (*args) {
- free(*args++);
- }
-
- free(p);
-}
int main(int argc, char *argv[])
{
+ int ret = 1;
char **arglist = broker_args(argc, argv);
- int ret = broker_os_start_broker(arglist);
+ if (arglist) {
+ ret = broker_os_start_broker(arglist);
- broker_args_free(arglist);
+ broker_args_free(arglist);
+ }
return ret;
}
diff --git a/src/lib/host_linux.c b/src/lib/host_linux.c
index c17c7ca..bae10f1 100644
--- a/src/lib/host_linux.c
+++ b/src/lib/host_linux.c
@@ -39,6 +39,10 @@
#include "matahari/host.h"
#include "host_private.h"
+
+#define UUID_STR_BUF_LEN 37
+
+
const char *
host_os_get_cpu_flags(void)
{
@@ -263,21 +267,25 @@ char *host_os_reboot_uuid(void)
const char *file = "/var/run/matahari-reboot-id";
char *uuid = mh_file_first_line(file);
- if(uuid == NULL) {
+ if (uuid == NULL) {
uuid_t buffer;
GError* error = NULL;
- uuid = malloc(38);
+ uuid = malloc(UUID_STR_BUF_LEN);
+ if (!uuid) {
+ return NULL;
+ }
+
uuid_generate(buffer);
uuid_unparse(buffer, uuid);
- if(g_file_set_contents(file, uuid, strlen(uuid), &error) == FALSE) {
+ if (g_file_set_contents(file, uuid, strlen(uuid), &error) == FALSE) {
mh_info("%s", error->message);
free(uuid);
uuid = strdup(error->message);
}
- if(error) {
+ if (error) {
g_error_free(error);
}
}
@@ -291,8 +299,10 @@ const char *host_os_agent_uuid(void)
static char *agent_uuid = NULL;
uuid_generate(buffer);
- agent_uuid = malloc(38);
- uuid_unparse(buffer, agent_uuid);
+ agent_uuid = malloc(UUID_STR_BUF_LEN);
+ if (agent_uuid) {
+ uuid_unparse(buffer, agent_uuid);
+ }
return agent_uuid;
}
12 years, 7 months
[PATCH] - Do not accept filenames prefixed with .. or / v2
by Adam Stokes
There is basically no limitation on how the key name
is defined. With that said we should at least make sure
the keys do not start with a '/' or '..'. This will
eliminate accidental typos and also intentional ones.
Signed-off-by: Adam Stokes <astokes(a)fedoraproject.org>
---
src/lib/sysconfig.c | 16 +++++++++++++++-
src/tests/mh_api_sysconfig.h | 6 ++++++
2 files changed, 21 insertions(+), 1 deletions(-)
diff --git a/src/lib/sysconfig.c b/src/lib/sysconfig.c
index 0301734..92bbfd4 100644
--- a/src/lib/sysconfig.c
+++ b/src/lib/sysconfig.c
@@ -68,10 +68,24 @@ static gboolean
set_key(const char *key, const char *contents)
{
char key_file[PATH_MAX];
+ char valid_chars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.";
+ char sanitized_key[PATH_MAX];
if (mh_strlen_zero(key)) {
mh_err("key cannot be empty");
- return -1;
+ return FALSE;
+ }
+
+ if (g_str_has_prefix(key, ".")) {
+ mh_err("Invalid key filename %s", key);
+ return FALSE;
+ }
+
+ mh_string_copy(sanitized_key, key, sizeof(sanitized_key));
+ g_strcanon(sanitized_key, valid_chars, '!');
+ if (g_strstr_len(sanitized_key, PATH_MAX, "!") != NULL) {
+ mh_err("Invalid key filename %s", sanitized_key);
+ return FALSE;
}
if (!g_file_test(keys_dir_get(), G_FILE_TEST_IS_DIR) &&
diff --git a/src/tests/mh_api_sysconfig.h b/src/tests/mh_api_sysconfig.h
index 0bab713..0088df5 100644
--- a/src/tests/mh_api_sysconfig.h
+++ b/src/tests/mh_api_sysconfig.h
@@ -29,6 +29,9 @@ class MhApiSysconfigSuite : public CxxTest::TestSuite
void testIsConfigured(void)
{
const char key[] = "org.matahariproject.test.unittest"; // Unimportant key defined
+ const char *invalid_keys[3] = {"../etc/passwd",
+ "./../etc/passwd#",
+ "HAPPY#HAMMY,@"};
char *key_res;
mh_sysconfig_keys_dir_set("/tmp/matahari-sysconfig-keys/");
@@ -38,6 +41,9 @@ class MhApiSysconfigSuite : public CxxTest::TestSuite
TS_ASSERT(!strcmp("OK", key_res));
free(key_res);
+ for (int i = 0; i < 3; i++) {
+ TS_ASSERT((mh_sysconfig_set_configured(invalid_keys[i], "OK")) == FALSE);
+ }
}
};
--
1.7.6.2
12 years, 7 months
Virt installer w/ vios-proxy
by Adam Stokes
Hi Cole,
Just wanted to make you aware of
https://github.com/matahari/matahari/wiki/Vios-Proxy where we are in a
proof of concept stage at the moment.
Our goal is to make vios-proxy integration as simple as possible and I
was told you may be doing some work on the virt-install code to add
support for these devices?
Would like to get your input or see if you need any help with getting
this rolling within the installer for virtual machines.
Thanks!
12 years, 7 months
[PATCH] build: run unit tests in autobuild.
by Russell Bryant
Update the spec file to optionally run the unit tests during a build.
Set this variable when doing RPM builds with mock on the autobuild
instance.
Signed-off-by: Russell Bryant <rbryant(a)redhat.com>
---
autobuild.sh | 2 +-
matahari.spec.in | 7 +++++++
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/autobuild.sh b/autobuild.sh
index f8bf747..0629628 100755
--- a/autobuild.sh
+++ b/autobuild.sh
@@ -59,7 +59,7 @@ make_srpm
results=$AUTOBUILD_PACKAGE_ROOT/rpm/RPMS/`rpm --eval %{_arch}`
rm -f $results/build.log $results/*.rpm
-/usr/bin/mock --root=$build_target --resultdir=$results --rebuild ${PWD}/*.src.rpm
+/usr/bin/mock --define="run_unit_tests 1" --root=$build_target --resultdir=$results --rebuild ${PWD}/*.src.rpm
rc=$?
if [ $rc != 0 ]; then
diff --git a/matahari.spec.in b/matahari.spec.in
index 381a977..fde36a0 100644
--- a/matahari.spec.in
+++ b/matahari.spec.in
@@ -64,6 +64,10 @@ BuildRequires: qmf-devel > 0.7
BuildRequires: dbus-devel dbus-glib-devel polkit-devel libxslt
%endif
+%if %{defined run_unit_tests}
+BuildRequires: cxxtest
+%endif
+
%description
Matahari provides QMF Agents that can be used to control and manage
@@ -193,6 +197,9 @@ QMF console for monitoring various agents
%build
%{cmake} -DCMAKE_BUILD_TYPE=RelWithDebInfo %{!?with_qmf: -DWITH-QMF:BOOL=OFF} %{!?with_dbus: -DWITH-DBUS:BOOL=OFF} -Dinitdir=%{_initddir} -Dsysconfdir=%{_sysconfdir} .
make %{?_smp_mflags}
+%if %{defined run_unit_tests}
+cd src/tests && ctest -V
+%endif
%install
rm -rf %{buildroot}
--
1.7.6.2
12 years, 7 months