コード例 #1
0
ファイル: statsd.cpp プロジェクト: valtri/htcondor
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) );
			}
		}
	}
}
コード例 #2
0
ファイル: statsd.cpp プロジェクト: valtri/htcondor
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());
	}
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: extra_tests.cpp プロジェクト: AlainRoy/htcondor
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;
}
コード例 #5
0
ファイル: view.cpp プロジェクト: AlainRoy/htcondor
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 );
}
コード例 #6
0
ファイル: condor_q.cpp プロジェクト: bbockelm/htcondor
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;
}