d7337bb5671fcd6d0bf26b40287e52bc42ea47fa
[gp-arc-client-c.git] / src / submit.cpp
1 /*
2  *  submit.cpp
3  *  arcclientc
4  *
5  *  Created by Tamas Jung on 4/7/10.
6  *  Copyright 2010 Interface Kft. All rights reserved.
7  *
8  */
9
10 #include "submit.h"
11 #include "common_utils.h"
12 #include "logger.h"
13 #include "config.h"
14 // -*- indent-tabs-mode: nil -*-
15
16 #ifdef HAVE_CONFIG_H
17 #include <config.h>
18 #endif
19
20 #include <fstream>
21 #include <iostream>
22 #include <list>
23 #include <string>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27
28 #include "arc_libs.h"
29 #pragma GCC visibility push(default)
30 extern "C" {
31 submit_result_t* submit(int argc, char **argv) {
32         
33         submit_result_t* result = (submit_result_t*)malloc(sizeof(submit_result_t));
34         if (!result) {
35                 return NULL;//TBD: throw sth?
36         }
37         result->message = NULL;
38         result->job_id = NULL;
39
40         //TODO: what necessary here?
41         Arc::OptionParser options(istring("[filename ...]"),
42                                                           istring("The arcsub command is used for "
43                                                                           "submitting jobs to grid enabled "
44                                                                           "computing\nresources."),
45                                                           istring("Argument to -i has the format "
46                                                                           "Flavour:URL e.g.\n"
47                                                                           "ARC0:ldap://grid.tsl.uu.se:2135/"
48                                                                           "mds-vo-name=sweden,O=grid\n"
49                                                                           "CREAM:ldap://cream.grid.upjs.sk:2170/"
50                                                                           "o=grid\n"
51                                                                           "\n"
52                                                                           "Argument to -c has the format "
53                                                                           "Flavour:URL e.g.\n"
54                                                                           "ARC0:ldap://grid.tsl.uu.se:2135/"
55                                                                           "nordugrid-cluster-name=grid.tsl.uu.se,"
56                                                                           "Mds-Vo-name=local,o=grid"));
57         
58         std::list<std::string> clusters;
59         options.AddOption('c', "cluster",
60                                           istring("explicity select or reject a specific cluster"),
61                                           istring("[-]name"),
62                                           clusters);
63         
64         std::list<std::string> indexurls;
65         options.AddOption('i', "index",
66                                           istring("explicity select or reject an index server"),
67                                           istring("[-]name"),
68                                           indexurls);
69         
70         std::string jobdescriptionstring;
71         options.AddOption('e', "jobdescrstring",
72                                           istring("jobdescription string describing the job to "
73                                                           "be submitted"),
74                                           istring("string"),
75                                           jobdescriptionstring);
76         
77
78         
79         
80         //jt: dryrun was commented out in the original file, I try to use it TODO:
81      bool dryrun = false;
82      options.AddOption('D', "dryrun", istring("add dryrun option"),
83          dryrun);
84          
85         int timeout = -1;
86         options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
87                                           istring("seconds"), timeout);
88         
89         std::string conffile;
90         options.AddOption('z', "conffile",
91                                           istring("configuration file (default ~/.arc/client.conf)"),
92                                           istring("filename"), conffile);
93                 
94         std::string broker;
95         options.AddOption('b', "broker",
96                                           istring("select broker method (Random (default), FastestQueue, or custom)"),
97                                           istring("broker"), broker);
98         
99         
100         std::list<std::string> params = options.Parse(argc, argv);
101         
102         std::cout << "conffile:";
103         std::cout << conffile.size();//TODO: clean
104         Arc::UserConfig usercfg(conffile);
105         if (!usercfg) {
106                 result->message = new_str("Failed configuration initialization");
107                 return result;
108         }
109         
110         
111         if (timeout > 0)
112                 usercfg.Timeout(timeout);
113         
114         if (!broker.empty())
115                 usercfg.Broker(broker);
116                 
117         if (!clusters.empty() || !indexurls.empty())
118                 usercfg.ClearSelectedServices();
119         
120         if (!clusters.empty())
121                 usercfg.AddServices(clusters, Arc::COMPUTING);
122         
123         if (!indexurls.empty())
124                 usercfg.AddServices(indexurls, Arc::INDEX);
125         
126         if (jobdescriptionstring.empty()) {
127                 result->message = new_str("No job description input specified");
128                 return result;
129         }
130         
131         
132
133                 
134         Arc::JobDescription jobdesc;
135         
136         jobdesc.Parse(jobdescriptionstring);
137         
138         if (!jobdesc){
139                 std::ostringstream sstr;
140                 sstr << "Invalid JobDescription:";
141                 sstr << jobdescriptionstring;
142                 result->message = ostringstream2cstring(sstr);
143                 return result;
144         }
145         
146         Arc::TargetGenerator targen(usercfg);
147         targen.GetTargets(0, 1);
148         
149         if (targen.FoundTargets().empty()) {
150                 
151                 result->message = new_str("Job submission aborted because no clusters returned any information");
152                 return result;
153         }
154         
155         
156         
157         Arc::BrokerLoader loader;
158         Arc::Broker *ChosenBroker = loader.load(usercfg.Broker().first, usercfg);
159         if (!ChosenBroker) {
160                 std::ostringstream sstream;
161                 sstream << "Unable to load broker " << usercfg.Broker().first;
162                 result->message = ostringstream2cstring(sstream);
163                 return result;
164         }
165         logger->msg(Arc::INFO, "Broker %s loaded", usercfg.Broker().first);
166         
167                 
168         ChosenBroker->PreFilterTargets(targen.ModifyFoundTargets(), jobdesc);
169         
170         while (true) {
171                 const Arc::ExecutionTarget* target = ChosenBroker->GetBestTarget();
172                 
173                 if (!target) {
174                         result->message = new_str("Job submission failed, no more possible targets");
175                         break;
176                 }
177                 
178                 Arc::Submitter *submitter = target->GetSubmitter(usercfg);
179                                 
180                 if (dryrun) {
181                         result->message = new_str("Dry run, job submission is skipped");
182                         break;
183                 }
184                 //submit the job
185                 Arc::URL jobid = submitter->Submit(jobdesc, *target);
186                 if (!jobid) {
187                         logger->msg(Arc::INFO, "Submission to %s failed, trying next target", target->url.str());
188                         continue;
189                 }
190                 
191                 ChosenBroker->RegisterJobsubmission();
192                 result->job_id = new_str(jobid.str().c_str());
193                 logger->msg(Arc::DEBUG, "Job submitted with jobid: %s", jobid.str());
194                 
195                 break;
196         } //end loop over all possible targets
197         
198         return result;
199 }
200 }
201