megoldas a loggerre, egyeb javitasok
[gp-arc-client-c.git] / src / submit.cpp
index 7dda03a..bd25b14 100644 (file)
@@ -8,6 +8,8 @@
  */
 
 #include "submit.h"
+#include "logger.h"
+#include "config.h" //TBD: Kell ez?
 // -*- indent-tabs-mode: nil -*-
 
 #ifdef HAVE_CONFIG_H
 #include <sys/stat.h>
 #include <unistd.h>
 
-#include <arc/ArcConfig.h>
-#include <arc/ArcLocation.h>
-#include <arc/DateTime.h>
-#include <arc/FileLock.h>
-#include <arc/IString.h>
-#include <arc/Logger.h>
-#include <arc/OptionParser.h>
-#include <arc/StringConv.h>
-#include <arc/URL.h>
-#include <arc/Utils.h>
-#include <arc/XMLNode.h>
-#include <arc/client/Submitter.h>
-#include <arc/client/TargetGenerator.h>
-#include <arc/client/JobDescription.h>
-#include <arc/UserConfig.h>
-#include <arc/client/Broker.h>
+#include "arc_libs.h"
 
-int main(int argc, char **argv) {
+
+submit_result_t* submit(int argc, char **argv) {
+       
+       
+       
        
-       setlocale(LC_ALL, "");
        
-       Arc::Logger logger(Arc::Logger::getRootLogger(), "arcsub");
-       Arc::LogStream logcerr(std::cerr);
-       logcerr.setFormat(Arc::ShortFormat);
-       Arc::Logger::getRootLogger().addDestination(logcerr);
-       Arc::Logger::getRootLogger().setThreshold(Arc::WARNING);
        
-       Arc::ArcLocation::Init(argv[0]);
        
+       
+       submit_result_t* result = (submit_result_t*)malloc(sizeof(submit_result_t));
+       if (!result) {
+               return NULL;//TBD: throw sth?
+       }
+       result->message = NULL;
+       result->job_id = NULL;
+       
+       
+
+       //TODO: what necessary here?
        Arc::OptionParser options(istring("[filename ...]"),
                                                          istring("The arcsub command is used for "
                                                                          "submitting jobs to grid enabled "
@@ -80,38 +75,21 @@ int main(int argc, char **argv) {
                                          istring("[-]name"),
                                          indexurls);
        
-       std::list<std::string> jobdescriptionstrings;
+       std::string jobdescriptionstring;
        options.AddOption('e', "jobdescrstring",
                                          istring("jobdescription string describing the job to "
                                                          "be submitted"),
                                          istring("string"),
-                                         jobdescriptionstrings);
+                                         jobdescriptionstring);
        
-       std::list<std::string> jobdescriptionfiles;
-       options.AddOption('f', "jobdescrfile",
-                                         istring("jobdescription file describing the job to "
-                                                         "be submitted"),
-                                         istring("string"),
-                                         jobdescriptionfiles);
+
        
-       std::string joblist;
-       options.AddOption('j', "joblist",
-                                         istring("file where the jobs will be stored"),
-                                         istring("filename"),
-                                         joblist);
        
-       /*
+       //jt: dryrun was commented out in the original file, I try to use it TODO:
      bool dryrun = false;
      options.AddOption('D', "dryrun", istring("add dryrun option"),
         dryrun);
         
-        */
-       bool dumpdescription = false;
-       options.AddOption('x', "dumpdescription",
-                                         istring("do not submit - dump job description "
-                                                         "in the language accepted by the target"),
-                                         dumpdescription);
-       
        int timeout = -1;
        options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
                                          istring("seconds"), timeout);
@@ -120,56 +98,28 @@ int main(int argc, char **argv) {
        options.AddOption('z', "conffile",
                                          istring("configuration file (default ~/.arc/client.conf)"),
                                          istring("filename"), conffile);
-       
-       std::string debug;
-       options.AddOption('d', "debug",
-                                         istring("FATAL, ERROR, WARNING, INFO, VERBOSE or DEBUG"),
-                                         istring("debuglevel"), debug);
-       
+               
        std::string broker;
        options.AddOption('b', "broker",
                                          istring("select broker method (Random (default), FastestQueue, or custom)"),
                                          istring("broker"), broker);
        
-       /**
-        * Sandboxing is always done atm. Maybe there should be a switch to turn it off? 'n' "nolocalsandbox"
-        bool dolocalsandbox = true;
-        options.AddOption('n', "dolocalsandbox",
-        istring("store job descriptions in local sandbox."),
-        dolocalsandbox);
-        */
-       
-       bool version = false;
-       options.AddOption('v', "version", istring("print version information"),
-                                         version);
        
        std::list<std::string> params = options.Parse(argc, argv);
        
-       // If debug is specified as argument, it should be set before loading the configuration.
-       if (!debug.empty())
-               Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(debug));
        
-       Arc::UserConfig usercfg(conffile, joblist);
+       Arc::UserConfig usercfg(conffile);
        if (!usercfg) {
-               logger.msg(Arc::ERROR, "Failed configuration initialization");
-               return 1;
+               result->message = new_str("Failed configuration initialization");
+               return result;  
        }
        
-       if (debug.empty() && !usercfg.Verbosity().empty())
-               Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(usercfg.Verbosity()));
-       
        if (timeout > 0)
                usercfg.Timeout(timeout);
        
        if (!broker.empty())
                usercfg.Broker(broker);
-       
-       if (version) {
-               std::cout << Arc::IString("%s version %s", "arcsub", VERSION)
-               << std::endl;
-               return 0;
-       }
-       
+               
        if (!clusters.empty() || !indexurls.empty())
                usercfg.ClearSelectedServices();
        
@@ -179,167 +129,79 @@ int main(int argc, char **argv) {
        if (!indexurls.empty())
                usercfg.AddServices(indexurls, Arc::INDEX);
        
-       jobdescriptionfiles.insert(jobdescriptionfiles.end(),
-                                                          params.begin(), params.end());
-       
-       if (jobdescriptionfiles.empty() && jobdescriptionstrings.empty()) {
-               logger.msg(Arc::ERROR, "No job description input specified");
-               return 1;
+       if (jobdescriptionstring.empty()) {
+               result->message = new_str("No job description input specified");
+               return result;
        }
        
-       std::list<Arc::JobDescription> jobdescriptionlist;
        
-       //Loop over input job description files
-       for (std::list<std::string>::iterator it = jobdescriptionfiles.begin();
-                it != jobdescriptionfiles.end(); it++) {
-               
-               std::ifstream descriptionfile(it->c_str());
-               
-               if (!descriptionfile) {
-                       logger.msg(Arc::ERROR, "Can not open job description file: %s", *it);
-                       return 1;
-               }
-               
-               descriptionfile.seekg(0, std::ios::end);
-               std::streamsize length = descriptionfile.tellg();
-               descriptionfile.seekg(0, std::ios::beg);
-               
-               char *buffer = new char[length + 1];
-               descriptionfile.read(buffer, length);
-               descriptionfile.close();
-               
-               buffer[length] = '\0';
-               Arc::JobDescription jobdesc;
-               jobdesc.Parse((std::string)buffer);
+
                
-               if (jobdesc)
-                       jobdescriptionlist.push_back(jobdesc);
-               else {
-                       logger.msg(Arc::ERROR, "Invalid JobDescription:");
-                       std::cout << buffer << std::endl;
-                       delete[] buffer;
-                       return 1;
-               }
-               delete[] buffer;
-       }
+       Arc::JobDescription jobdesc;
        
-       //Loop over job description input strings
-       for (std::list<std::string>::iterator it = jobdescriptionstrings.begin();
-                it != jobdescriptionstrings.end(); it++) {
-               
-               Arc::JobDescription jobdesc;
-               
-               jobdesc.Parse(*it);
-               
-               if (jobdesc)
-                       jobdescriptionlist.push_back(jobdesc);
-               else {
-                       logger.msg(Arc::ERROR, "Invalid JobDescription:");
-                       std::cout << *it << std::endl;
-                       return 1;
-               }
+       jobdesc.Parse(jobdescriptionstring);
+       
+       if (!jobdesc){
+               std::ostringstream sstr;
+               sstr << "Invalid JobDescription:";
+               sstr << jobdescriptionstring;
+               result->message = ostringstream2cstring(sstr);
+               return result;
        }
        
        Arc::TargetGenerator targen(usercfg);
        targen.GetTargets(0, 1);
        
        if (targen.FoundTargets().empty()) {
-               std::cout << Arc::IString("Job submission aborted because no clusters returned any information") << std::endl;
-               return 1;
+               
+               result->message = new_str("Job submission aborted because no clusters returned any information");
+               return result;
        }
        
-       std::map<int, std::string> notsubmitted;
        
-       int jobnr = 1;
-       std::list<std::string> jobids;
        
        Arc::BrokerLoader loader;
        Arc::Broker *ChosenBroker = loader.load(usercfg.Broker().first, usercfg);
        if (!ChosenBroker) {
-               logger.msg(Arc::ERROR, "Unable to load broker %s", usercfg.Broker().first);
-               return 1;
+               std::ostringstream sstream;
+               sstream << "Unable to load broker " << usercfg.Broker().first;
+               result->message = ostringstream2cstring(sstream);
+               return result;
        }
        logger.msg(Arc::INFO, "Broker %s loaded", usercfg.Broker().first);
        
-       for (std::list<Arc::JobDescription>::iterator it =
-         jobdescriptionlist.begin(); it != jobdescriptionlist.end();
-                it++, jobnr++) {
                
-               ChosenBroker->PreFilterTargets(targen.ModifyFoundTargets(), *it);
+       ChosenBroker->PreFilterTargets(targen.ModifyFoundTargets(), jobdesc);
+       
+       while (true) {
+               const Arc::ExecutionTarget* target = ChosenBroker->GetBestTarget();
                
-               while (true) {
-                       const Arc::ExecutionTarget* target = ChosenBroker->GetBestTarget();
-                       
-                       if (!target) {
-                               if (dumpdescription) {
-                                       std::cout << Arc::IString("Unable to print job description: No target found.") << std::endl;
-                                       return 1;
-                               }
-                               std::cout << Arc::IString("Job submission failed, no more possible targets") << std::endl;
-                               break;
-                       }
-                       
-                       Arc::Submitter *submitter = target->GetSubmitter(usercfg);
-                       
-                       if (dumpdescription) {
-                               Arc::JobDescription jobdescdump(*it);
-                               if (!submitter->ModifyJobDescription(jobdescdump, *target)) {
-                                       std::cout << "Unable to modify job description according to needs for target cluster." << std::endl;
-                                       return 1;
-                               }
-                               
-                               std::string jobdesclang = "ARCJSDL";
-                               if (target->GridFlavour == "ARC0")
-                                       jobdesclang = "XRSL";
-                               else if (target->GridFlavour == "CREAM")
-                                       jobdesclang = "JDL";
-                               const std::string jobdesc = jobdescdump.UnParse(jobdesclang);
-                               if (jobdesc.empty()) {
-                                       std::cout << Arc::IString("An error occurred during the generation of the job description output.") << std::endl;
-                                       return 1;
-                               }
+               if (!target) {
+                       result->message = new_str("Job submission failed, no more possible targets");
+                       break;
+               }
+               
+               Arc::Submitter *submitter = target->GetSubmitter(usercfg);
                                
-                               std::cout << Arc::IString("Job description to be send to ") << target->Cluster.str() << ":" << std::endl;
-                               std::cout << jobdesc << std::endl;
-                               return 0;
-                       }
-                       
-                       
-                       //submit the job
-                       Arc::URL jobid = submitter->Submit(*it, *target);
-                       if (!jobid) {
-                               std::cout << Arc::IString("Submission to %s failed, trying next target", target->url.str()) << std::endl;
-                               continue;
-                       }
-                       
-                       ChosenBroker->RegisterJobsubmission();
-                       std::cout << Arc::IString("Job submitted with jobid: %s", jobid.str())
-                       << std::endl;
-                       
+               if (dryrun) {
+                       result->message = new_str("Dry run, job submission is skipped");
                        break;
-               } //end loop over all possible targets
-       } //end loop over all job descriptions
-       
-       if (jobdescriptionlist.size() > 1) {
-               std::cout << std::endl << Arc::IString("Job submission summary:")
-               << std::endl;
-               std::cout << "-----------------------" << std::endl;
-               std::cout << Arc::IString("%d of %d jobs were submitted",
-                                                                 jobdescriptionlist.size() - notsubmitted.size(),
-                                                                 jobdescriptionlist.size()) << std::endl;
-               if (notsubmitted.size())
-                       std::cout << Arc::IString("The following %d were not submitted",
-                                                                         notsubmitted.size()) << std::endl;
-               /*
-                std::map<int, std::string>::iterator it;
-                for (it = notsubmitted.begin(); it != notsubmitted.end(); it++) {
-                std::cout << _("Job nr.") << " " << it->first;
-                if (it->second.size()>0) std::cout << ": " << it->second;
-                std::cout << std::endl;
-                }
-                */
-       }
+               }
+               //submit the job
+               Arc::URL jobid = submitter->Submit(jobdesc, *target);
+               if (!jobid) {
+                       logger.msg(Arc::INFO, "Submission to %s failed, trying next target", target->url.str());
+                       continue;
+               }
+               
+               ChosenBroker->RegisterJobsubmission();
+               result->job_id = new_str(jobid.str().c_str());
+               logger.msg(Arc::DEBUG, "Job submitted with jobid: %s", jobid.str());
+               
+               break;
+       } //end loop over all possible targets
        
-       return 0;
+       return result;
 }
 
+