Back to index

nordugrid-arc-nox  1.1.0~rc6
arcmigrate.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include <iostream>
00008 #include <list>
00009 #include <string>
00010 
00011 #include <arc/ArcConfig.h>
00012 #include <arc/ArcLocation.h>
00013 #include <arc/IString.h>
00014 #include <arc/Logger.h>
00015 #include <arc/XMLNode.h>
00016 #include <arc/OptionParser.h>
00017 #include <arc/StringConv.h>
00018 #include <arc/URL.h>
00019 #include <arc/client/JobController.h>
00020 #include <arc/client/JobSupervisor.h>
00021 #include <arc/client/TargetGenerator.h>
00022 #include <arc/UserConfig.h>
00023 #include <arc/client/Job.h>
00024 #include <arc/client/JobDescription.h>
00025 #include <arc/DateTime.h>
00026 #include <arc/FileLock.h>
00027 #include <arc/Utils.h>
00028 #include <arc/client/Submitter.h>
00029 #include <arc/client/Broker.h>
00030 
00031 int main(int argc, char **argv) {
00032 
00033   setlocale(LC_ALL, "");
00034 
00035   Arc::Logger logger(Arc::Logger::getRootLogger(), "arcmigrate");
00036   Arc::LogStream logcerr(std::cerr);
00037   logcerr.setFormat(Arc::ShortFormat);
00038   Arc::Logger::getRootLogger().addDestination(logcerr);
00039   Arc::Logger::getRootLogger().setThreshold(Arc::WARNING);
00040 
00041   Arc::ArcLocation::Init(argv[0]);
00042 
00043   Arc::OptionParser options(istring("[job ...]"),
00044                             istring("The arcmigrate command is used for "
00045                                     "migrating queud jobs to another cluster.\n"
00046                                     "Note that migration is only supported "
00047                                     "between ARC1 clusters."),
00048                             istring(" "));
00049 
00050   bool all = false;
00051   options.AddOption('a', "all",
00052                     istring("all jobs"),
00053                     all);
00054 
00055   bool forcemigration = false;
00056   options.AddOption('f', "force",
00057                     istring("force migration, ignore kill failure"),
00058                     forcemigration);
00059 
00060   std::string joblist;
00061   options.AddOption('j', "joblist",
00062                     istring("file containing a list of jobs"),
00063                     istring("filename"),
00064                     joblist);
00065 
00066   std::list<std::string> clusters;
00067   options.AddOption('c', "cluster",
00068                     istring("explicitly select or reject a cluster holding queued jobs"),
00069                     istring("[-]name"),
00070                     clusters);
00071 
00072   std::list<std::string> qlusters;
00073   options.AddOption('q', "qluster",
00074                     istring("explicitly select or reject a cluster to migrate to"),
00075                     istring("[-]name"),
00076                     qlusters);
00077 
00078   std::list<std::string> indexurls;
00079   options.AddOption('i', "index",
00080                     istring("explicitly select or reject an index server"),
00081                     istring("[-]name"),
00082                     indexurls);
00083 
00084   int timeout = -1;
00085   options.AddOption('t', "timeout", istring("timeout in seconds (default 20)"),
00086                     istring("seconds"), timeout);
00087 
00088   std::string conffile;
00089   options.AddOption('z', "conffile",
00090                     istring("configuration file (default ~/.arc/client.conf)"),
00091                     istring("filename"), conffile);
00092 
00093   std::string debug;
00094   options.AddOption('d', "debug",
00095                     istring("FATAL, ERROR, WARNING, INFO, VERBOSE or DEBUG"),
00096                     istring("debuglevel"), debug);
00097 
00098   bool version = false;
00099   options.AddOption('v', "version", istring("print version information"),
00100                     version);
00101 
00102   std::string broker;
00103   options.AddOption('b', "broker",
00104                     istring("select broker method (Random (default), FastestQueue, or custom)"),
00105                     istring("broker"), broker);
00106 
00107   std::list<std::string> jobs = options.Parse(argc, argv);
00108 
00109   // If debug is specified as argument, it should be set before loading the configuration.
00110   if (!debug.empty())
00111     Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(debug));
00112 
00113   Arc::UserConfig usercfg(conffile, joblist);
00114   if (!usercfg) {
00115     logger.msg(Arc::ERROR, "Failed configuration initialization");
00116     return 1;
00117   }
00118 
00119   if (debug.empty() && !usercfg.Verbosity().empty())
00120     Arc::Logger::getRootLogger().setThreshold(Arc::string_to_level(usercfg.Verbosity()));
00121 
00122   if (timeout > 0)
00123     usercfg.Timeout(timeout);
00124 
00125   if (!broker.empty())
00126     usercfg.Broker(broker);
00127 
00128   if (version) {
00129     std::cout << Arc::IString("%s version %s", "arcmigrate", VERSION)
00130               << std::endl;
00131     return 0;
00132   }
00133 
00134   if (!joblist.empty() && jobs.empty() && clusters.empty())
00135     all = true;
00136 
00137   if (jobs.empty() && clusters.empty() && !all) {
00138     logger.msg(Arc::ERROR, "No jobs given");
00139     return 1;
00140   }
00141 
00142   // Different selected services are needed in two different context,
00143   // so the two copies of UserConfig objects will contain different
00144   // selected services.
00145   Arc::UserConfig usercfg2 = usercfg;
00146 
00147   if (!jobs.empty() || all)
00148     usercfg.ClearSelectedServices();
00149 
00150   if (!clusters.empty()) {
00151     usercfg.ClearSelectedServices();
00152     usercfg.AddServices(clusters, Arc::COMPUTING);
00153   }
00154 
00155   if (!qlusters.empty() || !indexurls.empty())
00156     usercfg2.ClearSelectedServices();
00157 
00158   if (!qlusters.empty())
00159     usercfg2.AddServices(qlusters, Arc::COMPUTING);
00160 
00161   if (!indexurls.empty())
00162     usercfg2.AddServices(indexurls, Arc::INDEX);
00163 
00164   // If the user specified a joblist on the command line joblist equals
00165   // usercfg.JobListFile(). If not use the default, ie. usercfg.JobListFile().
00166   Arc::JobSupervisor jobmaster(usercfg, jobs);
00167   if (!jobmaster.JobsFound()) {
00168     std::cout << "No jobs" << std::endl;
00169     return 0;
00170   }
00171   std::list<Arc::JobController*> jobcont = jobmaster.GetJobControllers();
00172 
00173   if (jobcont.empty()) {
00174     logger.msg(Arc::ERROR, "No job controller plugins loaded");
00175     return 1;
00176   }
00177 
00178   Arc::TargetGenerator targetGen(usercfg2);
00179   targetGen.GetTargets(0, 1);
00180 
00181   if (targetGen.FoundTargets().empty()) {
00182     std::cout << Arc::IString("Job migration aborted because no clusters returned any information") << std::endl;
00183     return 1;
00184   }
00185 
00186   Arc::BrokerLoader loader;
00187   Arc::Broker *chosenBroker = loader.load(usercfg.Broker().first, usercfg);
00188   if (!chosenBroker) {
00189     logger.msg(Arc::ERROR, "Unable to load broker %s", usercfg.Broker().first);
00190     return 1;
00191   }
00192   logger.msg(Arc::INFO, "Broker %s loaded", usercfg.Broker().first);
00193 
00194   std::list<Arc::URL> migratedJobIDs;
00195 
00196   int retval = 0;
00197   // Loop over job controllers - arcmigrate should only support ARC-1 thus no loop...?
00198   for (std::list<Arc::JobController*>::iterator itJobCont = jobcont.begin(); itJobCont != jobcont.end(); itJobCont++) {
00199     // if ((*itJobCont)->Flavour() != "ARC1") {
00200     //  std::cout << Arc::IString("Cannot migrate from %s clusters.", (*itJobCont)->Flavour()) << std::endl;
00201     //  std::cout << Arc::IString("Note: Migration is currently only supported between ARC1 clusters.") << std::endl;
00202     //  continue;
00203     //}
00204 
00205     if (!(*itJobCont)->Migrate(targetGen, chosenBroker, usercfg, forcemigration, migratedJobIDs))
00206       retval = 1;
00207     for (std::list<Arc::URL>::iterator it = migratedJobIDs.begin();
00208          it != migratedJobIDs.end(); it++) {
00209       std::cout << Arc::IString("Job migrated with jobid: %s", it->str()) << std::endl;
00210     }
00211   } // Loop over job controllers
00212 
00213   return retval;
00214 }