bool DCStartd::getAds( ClassAdList &adsList ) { CondorError errstack; // fetch the query QueryResult q; CondorQuery* query; char* ad_addr; // instantiate query object if (!(query = new CondorQuery (STARTD_AD))) { dprintf( D_ALWAYS, "Error: Out of memory\n"); return(false); } if( this->locate() ){ ad_addr = this->addr(); q = query->fetchAds(adsList, ad_addr, &errstack); if (q != Q_OK) { if (q == Q_COMMUNICATION_ERROR) { dprintf( D_ALWAYS, "%s\n", errstack.getFullText(true).c_str() ); } else { dprintf (D_ALWAYS, "Error: Could not fetch ads --- %s\n", getStrQueryResult(q)); } delete query; return (false); } } else { delete query; return(false); } delete query; return(true); }
QueryResult CollectorList::query(CondorQuery & cQuery, ClassAdList & adList, CondorError *errstack) { int num_collectors = this->number(); if (num_collectors < 1) { return Q_NO_COLLECTOR_HOST; } std::vector<DCCollector *> vCollectors; DCCollector * daemon; QueryResult result = Q_COMMUNICATION_ERROR; bool problems_resolving = false; // switch containers for easier random access. this->rewind(); while (this->next(daemon)) { vCollectors.push_back(daemon); } while ( vCollectors.size() ) { // choose a random collector in the list to query. unsigned int idx = get_random_int() % vCollectors.size() ; daemon = vCollectors[idx]; if ( ! daemon->addr() ) { if ( daemon->name() ) { dprintf( D_ALWAYS, "Can't resolve collector %s; skipping\n", daemon->name() ); } else { dprintf( D_ALWAYS, "Can't resolve nameless collector; skipping\n" ); } problems_resolving = true; } else if ( daemon->isBlacklisted() && vCollectors.size() > 1 ) { dprintf( D_ALWAYS,"Collector %s blacklisted; skipping\n", daemon->name() ); } else { dprintf (D_FULLDEBUG, "Trying to query collector %s\n", daemon->addr()); if( num_collectors > 1 ) { daemon->blacklistMonitorQueryStarted(); } result = cQuery.fetchAds (adList, daemon->addr(), errstack); if( num_collectors > 1 ) { daemon->blacklistMonitorQueryFinished( result == Q_OK ); } if (result == Q_OK) { return result; } } // if you got here remove it from the list of potential candidates. vCollectors.erase( vCollectors.begin()+idx ); } // only push an error if the error stack exists and is currently empty if(problems_resolving && errstack && !errstack->code(0)) { char* tmplist = getCmHostFromConfig( "COLLECTOR" ); errstack->pushf("CONDOR_STATUS",1,"Unable to resolve COLLECTOR_HOST (%s).",tmplist?tmplist:"(null)"); } // If we've gotten here, there are no good collectors return result; }
bool Triggerd::PerformQueries() { ClassAdList result; CondorError errstack; QueryResult status; Trigger* trig = NULL; CondorQuery* query; bool ret_val = true; std::map<uint32_t,Trigger*>::iterator iter; ClassAd* ad = NULL; std::string eventText; char* token = NULL; std::string triggerText; char* queryString = NULL; ExprTree* attr = NULL; std::list<std::string> missing_nodes; size_t pos; size_t prev_pos; bool bad_trigger = false; const char* token_str = NULL; if (0 < triggers.size()) { dprintf(D_FULLDEBUG, "Triggerd: Evaluating %d triggers\n", (int)triggers.size()); query = new CondorQuery(ANY_AD); for (iter = triggers.begin(); iter != triggers.end(); iter++) { // Clear any pre-exhisting custom contraints and add the constraint // for this trigger trig = iter->second; query->clearORCustomConstraints(); query->clearANDCustomConstraints(); queryString = strdup(trig->GetQuery().c_str()); ReplaceAllChars(queryString, '\'', '"'); query->addANDConstraint(queryString); free(queryString); // Perform the query and check the result if (NULL != query_collector) { status = query->fetchAds(result, query_collector->addr(), &errstack); } else { status = collectors->query(*query, result, &errstack); } if (Q_OK != status) { // Problem with the query if (Q_COMMUNICATION_ERROR == status) { dprintf(D_ALWAYS, "Triggerd Error: Error contacting the collecter - %s\n", errstack.getFullText(true).c_str()); if (CEDAR_ERR_CONNECT_FAILED == errstack.code(0)) { dprintf(D_ALWAYS, "Triggerd Error: Couldn't contact the collector on the central manager\n"); } } else { dprintf(D_ALWAYS, "Triggerd Error: Could not retrieve ads - %s\n", getStrQueryResult(status)); } ret_val = false; break; } else { dprintf(D_FULLDEBUG, "Query successful. Parsing results\n"); // Query was successful, so parse the results result.Open(); while ((ad = result.Next())) { if (true == bad_trigger) { // Avoid processing a bad trigger multiple times. Remove // all result ads and reset the flag dprintf(D_FULLDEBUG, "Cleaning up after a bad trigger\n"); result.Delete(ad); while ((ad = result.Next())) { result.Delete(ad); } bad_trigger = false; break; } eventText = ""; triggerText = trig->GetText(); dprintf(D_FULLDEBUG, "Parsing trigger text '%s'\n", triggerText.c_str()); prev_pos = pos = 0; while (prev_pos < triggerText.length()) { pos = triggerText.find("$(", prev_pos, 2); if (std::string::npos == pos) { // Didn't find the start of a varible, so append the // remaining string dprintf(D_FULLDEBUG, "Adding text string to event text\n"); eventText += triggerText.substr(prev_pos, std::string::npos); prev_pos = triggerText.length(); } else { // Found a variable for substitution. Need to add // text before it to the string, grab the variable // to substitute for, and put its value in the text eventText += triggerText.substr(prev_pos, pos - prev_pos); dprintf(D_FULLDEBUG, "Adding text string prior to variable substitution to event text\n"); // Increment the position by 2 to skip the $( prev_pos = pos + 2; pos = triggerText.find(")", prev_pos, 1); if (std::string::npos == pos) { // Uh-oh. We have a start of a variable substitution // but no closing marker. dprintf(D_FULLDEBUG, "Error: Failed to find closing varable substitution marker ')'. Aborting processing of the trigger\n"); bad_trigger = true; break; } else { token_str = triggerText.substr(prev_pos, pos-prev_pos).c_str(); token = RemoveWS(token_str); dprintf(D_FULLDEBUG, "token: '%s'\n", token); if (NULL == token) { dprintf(D_ALWAYS, "Removing whitespace from %s produced unusable name. Aborting processing of the trigger\n", token_str); bad_trigger = true; break; } attr = ad->LookupExpr(token); if (NULL == attr) { // The token isn't found in the classad, so treat it // like a string dprintf(D_FULLDEBUG, "Adding text string to event text\n"); eventText += token; } else { dprintf(D_FULLDEBUG, "Adding classad value to event text\n"); eventText += ExprTreeToString(attr); } if (NULL != token) { free(token); token = NULL; } ++pos; } prev_pos = pos; } } // Remove the trailing space std::string::size_type notwhite = eventText.find_last_not_of(" "); eventText.erase(notwhite+1); // Send the event if (false == bad_trigger) { EventCondorTriggerNotify event(eventText, time(NULL)); singleton->getInstance()->raiseEvent(event); dprintf(D_FULLDEBUG, "Triggerd: Raised event with text '%s'\n", eventText.c_str()); } result.Delete(ad); } bad_trigger = false; result.Close(); } } delete query; } else { dprintf(D_FULLDEBUG, "Triggerd: No triggers to evaluate\n"); } // Look for absent nodes (nodes expected to be in the pool but aren't) if (NULL != console) { missing_nodes = console->findAbsentNodes(); if (0 < missing_nodes.size()) { for (std::list<std::string>::iterator node = missing_nodes.begin(); node != missing_nodes.end(); ++ node) { eventText = node->c_str(); eventText += " is missing from the pool"; EventCondorTriggerNotify event(eventText, time(NULL)); singleton->getInstance()->raiseEvent(event); dprintf(D_FULLDEBUG, "Triggerd: Raised event with text '%s'\n", eventText.c_str()); } } } return ret_val; }