예제 #1
0
void
makeAndDisplayRegular( char* name, char* pool )
{
	Daemon startd( DT_STARTD, name, pool );
	Daemon schedd( DT_SCHEDD, name, pool );
	Daemon master( DT_MASTER, name, pool );

	if( ! startd.locate() ) {
		dprintf( dflag, "%s\n", startd.error() );
	} else { 
		startd.display( dflag );
	} 
	dprintf( dflag, "\n" );
	if( ! schedd.locate() ) {
		dprintf( dflag, "%s\n", schedd.error() );
	} else { 
		schedd.display( dflag );
	} 
	dprintf( dflag, "\n" );
	if( ! master.locate() ) {
		dprintf( dflag, "%s\n", master.error() );
	} else { 
		master.display( dflag );
	} 
	dprintf( dflag, "\n" );
}
예제 #2
0
// This function calls up the schedd passed in on the command line and 
// registers the transferd as being available for the schedd's use.
RegisterResult
TransferD::register_to_schedd(ReliSock **regsock_ptr)
{
	CondorError errstack;
	MyString sname;
	MyString id;
	MyString sinful;
	bool rval;
	
	if (*regsock_ptr != NULL) {
		*regsock_ptr = NULL;
	}

	sname = m_features.get_schedd_sinful();
	id = m_features.get_id();

	if (sname == "N/A") {
		// no schedd supplied with which to register
		dprintf(D_ALWAYS, "No schedd specified to which to register.\n");
		return REG_RESULT_NO_SCHEDD;
	}
	
	// what is my sinful string?
	sinful = daemonCore->InfoCommandSinfulString(-1);

	dprintf(D_FULLDEBUG, "Registering myself(%s) to schedd(%s)\n",
		sinful.Value(), sname.Value());

	// hook up to the schedd.
	DCSchedd schedd(sname.Value(), NULL);

	// register myself, give myself 1 minute to connect.
	rval = schedd.register_transferd(sinful, id, 20*3, regsock_ptr, &errstack);

	if (rval == false) {
		// emit why 
		dprintf(D_ALWAYS, "TransferRequest::register_to_schedd(): Failed to "
			"register. Schedd gave reason '%s'\n", errstack.getFullText().c_str());
		return REG_RESULT_FAILED;
	}

	// WARNING WARNING WARNING WARNING //
	// WARNING WARNING WARNING WARNING //
	// WARNING WARNING WARNING WARNING //
	// WARNING WARNING WARNING WARNING //
	// WARNING WARNING WARNING WARNING //

	// Here, I must infact go back to daemon core without closing or doing
	// anything with the socket. This is because the schedd is going to
	// reconnect back to me, and I can't deadlock.

	dprintf(D_FULLDEBUG, 
		"Succesfully registered, awaiting treq channel message....\n");

	return REG_RESULT_SUCCESS;
}
예제 #3
0
bool
recycleShadow(int previous_job_exit_reason)
{
    if( previous_job_exit_reason != JOB_EXITED ) {
        return false;
    }
    if( shadow_worklife_expires && time(NULL) > shadow_worklife_expires ) {
        return false;
    }

    dprintf(D_ALWAYS,"Reporting job exit reason %d and attempting to fetch new job.\n",
            previous_job_exit_reason );

    ClassAd *new_job_ad = NULL;
    if (sendUpdatesToSchedd) {
        // If we're running under a schedd, get the next job ad
        // from the schedd
        ASSERT( schedd_addr );

        DCSchedd schedd(schedd_addr);
        MyString error_msg;
        if( !schedd.recycleShadow( previous_job_exit_reason, &new_job_ad, error_msg ) )
        {
            dprintf(D_ALWAYS,"recycleShadow() failed: %s\n",error_msg.Value());
            delete new_job_ad;
            return false;
        }
    } else {
        // if we are a free-running shadow
        new_job_ad = readJobAd();
    }

    if( !new_job_ad ) {
        dprintf(D_FULLDEBUG,"No new job found to run under this shadow.\n");
        return false;
    }

    new_job_ad->LookupInteger(ATTR_CLUSTER_ID,cluster);
    new_job_ad->LookupInteger(ATTR_PROC_ID,proc);
    dprintf(D_ALWAYS,"Switching to new job %d.%d\n",cluster,proc);

    delete Shadow;
    Shadow = NULL;
    is_reconnect = false;
    BaseShadow::myshadow_ptr = NULL;

    startShadow( new_job_ad );
    return true;
}
예제 #4
0
int GetMyProxyPasswordFromSchedD (int cluster_id, int proc_id,
								  char ** password)
{
	// This might seem not necessary, but it IS
	// For some reason you can't just pass cluster_id to sock->code() directly!!!!
	int cluster, proc;
	cluster = cluster_id;
	proc = proc_id;

	dprintf ( D_FULLDEBUG, " GetMyProxyPasswordFromSchedD %d, %d\n", cluster_id, proc_id);

	// Get At Schedd
	Daemon	schedd( DT_SCHEDD );
	if( ! schedd.locate() ) {
		dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Can't find address of local schedd\n" );
		return FALSE;
	}

	// Start command
	Sock* sock;
	if (!(sock = schedd.startCommand( GET_MYPROXY_PASSWORD, Stream::reli_sock, 0))) {
		dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Could not connect to local schedd\n" );
		return FALSE;
	}

	sock->encode();

	if (!sock->code (cluster) || !sock->code(proc)) {
		dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Could not encode clusterId, procId\n" );
		return FALSE;
	}

	sock->end_of_message();
	sock->decode();

	if (!sock->code (*password)) {
		dprintf( D_ALWAYS, "GetMyProxyPasswordFromSchedD: Can't retrieve password\n" );
		return FALSE;

	}

	sock->end_of_message();
	sock->close();
	delete sock;
	return TRUE;
}
예제 #5
0
파일: qedit.cpp 프로젝트: blueskyll/condor
int
main(int argc, char *argv[])
{

	has_proc = false;

	MyString constraint;
	Qmgr_connection *q;
	int nextarg = 1, cluster=0, proc=0;
	bool UseConstraint = false;
	MyString schedd_name;
	MyString pool_name;
	ExprTree* value_expr;

	myDistro->Init( argc, argv );
	config();

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, SIG_IGN );
#endif

	if (argc < 2) {
		usage(argv[0]);
	}

	// if -debug is present, it must be first. sigh.
	if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'd') {
		// output dprintf messages to stderror at TOOL_DEBUG level
		dprintf_set_tool_debug("TOOL", 0);
		nextarg++;
	}

	// if it is present, it must be first after debug.
	if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'n') {
		nextarg++;
		// use the given name as the schedd name to connect to
		if (argc <= nextarg) {
			fprintf(stderr, "%s: -n requires another argument\n", 
					argv[0]);
			exit(1);
		}				
		schedd_name = argv[nextarg];
		nextarg++;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	// if it is present, it must be just after -n flag
	if (argv[nextarg][0] == '-' && argv[nextarg][1] == 'p') {
		nextarg++;
		if (argc <= nextarg) {
			fprintf(stderr, "%s: -pool requires another argument\n", 
					argv[0]);
			exit(1);
		}
		pool_name = argv[nextarg];
		nextarg++;
	}

	DCSchedd schedd((schedd_name.Length() == 0) ? NULL : schedd_name.Value(),
					(pool_name.Length() == 0) ? NULL   : pool_name.Value());
	if ( schedd.locate() == false ) {
		if (schedd_name == "") {
			fprintf( stderr, "%s: ERROR: Can't find address of local schedd\n",
				argv[0] );
			exit(1);
		}

		if (pool_name == "") {
			fprintf( stderr, "%s: No such schedd named %s in local pool\n",
				argv[0], schedd_name.Value() );
		} else {
			fprintf( stderr, "%s: No such schedd named %s in "
				"pool %s\n",
				argv[0], schedd_name.Value(), pool_name.Value() );
		}
		exit(1);
	}

	// Open job queue 
	q = ConnectQ( schedd.addr(), 0, false, NULL, NULL, schedd.version() );
	if( !q ) {
		fprintf( stderr, "Failed to connect to queue manager %s\n", 
				 schedd.addr() );
		exit(1);
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	if (isdigit(argv[nextarg][0])) {
		char *tmp;
		cluster = strtol(argv[nextarg], &tmp, 10);
		if (cluster <= 0) {
			fprintf( stderr, "Invalid cluster # from %s.\n", argv[nextarg]);
			exit(1);
		}
		if (*tmp == '.') {
			proc = strtol(tmp + 1, &tmp, 10);
			if (cluster <= 0) {
				fprintf( stderr, "Invalid proc # from %s.\n", argv[nextarg]);
				exit(1);
			}
			UseConstraint = false;
			has_proc = true;
		} else {
			constraint.formatstr("(%s == %d)", ATTR_CLUSTER_ID, cluster);
			UseConstraint = true;
		}
		nextarg++;
	} else if (!match_prefix(argv[nextarg], "-constraint")) {
		constraint.formatstr("(%s == \"%s\")", ATTR_OWNER, argv[nextarg]);
		nextarg++;
		UseConstraint = true;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	while (match_prefix(argv[nextarg], "-constraint")) {

		if ( has_proc ){
			fprintf(stderr, "condor_qedit: proc_id specified. Ignoring constraint option\n");
			nextarg+=2;
			continue;
		}

		nextarg++;
		
		if (argc <= nextarg) {
			usage(argv[0]);
		}

		if ( !UseConstraint ){
			constraint = argv[nextarg];
		}
		else{
			constraint = "( " + constraint + " ) && " + argv[nextarg];
		}

		nextarg++;
		UseConstraint = true;
	}

	if (argc <= nextarg) {
		usage(argv[0]);
	}

	for (; nextarg < argc; nextarg += 2) {
		if (argc <= nextarg+1) {
			usage(argv[0]);
		}
		if (ProtectedAttribute(argv[nextarg])) {
			fprintf(stderr, "Update of attribute \"%s\" is not allowed.\n",
					argv[nextarg]);
			fprintf(stderr,
				"Transaction failed.  No attributes were set.\n");
			exit(1);
		}

		// Check validity of attribute-name
		if ( blankline(argv[nextarg]) ||
			 !IsValidAttrName(argv[nextarg]) )
		{
			fprintf(stderr,
				"Update aborted, illegal attribute-name specified for attribute \"%s\".\n",
				argv[nextarg]);
			fprintf(stderr,
				"Transaction failed.  No attributes were set.\n");
			exit(1);
		}

		// Check validity of attribute-value
		value_expr = NULL;
		if ( blankline(argv[nextarg+1]) ||
			 !IsValidAttrValue(argv[nextarg+1]) ||
			 ParseClassAdRvalExpr(argv[nextarg+1], value_expr) )
		{
			fprintf(stderr,
				"Update aborted, illegal attribute-value specified for attribute \"%s\".\n",
				argv[nextarg]);
			fprintf(stderr,
				"Transaction failed.  No attributes were set.\n");
			exit(1);
		}
		if (value_expr) delete value_expr;

		if (UseConstraint) {
			// Try to communicate with the newer protocol first
			if (SetAttributeByConstraint(constraint.Value(),
							argv[nextarg],
							argv[nextarg+1],
							SETDIRTY) < 0) {
				if (SetAttributeByConstraint(constraint.Value(),
							argv[nextarg],
							argv[nextarg+1]) < 0) {

					fprintf(stderr,
						"Failed to set attribute \"%s\" by constraint: %s\n",
						argv[nextarg], constraint.Value());
					fprintf(stderr,
						"Transaction failed.  No attributes were set.\n");
					exit(1);
				}
			}
		} else {
			if (SetAttribute(cluster, proc, argv[nextarg],
							 argv[nextarg+1], SETDIRTY) < 0) {
				fprintf(stderr,
						"Failed to set attribute \"%s\" for job %d.%d.\n",
						argv[nextarg], cluster, proc);
				fprintf(stderr,
						"Transaction failed.  No attributes were set.\n");
				exit(1);
			}
		}
		printf("Set attribute \"%s\".\n", argv[nextarg]);
	}

	if (!DisconnectQ(q)) {
		fprintf(stderr,
				"Queue transaction failed.  No attributes were set.\n");
		exit(1);
	}

	return 0;
}
예제 #6
0
파일: peek.cpp 프로젝트: AlainRoy/htcondor
bool
HTCondorPeek::create_session()
{
	m_retry_sensible = false;
	DCSchedd schedd(m_name.size() ? m_name.c_str() : NULL,
			m_pool.size() ? m_pool.c_str() : NULL);
		
	dprintf(D_FULLDEBUG,"Locating daemon process\n");

	if(!schedd.locate())
	{
		if (!m_name.size()) {
			std::cerr << "Can't find address of local schedd" << std::endl;
			return false;
		}
		if (!m_pool.size()) {
			std::cerr << "No such schedd named " << m_name << " in local pool" << std::endl;
		} else {
			std::cerr << "No such schedd named " << m_name << " in pool " << m_pool << std::endl;
		}
		return false;
	}

	m_xfer_q = new DCTransferQueue( schedd );

	MyString starter_claim_id;
	MyString slot_name;
	MyString error_msg;
	CondorError error_stack;
	int timeout = 300;

		// We want encryption because we will be transferring an ssh key.
		// must be in format expected by SecMan::ImportSecSessionInfo()
	char const *session_info = "[Encryption=\"YES\";Integrity=\"YES\";]";

	int job_status;
	MyString hold_reason;
	bool success = schedd.getJobConnectInfo(m_id,-1,session_info,timeout,&error_stack,m_starter_addr,starter_claim_id,m_starter_version,slot_name,error_msg,m_retry_sensible,job_status,hold_reason);

		// turn the ssh claim id into a security session so we can use it
		// to authenticate ourselves to the starter
	SecMan secman;
	ClaimIdParser cidp(starter_claim_id.Value());
	if( success ) {
		success = secman.CreateNonNegotiatedSecuritySession(
					DAEMON,
					cidp.secSessionId(),
					cidp.secSessionKey(),
					cidp.secSessionInfo(),
					EXECUTE_SIDE_MATCHSESSION_FQU,
					m_starter_addr.Value(),
					0 );
		if( !success ) {
			error_msg = "Failed to create security session to connect to starter.";
		}
		else {
			m_sec_session_id = cidp.secSessionId();
		}
	}

	CondorVersionInfo vi(m_starter_version.Value());
	if (vi.is_valid() && !vi.built_since_version(7, 9, 5))
	{
		std::cerr << "Remote starter (version " << m_starter_version.Value() << ") is too old for condor_peek" << std::endl;
		return false;
	}

	if( !success ) {
		if ( !m_retry_sensible ) {
			std::cerr << error_msg.Value() << std::endl;
		}
		return false;
	}

	dprintf(D_FULLDEBUG,"Got connect info for starter %s\n",
			m_starter_addr.Value());
	return true;
}
예제 #7
0
// Read history from a remote schedd
static void readHistoryRemote(classad::ExprTree *constraintExpr)
{
	printHeader();
	if(longformat && use_xml) {
		std::string out;
		AddClassAdXMLFileHeader(out);
		printf("%s\n", out.c_str());
	}

	classad::ClassAd ad;
	classad::ExprList *projList(new classad::ExprList());
	classad::ExprTree *projTree = static_cast<classad::ExprTree*>(projList);
	ad.Insert(ATTR_PROJECTION, projTree);
	ad.Insert(ATTR_REQUIREMENTS, constraintExpr);
	ad.InsertAttr(ATTR_NUM_MATCHES, specifiedMatch <= 0 ? -1 : specifiedMatch);

	DCSchedd schedd(g_name.size() ? g_name.c_str() : NULL, g_pool.size() ? g_pool.c_str() : NULL);
	if (!schedd.locate(Daemon::LOCATE_FOR_LOOKUP)) {
		fprintf(stderr, "Unable to locate remote schedd (name=%s, pool=%s).\n", g_name.c_str(), g_pool.c_str());
		exit(1);
	}
	Sock* sock;
	if (!(sock = schedd.startCommand(QUERY_SCHEDD_HISTORY, Stream::reli_sock, 0))) {
		fprintf(stderr, "Unable to send history command to remote schedd;\n"
			"Typically, either the schedd is not responding, does not authorize you, or does not support remote history.\n");
		exit(1);
	}
	classad_shared_ptr<Sock> sock_sentry(sock);

	if (!putClassAd(sock, ad) || !sock->end_of_message()) {
		fprintf(stderr, "Unable to send request to remote schedd; likely a server or network error.\n");
		exit(1);
	}

	while (true) {
		compat_classad::ClassAd ad;
		if (!getClassAd(sock, ad)) {
			fprintf(stderr, "Failed to recieve remote ad.\n");
			exit(1);
		}
		long long intVal;
		if (ad.EvaluateAttrInt(ATTR_OWNER, intVal) && (intVal == 0)) { // Last ad.
			if (!sock->end_of_message()) {
				fprintf(stderr, "Unable to close remote socket.\n");
			}
			sock->close();
			std::string errorMsg;
			if (ad.EvaluateAttrInt(ATTR_ERROR_CODE, intVal) && intVal && ad.EvaluateAttrString(ATTR_ERROR_STRING, errorMsg)) {
				fprintf(stderr, "Error %lld: %s\n", intVal, errorMsg.c_str());
				exit(intVal);
			}
			if (ad.EvaluateAttrInt("MalformedAds", intVal) && intVal) {
				fprintf(stderr, "Remote side had parse errors on history file");
				exit(1);
			}
			if (!ad.EvaluateAttrInt(ATTR_NUM_MATCHES, intVal) || (intVal != matchCount)) {
				fprintf(stderr, "Client and server do not agree on number of ads sent;\n"
					"Indicates lost network packets or an internal error\n");
				exit(1);
			}
			break;
		}
		matchCount++;
		printJob(ad);
	}

	if(longformat && use_xml) {
		std::string out;
		AddClassAdXMLFileFooter(out);
		printf("%s\n", out.c_str());
	}
}
예제 #8
0
int
main(int argc, char* argv[])
{
  Collectors = NULL;

#ifdef HAVE_EXT_POSTGRESQL
  HistorySnapshot *historySnapshot;
  SQLQuery queryhor;
  SQLQuery queryver;
  QuillErrCode st;
  bool remotequill=false;
  char *quillName=NULL;
  AttrList *ad=0;
  int flag = 1;
  void **parameters;
  char *dbconn=NULL;
  char *completedsince = NULL;
  char *dbIpAddr=NULL, *dbName=NULL,*queryPassword=NULL;
  bool remoteread = false;
#endif /* HAVE_EXT_POSTGRESQL */

  const char *owner=NULL;
  bool readfromfile = true;
  bool fileisuserlog = false;

  char* JobHistoryFileName=NULL;
  const char * pcolon=NULL;


  GenericQuery constraint; // used to build a complex constraint.
  ExprTree *constraintExpr=NULL;

  std::string tmp;

  int i;
  myDistro->Init( argc, argv );

  config();

#ifdef HAVE_EXT_POSTGRESQL
  parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *));
  queryhor.setQuery(HISTORY_ALL_HOR, NULL);
  queryver.setQuery(HISTORY_ALL_VER, NULL);
#endif /* HAVE_EXT_POSTGRESQL */

  for(i=1; i<argc; i++) {
    if (is_dash_arg_prefix(argv[i],"long",1)) {
      longformat=TRUE;   
    }
    
    else if (is_dash_arg_prefix(argv[i],"xml",3)) {
		use_xml = true;	
		longformat = true;
	}
    
    else if (is_dash_arg_prefix(argv[i],"backwards",1)) {
        backwards=TRUE;
    }

	// must be at least -forw to avoid conflict with -f (for file) and -format
    else if (is_dash_arg_prefix(argv[i],"nobackwards",3) ||
			 is_dash_arg_prefix(argv[i],"forwards",4)) {
        backwards=FALSE;
    }

    else if (is_dash_arg_colon_prefix(argv[i],"wide", &pcolon, 1)) {
        wide_format=TRUE;
        if (pcolon) {
            wide_format_width = atoi(++pcolon);
            if ( ! mask.IsEmpty()) mask.SetOverallWidth(getDisplayWidth()-1);
            if (wide_format_width <= 80) wide_format = FALSE;
        }
    }

    else if (is_dash_arg_prefix(argv[i],"match",1) || is_dash_arg_prefix(argv[i],"limit",3)) {
        i++;
        if (argc <= i) {
            fprintf(stderr,
                    "Error: Argument -match requires a number value "
                    " as a parameter.\n");
            exit(1);
        }
        specifiedMatch = atoi(argv[i]);
    }

#ifdef HAVE_EXT_POSTGRESQL
    else if(is_dash_arg_prefix(argv[i], "dbname",1)) {
		i++;
		if (argc <= i) {
			fprintf( stderr,
					 "Error: Argument -dbname requires the name of a quilld as a parameter\n" );
			exit(1);
		}
		

/*
		if( !(quillName = get_daemon_name(argv[i])) ) {
			fprintf( stderr, "Error: unknown host %s\n",
					 get_host_part(argv[i]) );
			printf("\n");
			print_wrapped_text("Extra Info: The name given with the -dbname "
							   "should be the name of a condor_quilld process. "
							   "Normally it is either a hostname, or "
							   "\"name@hostname\". "
							   "In either case, the hostname should be the "
							   "Internet host name, but it appears that it "
							   "wasn't.",
							   stderr);
			exit(1);
		}
		sprintf (tmp, "%s == \"%s\"", ATTR_NAME, quillName);      		
		quillQuery.addORConstraint (tmp);

*/
		quillName = argv[i];

		sprintf (tmp, "%s == \"%s\"", ATTR_SCHEDD_NAME, quillName);
		quillQuery.addORConstraint (tmp.c_str());

		remotequill = false;
		readfromfile = false;
    }
#endif /* HAVE_EXT_POSTGRESQL */
    else if (is_dash_arg_prefix(argv[i],"file",2)) {
		if (i+1==argc || JobHistoryFileName) break;
		i++;
		JobHistoryFileName=argv[i];
		readfromfile = true;
    }
	else if (is_dash_arg_prefix(argv[i],"userlog",1)) {
		if (i+1==argc || JobHistoryFileName) break;
		i++;
		JobHistoryFileName=argv[i];
		readfromfile = true;
		fileisuserlog = true;
	}
    else if (is_dash_arg_prefix(argv[i],"help",1)) {
		Usage(argv[0],0);
    }
    else if (is_dash_arg_prefix(argv[i],"format",1)) {
		if (argc <= i + 2) {
			fprintf(stderr,
					"Error: Argument -format requires a spec and "
					"classad attribute name as parameters.\n");
			fprintf(stderr,
					"\t\te.g. condor_history -format '%%d' ClusterId\n");
			exit(1);
		}
		mask.registerFormat(argv[i + 1], argv[i + 2]);
		customFormat = true;
		i += 2;
    }
	else if (*(argv[i]) == '-' && 
				(is_arg_colon_prefix(argv[i]+1,"af", &pcolon, 2) ||
				 is_arg_colon_prefix(argv[i]+1,"autoformat", &pcolon, 5))) {
		// make sure we have at least one argument to autoformat
		if (argc <= i+1 || *(argv[i+1]) == '-') {
			fprintf (stderr, "Error: Argument %s requires at last one attribute parameter\n", argv[i]);
			fprintf(stderr, "\t\te.g. condor_history %s ClusterId\n", argv[i]);
			exit(1);
		}
		if (pcolon) ++pcolon; // if there are options, skip over the colon to the options.
		int ixNext = parse_autoformat_args(argc, argv, i+1, pcolon, mask, diagnostic);
		if (ixNext > i)
			i = ixNext-1;
		customFormat = true;
	}
	else if (is_dash_arg_colon_prefix(argv[i], "print-format", &pcolon, 2)) {
		if ( (argc <= i+1)  || (*(argv[i+1]) == '-' && (argv[i+1])[1] != 0)) {
			fprintf( stderr, "Error: Argument -print-format requires a filename argument\n");
			exit( 1 );
		}
		// hack allow -pr ! to disable use of user-default print format files.
		if (MATCH == strcmp(argv[i+1], "!")) {
			++i;
			disable_user_print_files = true;
			continue;
		}
		if ( ! wide_format) mask.SetOverallWidth(getDisplayWidth()-1);
		customFormat = true;
		++i;
		std::string where_expr;
		if (set_print_mask_from_stream(mask, where_expr, argv[i], true) < 0) {
			fprintf(stderr, "Error: cannot execute print-format file %s\n", argv[i]);
			exit (1);
		}
		if ( ! where_expr.empty()) {
			constraint.addCustomAND(where_expr.c_str());
		}
	}
    else if (is_dash_arg_prefix(argv[i],"constraint",1)) {
		// make sure we have at least one more argument
		if (argc <= i+1) {
			fprintf( stderr, "Error: Argument %s requires another parameter\n", argv[i]);
			exit(1);
		}
		i++;
		constraint.addCustomAND(argv[i]);
    }
#ifdef HAVE_EXT_POSTGRESQL
    else if (is_dash_arg_prefix(argv[i],"completedsince",3)) {
		i++;
		if (argc <= i) {
			fprintf(stderr,
					"Error: Argument -completedsince requires a date and "
					"optional timestamp as a parameter.\n");
			fprintf(stderr,
					"\t\te.g. condor_history -completedsince \"2004-10-19 10:23:54\"\n");
			exit(1);
		}
		
		if (constraint!="") break;
		completedsince = strdup(argv[i]);
		parameters[0] = completedsince;
		queryhor.setQuery(HISTORY_COMPLETEDSINCE_HOR,parameters);
		queryver.setQuery(HISTORY_COMPLETEDSINCE_VER,parameters);
    }
#endif /* HAVE_EXT_POSTGRESQL */

    else if (sscanf (argv[i], "%d.%d", &cluster, &proc) == 2) {
		std::string jobconst;
		formatstr (jobconst, "%s == %d && %s == %d", 
				 ATTR_CLUSTER_ID, cluster,ATTR_PROC_ID, proc);
		constraint.addCustomOR(jobconst.c_str());
		#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = &cluster;
		parameters[1] = &proc;
		queryhor.setQuery(HISTORY_CLUSTER_PROC_HOR, parameters);
		queryver.setQuery(HISTORY_CLUSTER_PROC_VER, parameters);
		#endif /* HAVE_EXT_POSTGRESQL */
    }
    else if (sscanf (argv[i], "%d", &cluster) == 1) {
		std::string jobconst;
		formatstr (jobconst, "%s == %d", ATTR_CLUSTER_ID, cluster);
		constraint.addCustomOR(jobconst.c_str());
		#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = &cluster;
		queryhor.setQuery(HISTORY_CLUSTER_HOR, parameters);
		queryver.setQuery(HISTORY_CLUSTER_VER, parameters);
		#endif /* HAVE_EXT_POSTGRESQL */
    }
    else if (is_dash_arg_prefix(argv[i],"debug",1)) {
          // dprintf to console
          dprintf_set_tool_debug("TOOL", 0);
    }
    else if (is_dash_arg_prefix(argv[i],"diagnostic",4)) {
          // dprintf to console
          diagnostic = true;
    }
    else if (is_dash_arg_prefix(argv[i], "name", 1)) {
        i++;
        if (argc <= i)
        {
            fprintf(stderr,
                "Error: Argument -name requires name of a remote schedd\n");
            fprintf(stderr,
                "\t\te.g. condor_history -name submit.example.com \n");
            exit(1);
        }
        g_name = argv[i];
        readfromfile = false;
       #ifdef HAVE_EXT_POSTGRESQL
        remoteread = true;
       #endif
    }
    else if (is_dash_arg_prefix(argv[i], "pool", 1)) {
        i++;    
        if (argc <= i)
        {
            fprintf(stderr,
                "Error: Argument -name requires name of a remote schedd\n");
            fprintf(stderr,
                "\t\te.g. condor_history -name submit.example.com \n");
            exit(1);    
        }       
        g_pool = argv[i];
        readfromfile = false;
       #ifdef HAVE_EXT_POSTGRESQL
        remoteread = true;
       #endif
    }
    else {
		std::string ownerconst;
		owner = argv[i];
		formatstr(ownerconst, "%s == \"%s\"", ATTR_OWNER, owner);
		constraint.addCustomOR(ownerconst.c_str());
#ifdef HAVE_EXT_POSTGRESQL
		parameters[0] = owner;
		queryhor.setQuery(HISTORY_OWNER_HOR, parameters);
		queryver.setQuery(HISTORY_OWNER_VER, parameters);
#endif /* HAVE_EXT_POSTGRESQL */
    }
  }
  if (i<argc) Usage(argv[0]);
  
  
  MyString my_constraint;
  constraint.makeQuery(my_constraint);
  if (diagnostic) {
	  fprintf(stderr, "Using effective constraint: %s\n", my_constraint.c_str());
  }
  if ( ! my_constraint.empty() && ParseClassAdRvalExpr( my_constraint.c_str(), constraintExpr ) ) {
	  fprintf( stderr, "Error:  could not parse constraint %s\n", my_constraint.c_str() );
	  exit( 1 );
  }

#ifdef HAVE_EXT_POSTGRESQL
	/* This call must happen AFTER config() is called */
  if (checkDBconfig() == true && !readfromfile) {
  	readfromfile = false;
  } else {
  	readfromfile = true;
  }
#endif /* HAVE_EXT_POSTGRESQL */

#ifdef HAVE_EXT_POSTGRESQL
  if(!readfromfile && !remoteread) {
	  if(remotequill) {
		  if (Collectors == NULL) {
			  Collectors = CollectorList::create();
			  if(Collectors == NULL ) {
				  printf("Error: Unable to get list of known collectors\n");
				  exit(1);
			  }
		  }
		  result = Collectors->query ( quillQuery, quillList );
		  if(result != Q_OK) {
			  printf("Fatal Error querying collectors\n");
			  exit(1);
		  }

		  if(quillList.MyLength() == 0) {
			  printf("Error: Unknown quill server %s\n", quillName);
			  exit(1);
		  }
		  
		  quillList.Open();
		  while ((ad = quillList.Next())) {
				  // get the address of the database
			  dbIpAddr = dbName = queryPassword = NULL;
			  if (!ad->LookupString(ATTR_QUILL_DB_IP_ADDR, &dbIpAddr) ||
				  !ad->LookupString(ATTR_QUILL_DB_NAME, &dbName) ||
				  !ad->LookupString(ATTR_QUILL_DB_QUERY_PASSWORD, &queryPassword) || 
				  (ad->LookupBool(ATTR_QUILL_IS_REMOTELY_QUERYABLE,flag) && !flag)) {
				  printf("Error: The quill daemon \"%s\" is not set up "
						 "for database queries\n", 
						 quillName);
				  exit(1);
			  }
		  }
	  } else {
			// they just typed 'condor_history' on the command line and want
			// to use quill, so get the schedd ad for the local machine if
			// we can, figure out the name of the schedd and the 
			// jobqueuebirthdate
		Daemon schedd( DT_SCHEDD, 0, 0 );

        if ( schedd.locate(Daemon::LOCATE_FULL) ) {
			char *scheddname = quillName;	
			if (scheddname == NULL) {
				// none set explictly, look it up in the daemon ad
				scheddname = schedd.name();
				ClassAd *daemonAd = schedd.daemonAd();
				int scheddbirthdate;
				if(daemonAd) {
					if(daemonAd->LookupInteger( ATTR_JOB_QUEUE_BIRTHDATE, 	
								scheddbirthdate) ) {
						queryhor.setJobqueuebirthdate( (time_t)scheddbirthdate);	
						queryver.setJobqueuebirthdate( (time_t)scheddbirthdate);	
					}
				}
			} else {
				queryhor.setJobqueuebirthdate(0);	
				queryver.setJobqueuebirthdate(0);	
			}
			queryhor.setScheddname(scheddname);	
			queryver.setScheddname(scheddname);	
			
		}
	  }
	  dbconn = getDBConnStr(quillName,dbIpAddr,dbName,queryPassword);
	  historySnapshot = new HistorySnapshot(dbconn);
	  if (!customFormat) {
		  printf ("\n\n-- Quill: %s : %s : %s\n", quillName, 
			  dbIpAddr, dbName);
		}		

	  queryhor.prepareQuery();  // create the query strings before sending off to historySnapshot
	  queryver.prepareQuery();
	  
	  st = historySnapshot->sendQuery(&queryhor, &queryver, longformat,
		false, customFormat, &mask, constraint.c_str());

		  //if there's a failure here and if we're not posing a query on a 
		  //remote quill daemon, we should instead query the local file
	  if(st == QUILL_FAILURE) {
	        printf( "-- Database at %s not reachable\n", dbIpAddr);
		if(!remotequill) {
			char *tmp_hist = param("HISTORY");
			if (!customFormat) {
				printf( "--Failing over to the history file at %s instead --\n",
						tmp_hist ? tmp_hist : "(null)" );
			}
			if(!tmp_hist) {
				free(tmp_hist);
			}
			readfromfile = true;
	  	}
	  }
		  // query history table
	  if (historySnapshot->isHistoryEmpty()) {
		  printf("No historical jobs in the database match your query\n");
	  }
	  historySnapshot->release();
	  delete(historySnapshot);
  }
#endif /* HAVE_EXT_POSTGRESQL */
  
  if(readfromfile == true) {
      readHistoryFromFiles(fileisuserlog, JobHistoryFileName, my_constraint.c_str(), constraintExpr);
  }
  else {
      readHistoryRemote(constraintExpr);
  }
  
  
#ifdef HAVE_EXT_POSTGRESQL
  if(completedsince) free(completedsince);
  if(parameters) free(parameters);
  if(dbIpAddr) free(dbIpAddr);
  if(dbName) free(dbName);
  if(queryPassword) free(queryPassword);
  if(dbconn) free(dbconn);
#endif
  return 0;
}
예제 #9
0
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;
}
예제 #10
0
int
CondorQ::fetchQueueFromHostAndProcessV2(const char *host,
					const char *constraint,
					StringList &attrs,
					condor_q_process_func process_func,
					void * process_func_data,
					int connect_timeout,
					CondorError *errstack)
{
	classad::ClassAdParser parser;
	classad::ExprTree *expr = NULL;
	parser.ParseExpression(constraint, expr);
	if (!expr) return Q_INVALID_REQUIREMENTS;

	classad::ExprList *projList = new classad::ExprList();
	if (!projList) return Q_INTERNAL_ERROR;
	attrs.rewind();
	const char *attr;
	while ((attr = attrs.next())) {
		classad::Value value; value.SetStringValue(attr);
		classad::ExprTree *entry = classad::Literal::MakeLiteral(value);
		if (!entry) return Q_INTERNAL_ERROR;
		projList->push_back(entry);
	}
	classad::ClassAd ad;
	ad.Insert(ATTR_REQUIREMENTS, expr);
	classad::ExprTree *projTree = static_cast<classad::ExprTree*>(projList);
	ad.Insert(ATTR_PROJECTION, projTree);

	DCSchedd schedd(host);
	Sock* sock;
	if (!(sock = schedd.startCommand(QUERY_JOB_ADS, Stream::reli_sock, connect_timeout, errstack))) return Q_SCHEDD_COMMUNICATION_ERROR;

	classad_shared_ptr<Sock> sock_sentry(sock);

	if (!putClassAd(sock, ad) || !sock->end_of_message()) return Q_SCHEDD_COMMUNICATION_ERROR;
	dprintf(D_FULLDEBUG, "Sent classad to schedd\n");

	do {
		classad_shared_ptr<compat_classad::ClassAd> ad(new ClassAd());
		if (!getClassAd(sock, *ad.get())) return Q_SCHEDD_COMMUNICATION_ERROR;
		if (!sock->end_of_message()) return Q_SCHEDD_COMMUNICATION_ERROR;
		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());
				return Q_REMOTE_ERROR;
			}
			break;
		}
		(*process_func) (process_func_data, ad);
	} while (true);

	return 0;
}
예제 #11
0
int
main(int argc, char* argv[])
{

  void **parameters;

  char* JobHistoryFileName=NULL;

  int i;
  parameters = (void **) malloc(NUM_PARAMETERS * sizeof(void *));
  myDistro->Init( argc, argv );

  config();
  Termlog = 1;
  dprintf_config("TOOL", get_param_functions());

  for(i=1; i<argc; i++) {

    if (strcmp(argv[i],"-f")==0) {
		if (i+1==argc || JobHistoryFileName) break;
		i++;
		JobHistoryFileName=argv[i];
    }
    else if (strcmp(argv[i],"-help")==0) {
		Usage(argv[0],0);
    }
    else if (strcmp(argv[i],"-name")==0) {
		if (i+1==argc || ScheddName) break;
		i++;
		ScheddName=strdup(argv[i]);
        if ((i+1==argc) || ScheddBirthdate) break;
        i++;
        ScheddBirthdate = atoi(argv[i]);
    }
/*    else if (strcmp(argv[i],"-debug")==0) {
          // dprintf to console
          Termlog = 1;
    }
*/
    else {
		Usage(argv[0]);
    }
  }
  if (i<argc) Usage(argv[0]);

  if (JobHistoryFileName == NULL) 
	  Usage(argv[0]);

  if ((ScheddName == NULL) || (ScheddBirthdate == 0)) {

    if (ScheddName) 
        fprintf(stdout, "You specified Schedd name without a Job Queue"
                        "Birthdate. Ignoring value %s\n", ScheddName);
        
    Daemon schedd( DT_SCHEDD, 0, 0 );

    if ( schedd.locate() ) {
        char *scheddname; 
        if( (scheddname = schedd.name()) ) {
            ScheddName = strdup(scheddname);
        } else {
            fprintf(stderr, "You did not specify a Schedd name and Job Queue "
                           "Birthdate on the command line "
                           "and there was an error getting the Schedd "
                           "name from the local Schedd Daemon Ad. Please "
                           "check that the SCHEDD_DAEMON_AD_FILE config "
                           "parameter is set and the file contains a valid "
                           "Schedd Daemon ad.\n");
            exit(1);
        }
        ClassAd *daemonAd = schedd.daemonAd();
        if(daemonAd) {
            if (!(daemonAd->LookupInteger( ATTR_JOB_QUEUE_BIRTHDATE, 
                        ScheddBirthdate) )) {
                // Can't find the job queue birthdate
                fprintf(stderr, "You did not specify a Schedd name and "
                           "Job Queue Birthdate on the command line "
                           "and there was an error getting the Job Queue "
                           "Birthdate from the local Schedd Daemon Ad. Please "
                           "check that the SCHEDD_DAEMON_AD_FILE config "
                           "parameter is set and the file contains a valid "
                           "Schedd Daemon ad.\n");
                exit(1);
            }
        }
    } else {

		fprintf(stderr, "You did not specify a Schedd name and Job Queue "
				        "Birthdate on the command line and there was "
				        "an error getting the Schedd Daemon Ad. Please "
				        "check that Condor is running and the SCHEDD_DAEMON_AD_FILE "
				        "config parameter is set and the file contains a valid "
				        "Schedd Daemon ad.\n");
		exit(1);
	}
  }

  doDBconfig();
  readHistoryFromFile(JobHistoryFileName);

  if(parameters) free(parameters);
  if(ScheddName) free(ScheddName);
  return 0;
}