Update to ARC 4.1.0
[gp-arc-client-c.git] / ext / arc_stat.cpp
index a71cc3d..66fcd36 100644 (file)
 #include <algorithm>
 #include "arc_libs.h"
 
+#include "utils.h"
 char*  arc_stat(int argc, char **argv) {
        
   char* result;
-       Arc::OptionParser options(istring("[job ...]"),
-                                                         istring("The arcstat command is used for "
-                                                                         "obtaining the status of jobs that have\n"
-                                                                         "been submitted to Grid enabled resources."),
-                                                         istring("Argument to -c has the format "
-                                                                         "Flavour:URL e.g.\n"
-                                                                         "ARC0:ldap://grid.tsl.uu.se:2135/"
-                                                                         "nordugrid-cluster-name=grid.tsl.uu.se,"
-                                                                         "Mds-Vo-name=local,o=grid"));
-       
-       
-       std::string joblist;
-       options.AddOption('j', "joblist",
-                                         istring("file containing a list of jobs"),
-                                         istring("filename"),
-                                         joblist);
-       
-       std::list<std::string> clusters;
-       options.AddOption('c', "cluster",
-                                         istring("explicitly select or reject a specific resource"),
-                                         istring("[-]name"),
-                                         clusters);
-       
-       
-       int timeout = -1;
-       options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
-                                         istring("seconds"), timeout);
-       
-       std::string conffile;
-       options.AddOption('z', "conffile",
-                                         istring("configuration file (default ~/.arc/client.conf)"),
-                                         istring("filename"), conffile);
-               
-       
-       std::list<std::string> jobs = options.Parse(argc, argv);
-       
-       
-               
-       Arc::UserConfig usercfg(conffile, joblist);
-       if (!usercfg) {
-               //result  -> message = new_str("Failed configuration initialization");
-               logger.msg(Arc::ERROR, "Failed configuration initialization");
-               return NULL;
-       }
-               
-       if (timeout > 0)
-       usercfg.Timeout(timeout);
-       
+  Arc::ArcLocation::Init(argv[0]);
 
+  ClientOptions opt(ClientOptions::CO_STAT,
+                    istring("[job ...]"),
+                    istring("The arcstat command is used for "
+                            "obtaining the status of jobs that have\n"
+                            "been submitted to Grid enabled resources."));
+
+  std::list<std::string> jobidentifiers = opt.Parse(argc, argv);
+
+  if (opt.showversion) {
+    std::cout << Arc::IString("%s version %s", "arcstat", "4.1.0")
+              << std::endl;
+    return NULL;
+  }
+
+  // If debug is specified as argument, it should be set before loading the configuration.
+  if (!opt.debug.empty())
+    Arc::Logger::getRootLogger().setThreshold(Arc::istring_to_level(opt.debug));
+
+  logger.msg(Arc::VERBOSE, "Running command: %s", opt.GetCommandWithArguments());
+
+  if (opt.show_plugins) {
+    std::list<std::string> types;
+    types.push_back("HED:JobControllerPlugin");
+    showplugins("arcstat", types, logger);
+    return NULL;
+  }
+
+  Arc::UserConfig usercfg(opt.conffile, opt.joblist);
+  if (!usercfg) {
+    logger.msg(Arc::ERROR, "Failed configuration initialization");
+    return NULL;
+  }
+
+  if (opt.debug.empty() && !usercfg.Verbosity().empty())
+    Arc::Logger::getRootLogger().setThreshold(Arc::istring_to_level(usercfg.Verbosity()));
+
+  for (std::list<std::string>::const_iterator it = opt.jobidinfiles.begin(); it != opt.jobidinfiles.end(); it++) {
+    if (!Arc::Job::ReadJobIDsFromFile(*it, jobidentifiers)) {
+      logger.msg(Arc::WARNING, "Cannot read specified jobid file: %s", *it);
+    }
+  }
+
+  if (opt.timeout > 0)
+    usercfg.Timeout(opt.timeout);
+
+  if (!opt.sort.empty() && !opt.rsort.empty()) {
+    logger.msg(Arc::ERROR, "The 'sort' and 'rsort' flags cannot be specified at the same time.");
+    return NULL;
+  }
+
+  if (!opt.rsort.empty()) {
+    opt.sort = opt.rsort;
+  }
+
+  typedef bool (*JobSorting)(const Arc::Job&, const Arc::Job&);
+  std::map<std::string, JobSorting> orderings;
+  orderings["jobid"] = &Arc::Job::CompareJobID;
+  orderings["submissiontime"] = &Arc::Job::CompareSubmissionTime;
+  orderings["jobname"] = &Arc::Job::CompareJobName;
+
+  if (!opt.sort.empty() && orderings.find(opt.sort) == orderings.end()) {
+    std::cerr << "Jobs cannot be sorted by \"" << opt.sort << "\", the following orderings are supported:" << std::endl;
+    for (std::map<std::string, JobSorting>::const_iterator it = orderings.begin();
+         it != orderings.end(); it++)
+      std::cerr << it->first << std::endl;
+    return NULL;
+  }
+
+  if ((!opt.joblist.empty() || !opt.status.empty()) && jobidentifiers.empty() && opt.clusters.empty())
+    opt.all = true;
+
+  if (jobidentifiers.empty() && opt.clusters.empty() && !opt.all) {
+    logger.msg(Arc::ERROR, "No jobs given");
+    return NULL;
+  }
+  
+  std::list<std::string> selectedURLs;
+  if (!opt.clusters.empty()) {
+    selectedURLs = getSelectedURLsFromUserConfigAndCommandLine(usercfg, opt.clusters);
+  }
+  std::list<std::string> rejectManagementURLs = getRejectManagementURLsFromUserConfigAndCommandLine(usercfg, opt.rejectmanagement);
+  std::list<Arc::Job> jobs;
+  Arc::JobInformationStorage *jobstore = createJobInformationStorage(usercfg);
+  if (jobstore != NULL && !jobstore->IsStorageExisting()) {
+    logger.msg(Arc::ERROR, "Job list file (%s) doesn't exist", usercfg.JobListFile());
+    delete jobstore;
+    return NULL;
+  }
+  if (jobstore == NULL ||
+      ( opt.all && !jobstore->ReadAll(jobs, rejectManagementURLs)) ||
+      (!opt.all && !jobstore->Read(jobs, jobidentifiers, selectedURLs, rejectManagementURLs))) {
+    logger.msg(Arc::ERROR, "Unable to read job information from file (%s)", usercfg.JobListFile());
+    delete jobstore;
+    return NULL;
+  }
+  delete jobstore;
+
+  if (!opt.all) {
+    for (std::list<std::string>::const_iterator itJIDAndName = jobidentifiers.begin();
+         itJIDAndName != jobidentifiers.end(); ++itJIDAndName) {
+      std::cout << Arc::IString("Warning: Job not found in job list: %s", *itJIDAndName) << std::endl;
+    }
+  }
+
+  Arc::JobSupervisor jobmaster(usercfg, jobs);
+  jobmaster.Update();
+  unsigned int queried_num = jobmaster.GetAllJobs().size();
+  if (!opt.status.empty()) {
+    jobmaster.SelectByStatus(opt.status);
+  }
+  if (!opt.show_unavailable) {
+    jobmaster.SelectValid();
+  }
+  jobs = jobmaster.GetSelectedJobs();
+
+  if (queried_num == 0) {
+    std::cout << Arc::IString("No jobs found, try later") << std::endl;
+    return NULL;
+  }
+
+  std::vector<Arc::Job> jobsSortable(jobs.begin(), jobs.end());
+
+  if (!opt.sort.empty()) {
+    opt.rsort.empty() ? std::sort(jobsSortable.begin(),  jobsSortable.end(),  orderings[opt.sort]) :
+                        std::sort(jobsSortable.rbegin(), jobsSortable.rend(), orderings[opt.sort]);
+  }
+
+  for (std::vector<Arc::Job>::const_iterator it = jobsSortable.begin();
+       it != jobsSortable.end(); it++) {
+    // Option 'long' (longlist) takes precedence over option 'print-jobids' (printids)
+//    if (opt.longlist || !opt.printids) {
+      it->SaveToStream(std::cout, opt.longlist);
+//    }
+//    else {
+//      std::cout << it->JobID << std::endl;
+      result = strdup((it->State).GetGeneralState().c_str());
+         
+      return result;
+//    }
+  }
+
+  if (opt.show_unavailable) {
+    jobmaster.SelectValid();
+  }
+  unsigned int returned_info_num = jobmaster.GetSelectedJobs().size();
+
+  std::cout << Arc::IString("Status of %d jobs was queried, %d jobs returned information", queried_num, returned_info_num) << std::endl;
        
-       if (!jobs.empty())
-       usercfg.ClearSelectedServices();
-       
-       if (!clusters.empty()) {
-               usercfg.ClearSelectedServices();
-               usercfg.AddServices(clusters, Arc::COMPUTING);
-       }
-       
-       Arc::JobSupervisor jobmaster(usercfg, jobs);
-       if (!jobmaster.JobsFound()) {
-               //result -> message = new_str("No jobs");
-    logger.msg(Arc::INFO, "No jobs");
-               return NULL;
-       }
-       std::list<Arc::JobController*> jobcont = jobmaster.GetJobControllers();
-       
-       if (jobcont.empty()) {
-               //result -> message = new_str("No job controller plugins loaded");
-    logger.msg(Arc::INFO, "No job controller plugins loaded");
-               return NULL;
-       }
-       
-       if (jobcont.size() != 1){
-               //result -> message = new_str("Too many jobs found");
-    logger.msg(Arc::ERROR, "Too many jobs found");
-               return NULL;
-       } 
-       Arc::JobController* it = jobcont.front();
-       
-       it->GetJobInformation();
-       
-       std::list<Arc::Job> jobs_list = it->GetJobs();
-       
-       if (jobs_list.size() != 1) {
-               //result -> message = new_str("Ambiguous job");
-    logger.msg(Arc::ERROR, "Ambiguous job");
-               return NULL;
-       }
-       
-       Arc::Job& job = jobs_list.front();
-       
-       result = new_str(job.State().c_str());
-       
-       return result;
-       
-       
+  return NULL;
 }