The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
jsondiscovery.c
Go to the documentation of this file.
1 
24 #include <projectcommon.h>
25 #ifdef HAVE_UNISTD_H
26 # include <unistd.h>
27 #endif
28 #include <memory.h>
29 #define DISCOVERY_SUBCLASS
30 #include <frameset.h>
31 #include <configcontext.h>
32 #include <cstringframe.h>
33 #include <frametypes.h>
34 #include <framesettypes.h>
35 #include <jsondiscovery.h>
36 #include <assert.h>
37 #include <fsprotocol.h>
43 
47 FSTATIC void _jsondiscovery_childwatch(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped);
50 
52 FSTATIC guint
54 {
55  const JsonDiscovery* self = CASTTOCONSTCLASS(JsonDiscovery, dself);
56  return self->_intervalsecs;
57 }
58 
60 FSTATIC void
62 {
63  JsonDiscovery* self = CASTTOCLASS(JsonDiscovery, dself);
64  if (self->jsonparams) {
65  UNREF(self->jsonparams);
66  }
67  if (self->logprefix) {
68  g_free(self->logprefix);
69  self->logprefix = NULL;
70  }
71  if (self->_fullpath) {
72  g_free(self->_fullpath);
73  self->_fullpath = NULL;
74  }
75  _discovery_finalize(dself);
76 }
77 
79 FSTATIC gboolean
81 {
82  JsonDiscovery* self = CASTTOCLASS(JsonDiscovery, dself);
83  gchar* argv[3];
84  static char discoverword [] = "discover";
85  ConfigContext* cfg = self->baseclass._config;
86  if (NULL != self->child) {
87  g_warning("%s.%d: JSON discovery process still running - skipping this iteration."
88  , __FUNCTION__, __LINE__);
89  return TRUE;
90  }
91  ++ self->baseclass.discovercount;
92  if (cfg->getaddr(cfg, CONFIGNAME_CMADISCOVER) == NULL) {
93  DEBUGMSG2("%s.%d: don't have [%s] address yet - continuing."
95  }
96  argv[0] = self->_fullpath;
97  argv[1] = discoverword;
98  argv[2] = NULL;
99 
100  DEBUGMSG1("Running Discovery [%s]", argv[0]);
101 
102  self->child = childprocess_new(0 // object size (0 == default size)
103 , argv // char** argv
104 , NULL // char** envp
105 , self->jsonparams // ConfigContext*envmod
106 , NULL // const char* curdir
108  //gboolean (*notify)(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped)
109 , TRUE // gboolean save_stdout
110 , G_LOG_DOMAIN // const char * logdomain
111 , self->logprefix // const char * logprefix
112 , G_LOG_LEVEL_MESSAGE // GLogLevelFlags loglevel
113 , 0 //guint32 timeout_seconds;
114 , self // gpointer user_data
116 , NULL
117  );
118  if (NULL == self->child) {
119  // Can't call childwatch w/o valid child...
120  return FALSE;
121  }
122 
123  // Don't want us going away while we have a child out there...
124  REF2(self);
125  return TRUE;
126 }
128 FSTATIC void
130 , enum HowDied status
131 , int rc
132 , int signal
133 , gboolean core_dumped)
134 {
136  gchar* jsonout = NULL;
137  gsize jsonlen = 0;
138 
139  (void)core_dumped;
140  (void)rc;
141  (void)signal;
142  if (status != EXITED_ZERO) {
143  // We don't need to log anything... It's being done for us...
144  goto quitchild;
145  }
146  jsonout = g_strdup(child->stdout_src->textread->str);
147  jsonlen = strlen(jsonout);
148  if (jsonlen == 0) {
149  g_warning("JSON discovery [%s] produced no output.", self->_fullpath);
150  goto quitchild;
151  }
152  DEBUGMSG3("Got %zd bytes of JSON TEXT: [%s]", jsonlen, jsonout);
153  if (DEBUG) {
155  if (jsobj == NULL) {
156  g_warning("JSON discovery [%s - %zd bytes] produced bad JSON."
157  , self->_fullpath, jsonlen);
158  FREE(jsonout); jsonout = NULL;
159  goto quitchild;
160  }else{
161  // Good output!
162  UNREF(jsobj);
163  }
164  }
165  self->baseclass.sendjson(&self->baseclass, jsonout, jsonlen);
166 
167 quitchild:
168  UNREF(self->child);
169  self->child = child = NULL;
170  // We did a 'ref' in _jsondiscovery_discover above to keep us from disappearing while
171  // our child process was running.
172  UNREF2(self);
173 }
174 
175 
178 jsondiscovery_new(const char * discoverytype,
179  const char * instancename,
180  gint intervalsecs,
181  ConfigContext*jsoninst,
182  NetGSource* iosource,
183  ConfigContext*context,
184  gsize objsize)
185 {
186  const char * basedir = NULL;
187  ConfigContext* jsonparams;
188  JsonDiscovery* ret;
189  char * fullpath;
190 
192  g_return_val_if_fail(jsoninst != NULL, NULL);
193  g_return_val_if_fail(*discoverytype != '/', NULL);
194  jsonparams = jsoninst->getconfig(jsoninst, "parameters");
195  g_return_val_if_fail(jsonparams != NULL, NULL);
196  basedir = context->getstring(context, "JSONAGENTROOT");
197  if (NULL == basedir) {
198  basedir = JSONAGENTROOT;
199  }
200  fullpath = g_build_filename(basedir, discoverytype, NULL);
201  if ( !g_file_test(fullpath, G_FILE_TEST_IS_REGULAR)
202  || !g_file_test(fullpath, G_FILE_TEST_IS_EXECUTABLE)) {
203  g_warning("%s.%d: No such JSON discovery agent [%s]", __FUNCTION__, __LINE__
204  , fullpath);
205  g_free(fullpath); fullpath = NULL;
206  return NULL;
207  }
209  , discovery_new(instancename, iosource, context
210  , objsize < sizeof(JsonDiscovery) ? sizeof(JsonDiscovery) : objsize));
211  g_return_val_if_fail(ret != NULL, NULL);
212  ret->_fullpath = fullpath;
216  ret->jsonparams = jsonparams;
217  REF(ret->jsonparams);
218  ret->_intervalsecs = intervalsecs;
219  ret->logprefix = g_strdup_printf("Discovery %s: ", instancename);
220  DEBUGMSG2("%s.%d: FULLPATH=[%s] discoverytype[%s]"
221  , __FUNCTION__, __LINE__, ret->_fullpath, discoverytype);
223  return ret;
224 }
ConfigContext * configcontext_new_JSON_string(const char *jsontext)
Construct a ConfigContext object from the given JSON string.
#define CONFIGNAME_CMADISCOVER
Address of where to send discovery reports.
const char *(* getstring)(const ConfigContext *, const char *name)
Get String value.
Definition: configcontext.h:86
#define DEBUGMSG1(...)
Definition: proj_classes.h:89
void discovery_register(Discovery *self)
Function for registering a discovery object with the discovery infrastructure.
Definition: discovery.c:172
#define REF2(obj)
Definition: assimobj.h:40
WINEXPORT ChildProcess * childprocess_new(gsize cpsize, char **argv, const char **envp, ConfigContext *envmod, const char *curdir, void(*notify)(ChildProcess *, enum HowDied, int rc, int signal, gboolean core_dumped), gboolean save_stdout, const char *logdomain, const char *logprefix, GLogLevelFlags loglevel, guint32 timeout_seconds, gpointer user_data, enum ChildErrLogMode logmode, const char *logname)
ChildProcess class. constructor.
Definition: childprocess.c:85
Implements minimal client-oriented Frame and Frameset capabilities.
Describes interfaces to C-String Frame (Cstringframe) C-Class It holds conventional zero-terminated b...
FSTATIC void _jsondiscovery_finalize(AssimObj *self)
Finalizing function for Discovery objects.
Definition: jsondiscovery.c:61
class defining object discovered by invoking commands that return JSON as their output.
DEBUGDECLARATIONS
Definition: jsondiscovery.c:49
#define FSTATIC
Definition: projectcommon.h:31
FSTATIC void _jsondiscovery_childwatch(ChildProcess *, enum HowDied, int rc, int signal, gboolean core_dumped)
Watch our child - we get called when our child process exits.
#define DEBUGMSG3(...)
Definition: proj_classes.h:91
Discovery * discovery_new(const char *instname, NetGSource *iosource, ConfigContext *context, gsize objsize)
Discovery constructor.
Definition: discovery.c:142
gpointer user_data
User data given to us when the object was created.
Definition: childprocess.h:68
int signal
Definition: childprocess.c:238
#define BINDDEBUG(Cclass)
BINDDEBUG is for telling the class system where the debug variable for this class is - put it in the ...
Definition: proj_classes.h:82
NetAddr *(* getaddr)(const ConfigContext *, const char *name)
Get NetAddr value.
Definition: configcontext.h:92
AssimObj baseclass
Definition: configcontext.h:72
#define __FUNCTION__
#define DEBUG
Definition: proj_classes.h:85
char * logprefix
Prefix for logging stderr messages.
Definition: jsondiscovery.h:40
Log signal, timeouts, or non-zero exits.
Definition: childprocess.h:47
Header file defining all known FrameSet types THIS FILE MECHANICALLY GENERATED by "/home/alanr/assim/...
JsonDiscovery * jsondiscovery_new(const char *discoverytype, const char *instancename, gint intervalsecs, ConfigContext *jsoninst, NetGSource *iosource, ConfigContext *context, gsize objsize)
JsonDiscovery constructor.
FSTATIC gboolean _jsondiscovery_discover(Discovery *dself)
Perform the requested discovery action.
Definition: jsondiscovery.c:80
#define FREE(m)
Our interface to free.
Definition: projectcommon.h:29
#define REF(obj)
Definition: assimobj.h:39
GString * textread
The text we've read so far.
Definition: gmainfd.h:37
FSTATIC guint _jsondiscovery_discoverintervalsecs(const Discovery *self)
Return how often we are scheduled to perform this particular discovery action.
Definition: jsondiscovery.c:53
#define CASTTOCONSTCLASS(Cclass, obj)
Safely cast 'obj' to const C-class 'class' - verifying that it was registered as being of type class ...
Definition: proj_classes.h:71
GMainFd * stdout_src
GSource for logging/saving the standard output of child.
Definition: childprocess.h:55
Project common header file.
Header file defining the data layouts for our Frames.
JsonDiscovery abstract C-class - it supports discovering "things" through running commands outputting...
Definition: jsondiscovery.h:37
Implements Configuration Context class.
Discovery class abstract C-class - it supports discovering "things" through subclasses for different ...
Definition: discovery.h:47
#define JSONAGENTROOT
Definition: jsondiscovery.h:33
void(* _finalize)(AssimObj *)
Free object (private)
Definition: assimobj.h:55
ConfigContext * jsonparams
Parameters to the resource agent.
Definition: jsondiscovery.h:44
HowDied
Definition: childprocess.h:35
char * _fullpath
Full pathname of the discovery agent.
Definition: jsondiscovery.h:41
ConfigContext *(* getconfig)(const ConfigContext *, const char *name)
Get ConfigContext value.
Definition: configcontext.h:95
gboolean(* discover)(Discovery *self)
Perform the discovery.
Definition: discovery.h:51
Discovery baseclass
Base discovery object.
Definition: jsondiscovery.h:38
Exited with zero return code.
Definition: childprocess.h:37
guint _intervalsecs
How often to run this discovery method?
Definition: jsondiscovery.h:43
#define DEBUGMSG2(...)
Definition: proj_classes.h:90
guint(* discoverintervalsecs)(const Discovery *self)
How often to re-discover? (in seconds)
Definition: discovery.h:52
#define UNREF2(obj)
Definition: assimobj.h:36
#define CASTTOCLASS(Cclass, obj)
Safely cast 'obj' to C-class 'class' - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
#define UNREF(obj)
Definition: assimobj.h:35
Implements the FsProtocol object.
AssimObj baseclass
Base object class.
Definition: discovery.h:48
FSTATIC void _jsondiscovery_fullpath(JsonDiscovery *self)
The NetGSource class objects integrate NetIO class objects into the g_main_loop paradigm.
Definition: netgsource.h:43
#define NEWSUBCLASS(Cclass, obj)
Definition: proj_classes.h:67
FSTATIC void _discovery_finalize(AssimObj *gself)
Finalizing function for Discovery objects.
Definition: discovery.c:71