[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