[Reconnoiter-devel] [reconnoiter commit] Reconnoiter branch, master, updated. c6c11c3827cd812cc0f9cc92cf6de8140b859416
git at labs.omniti.com
git at labs.omniti.com
Wed Jan 4 09:54:38 EST 2012
Pushed by: jesus
The branch, master has been updated
via c6c11c3827cd812cc0f9cc92cf6de8140b859416 (commit)
from 8dfd79782e697b0ac7f68e010887609de0ff34e9 (commit)
Summary of changes:
src/modules/check_test.c | 25 +++++++++-
src/noit_check.c | 124 +++++++++++++++++++++++++++++++++++++++++++++-
src/noit_check.h | 20 +++++++
src/noit_check_rest.c | 29 +++++++++--
src/noit_conf.c | 46 +++++++++++++----
src/noit_conf.h | 3 +
6 files changed, 229 insertions(+), 18 deletions(-)
Log:
commit c6c11c3827cd812cc0f9cc92cf6de8140b859416
Author: Theo Schlossnagle <jesus at omniti.com>
Date: Wed Jan 4 09:53:41 2012 -0500
Support generic module configuration with using XML namespaces and
allow modules to register themselves as as interested in such for
all checks.
diff --git a/src/modules/check_test.c b/src/modules/check_test.c
index 131a13c..b4a507a 100644
--- a/src/modules/check_test.c
+++ b/src/modules/check_test.c
@@ -97,11 +97,12 @@ noit_check_t *
noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
char *target = NULL, *name = NULL, *module = NULL, *filterset = NULL;
char *resolve_rtype = NULL;
- int timeout = 0, flags = NP_TRANSIENT;
+ int timeout = 0, flags = NP_TRANSIENT, i, mod_cnt;
noit_module_t *m;
noit_check_t *c = NULL;
xmlNodePtr a, co;
noit_hash_table *conf_hash = NULL;
+ noit_hash_table **moptions = NULL;
for(a = attr->children; a; a = a->next) {
if(!strcmp((char *)a->name, "target"))
@@ -136,6 +137,18 @@ noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
xmlFree(tmp_val);
}
}
+ mod_cnt = noit_check_registered_module_cnt();
+ if(mod_cnt > 0) {
+ moptions = alloca(mod_cnt * sizeof(*moptions));
+ memset(moptions, 0, mod_cnt * sizeof(*moptions));
+ for(i=0; i<mod_cnt; i++) {
+ const char *name;
+ noit_conf_section_t checks;
+ name = noit_check_registered_module(i);
+ checks = noit_conf_get_section(NULL, "/noit/checks");
+ if(name) moptions[i] = noit_conf_get_namespaced_hash(checks, "config", name);
+ }
+ }
if(!m->initiate_check) {
*error = "that module cannot run checks";
goto error;
@@ -143,7 +156,7 @@ noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
flags |= noit_calc_rtype_flag(resolve_rtype);
c = calloc(1, sizeof(*c));
noit_check_update(c, target, name, filterset,
- conf_hash, 0, timeout, NULL, flags);
+ conf_hash, moptions, 0, timeout, NULL, flags);
c->module = strdup(module);
uuid_generate(c->checkid);
c->flags |= NP_DISABLED; /* this is hack to know we haven't run it yet */
@@ -155,6 +168,14 @@ noit_fire_check(xmlNodePtr attr, xmlNodePtr config, const char **error) {
noit_hash_destroy(conf_hash, free, free);
free(conf_hash);
}
+ if(moptions) {
+ for(i=0; i<mod_cnt; i++) {
+ if(moptions[i]) {
+ noit_hash_destroy(moptions[i], free, free);
+ free(moptions[i]);
+ }
+ }
+ }
if(target) xmlFree(target);
if(name) xmlFree(name);
if(module) xmlFree(module);
diff --git a/src/noit_check.c b/src/noit_check.c
index f0eed27..f42d81b 100644
--- a/src/noit_check.c
+++ b/src/noit_check.c
@@ -56,7 +56,17 @@
/* 60 seconds of possible stutter */
#define MAX_INITIAL_STUTTER 60000
+#define MAX_MODULE_REGISTRATIONS 64
+/* used to manage per-check generic module metadata */
+struct vp_w_free {
+ void *ptr;
+ void (*freefunc)(void *);
+};
+
+static int reg_module_id = 0;
+static char *reg_module_names[MAX_MODULE_REGISTRATIONS] = { NULL };
+static int reg_module_used = -1;
static u_int64_t check_completion_count = 0;
static noit_hash_table polls = NOIT_HASH_EMPTY;
static noit_skiplist watchlist = { 0 };
@@ -161,12 +171,20 @@ noit_poller_process_checks(const char *xpath) {
char filterset[256] = "";
char oncheck[1024] = "";
char resolve_rtype[16] = "";
+ int ridx;
int no_period = 0;
int no_oncheck = 0;
int period = 0, timeout = 0;
noit_boolean disabled = noit_false, busted = noit_false;
uuid_t uuid, out_uuid;
noit_hash_table *options;
+ noit_hash_table **moptions = NULL;
+ noit_boolean moptions_used = noit_false;
+
+ if(reg_module_id > 0) {
+ moptions = alloca(reg_module_id * sizeof(noit_hash_table *));
+ memset(moptions, 0, reg_module_id * sizeof(noit_hash_table *));
+ }
#define NEXT(...) noitL(noit_stderr, __VA_ARGS__); continue
#define MYATTR(type,a,...) noit_conf_get_##type(sec[i], "@" #a, __VA_ARGS__)
@@ -226,6 +244,11 @@ noit_poller_process_checks(const char *xpath) {
timeout = period/2;
}
options = noit_conf_get_hash(sec[i], "config");
+ for(ridx=0; ridx<reg_module_id; ridx++) {
+ moptions[ridx] = noit_conf_get_namespaced_hash(sec[i], "config",
+ reg_module_names[ridx]);
+ if(moptions[ridx]) moptions_used = noit_true;
+ }
INHERIT(boolean, disable, &disabled);
flags = 0;
@@ -248,17 +271,25 @@ noit_poller_process_checks(const char *xpath) {
existing_check->module = strdup(module);
}
noit_check_update(existing_check, target, name, filterset, options,
+ moptions_used ? moptions : NULL,
period, timeout, oncheck[0] ? oncheck : NULL,
flags);
noitL(noit_debug, "reloaded uuid: %s\n", uuid_str);
}
else {
noit_poller_schedule(target, module, name, filterset, options,
+ moptions_used ? moptions : NULL,
period, timeout, oncheck[0] ? oncheck : NULL,
flags, uuid, out_uuid);
noitL(noit_debug, "loaded uuid: %s\n", uuid_str);
}
+ for(ridx=0; ridx<reg_module_id; ridx++) {
+ if(moptions[ridx]) {
+ noit_hash_destroy(moptions[ridx], free, free);
+ free(moptions[ridx]);
+ }
+ }
noit_hash_destroy(options, free, free);
free(options);
}
@@ -634,6 +665,7 @@ noit_check_update(noit_check_t *new_check,
const char *name,
const char *filterset,
noit_hash_table *config,
+ noit_hash_table **mconfigs,
u_int32_t period,
u_int32_t timeout,
const char *oncheck,
@@ -681,6 +713,16 @@ noit_check_update(noit_check_t *new_check,
noit_hash_store(new_check->config, strdup(k), klen, strdup((char *)data));
}
}
+ if(mconfigs != NULL) {
+ int i;
+ for(i=0; i<reg_module_id; i++) {
+ if(mconfigs[i]) {
+ noit_hash_table *t = calloc(1, sizeof(*new_check->config));
+ noit_hash_merge_as_dict(t, mconfigs[i]);
+ noit_check_set_module_config(new_check, i, t);
+ }
+ }
+ }
if(new_check->oncheck) free(new_check->oncheck);
new_check->oncheck = oncheck ? strdup(oncheck) : NULL;
new_check->period = period;
@@ -710,6 +752,7 @@ noit_poller_schedule(const char *target,
const char *name,
const char *filterset,
noit_hash_table *config,
+ noit_hash_table **mconfigs,
u_int32_t period,
u_int32_t timeout,
const char *oncheck,
@@ -727,7 +770,7 @@ noit_poller_schedule(const char *target,
else
uuid_copy(new_check->checkid, in);
- noit_check_update(new_check, target, name, filterset, config,
+ noit_check_update(new_check, target, name, filterset, config, mconfigs,
period, timeout, oncheck, flags);
assert(noit_hash_store(&polls,
(char *)new_check->checkid, UUID_SIZE,
@@ -778,6 +821,26 @@ noit_poller_free_check(noit_check_t *checker) {
free(checker->config);
checker->config = NULL;
}
+ if(checker->module_metadata) {
+ int i;
+ for(i=0; i<reg_module_id; i++) {
+ struct vp_w_free *tuple;
+ tuple = checker->module_metadata[i];
+ if(tuple && tuple->freefunc) tuple->freefunc(tuple->ptr);
+ free(tuple);
+ }
+ free(checker->module_metadata);
+ }
+ if(checker->module_configs) {
+ int i;
+ for(i=0; i<reg_module_id; i++) {
+ if(checker->module_configs[i]) {
+ noit_hash_destroy(checker->module_configs[i], free, free);
+ free(checker->module_configs[i]);
+ }
+ }
+ free(checker->module_metadata);
+ }
free(checker);
}
static int
@@ -1423,3 +1486,62 @@ register_console_check_commands() {
NCSCMD("watches", noit_console_show_watchlist, NULL, NULL, NULL));
}
+int
+noit_check_register_module(const char *name) {
+ int i;
+ for(i=0; i<reg_module_id; i++)
+ if(!strcmp(reg_module_names[i], name)) return i;
+ if(reg_module_id >= MAX_MODULE_REGISTRATIONS) return -1;
+ noitL(noit_debug, "Registered module %s as %d\n", name, i);
+ i = reg_module_id++;
+ reg_module_names[i] = strdup(name);
+ return i;
+}
+int
+noit_check_registered_module_cnt() {
+ return reg_module_id;
+}
+const char *
+noit_check_registered_module(int idx) {
+ if(reg_module_used < 0) reg_module_used = reg_module_id;
+ assert(reg_module_used == reg_module_id);
+ if(idx >= reg_module_id || idx < 0) return NULL;
+ return reg_module_names[idx];
+}
+
+void
+noit_check_set_module_metadata(noit_check_t *c, int idx, void *md, void (*freefunc)(void *)) {
+ struct vp_w_free *tuple;
+ if(reg_module_used < 0) reg_module_used = reg_module_id;
+ assert(reg_module_used == reg_module_id);
+ if(idx >= reg_module_id || idx < 0) return;
+ if(!c->module_metadata) c->module_metadata = calloc(reg_module_id, sizeof(void *));
+ c->module_metadata[idx] = calloc(1, sizeof(struct vp_w_free));
+ tuple = c->module_metadata[idx];
+ tuple->ptr = md;
+ tuple->freefunc = freefunc;
+}
+void
+noit_check_set_module_config(noit_check_t *c, int idx, noit_hash_table *config) {
+ if(reg_module_used < 0) reg_module_used = reg_module_id;
+ assert(reg_module_used == reg_module_id);
+ if(idx >= reg_module_id || idx < 0) return;
+ if(!c->module_configs) c->module_configs = calloc(reg_module_id, sizeof(noit_hash_table *));
+ c->module_configs[idx] = config;
+}
+void *
+noit_check_get_module_metadata(noit_check_t *c, int idx) {
+ struct vp_w_free *tuple;
+ if(reg_module_used < 0) reg_module_used = reg_module_id;
+ assert(reg_module_used == reg_module_id);
+ if(idx >= reg_module_id || idx < 0 || !c->module_metadata) return NULL;
+ tuple = c->module_metadata[idx];
+ return tuple ? tuple->ptr : NULL;
+}
+noit_hash_table *
+noit_check_get_module_config(noit_check_t *c, int idx) {
+ if(reg_module_used < 0) reg_module_used = reg_module_id;
+ assert(reg_module_used == reg_module_id);
+ if(idx >= reg_module_id || idx < 0 || !c->module_configs) return NULL;
+ return c->module_configs[idx];
+}
diff --git a/src/noit_check.h b/src/noit_check.h
index 395c3a6..e512768 100644
--- a/src/noit_check.h
+++ b/src/noit_check.h
@@ -153,6 +153,8 @@ typedef struct noit_check {
noit_skiplist *feeds;
char target_ip[INET6_ADDRSTRLEN];
+ void **module_metadata;
+ noit_hash_table **module_configs;
} noit_check_t;
#define NOIT_CHECK_LIVE(a) ((a)->fire_event != NULL)
@@ -185,6 +187,7 @@ API_EXPORT(int)
const char *name,
const char *filterset,
noit_hash_table *config,
+ noit_hash_table **mconfig,
u_int32_t period,
u_int32_t timeout,
const char *oncheck,
@@ -201,6 +204,7 @@ API_EXPORT(int)
const char *name,
const char *filterset,
noit_hash_table *config,
+ noit_hash_table **mconfig,
u_int32_t period,
u_int32_t timeout,
const char *oncheck,
@@ -278,6 +282,22 @@ API_EXPORT(void)
API_EXPORT(void)
noit_check_transient_remove_feed(noit_check_t *check, const char *feed);
+API_EXPORT(int)
+ noit_check_register_module(const char *);
+API_EXPORT(int)
+ noit_check_registered_module_cnt();
+API_EXPORT(const char *)
+ noit_check_registered_module(int);
+
+API_EXPORT(void)
+ noit_check_set_module_metadata(noit_check_t *, int, void *, void (*freefunc)(void *));
+API_EXPORT(void)
+ noit_check_set_module_config(noit_check_t *, int, noit_hash_table *);
+API_EXPORT(void *)
+ noit_check_get_module_metadata(noit_check_t *, int);
+API_EXPORT(noit_hash_table *)
+ noit_check_get_module_config(noit_check_t *, int);
+
/* These are from noit_check_log.c */
API_EXPORT(void) noit_check_log_check(noit_check_t *check);
API_EXPORT(void) noit_check_log_status(noit_check_t *check);
diff --git a/src/noit_check_rest.c b/src/noit_check_rest.c
index 920f3a5..d4c4705 100644
--- a/src/noit_check_rest.c
+++ b/src/noit_check_rest.c
@@ -47,14 +47,15 @@
#define FAIL(a) do { error = (a); goto error; } while(0)
-#define NODE_CONTENT(parent, k, v) do { \
+#define NS_NODE_CONTENT(parent, ns, k, v) do { \
xmlNodePtr tmp; \
if(v) { \
- tmp = xmlNewNode(NULL, (xmlChar *)(k)); \
+ tmp = xmlNewNode(ns, (xmlChar *)(k)); \
xmlNodeAddContent(tmp, (xmlChar *)(v)); \
xmlAddChild(parent, tmp); \
} \
} while(0)
+#define NODE_CONTENT(parent, k, v) NS_NODE_CONTENT(parent, NULL, k, v)
xmlNodePtr
noit_check_state_as_xml(noit_check_t *check) {
@@ -127,7 +128,7 @@ rest_show_check(noit_http_rest_closure_t *restc,
uuid_t checkid;
noit_check_t *check;
char xpath[1024], *uuid_conf, *module, *value;
- int rv, cnt, error_code = 500;
+ int rv, mod, mod_cnt, cnt, error_code = 500;
noit_hash_iter iter = NOIT_HASH_ITER_ZERO;
const char *k;
int klen;
@@ -210,6 +211,21 @@ rest_show_check(noit_http_rest_closure_t *restc,
NODE_CONTENT(config, k, data);
noit_hash_destroy(configh, free, free);
free(configh);
+ mod_cnt = noit_check_registered_module_cnt();
+ for(mod=0; mod<mod_cnt; mod++) {
+ xmlNsPtr ns;
+ const char *nsname;
+ char buff[256];
+ nsname = noit_check_registered_module(mod);
+ snprintf(buff, sizeof(buff), "noit://module/%s", nsname);
+ ns = xmlNewNs(config, (xmlChar *)buff, (xmlChar *)nsname);
+ if(NULL != (configh = noit_conf_get_namespaced_hash(node, "config", nsname))) {
+ while(noit_hash_next(configh, &iter, &k, &klen, &data))
+ NS_NODE_CONTENT(config, ns, k, data);
+ noit_hash_destroy(configh, free, free);
+ free(configh);
+ }
+ }
xmlAddChild(root, config);
/* Add the state */
@@ -386,8 +402,13 @@ configure_xml_check(xmlNodePtr check, xmlNodePtr a, xmlNodePtr c) {
inherit->children && inherit->children->content)
xmlSetProp(config, (xmlChar *)"inherit", inherit->children->content);
for(n = c->children; n; n = n->next) {
+ xmlNsPtr targetns = NULL;
xmlChar *v = xmlNodeGetContent(n);
- xmlNodePtr co = xmlNewNode(NULL, n->name);
+ if(n->ns) {
+ targetns = xmlSearchNs(check->doc, config, n->ns->prefix);
+ if(!targetns) targetns = xmlNewNs(config, n->ns->href, n->ns->prefix);
+ }
+ xmlNodePtr co = xmlNewNode(targetns, n->name);
xmlNodeAddContent(co, v);
xmlFree(v);
xmlAddChild(config, co);
diff --git a/src/noit_conf.c b/src/noit_conf.c
index 6ae7de8..a52d0dc 100644
--- a/src/noit_conf.c
+++ b/src/noit_conf.c
@@ -385,7 +385,8 @@ int noit_conf_save(const char *path) {
void noit_conf_get_elements_into_hash(noit_conf_section_t section,
const char *path,
- noit_hash_table *table) {
+ noit_hash_table *table,
+ const char *namespace) {
int i, cnt;
xmlXPathObjectPtr pobj = NULL;
xmlXPathContextPtr current_ctxt;
@@ -405,11 +406,20 @@ void noit_conf_get_elements_into_hash(noit_conf_section_t section,
for(i=0; i<cnt; i++) {
char *value;
node = xmlXPathNodeSetItem(pobj->nodesetval, i);
- value = (char *)xmlXPathCastNodeToString(node);
- noit_hash_replace(table,
- strdup((char *)node->name), strlen((char *)node->name),
- strdup(value), free, free);
- xmlFree(value);
+ if(namespace && node->ns && !strcmp((char *)node->ns->prefix, namespace)) {
+ value = (char *)xmlXPathCastNodeToString(node);
+ noit_hash_replace(table,
+ strdup((char *)node->name), strlen((char *)node->name),
+ strdup(value), free, free);
+ xmlFree(value);
+ }
+ else if(!namespace && !node->ns) {
+ value = (char *)xmlXPathCastNodeToString(node);
+ noit_hash_replace(table,
+ strdup((char *)node->name), strlen((char *)node->name),
+ strdup(value), free, free);
+ xmlFree(value);
+ }
}
out:
if(pobj) xmlXPathFreeObject(pobj);
@@ -418,7 +428,8 @@ void noit_conf_get_elements_into_hash(noit_conf_section_t section,
}
void noit_conf_get_into_hash(noit_conf_section_t section,
const char *path,
- noit_hash_table *table) {
+ noit_hash_table *table,
+ const char *namespace) {
unsigned int cnt;
xmlXPathObjectPtr pobj = NULL;
xmlXPathContextPtr current_ctxt;
@@ -453,29 +464,42 @@ void noit_conf_get_into_hash(noit_conf_section_t section,
if(cnt > 1 && node) {
parent_node = xmlXPathNodeSetItem(pobj->nodesetval, cnt-2);
if(parent_node != current_node)
- noit_conf_get_into_hash(parent_node, (const char *)node->name, table);
+ noit_conf_get_into_hash(parent_node, (const char *)node->name, table, namespace);
}
/* 2. */
inheritid = (char *)xmlGetProp(node, (xmlChar *)"inherit");
if(inheritid) {
snprintf(xpath_expr, sizeof(xpath_expr), "//*[@id=\"%s\"]", inheritid);
- noit_conf_get_into_hash(NULL, xpath_expr, table);
+ noit_conf_get_into_hash(NULL, xpath_expr, table, namespace);
xmlFree(inheritid);
}
/* 3. */
- noit_conf_get_elements_into_hash(node, "*", table);
+ noit_conf_get_elements_into_hash(node, "*", table, namespace);
out:
if(pobj) xmlXPathFreeObject(pobj);
if(current_ctxt && current_ctxt != xpath_ctxt)
xmlXPathFreeContext(current_ctxt);
}
+noit_hash_table *noit_conf_get_namespaced_hash(noit_conf_section_t section,
+ const char *path, const char *ns) {
+ noit_hash_table *table = NULL;
+
+ table = calloc(1, sizeof(*table));
+ noit_conf_get_into_hash(section, path, table, ns);
+ if(table->size == 0) {
+ noit_hash_destroy(table, free, free);
+ free(table);
+ table = NULL;
+ }
+ return table;
+}
noit_hash_table *noit_conf_get_hash(noit_conf_section_t section,
const char *path) {
noit_hash_table *table = NULL;
table = calloc(1, sizeof(*table));
- noit_conf_get_into_hash(section, path, table);
+ noit_conf_get_into_hash(section, path, table, NULL);
return table;
}
noit_conf_section_t noit_conf_get_section(noit_conf_section_t section,
diff --git a/src/noit_conf.h b/src/noit_conf.h
index 9d6fd88..bd10608 100644
--- a/src/noit_conf.h
+++ b/src/noit_conf.h
@@ -76,6 +76,9 @@ API_EXPORT(noit_conf_section_t *)
API_EXPORT(noit_hash_table *)
noit_conf_get_hash(noit_conf_section_t section, const char *path);
+API_EXPORT(noit_hash_table *)
+ noit_conf_get_namespaced_hash(noit_conf_section_t section,
+ const char *path, const char *ns);
API_EXPORT(int) noit_conf_get_string(noit_conf_section_t section,
const char *path, char **value);
hooks/post-receive
--
Reconnoiter
More information about the Reconnoiter-devel
mailing list