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