#include "dial_condor/CondorCodTable.h" #include #include #include #include #include #include #include #include "dataset_util/Text.h" #include "dataset_util/FileStatus.h" #include "dataset_util/FileName.h" #include "dataset_util/Environment.h" using std::string; using std::vector; using std::endl; using std::ostream; using std::multimap; using std::pair; using dial::CondorCodTable; using dial::structClaimDetails; namespace { int ssystem(string com) { return system(com.c_str()); } bool check_dir(Text::Name name) { if ( name == "" ) return false; FileStatus stat(name); return stat.is_directory() && stat.is_readable(); } bool check_file(Text::Name name) { if ( name == "" ) return false; FileStatus stat(name); return stat.is_regular() && stat.is_readable(); } } //********************************************************************** CondorCodTable::CondorCodTable(string strMachines_fname, string strClaimID_fname, string strtmp_fname): m_MachineFile(strMachines_fname), m_ClaimIdFile(strClaimID_fname), m_tmpFile(strtmp_fname) { // the keys are the machine names // the values are the claims on that machine // generate the table of machines and claims char tmpdir[] = "//tmp//DIAL_CondorCodJob_CondorCodTable_XXXXXX"; char *p; p = mkdtemp(tmpdir); const Environment& sysenv = Environment::initial(); bool defined = sysenv.has("DIAL_CONDOR_COD_CONF"); if( defined != true ) { std::cout << "Error: DIAL_CONDOR_COD_CONF env variable not defined" << endl; exit(2); } m_WorkingDir = sysenv.value("DIAL_CONDOR_COD_CONF"); FileName fnamewrk(m_WorkingDir); if( fnamewrk.is_relative() ) m_WorkingDir = fnamewrk.fullpath().name(); FileStatus statconfd(m_WorkingDir); // check for whether it is a directory and whether it is readable if ( !( statconfd.is_directory() && statconfd.is_readable() ) ) { std::cout << "Error:DIAL_CONDOR_COD_CONF directory is not a directory or not readable" << endl; exit(3); } // make a temporary directory to add the claim id file m_TmpDir = string(p); m_MachineFile = m_WorkingDir + "/" + m_MachineFile; m_ClaimIdFile = m_TmpDir + "/" + m_ClaimIdFile; Text claimfile(m_ClaimIdFile); int iRet = claimfile.write(m_ClaimIdFile); if (iRet != 0) { std::cout << "Error: No write permissions for user" << endl; exit(4); } if (!check_file(m_MachineFile)) { std::cout << "Error: " << m_MachineFile << " file could not be read or is not regular" << endl; exit(5); } } //********************************************************************** int CondorCodTable::requestclaims() { Text::Name nmFnameMac = m_MachineFile; Text txtMachines(nmFnameMac); int iReturnVal = 0; for(int i = 0; i < (signed int) txtMachines.size(); i++) { Text::Line objLine = txtMachines.line(i); // make claim and append to file .. int iRet = ssystem("cd " + m_TmpDir + "; condor_cod request -name " + objLine + " -classad classadfile 1>&/dev/null 2>&1"); // if successful in obtaining the claim store the claim // else do not if (iRet == 0) { ssystem("cd " + m_TmpDir + "; grep ^ClaimId classadfile >> " + m_ClaimIdFile); storeclaimID(objLine); // write the claim ID to file } else iReturnVal = 100; } return iReturnVal; } //********************************************************************** void CondorCodTable::storeclaimID(string strMachineName) { // open file // read last line to extract Claim ID // place in multimap Text::Name nmFname = m_ClaimIdFile; Text txtClaims(nmFname); string ClaimID = (Text::split(txtClaims.line(txtClaims.size() - 1)))[2]; typedef multimap::value_type valType; structClaimDetails newEntry; newEntry.strMachineName = strMachineName; newEntry.strClaimStatus = "Idle"; m_MmapMachine_IDs.insert(valType(ClaimID, newEntry)); } void CondorCodTable::updateClaimState(string ClaimIdA, string Status) { Mmap_string::iterator iter; iter = m_MmapMachine_IDs.find(ClaimIdA); ((*iter).second).strClaimStatus = Status; } //********************************************************************** ostream& CondorCodTable::ostr(ostream& lhs) const { return display_table(lhs, *this); } //********************************************************************** string CondorCodTable::getfreeclaim(string* pstrMachineA) { static bool firstvisit = true; if (firstvisit == true) { if (requestclaims() != 0) return "No Free Claim"; firstvisit = false; } Mmap_string::iterator iter = m_MmapMachine_IDs.begin(), iter_end = m_MmapMachine_IDs.end(); while(iter != iter_end) { if (((*iter).second).strClaimStatus == "Idle") { if (pstrMachineA) *pstrMachineA = ((*iter).second).strMachineName ; return (*iter).first; } iter++; } return "No Free Claim"; } //********************************************************************** CondorCodTable::~CondorCodTable() { // release the requested claims // condor_cod release -id Mmap_string::iterator iter = m_MmapMachine_IDs.begin(), iter_end = m_MmapMachine_IDs.end(); string strRelease_prefix = "condor_cod release -id "; while(iter != iter_end) { ssystem(strRelease_prefix + (*iter).first + " 1>&/dev/null 2>&1" ); iter++; } // remove the temporary directory ssystem("rm -rf " + m_TmpDir ); } //********************************************************************** ostream& display_table(ostream& lhs, const CondorCodTable& rhs) { // display the contents of the table multimap::const_iterator iter = rhs.getmapmachine_IDs().begin(), iter_end = rhs.getmapmachine_IDs().end(); lhs << endl << endl << "Machine vs Claim Details " << endl; lhs << "-------------------------------- " << endl << endl; if (iter != iter_end) { lhs << "Machine " << " Claim ID" << endl; lhs << "------- " << " --------" << endl; } else { lhs << "Claim Ids could not be obtained .. could be old claims " << endl << endl; } while (iter != iter_end) { lhs << (*iter).first << " "; lhs << ((*iter).second).strMachineName; lhs << endl; iter++; } lhs << endl << endl; return lhs; } //********************************************************************** int CondorCodTable::suspendclaim(string strClaimIdA) { return ssystem("condor_cod suspend -id " + strClaimIdA + " 1>&/dev/null 2>&1"); } //********************************************************************** int CondorCodTable::resumeclaim(string strClaimIdA) { return ssystem("condor_cod resume -id " + strClaimIdA + " 1>&/dev/null 2>&1"); } //********************************************************************** // Output stream. ostream& operator<<(ostream& lhs, const CondorCodTable& rhs) { return rhs.ostr(lhs); } //**********************************************************************