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