Back to index

nordugrid-arc-nox  1.1.0~rc6
job_desc.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <list>
00006 #include <fstream>
00007 
00008 #include <arc/DateTime.h>
00009 #include <arc/Logger.h>
00010 #include <arc/StringConv.h>
00011 #include <arc/XMLNode.h>
00012 
00013 #include "job_desc.h"
00014 #include "../files/info_files.h"
00015 #include "../misc/canonical_dir.h"
00016 
00017 
00018 static Arc::Logger& logger = Arc::Logger::getRootLogger();
00019 
00020 bool get_arc_job_description(const std::string& fname, Arc::JobDescription& desc) {
00021   std::string job_desc_str;
00022   if (!job_description_read_file(fname, job_desc_str)) {
00023     logger.msg(Arc::ERROR, "Job description file could not be read.");
00024     return false;
00025   }
00026 
00027   desc.AddHint("SOURCEDIALECT","GRIDMANAGER");
00028   return desc.Parse(job_desc_str);
00029 }
00030 
00031 bool write_grami(const Arc::JobDescription& arc_job_desc, const JobDescription& job_desc, const JobUser& user, const char* opt_add) {
00032   if(job_desc.get_local() == NULL) return false;
00033   const std::string session_dir = job_desc.SessionDir();
00034   JobLocalDescription& job_local_desc = *(job_desc.get_local());
00035   const std::string fgrami = user.ControlDir() + "/job." + job_desc.get_id() + ".grami";
00036   std::ofstream f(fgrami.c_str(),std::ios::out | std::ios::trunc);
00037   if(!f.is_open()) return false;
00038   if(!fix_file_owner(fgrami,job_desc,user)) return false;
00039 
00040 
00041   f<<"joboption_directory='"<<session_dir<<"'"<<std::endl;
00042 
00043   {
00044     std::string executable = Arc::trim(arc_job_desc.Application.Executable.Name);
00045     if (executable[0] != '/' && executable[0] != '$' && !(executable[0] == '.' && executable[1] == '/')) executable = "./"+executable;
00046     f<<"joboption_arg_0"<<"="<<value_for_shell(executable.c_str(),true)<<std::endl;
00047     int i = 1;
00048     for (std::list<std::string>::const_iterator it = arc_job_desc.Application.Executable.Argument.begin();
00049          it != arc_job_desc.Application.Executable.Argument.end(); it++, i++) {
00050       f<<"joboption_arg_"<<i<<"="<<value_for_shell(it->c_str(),true)<<std::endl;
00051     }
00052   }
00053   
00054   f<<"joboption_stdin="<<value_for_shell(arc_job_desc.Application.Input.empty()?NG_RSL_DEFAULT_STDIN:arc_job_desc.Application.Input,true)<<std::endl;
00055 
00056   if (!arc_job_desc.Application.Output.empty()) {
00057     std::string output = arc_job_desc.Application.Output;
00058     if (canonical_dir(output) != 0) {
00059       logger.msg(Arc::ERROR,"Bad name for stdout: %s", output);
00060       return false;
00061     }
00062   }
00063   f<<"joboption_stdout="<<value_for_shell(arc_job_desc.Application.Output.empty()?NG_RSL_DEFAULT_STDOUT:session_dir+"/"+arc_job_desc.Application.Output,true)<<std::endl;
00064   if (!arc_job_desc.Application.Error.empty()) {
00065     std::string error = arc_job_desc.Application.Error;
00066     if (canonical_dir(error) != 0) {
00067       logger.msg(Arc::ERROR,"Bad name for stderr: %s", error);
00068       return false;
00069     }
00070   }
00071   f<<"joboption_stderr="<<value_for_shell(arc_job_desc.Application.Error.empty()?NG_RSL_DEFAULT_STDERR:session_dir+"/"+arc_job_desc.Application.Error,true)<<std::endl;
00072 
00073   {
00074     int i = 0;
00075     for (std::list< std::pair<std::string, std::string> >::const_iterator it = arc_job_desc.Application.Environment.begin();
00076          it != arc_job_desc.Application.Environment.end(); it++, i++) {
00077         f<<"joboption_env_"<<i<<"="<<value_for_shell(it->first+"="+it->second,true)<<std::endl;
00078     }
00079     value_for_shell globalid=value_for_shell(job_local_desc.globalid,true);
00080     f<<"joboption_env_"<<i<<"=GRID_GLOBAL_JOBID="<<globalid<<std::endl;
00081   }
00082 
00083   
00084   f<<"joboption_cputime="<<(arc_job_desc.Resources.TotalCPUTime.range.max != -1 ? Arc::tostring(arc_job_desc.Resources.TotalCPUTime.range.max):"")<<std::endl;
00085   f<<"joboption_walltime="<<(arc_job_desc.Resources.TotalWallTime.range.max != -1 ? Arc::tostring(arc_job_desc.Resources.TotalWallTime.range.max):"")<<std::endl;
00086   f<<"joboption_memory="<<(arc_job_desc.Resources.IndividualPhysicalMemory.max != -1 ? Arc::tostring(arc_job_desc.Resources.IndividualPhysicalMemory.max):"")<<std::endl;
00087   f<<"joboption_count="<<(arc_job_desc.Resources.SlotRequirement.ProcessPerHost.max != -1 ? Arc::tostring(arc_job_desc.Resources.SlotRequirement.ProcessPerHost.max):"1")<<std::endl;
00088 
00089   {
00090     int i = 0; 
00091     for (std::list<Arc::Software>::const_iterator itSW = arc_job_desc.Resources.RunTimeEnvironment.getSoftwareList().begin();
00092          itSW != arc_job_desc.Resources.RunTimeEnvironment.getSoftwareList().end(); itSW++) {
00093       if (itSW->empty()) continue;
00094       std::string rte = Arc::upper(*itSW);
00095       if (canonical_dir(rte) != 0) {
00096         logger.msg(Arc::ERROR, "Bad name for runtime environment: %s", (std::string)*itSW);
00097         return false;
00098       }
00099       f<<"joboption_runtime_"<<i++<<"="<<value_for_shell((std::string)*itSW,true)<<std::endl;
00100     }
00101   }
00102 
00103   f<<"joboption_jobname="<<value_for_shell(job_local_desc.jobname,true)<<std::endl;
00104   f<<"joboption_queue="<<value_for_shell(job_local_desc.queue,true)<<std::endl;
00105   f<<"joboption_starttime="<<(job_local_desc.exectime != -1?job_local_desc.exectime.str(Arc::MDSTime):"")<<std::endl;
00106   f<<"joboption_gridid="<<value_for_shell(job_desc.get_id(),true)<<std::endl;
00107 
00108   if(opt_add) f<<opt_add<<std::endl;
00109 
00110   return true;
00111 }
00112      
00113 JobReqResult get_acl(const Arc::JobDescription& arc_job_desc, std::string& acl) {
00114   if( !arc_job_desc.Application.AccessControl ) return JobReqSuccess;
00115   Arc::XMLNode typeNode = arc_job_desc.Application.AccessControl["Type"];
00116   Arc::XMLNode contentNode = arc_job_desc.Application.AccessControl["Content"];
00117   if( !contentNode ) {
00118     logger.msg(Arc::ERROR, "ARC: acl element wrongly formated - missing Content element");
00119     return JobReqMissingFailure;
00120   };
00121   if( (!typeNode) || ( ( (std::string) typeNode ) == "GACL" ) || ( ( (std::string) typeNode ) == "ARC" ) ) {
00122     std::string str_content;
00123     if(contentNode.Size() > 0) {
00124       Arc::XMLNode acl_doc;
00125       contentNode.Child().New(acl_doc);
00126       acl_doc.GetDoc(str_content);
00127     } else {
00128       str_content = (std::string)contentNode;
00129     }
00130     if( str_content != "" ) acl=str_content;
00131   } else {
00132     logger.msg(Arc::ERROR, "ARC: unsupported ACL type specified: %s", (std::string)typeNode);
00133     return JobReqUnsupportedFailure;
00134   };
00135   return JobReqSuccess;
00136 }
00137 
00138 bool set_execs(const Arc::JobDescription& desc, const std::string& session_dir) {
00139   if (!desc) return false;
00140 
00141   if (desc.Application.Executable.Name[0] != '/' && desc.Application.Executable.Name[0] != '$') {
00142     std::string executable = desc.Application.Executable.Name;
00143     if(canonical_dir(executable) != 0) {
00144       logger.msg(Arc::ERROR, "Bad name for executable: ", executable);
00145       return false;
00146     }
00147     fix_file_permissions(session_dir+"/"+executable,true);
00148   }
00149 
00150   for(std::list<Arc::FileType>::const_iterator it = desc.DataStaging.File.begin();
00151       it!=desc.DataStaging.File.end();it++) {
00152     if(it->IsExecutable) {
00153       std::string executable = it->Name;
00154       if (executable[0] != '/' && executable[0] != '.' && executable[1] != '/') executable = "./"+executable;
00155       if(canonical_dir(executable) != 0) {
00156         logger.msg(Arc::ERROR, "Bad name for executable: %s", executable); 
00157         return false;
00158       }
00159       fix_file_permissions(session_dir+"/"+executable,true);
00160     }
00161   }
00162 
00163   return true;
00164 }
00165 
00166 std::ostream& operator<<(std::ostream &o,const value_for_shell &s) {
00167   if(s.str == NULL) return o;
00168   if(s.quote) o<<"'";
00169   const char* p = s.str;
00170   for(;;) {
00171     const char* pp = strchr(p,'\'');
00172     if(pp == NULL) { o<<p; if(s.quote) o<<"'"; break; };
00173     o.write(p,pp-p); o<<"'\\''"; p=pp+1;
00174   };
00175   return o;
00176 }
00177 
00178 std::ostream& operator<<(std::ostream &o,const numvalue_for_shell &s) {
00179   o<<s.n;
00180   return o;
00181 }
00182