Beispiel #1
0
/** Get the command-line options we want to preserve from the .condor.sub
    file we're overwriting, and plug them into the shallowOpts structure.
	Note that it's *not* an error for the .condor.sub file to not exist.
	@param shallowOpts: the condor_submit_dag shallow options
	@return 0 if successful, 1 if failed
*/
int
getOldSubmitFlags(SubmitDagShallowOptions &shallowOpts)
{
		// It's not an error for the submit file to not exist.
	if ( fileExists( shallowOpts.strSubFile ) ) {
		MultiLogFiles::FileReader reader;
		MyString error = reader.Open( shallowOpts.strSubFile );
		if ( error != "" ) {
			fprintf( stderr, "Error reading submit file: %s\n",
						error.Value() );
			return 1;
		}

		MyString subLine;
		while ( reader.NextLogicalLine( subLine ) ) {
			StringList tokens( subLine.Value(), " \t" );
			tokens.rewind();
			const char *first = tokens.next();
			if ( first && !strcasecmp( first, "arguments" ) ) {
				if ( parseArgumentsLine( subLine, shallowOpts ) != 0 ) {
					return 1;
				}
			}
		}

		reader.Close();
	}

	return 0;
}
//-------------------------------------------------------------------------
bool
GetConfigAndAttrs( /* const */ StringList &dagFiles, bool useDagDir, 
			MyString &configFile, StringList &attrLines, MyString &errMsg )
{
	bool		result = true;

		// Note: destructor will change back to original directory.
	TmpDir		dagDir;

	dagFiles.rewind();
	char *dagFile;
	while ( (dagFile = dagFiles.next()) != NULL ) {

			//
			// Change to the DAG file's directory if necessary, and
			// get the filename we need to use for it from that directory.
			//
		const char *	newDagFile;
		if ( useDagDir ) {
			MyString	tmpErrMsg;
			if ( !dagDir.Cd2TmpDirFile( dagFile, tmpErrMsg ) ) {
				AppendError( errMsg,
						MyString("Unable to change to DAG directory ") +
						tmpErrMsg );
				return false;
			}
			newDagFile = condor_basename( dagFile );
		} else {
			newDagFile = dagFile;
		}

		StringList		configFiles;

			// Note: destructor will close file.
		MultiLogFiles::FileReader reader;
		errMsg = reader.Open( newDagFile );
		if ( errMsg != "" ) {
			return false;
		}

		MyString logicalLine;
		while ( reader.NextLogicalLine( logicalLine ) ) {
			if ( logicalLine != "" ) {
					// Note: StringList constructor removes leading
					// whitespace from lines.
				StringList tokens( logicalLine.Value(), " \t" );
				tokens.rewind();

				const char *firstToken = tokens.next();
				if ( !strcasecmp( firstToken, "config" ) ) {

						// Get the value.
					const char *newValue = tokens.next();
					if ( !newValue || !strcmp( newValue, "" ) ) {
						AppendError( errMsg, "Improperly-formatted "
									"file: value missing after keyword "
									"CONFIG" );
			    		result = false;
					} else {

							// Add the value we just found to the config
							// files list (if it's not already in the
							// list -- we don't want duplicates).
						configFiles.rewind();
						char *existingValue;
						bool alreadyInList = false;
						while ( ( existingValue = configFiles.next() ) ) {
							if ( !strcmp( existingValue, newValue ) ) {
								alreadyInList = true;
							}
						}

						if ( !alreadyInList ) {
								// Note: append copies the string here.
							configFiles.append( newValue );
						}
					}

					//some DAG commands are needed for condor_submit_dag, too...
				} else if ( !strcasecmp( firstToken, "SET_JOB_ATTR" ) ) {
						// Strip of DAGMan-specific command name; the
						// rest we pass to the submit file.
					logicalLine.replaceString( "SET_JOB_ATTR", "" );
					logicalLine.trim();
					if ( logicalLine == "" ) {
						AppendError( errMsg, "Improperly-formatted "
									"file: value missing after keyword "
									"SET_JOB_ATTR" );
						result = false;
					} else {
						attrLines.append( logicalLine.Value() );
					}
				}
			}
		}
	
		reader.Close();

			//
			// Check the specified config file(s) against whatever we
			// currently have, setting the config file if it hasn't
			// been set yet, flagging an error if config files conflict.
			//
		configFiles.rewind();
		char *		cfgFile;
		while ( (cfgFile = configFiles.next()) ) {
			MyString	cfgFileMS = cfgFile;
			MyString	tmpErrMsg;
			if ( MakePathAbsolute( cfgFileMS, tmpErrMsg ) ) {
				if ( configFile == "" ) {
					configFile = cfgFileMS;
				} else if ( configFile != cfgFileMS ) {
					AppendError( errMsg, MyString("Conflicting DAGMan ") +
								"config files specified: " + configFile +
								" and " + cfgFileMS );
					result = false;
				}
			} else {
				AppendError( errMsg, tmpErrMsg );
				result = false;
			}
		}

			//
			// Go back to our original directory.
			//
		MyString	tmpErrMsg;
		if ( !dagDir.Cd2MainDir( tmpErrMsg ) ) {
			AppendError( errMsg,
					MyString("Unable to change to original directory ") +
					tmpErrMsg );
			result = false;
		}
	}

	return result;
}
Beispiel #3
0
/** Recursively call condor_submit_dag on nested DAGs.
	@param deepOpts: the condor_submit_dag deep options
	@return 0 if successful, 1 if failed
*/
int
doRecursionNew( SubmitDagDeepOptions &deepOpts,
			SubmitDagShallowOptions &shallowOpts )
{
	int result = 0;

	shallowOpts.dagFiles.rewind();

		// Go through all DAG files specified on the command line...
	StringList submitFiles;
	const char *dagFile;
	while ( (dagFile = shallowOpts.dagFiles.next()) ) {

			// Get logical lines from this DAG file.
		MultiLogFiles::FileReader reader;
		MyString errMsg = reader.Open( dagFile );
		if ( errMsg != "" ) {
			fprintf( stderr, "Error reading DAG file: %s\n",
						errMsg.Value() );
			return 1;
		}


			// Find and parse JOB and SUBDAG lines.
		MyString dagLine;
		while ( reader.NextLogicalLine( dagLine ) ) {
			StringList tokens( dagLine.Value(), " \t" );
			tokens.rewind();
			const char *first = tokens.next();

			if ( first && !strcasecmp( first, "JOB" ) ) {

					// Get the submit file and directory from the DAG
					// file line.
				const char *subFile;
				const char *directory;
				if ( parseJobOrDagLine( dagLine.Value(), tokens, "submit",
							subFile, directory ) != 0 ) {
					return 1;
				}

					// Now figure out whether JOB line is a nested DAG.
				MyString submitFile( subFile );

					// If submit file ends in ".condor.sub", we assume it
					// refers to a sub-DAG.
				int start = submitFile.find( DAG_SUBMIT_FILE_SUFFIX );
				if ( start >= 0 &&
							start + (int)strlen( DAG_SUBMIT_FILE_SUFFIX) ==
							submitFile.Length() ) {

						// Change submit file name to DAG file name.
					submitFile.replaceString( DAG_SUBMIT_FILE_SUFFIX, "" );

						// Now run condor_submit_dag on the DAG file.
					if ( runSubmitDag( deepOpts, submitFile.Value(),
								directory, false ) != 0 ) {
						result = 1;
					}
				}

			} else if ( first && !strcasecmp( first, "SUBDAG" ) ) {

				const char *inlineOrExt = tokens.next();
				if ( strcasecmp( inlineOrExt, "EXTERNAL" ) ) {
					fprintf( stderr, "ERROR: only SUBDAG EXTERNAL is supported "
								"at this time (line: <%s>)\n", dagLine.Value() );
					return 1;
				}

					// Get the nested DAG file and directory from the DAG
					// file line.
				const char *nestedDagFile;
				const char *directory;
				if ( parseJobOrDagLine( dagLine.Value(), tokens, "DAG",
							nestedDagFile, directory ) != 0 ) {
					return 1;
				}

					// Now run condor_submit_dag on the DAG file.
				if ( runSubmitDag( deepOpts, nestedDagFile, directory,
							false ) != 0 ) {
					result = 1;
				}
			}
		}

		reader.Close();
	}

	return result;
}