Update to ARC 4.1.0
[gp-arc-client-c.git] / ext / arc_stat.cpp
1 /*
2  *  arc_stat.cpp
3  *  arcclientc
4  *
5  *  Created by Tamas Jung on 10/25/10.
6  *
7  */
8
9 #include "arc_stat.h"
10
11 // -*- indent-tabs-mode: nil -*-
12
13 #include "logger.h"
14 #include <iostream>
15 #include <list>
16 #include <string>
17 #include <algorithm>
18 #include "arc_libs.h"
19
20 #include "utils.h"
21 char*  arc_stat(int argc, char **argv) {
22         
23   char* result;
24   Arc::ArcLocation::Init(argv[0]);
25
26   ClientOptions opt(ClientOptions::CO_STAT,
27                     istring("[job ...]"),
28                     istring("The arcstat command is used for "
29                             "obtaining the status of jobs that have\n"
30                             "been submitted to Grid enabled resources."));
31
32   std::list<std::string> jobidentifiers = opt.Parse(argc, argv);
33
34   if (opt.showversion) {
35     std::cout << Arc::IString("%s version %s", "arcstat", "4.1.0")
36               << std::endl;
37     return NULL;
38   }
39
40   // If debug is specified as argument, it should be set before loading the configuration.
41   if (!opt.debug.empty())
42     Arc::Logger::getRootLogger().setThreshold(Arc::istring_to_level(opt.debug));
43
44   logger.msg(Arc::VERBOSE, "Running command: %s", opt.GetCommandWithArguments());
45
46   if (opt.show_plugins) {
47     std::list<std::string> types;
48     types.push_back("HED:JobControllerPlugin");
49     showplugins("arcstat", types, logger);
50     return NULL;
51   }
52
53   Arc::UserConfig usercfg(opt.conffile, opt.joblist);
54   if (!usercfg) {
55     logger.msg(Arc::ERROR, "Failed configuration initialization");
56     return NULL;
57   }
58
59   if (opt.debug.empty() && !usercfg.Verbosity().empty())
60     Arc::Logger::getRootLogger().setThreshold(Arc::istring_to_level(usercfg.Verbosity()));
61
62   for (std::list<std::string>::const_iterator it = opt.jobidinfiles.begin(); it != opt.jobidinfiles.end(); it++) {
63     if (!Arc::Job::ReadJobIDsFromFile(*it, jobidentifiers)) {
64       logger.msg(Arc::WARNING, "Cannot read specified jobid file: %s", *it);
65     }
66   }
67
68   if (opt.timeout > 0)
69     usercfg.Timeout(opt.timeout);
70
71   if (!opt.sort.empty() && !opt.rsort.empty()) {
72     logger.msg(Arc::ERROR, "The 'sort' and 'rsort' flags cannot be specified at the same time.");
73     return NULL;
74   }
75
76   if (!opt.rsort.empty()) {
77     opt.sort = opt.rsort;
78   }
79
80   typedef bool (*JobSorting)(const Arc::Job&, const Arc::Job&);
81   std::map<std::string, JobSorting> orderings;
82   orderings["jobid"] = &Arc::Job::CompareJobID;
83   orderings["submissiontime"] = &Arc::Job::CompareSubmissionTime;
84   orderings["jobname"] = &Arc::Job::CompareJobName;
85
86   if (!opt.sort.empty() && orderings.find(opt.sort) == orderings.end()) {
87     std::cerr << "Jobs cannot be sorted by \"" << opt.sort << "\", the following orderings are supported:" << std::endl;
88     for (std::map<std::string, JobSorting>::const_iterator it = orderings.begin();
89          it != orderings.end(); it++)
90       std::cerr << it->first << std::endl;
91     return NULL;
92   }
93
94   if ((!opt.joblist.empty() || !opt.status.empty()) && jobidentifiers.empty() && opt.clusters.empty())
95     opt.all = true;
96
97   if (jobidentifiers.empty() && opt.clusters.empty() && !opt.all) {
98     logger.msg(Arc::ERROR, "No jobs given");
99     return NULL;
100   }
101   
102   std::list<std::string> selectedURLs;
103   if (!opt.clusters.empty()) {
104     selectedURLs = getSelectedURLsFromUserConfigAndCommandLine(usercfg, opt.clusters);
105   }
106   std::list<std::string> rejectManagementURLs = getRejectManagementURLsFromUserConfigAndCommandLine(usercfg, opt.rejectmanagement);
107   std::list<Arc::Job> jobs;
108   Arc::JobInformationStorage *jobstore = createJobInformationStorage(usercfg);
109   if (jobstore != NULL && !jobstore->IsStorageExisting()) {
110     logger.msg(Arc::ERROR, "Job list file (%s) doesn't exist", usercfg.JobListFile());
111     delete jobstore;
112     return NULL;
113   }
114   if (jobstore == NULL ||
115       ( opt.all && !jobstore->ReadAll(jobs, rejectManagementURLs)) ||
116       (!opt.all && !jobstore->Read(jobs, jobidentifiers, selectedURLs, rejectManagementURLs))) {
117     logger.msg(Arc::ERROR, "Unable to read job information from file (%s)", usercfg.JobListFile());
118     delete jobstore;
119     return NULL;
120   }
121   delete jobstore;
122
123   if (!opt.all) {
124     for (std::list<std::string>::const_iterator itJIDAndName = jobidentifiers.begin();
125          itJIDAndName != jobidentifiers.end(); ++itJIDAndName) {
126       std::cout << Arc::IString("Warning: Job not found in job list: %s", *itJIDAndName) << std::endl;
127     }
128   }
129
130   Arc::JobSupervisor jobmaster(usercfg, jobs);
131   jobmaster.Update();
132   unsigned int queried_num = jobmaster.GetAllJobs().size();
133   if (!opt.status.empty()) {
134     jobmaster.SelectByStatus(opt.status);
135   }
136   if (!opt.show_unavailable) {
137     jobmaster.SelectValid();
138   }
139   jobs = jobmaster.GetSelectedJobs();
140
141   if (queried_num == 0) {
142     std::cout << Arc::IString("No jobs found, try later") << std::endl;
143     return NULL;
144   }
145
146   std::vector<Arc::Job> jobsSortable(jobs.begin(), jobs.end());
147
148   if (!opt.sort.empty()) {
149     opt.rsort.empty() ? std::sort(jobsSortable.begin(),  jobsSortable.end(),  orderings[opt.sort]) :
150                         std::sort(jobsSortable.rbegin(), jobsSortable.rend(), orderings[opt.sort]);
151   }
152
153   for (std::vector<Arc::Job>::const_iterator it = jobsSortable.begin();
154        it != jobsSortable.end(); it++) {
155     // Option 'long' (longlist) takes precedence over option 'print-jobids' (printids)
156 //    if (opt.longlist || !opt.printids) {
157       it->SaveToStream(std::cout, opt.longlist);
158 //    }
159 //    else {
160 //      std::cout << it->JobID << std::endl;
161       result = strdup((it->State).GetGeneralState().c_str());
162          
163       return result;
164 //    }
165   }
166
167   if (opt.show_unavailable) {
168     jobmaster.SelectValid();
169   }
170   unsigned int returned_info_num = jobmaster.GetSelectedJobs().size();
171
172   std::cout << Arc::IString("Status of %d jobs was queried, %d jobs returned information", queried_num, returned_info_num) << std::endl;
173         
174   return NULL;
175 }