Update to ARC 4.1.0
[gp-arc-client-c.git] / ext / arc_get.cpp
1 /*
2  *  get.cpp
3  *  arcclientc
4  *
5  *  Created by Tamas Jung on 10/25/10.
6  *
7  */
8
9 #include "arc_get.h"
10
11 // -*- indent-tabs-mode: nil -*-
12
13
14 #include "logger.h"
15 #include <iostream>
16 #include <list>
17 #include <string>
18 #include <sys/stat.h>
19 #include "arc_libs.h"
20
21 #include "utils.h"
22
23 int arc_get(int argc, char **argv) {
24         
25   Arc::ArcLocation::Init(argv[0]);
26
27   ClientOptions opt(ClientOptions::CO_GET,
28                     istring("[job ...]"),
29                     istring("The arcget command is used for "
30                             "retrieving the results from a job."));
31
32   std::list<std::string> jobidentifiers = opt.Parse(argc, argv);
33
34   if (opt.showversion) {
35     std::cout << Arc::IString("%s version %s", "arcget", "4.1.0")
36               << std::endl;
37     return 0;
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("arcget", types, logger);
50     return 0;
51   }
52
53   Arc::UserConfig usercfg(opt.conffile, opt.joblist);
54   if (!usercfg) {
55     logger.msg(Arc::ERROR, "Failed configuration initialization");
56     return 1;
57   }
58
59   if (!checkproxy(usercfg)) {
60     return 1;
61   }
62
63   if (opt.debug.empty() && !usercfg.Verbosity().empty())
64     Arc::Logger::getRootLogger().setThreshold(Arc::istring_to_level(usercfg.Verbosity()));
65
66   if (opt.downloaddir.empty()) {
67     if (!usercfg.JobDownloadDirectory().empty()) {
68       opt.downloaddir = usercfg.JobDownloadDirectory();
69       logger.msg(Arc::INFO, "Job download directory from user configuration file: %s ", opt.downloaddir);
70     }
71     else {
72       logger.msg(Arc::INFO, "Job download directory will be created in present working directory. ");
73     }
74   }
75   else {
76     logger.msg(Arc::INFO, "Job download directory: %s ", opt.downloaddir);
77   }
78
79   for (std::list<std::string>::const_iterator it = opt.jobidinfiles.begin(); it != opt.jobidinfiles.end(); it++) {
80     if (!Arc::Job::ReadJobIDsFromFile(*it, jobidentifiers)) {
81       logger.msg(Arc::WARNING, "Cannot read specified jobid file: %s", *it);
82     }
83   }
84
85   if (opt.timeout > 0)
86     usercfg.Timeout(opt.timeout);
87
88   if ((!opt.joblist.empty() || !opt.status.empty()) && jobidentifiers.empty() && opt.clusters.empty())
89     opt.all = true;
90
91   if (jobidentifiers.empty() && opt.clusters.empty() && !opt.all) {
92     logger.msg(Arc::ERROR, "No jobs given");
93     return 1;
94   }
95
96   std::list<std::string> selectedURLs;
97   if (!opt.clusters.empty()) {
98     selectedURLs = getSelectedURLsFromUserConfigAndCommandLine(usercfg, opt.clusters);
99   }
100   std::list<std::string> rejectManagementURLs = getRejectManagementURLsFromUserConfigAndCommandLine(usercfg, opt.rejectmanagement);
101
102   std::list<Arc::Job> jobs;
103   Arc::JobInformationStorage *jobstore = createJobInformationStorage(usercfg);
104   if (jobstore != NULL && !jobstore->IsStorageExisting()) {
105     logger.msg(Arc::ERROR, "Job list file (%s) doesn't exist", usercfg.JobListFile());
106     delete jobstore;
107     return 1;
108   }
109   if (jobstore == NULL ||
110       ( opt.all && !jobstore->ReadAll(jobs, rejectManagementURLs)) ||
111       (!opt.all && !jobstore->Read(jobs, jobidentifiers, selectedURLs, rejectManagementURLs))) {
112     logger.msg(Arc::ERROR, "Unable to read job information from file (%s)", usercfg.JobListFile());
113     delete jobstore;
114     return 1;
115   }
116
117   if (!opt.all) {
118     for (std::list<std::string>::const_iterator itJIdentifier = jobidentifiers.begin();
119          itJIdentifier != jobidentifiers.end(); ++itJIdentifier) {
120       std::cout << Arc::IString("Warning: Job not found in job list: %s", *itJIdentifier) << std::endl;
121     }
122   }
123
124   Arc::JobSupervisor jobmaster(usercfg, jobs);
125
126   jobmaster.Update();
127   jobmaster.SelectValid();
128   if (!opt.status.empty()) {
129     jobmaster.SelectByStatus(opt.status);
130   }
131
132   if (jobmaster.GetSelectedJobs().empty()) {
133     std::cout << Arc::IString("No jobs") << std::endl;
134     delete jobstore;
135     return 1;
136   }
137
138   if(!opt.downloaddir.empty()) {
139     Arc::URL dirpath(opt.downloaddir);
140     if(dirpath.Protocol() == "file") {
141       if(!Arc::DirCreate(dirpath.Path(),S_IRWXU,true)) {
142         std::string errstr = Arc::StrError();
143         logger.msg(Arc::ERROR, "Unable to create directory for storing results (%s) - %s", dirpath.Path(), errstr);
144         return 1;
145       }
146     }
147   }
148   std::list<std::string> downloaddirectories;
149   int retval = (int)!jobmaster.Retrieve(opt.downloaddir, opt.usejobname, opt.forcedownload, downloaddirectories);
150
151   for (std::list<std::string>::const_iterator it = downloaddirectories.begin();
152        it != downloaddirectories.end(); ++it) {
153     std::cout << Arc::IString("Results stored at: %s", *it) << std::endl;
154   }
155
156   unsigned int processed_num = jobmaster.GetIDsProcessed().size();
157   unsigned int retrieved_num = downloaddirectories.size();
158   unsigned int cleaned_num = 0;
159
160   if (!opt.keep) {
161     std::list<std::string> retrieved = jobmaster.GetIDsProcessed();
162     // No need to clean selection because retrieved is subset of selected
163     jobmaster.SelectByID(retrieved);
164     if(!jobmaster.Clean()) {
165       std::cout << Arc::IString("Warning: Some jobs were not removed from server") << std::endl;
166       std::cout << Arc::IString("         Use arclean to remove retrieved jobs from job list", usercfg.JobListFile()) << std::endl;
167       retval = 1;
168     }
169     cleaned_num = jobmaster.GetIDsProcessed().size();
170
171     if (!jobstore->Remove(jobmaster.GetIDsProcessed())) {
172       std::cout << Arc::IString("Warning: Failed removing jobs from file (%s)", usercfg.JobListFile()) << std::endl;
173       std::cout << Arc::IString("         Use arclean to remove retrieved jobs from job list", usercfg.JobListFile()) << std::endl;
174       retval = 1;
175     }
176
177     std::cout << Arc::IString("Jobs processed: %d, successfully retrieved: %d, successfully cleaned: %d", processed_num, retrieved_num, cleaned_num) << std::endl;
178
179   } else {
180
181     std::cout << Arc::IString("Jobs processed: %d, successfully retrieved: %d", processed_num, retrieved_num) << std::endl;
182
183   }
184   delete jobstore;
185
186   return retval;        
187 }