Update to ARC 4.1.0
[gp-arc-client-c.git] / ext / arc_kill.cpp
1 /*
2  *  arc_kill.cpp
3  *  arcclientc
4  *
5  *  Created by Tamas Jung on 10/25/10.
6  *
7  */
8
9 #include "arc_kill.h"
10
11 // -*- indent-tabs-mode: nil -*-
12 #include "logger.h"
13
14
15 #include <iostream>
16 #include <list>
17 #include <string>
18 #include <algorithm>
19 #include "arc_libs.h"
20
21 #include "utils.h"
22
23 int  arc_kill(int argc, char **argv) {
24
25   Arc::ArcLocation::Init(argv[0]);
26
27   ClientOptions opt(ClientOptions::CO_KILL,
28                     istring("[job ...]"),
29                     istring("The arckill command is used to kill "
30                             "running jobs."));
31
32   std::list<std::string> jobidentifiers = opt.Parse(argc, argv);
33
34   if (opt.showversion) {
35     std::cout << Arc::IString("%s version %s", "arckill", "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("arckill", 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   for (std::list<std::string>::const_iterator it = opt.jobidinfiles.begin(); it != opt.jobidinfiles.end(); it++) {
67     if (!Arc::Job::ReadJobIDsFromFile(*it, jobidentifiers)) {
68       logger.msg(Arc::WARNING, "Cannot read specified jobid file: %s", *it);
69     }
70   }
71
72   if (opt.timeout > 0)
73     usercfg.Timeout(opt.timeout);
74
75   if ((!opt.joblist.empty() || !opt.status.empty()) && jobidentifiers.empty() && opt.clusters.empty())
76     opt.all = true;
77
78   if (jobidentifiers.empty() && opt.clusters.empty() && !opt.all) {
79     logger.msg(Arc::ERROR, "No jobs given");
80     return 1;
81   }
82
83   std::list<std::string> selectedURLs;
84   if (!opt.clusters.empty()) {
85     selectedURLs = getSelectedURLsFromUserConfigAndCommandLine(usercfg, opt.clusters);
86   }
87   std::list<std::string> rejectManagementURLs = getRejectManagementURLsFromUserConfigAndCommandLine(usercfg, opt.rejectmanagement);
88
89   std::list<Arc::Job> jobs;
90   Arc::JobInformationStorage *jobstore = createJobInformationStorage(usercfg);
91   if (jobstore != NULL && !jobstore->IsStorageExisting()) {
92     logger.msg(Arc::ERROR, "Job list file (%s) doesn't exist", usercfg.JobListFile());
93     delete jobstore;
94     return 1;
95   }
96   if (jobstore == NULL ||
97       ( opt.all && !jobstore->ReadAll(jobs, rejectManagementURLs)) ||
98       (!opt.all && !jobstore->Read(jobs, jobidentifiers, selectedURLs, rejectManagementURLs))) {
99     logger.msg(Arc::ERROR, "Unable to read job information from file (%s)", usercfg.JobListFile());
100     delete jobstore;
101     return 1;
102   }
103
104   if (!opt.all) {
105     for (std::list<std::string>::const_iterator itJIDAndName = jobidentifiers.begin();
106          itJIDAndName != jobidentifiers.end(); ++itJIDAndName) {
107       std::cout << Arc::IString("Warning: Job not found in job list: %s", *itJIDAndName) << std::endl;
108     }
109   }
110
111   Arc::JobSupervisor jobmaster(usercfg, jobs);
112   jobmaster.Update();
113   jobmaster.SelectValid();
114   if (!opt.status.empty()) {
115     jobmaster.SelectByStatus(opt.status);
116   }
117
118   if (jobmaster.GetSelectedJobs().empty()) {
119     std::cout << Arc::IString("No jobs") << std::endl;
120     delete jobstore;
121     return 1;
122   }
123
124   int retval = (int)!jobmaster.Cancel();
125
126   unsigned int selected_num = jobmaster.GetSelectedJobs().size();
127   unsigned int canceled_num = jobmaster.GetIDsProcessed().size();
128   unsigned int cleaned_num = 0;
129
130   if (!opt.keep) {
131     std::list<std::string> canceled = jobmaster.GetIDsProcessed();
132     // No need to clean selection because retrieved is subset of selected
133     jobmaster.SelectByID(canceled);
134     if(!jobmaster.Clean()) {
135       std::cout << Arc::IString("Warning: Some jobs were not removed from server") << std::endl;
136       std::cout << Arc::IString("         Use arclean to remove retrieved jobs from job list", usercfg.JobListFile()) << std::endl;
137       retval = 1;
138     }
139     cleaned_num = jobmaster.GetIDsProcessed().size();
140
141     if (!jobstore->Remove(jobmaster.GetIDsProcessed())) {
142       std::cout << Arc::IString("Warning: Failed removing jobs from file (%s)", usercfg.JobListFile()) << std::endl;
143       std::cout << Arc::IString("         Run 'arcclean -s Undefined' to remove killed jobs from job list", usercfg.JobListFile()) << std::endl;
144       retval = 1;
145     }
146     std::cout << Arc::IString("Jobs processed: %d, successfully killed: %d, successfully cleaned: %d", selected_num, canceled_num, cleaned_num) << std::endl;
147   } else {
148     std::cout << Arc::IString("Jobs processed: %d, successfully killed: %d", selected_num, canceled_num) << std::endl;
149   }
150   delete jobstore;
151
152   return retval;
153
154 }