void StatsD::mapDaemonIPs(ClassAdList &daemon_ads,CollectorList &collectors) { // The map of machines to IPs is used when directing ganglia to // associate specific metrics with specific hosts (host spoofing) m_daemon_ips.clear(); daemon_ads.Open(); ClassAd *daemon; while( (daemon=daemon_ads.Next()) ) { std::string machine,name,my_address; daemon->EvaluateAttrString(ATTR_MACHINE,machine); daemon->EvaluateAttrString(ATTR_MACHINE,name); daemon->EvaluateAttrString(ATTR_MY_ADDRESS,my_address); Sinful s(my_address.c_str()); if( !s.getHost() ) { continue; } std::string ip = s.getHost(); if( !machine.empty() ) { m_daemon_ips.insert( std::map< std::string,std::string >::value_type(machine,ip) ); } if( !name.empty() ) { m_daemon_ips.insert( std::map< std::string,std::string >::value_type(name,ip) ); } } daemon_ads.Close(); // Also add a mapping of collector hosts to IPs, and determine the // collector host to use as the default machine name for aggregate // metrics. m_default_aggregate_host = ""; DCCollector *collector=NULL; collectors.rewind(); while( (collectors.next(collector)) ) { char const *collector_host = collector->fullHostname(); char const *collector_addr = collector->addr(); if( collector_host && m_default_aggregate_host.empty() ) { m_default_aggregate_host = collector_host; } if( collector_host && collector_addr ) { Sinful s(collector_addr); if( s.getHost() ) { char const *ip = s.getHost(); m_daemon_ips.insert( std::map< std::string,std::string >::value_type(collector_host,ip) ); } } } }
void StatsD::determineExecuteNodes(ClassAdList &daemon_ads) { std::set< std::string > submit_nodes; std::set< std::string > execute_nodes; std::set< std::string > cm_nodes; daemon_ads.Open(); ClassAd *daemon; while( (daemon=daemon_ads.Next()) ) { std::string machine,my_type; daemon->EvaluateAttrString(ATTR_MACHINE,machine); daemon->EvaluateAttrString(ATTR_MY_TYPE,my_type); if( strcasecmp(my_type.c_str(),"machine")==0 ) { execute_nodes.insert( std::set< std::string >::value_type(machine) ); } else if( strcasecmp(my_type.c_str(),"scheduler")==0 ) { submit_nodes.insert( std::set< std::string >::value_type(machine) ); } else if( strcasecmp(my_type.c_str(),"negotiator")==0 || strcasecmp(my_type.c_str(),"collector")==0 ) { cm_nodes.insert( std::set< std::string >::value_type(machine) ); } } daemon_ads.Close(); m_execute_only_nodes.clear(); for( std::set< std::string >::iterator itr = execute_nodes.begin(); itr != execute_nodes.end(); itr++ ) { if( !submit_nodes.count(*itr) && !cm_nodes.count(*itr) ) { m_execute_only_nodes.insert(*itr); } } if( !m_per_execute_node_metrics && m_execute_only_nodes.size()>0 ) { dprintf(D_FULLDEBUG,"Filtering out metrics for %d execute nodes because PER_EXECUTE_NODE_METRICS=False.\n", (int)m_execute_only_nodes.size()); } }
bool SharedPortEndpoint::InitRemoteAddress() { // Why do we read SharedPortServer's address from a file rather // than getting it passed down to us via the environment or // having a (configurable) fixed port? Because the // SharedPortServer daemon may be listening via CCB, and its CCB // contact info may not be known as soon as it is started up // or may even change over time. // Why don't we just use a daemon client object to find the // address of the SharedPortServer daemon? Because daemon // client assumes we want the best address for _us_ to connect // to. That's not necessarily the public address that we want // to advertise for others to connect to. MyString shared_port_server_ad_file; if( !param(shared_port_server_ad_file,"SHARED_PORT_DAEMON_AD_FILE") ) { EXCEPT("SHARED_PORT_DAEMON_AD_FILE must be defined"); } FILE *fp = safe_fopen_wrapper_follow(shared_port_server_ad_file.Value(),"r"); if( !fp ) { dprintf(D_ALWAYS,"SharedPortEndpoint: failed to open %s: %s\n", shared_port_server_ad_file.Value(), strerror(errno)); return false; } int adIsEOF = 0, errorReadingAd = 0, adEmpty = 0; ClassAd *ad = new ClassAd(fp, "[classad-delimiter]", adIsEOF, errorReadingAd, adEmpty); ASSERT(ad); fclose( fp ); // avoid leaking ad when returning from this function counted_ptr<ClassAd> smart_ad_ptr(ad); if( errorReadingAd ) { dprintf(D_ALWAYS,"SharedPortEndpoint: failed to read ad from %s.\n", shared_port_server_ad_file.Value()); return false; } MyString public_addr; if( !ad->LookupString(ATTR_MY_ADDRESS,public_addr) ) { dprintf(D_ALWAYS, "SharedPortEndpoint: failed to find %s in ad from %s.\n", ATTR_MY_ADDRESS, shared_port_server_ad_file.Value()); return false; } Sinful sinful(public_addr.Value()); sinful.setSharedPortID( m_local_id.Value() ); // if there is a private address, set the shared port id on that too char const *private_addr = sinful.getPrivateAddr(); if( private_addr ) { Sinful private_sinful( private_addr ); private_sinful.setSharedPortID( m_local_id.Value() ); sinful.setPrivateAddr( private_sinful.getSinful() ); } // Next, look for alternate command strings std::string commandStrings; if (ad->EvaluateAttrString(ATTR_SHARED_PORT_COMMAND_SINFULS, commandStrings)) { m_remote_addrs.clear(); StringList sl(commandStrings.c_str()); sl.rewind(); const char *commandSinfulStr; while ((commandSinfulStr = sl.next())) { Sinful altsinful(commandSinfulStr); altsinful.setSharedPortID(m_local_id.Value()); char const *private_addr = sinful.getPrivateAddr(); if (private_addr) { Sinful private_sinful(private_addr); private_sinful.setSharedPortID(m_local_id.Value()); altsinful.setPrivateAddr(private_sinful.getSinful()); } m_remote_addrs.push_back(altsinful); } } m_remote_addr = sinful.getSinful(); return true; }
static void test_user_functions(void) { string name = "triple"; string classad_text = "[ Test1 = 3 + triple(9); Test2 = 3 + double(9); " "Test3 = todays_date(); ]"; ClassAd *classad; ClassAdParser parser; cout << "Testing user functions...\n"; FunctionCall::RegisterFunction(name, triple); #if defined(HAVE_DLOPEN) && !defined(DISABLE_DLOPEN_CHECK) bool opened_library; char path[10240]; string libname; path[0] = 0; getcwd(path, 10239); libname = path; libname += "/"; libname += TEST_LIBNAME; // TEST_LIBNAME is #define'd opened_library = FunctionCall::RegisterSharedLibraryFunctions(libname.c_str()); if (!opened_library) { cout << " Failed to open libshared.so: " << CondorErrMsg << endl; } #endif classad = parser.ParseClassAd(classad_text); if (classad == NULL) { cout << " Failed to parse ClassAd in test_internal_user_function().\n"; exit(1); } int test; if (!classad->EvaluateAttrInt("Test1", test) || test != 30) { cout << " Failed: Couldn't evaluate internal user function triple correctly."; } else { cout << " OK: Evaluated internal user function triple ("; cout << test << ") correctly.\n"; } #if defined(HAVE_DLOPEN) && !defined(DISABLE_DLOPEN_CHECK) if (opened_library) { // The library defines triple, but it shouldn't be allowed to // overwrite the original defintion, so we verify that the // result hasn't changed. if (!classad->EvaluateAttrInt("Test1", test) || test != 30) { cout << " Failed: Couldn't evaluate internal user function triple correctly." << endl; } else { cout << " OK: Evaluated internal user function triple ("; cout << test << ") correctly.\n"; } // Then we test one function that comes from the shared library. if (!classad->EvaluateAttrInt("Test2", test) || test != 21) { cout << " Failed: Couldn't evaluate shared user function double " << " (" << test << ") correctly." << endl; if (!classad->EvaluateAttrInt("Test2", test)) { cout << " Couldn't even evaluate it at all." << endl; } } else { cout << " OK: Evaluated shared user function double ("; cout << test << ") correctly.\n"; } // Then we test another function that comes from the shared library. string date; if (!classad->EvaluateAttrString("Test3", date)) { cout << " Failed: Couldn't evaluate shared user function " << " todays_date (" << test << ") correctly." << endl; } else { cout << " OK: Evaluated shared function todays_date: "; cout << date << endl; } } #endif return; }
bool View:: SetViewInfo( ClassAdCollection *coll, ClassAd *ad ) { ExprTree *rankExpr=NULL, *constraintExpr=NULL, *tmp=NULL; ExprList *partitionExprs=NULL; if( !( rankExpr = ad->Remove( ATTR_RANK ) ) ) { Value val; val.SetUndefinedValue( ); rankExpr = Literal::MakeLiteral( val ); } if( !( constraintExpr = ad->Remove( ATTR_REQUIREMENTS ) ) ) { Value val; val.SetBooleanValue( true ); constraintExpr = Literal::MakeLiteral( val ); } if( ( ( tmp = ad->Remove( ATTR_PARTITION_EXPRS ) ) && tmp->GetKind( ) != ExprTree::EXPR_LIST_NODE ) || !tmp ) { vector<ExprTree*> vec; if( tmp ) delete tmp; partitionExprs = ExprList::MakeExprList( vec ); } else { partitionExprs = (ExprList*) tmp; } // Preserve the view name and parent view name. ClassAd *eval; string view_name, parent_view_name; eval = evalEnviron.GetLeftAd(); eval->EvaluateAttrString("ViewName", view_name); eval->EvaluateAttrString("ParentViewName", parent_view_name); ad->InsertAttr("ViewName", view_name); ad->InsertAttr("ParentViewName", parent_view_name); if( !evalEnviron.ReplaceLeftAd( ad ) ) { CondorErrMsg+="; could not replace view info; failed to set view info"; delete constraintExpr; delete rankExpr; delete partitionExprs; return( false ); } if( constraintExpr && !SetConstraintExpr( coll, constraintExpr ) ) { CondorErrMsg += "; failed to set view info"; delete constraintExpr; delete rankExpr; delete partitionExprs; return( false ); } if( !SetRankExpr( coll, rankExpr ) ) { CondorErrMsg += "; failed to set view info"; delete rankExpr; delete partitionExprs; return( false ); } if( !SetPartitionExprs( coll, partitionExprs ) ) { CondorErrMsg += "; failed to set view info"; delete partitionExprs; return( false ); } return( true ); }
int CondorQ::fetchQueueFromHostAndProcessV2(const char *host, const char *constraint, StringList &attrs, int fetch_opts, int match_limit, condor_q_process_func process_func, void * process_func_data, int connect_timeout, int useFastPath, CondorError *errstack, ClassAd ** psummary_ad) { classad::ClassAdParser parser; classad::ExprTree *expr = NULL; parser.ParseExpression(constraint, expr); if (!expr) return Q_INVALID_REQUIREMENTS; classad::ClassAd request_ad; // query ad to send to schedd ClassAd *ad = NULL; // job ad result request_ad.Insert(ATTR_REQUIREMENTS, expr); char *projection = attrs.print_to_delimed_string("\n"); if (projection) { request_ad.InsertAttr(ATTR_PROJECTION, projection); free(projection); } bool want_authentication = false; if (fetch_opts == fetch_DefaultAutoCluster) { request_ad.InsertAttr("QueryDefaultAutocluster", true); request_ad.InsertAttr("MaxReturnedJobIds", 2); // TODO: make this settable by caller of this function. } else if (fetch_opts == fetch_GroupBy) { request_ad.InsertAttr("ProjectionIsGroupBy", true); request_ad.InsertAttr("MaxReturnedJobIds", 2); // TODO: make this settable by caller of this function. } else { if (fetch_opts & fetch_MyJobs) { const char * owner = my_username(); if (owner) { request_ad.InsertAttr("Me", owner); } request_ad.InsertAttr("MyJobs", owner ? "(Owner == Me)" : "true"); want_authentication = true; } if (fetch_opts & fetch_SummaryOnly) { request_ad.InsertAttr("SummaryOnly", true); } if (fetch_opts & fetch_IncludeClusterAd) { request_ad.InsertAttr("IncludeClusterAd", true); } } if (match_limit >= 0) { request_ad.InsertAttr(ATTR_LIMIT_RESULTS, match_limit); } // determine if authentication can/will happen. three reasons why it might not: // 1) security negotiation is disabled (NEVER or OPTIONAL for outgoing connections) // 2) Authentication is disabled (NEVER) by the client // 3) Authentication is disabled (NEVER) by the server. this is actually impossible to // get correct without actually querying the server but we make an educated guess by // paraming the READ auth level. bool can_auth = true; char *paramer = NULL; paramer = SecMan::getSecSetting ("SEC_%s_NEGOTIATION", CLIENT_PERM); if (paramer != NULL) { char p = toupper(paramer[0]); free(paramer); if (p == 'N' || p == 'O') { // authentication will not happen since no security negotiation will occur can_auth = false; } } paramer = SecMan::getSecSetting ("SEC_%s_AUTHENTICATION", CLIENT_PERM); if (paramer != NULL) { char p = toupper(paramer[0]); free(paramer); if (p == 'N') { // authentication will not happen since client doesn't allow it. can_auth = false; } } // authentication will not happen since server probably doesn't allow it. // on the off chance that someone's config manages to trick us, leave an // undocumented knob as a last resort to disable our inference. if (param_boolean("CONDOR_Q_INFER_SCHEDD_AUTHENTICATION", true)) { paramer = SecMan::getSecSetting ("SEC_%s_AUTHENTICATION", READ); if (paramer != NULL) { char p = toupper(paramer[0]); free(paramer); if (p == 'N') { can_auth = false; } } paramer = SecMan::getSecSetting ("SCHEDD.SEC_%s_AUTHENTICATION", READ); if (paramer != NULL) { char p = toupper(paramer[0]); free(paramer); if (p == 'N') { can_auth = false; } } } if (!can_auth) { dprintf (D_ALWAYS, "detected that authentication will not happen. falling back to QUERY_JOB_ADS without authentication.\n"); } DCSchedd schedd(host); int cmd = QUERY_JOB_ADS; if (want_authentication && can_auth && (useFastPath > 2)) { cmd = QUERY_JOB_ADS_WITH_AUTH; } Sock* sock; if (!(sock = schedd.startCommand(cmd, Stream::reli_sock, connect_timeout, errstack))) return Q_SCHEDD_COMMUNICATION_ERROR; classad_shared_ptr<Sock> sock_sentry(sock); if (!putClassAd(sock, request_ad) || !sock->end_of_message()) return Q_SCHEDD_COMMUNICATION_ERROR; dprintf(D_FULLDEBUG, "Sent classad to schedd\n"); int rval = 0; do { ad = new ClassAd(); if ( ! getClassAd(sock, *ad) || ! sock->end_of_message()) { rval = Q_SCHEDD_COMMUNICATION_ERROR; break; } dprintf(D_FULLDEBUG, "Got classad from schedd.\n"); long long intVal; if (ad->EvaluateAttrInt(ATTR_OWNER, intVal) && (intVal == 0)) { // Last ad. sock->close(); dprintf(D_FULLDEBUG, "Ad was last one from schedd.\n"); std::string errorMsg; if (ad->EvaluateAttrInt(ATTR_ERROR_CODE, intVal) && intVal && ad->EvaluateAttrString(ATTR_ERROR_STRING, errorMsg)) { if (errstack) errstack->push("TOOL", intVal, errorMsg.c_str()); rval = Q_REMOTE_ERROR; } if (psummary_ad && rval == 0) { std::string val; if (ad->LookupString(ATTR_MY_TYPE, val) && val == "Summary") { ad->Delete(ATTR_OWNER); // remove the bogus owner attribute *psummary_ad = ad; // return the final ad, because it has summary information ad = NULL; // so we don't delete it below. } } break; } // Note: According to condor_q.h, process_func() will return false if taking // ownership of ad, so only delete if it returns true, else set to NULL // so we don't delete it here. Either way, next set ad to NULL since either // it has been deleted or will be deleted later by process_func(). if (process_func(process_func_data, ad)) { delete ad; } ad = NULL; } while (true); // Make sure ad is not leaked no matter how we break out of the above loop. delete ad; return rval; }