Back to index

nordugrid-arc-nox  1.1.0~rc6
conf_pre.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <string>
00006 #include <fstream>
00007 #include <iostream>
00008 #include <pwd.h>
00009 
00010 #include <arc/StringConv.h>
00011 #include <arc/Logger.h>
00012 #include "conf.h"
00013 #include "conf_sections.h"
00014 #include "environment.h"
00015 #include "gridmap.h"
00016 #include "../jobs/job.h"
00017 #include "../jobs/users.h"
00018 #include "../jobs/plugins.h"
00019 #include "../run/run_plugin.h"
00020 #include "conf_pre.h"
00021 
00022 Arc::Logger& logger = Arc::Logger::getRootLogger();
00023 
00024 bool configure_user_dirs(const std::string &my_username,
00025                 std::string &control_dir,std::vector<std::string> &session_roots,
00026                 std::vector<std::string> &session_roots_non_draining,
00027                 std::string &default_lrms,std::string &default_queue,
00028                 std::list<std::string>& queues,
00029                 ContinuationPlugins &plugins,RunPlugin &cred_plugin,
00030                 std::string& allow_submit,bool& strict_session) {
00031   std::ifstream cfile;
00032   read_env_vars(true);
00033   bool configured = false;
00034   std::string central_control_dir("");
00035   ConfigSections* cf = NULL;
00036   std::list<std::string>::iterator last_queue = queues.end();
00037 
00038   strict_session = false;
00039   if(!config_open(cfile)) {
00040     logger.msg(Arc::ERROR,"Can't open configuration file"); return false;
00041   };
00042   switch(config_detect(cfile)) {
00043     case config_file_XML: {
00044       Arc::XMLNode cfg;
00045       if(!cfg.ReadFromStream(cfile)) {
00046         logger.msg(Arc::ERROR,"Can't interpret configuration file as XML");
00047         config_close(cfile);
00048         return false;
00049       };
00050       // Unsupported elements:
00051       //   std::string& allow_submit
00052       allow_submit=true;
00053       Arc::XMLNode tmp_node;
00054       tmp_node = cfg["LRMS"];
00055       if(tmp_node) {
00056         default_lrms = (std::string)(tmp_node["type"]);
00057         default_queue = (std::string)(tmp_node["defaultShare"]);
00058       };
00059       tmp_node = cfg["authPlugin"];
00060       for(;tmp_node;++tmp_node) {
00061         std::string state_name = tmp_node["state"];
00062         if(state_name.empty()) continue;
00063         std::string command = tmp_node["command"];
00064         if(command.empty()) continue;
00065         std::string options;
00066         Arc::XMLNode onode;
00067         onode = tmp_node.Attribute("timeout");
00068         if(onode) options+="timeout="+(std::string)onode;
00069         onode = tmp_node.Attribute("onSuccess");
00070         if(onode) options+="onsuccess="+Arc::lower((std::string)onode);
00071         onode = tmp_node.Attribute("onFailure");
00072         if(onode) options+="onfailure="+Arc::lower((std::string)onode);
00073         onode = tmp_node.Attribute("onTimeout");
00074         if(onode) options+="ontimeout="+Arc::lower((std::string)onode);
00075         if(!plugins.add(state_name.c_str(),options.c_str(),command.c_str())) {
00076           config_close(cfile);
00077           return false;
00078         };
00079       };
00080       tmp_node = cfg["localCred"];
00081       if(tmp_node) {
00082         std::string command = tmp_node["command"];
00083         if(command.empty()) return false;
00084         std::string options;
00085         Arc::XMLNode onode;
00086         onode = tmp_node.Attribute("timeout");
00087         if(!onode) return false;
00088         int to;
00089         if(!elementtoint(onode,NULL,to,&logger)) return false;
00090         cred_plugin = command;
00091         cred_plugin.timeout(to);
00092       };
00093       tmp_node = cfg["ComputingService"];
00094       if(tmp_node) {
00095         Arc::XMLNode shnode = tmp_node["ComputingShare"];
00096         for(;shnode;++shnode) {
00097           std::string qname = shnode["MappingQueue"];
00098           if(qname.empty()) qname=(std::string)(shnode.Attribute("name"));
00099           if(!qname.empty()) queues.insert(queues.end(),qname);
00100         };
00101       }
00102       tmp_node = cfg["control"];
00103       for(;tmp_node;++tmp_node) {
00104         Arc::XMLNode unode = tmp_node["username"];
00105         bool user_match = false;
00106         std::string username;
00107         for(;unode;++unode) {
00108           username = (std::string)unode;
00109           if(username.empty()) continue;
00110           if(username == "*") {  /* add all gridmap users */
00111             std::list<std::string> userlist;
00112             if(!gridmap_user_list(userlist)) {
00113               logger.msg(Arc::ERROR,"Can't read users in gridmap file %s",globus_gridmap());
00114               config_close(cfile);
00115               return false;
00116             };
00117             for(std::list<std::string>::iterator u = userlist.begin();
00118                                      u != userlist.end();++u) {
00119               username = *u;
00120               if(username == my_username) {
00121                 user_match=true;
00122                 break;
00123               };
00124             };
00125             if(user_match) break;
00126             continue;
00127           };
00128           if(username == ".") {
00129             user_match=true;
00130             break;
00131           };
00132           if(username == my_username) {
00133             user_match=true;
00134             break;
00135           };
00136         };
00137         if(user_match) {
00138           std::string control_dir_ = tmp_node["controlDir"];
00139           Arc::XMLNode session_node = tmp_node["sessionRootDir"];
00140           for (;session_node; ++session_node) {
00141             std::string session_root = session_node;
00142             if(session_root.empty()) {
00143               logger.msg(Arc::ERROR,"sessionRootDir is missing"); return false;
00144             };
00145             std::string::size_type i = session_root.find(' ');
00146             if (i != std::string::npos) {
00147               if (session_root.substr(i+1) != "drain") {
00148                 session_roots_non_draining.push_back(session_root.substr(0, i));
00149               }
00150               session_root = session_root.substr(0, i);
00151             } else {
00152               session_roots_non_draining.push_back(session_root);
00153             }
00154             session_roots.push_back(session_root);
00155           }
00156           if(username == ".") username = "";
00157           JobUser user(username);
00158           if(!user.is_valid()) { config_close(cfile); return false; };
00159           strict_session = false;
00160           elementtobool(tmp_node,"noRootPower",strict_session,&logger);
00161           user.SetLRMS(default_lrms,default_queue);
00162           user.substitute(control_dir_);
00163           user.SetControlDir(control_dir_);
00164           for(std::vector<std::string>::iterator i = session_roots_non_draining.begin(); i != session_roots_non_draining.end(); i++) {
00165             user.substitute(*i);
00166           }
00167           user.SetSessionRoot(session_roots_non_draining);
00168           session_roots_non_draining = user.SessionRoots();
00169           for(std::vector<std::string>::iterator i = session_roots.begin(); i != session_roots.end(); i++) {
00170             user.substitute(*i);
00171           }
00172           user.SetSessionRoot(session_roots);
00173           session_roots=user.SessionRoots();
00174           control_dir=user.ControlDir();
00175           configured=true;
00176           break;
00177         };
00178       }; // for(control)
00179     }; break;
00180     case config_file_INI: {
00181       cf=new ConfigSections(cfile);
00182       cf->AddSection("common");
00183       cf->AddSection("grid-manager");
00184       cf->AddSection("queue");
00185       for(;;) {
00186         std::string rest;
00187         std::string command;
00188         cf->ReadNext(command,rest);
00189         if(command.length() == 0) {
00190           if(central_control_dir.length() != 0) {
00191             command="control"; rest=central_control_dir+" .";
00192             central_control_dir="";
00193           } else {
00194             break;
00195           };
00196         };
00197         if(cf->SectionNum() == 2) { // queue
00198           if(cf->SectionNew()) {
00199             const char* name = cf->SubSection();
00200             if(!name) name="";
00201             last_queue=queues.insert(queues.end(),std::string(name));
00202           };
00203           if(command == "name") {
00204             if(last_queue != queues.end()) *last_queue=config_next_arg(rest);
00205           };
00206         }
00207         else if(command == "lrms") {
00208           if(configured) continue;
00209           default_lrms = config_next_arg(rest);
00210           default_queue = config_next_arg(rest);
00211           if(default_lrms.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00212         }
00213         else if(command == "authplugin") { /* set plugin to be called on
00214                                               state changes */
00215           std::string state_name = config_next_arg(rest);
00216           if(state_name.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00217           std::string options_s = config_next_arg(rest);
00218           if(options_s.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00219           if(!plugins.add(state_name.c_str(),options_s.c_str(),rest.c_str())) {
00220             config_close(cfile); if(cf) delete cf; return false;
00221           };
00222         }
00223         else if(command == "localcred") {
00224           std::string timeout_s = config_next_arg(rest);
00225           if(timeout_s.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00226           char *ep;
00227           int to = strtoul(timeout_s.c_str(),&ep,10);
00228           if((*ep != 0) || (to<0)) { config_close(cfile); if(cf) delete cf; return false; };
00229           cred_plugin = rest;
00230           cred_plugin.timeout(to);
00231         }
00232         else if(command == "allowsubmit") {
00233           allow_submit+=" "; allow_submit+=rest;
00234         }
00235         else if(command == "norootpower") {
00236           std::string s = config_next_arg(rest);
00237           if(strcasecmp("yes",s.c_str()) == 0) {
00238             strict_session=true;
00239           }
00240           else if(strcasecmp("no",s.c_str()) == 0) {
00241             strict_session=false;
00242           };
00243         }
00244         else if(command == "sessiondir") {
00245           if(configured) continue;
00246           std::string session_root = config_next_arg(rest);
00247           if(session_root.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00248           session_roots.push_back(session_root);
00249           std::string drain = config_next_arg(rest);
00250           if (drain.empty() || drain != "drain") {
00251             session_roots_non_draining.push_back(session_root);
00252           }
00253         }
00254         else if(command == "controldir") {
00255           central_control_dir=rest;
00256         }
00257         else if(command == "control") {
00258           if(configured) continue;
00259           control_dir = config_next_arg(rest);
00260           if(control_dir.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00261           if(control_dir == "*") control_dir="";
00262           for(;;) {
00263             std::string username = config_next_arg(rest);
00264             if(username.length() == 0) break;
00265             if(username == "*") {  /* add all gridmap users */
00266               if(!gridmap_user_list(rest)) { config_close(cfile); if(cf) delete cf; return false; };
00267               continue;
00268             };
00269             if((username == my_username) || (username == ".")) { 
00270               if(username == ".") username = "";
00271               JobUser user(username);
00272               if(!user.is_valid()) { config_close(cfile); if(cf) delete cf; return false; };
00273               user.SetLRMS(default_lrms,default_queue);
00274               user.substitute(control_dir);
00275               user.SetControlDir(control_dir);
00276               for(std::vector<std::string>::iterator i = session_roots_non_draining.begin(); i != session_roots_non_draining.end(); i++) {
00277                 user.substitute(*i);
00278               }
00279               user.SetSessionRoot(session_roots_non_draining);
00280               session_roots_non_draining=user.SessionRoots();
00281               for(std::vector<std::string>::iterator i = session_roots.begin(); i != session_roots.end(); i++) {
00282                 user.substitute(*i);
00283               }
00284               user.SetSessionRoot(session_roots);
00285               session_roots=user.SessionRoots();
00286               control_dir=user.ControlDir();
00287               configured=true;
00288             } else {
00289               session_roots.clear();
00290               session_roots_non_draining.clear();
00291             };
00292           };
00293         };
00294       };
00295     }; break;
00296 
00297     default: {
00298     }; break;
00299   };
00300   config_close(cfile);
00301   if(cf) delete cf;
00302   return configured;
00303 }
00304 
00305 bool configure_users_dirs(Arc::XMLNode cfg,JobUsers& users) {
00306   Arc::XMLNode tmp_node;
00307   tmp_node = cfg["control"];
00308   for(;tmp_node;++tmp_node) {
00309     Arc::XMLNode unode = tmp_node["username"];
00310     std::list<std::string> usernames;
00311     for(;unode;++unode) {
00312       std::string username;
00313       username = (std::string)unode;
00314       if(username.empty()) continue;
00315       if(username == "*") {  /* add all gridmap users */
00316         std::list<std::string> userlist;
00317         if(!gridmap_user_list(userlist)) {
00318           logger.msg(Arc::ERROR,"Can't read users in gridmap file %s",globus_gridmap());
00319           return false;
00320         };
00321         for(std::list<std::string>::iterator u = userlist.begin();
00322                                  u != userlist.end();++u) {
00323           usernames.push_back(*u);
00324         };
00325         continue;
00326       };
00327       if(username == ".") {
00328         usernames.push_back("");
00329         continue;
00330       };
00331       usernames.push_back(username);
00332     };
00333     for(std::list<std::string>::iterator u = usernames.begin();
00334                              u != usernames.end();++u) {
00335       std::string control_dir = tmp_node["controlDir"];
00336       std::string session_root = tmp_node["sessionRootDir"];
00337       JobUsers::iterator user=users.AddUser(*u);
00338       if(user == users.end()) return false;
00339       user->substitute(control_dir);
00340       user->substitute(session_root);
00341       user->SetControlDir(control_dir);
00342       user->SetSessionRoot(session_root);
00343     };
00344   }; // for(control)
00345   return true;
00346 }
00347 
00348 bool configure_users_dirs(JobUsers& users) {
00349   std::ifstream cfile;
00350   read_env_vars(true);
00351   std::string central_control_dir("");
00352   ConfigSections* cf = NULL;
00353   std::string session_root;
00354 
00355   if(!config_open(cfile)) {
00356     logger.msg(Arc::ERROR,"Can't open configuration file"); return false;
00357   };
00358   switch(config_detect(cfile)) {
00359     case config_file_XML: {
00360       Arc::XMLNode cfg;
00361       if(!cfg.ReadFromStream(cfile)) {
00362         logger.msg(Arc::ERROR,"Can't interpret configuration file as XML");
00363         config_close(cfile);
00364         return false;
00365       };
00366       if(!configure_users_dirs(cfg,users)) {
00367         config_close(cfile);
00368         return false;
00369       };
00370     }; break;
00371     case config_file_INI: {
00372       cf=new ConfigSections(cfile);
00373       cf->AddSection("common");
00374       cf->AddSection("grid-manager");
00375       cf->AddSection("queue");
00376       for(;;) {
00377         std::string rest;
00378         std::string command;
00379         cf->ReadNext(command,rest);
00380         if(command.length() == 0) {
00381           if(central_control_dir.length() != 0) {
00382             command="control"; rest=central_control_dir+" .";
00383             central_control_dir="";
00384           } else {
00385             break;
00386           };
00387         };
00388         if(cf->SectionNum() == 2) { // queue
00389         }
00390         else if(command == "sessiondir") {
00391           session_root = config_next_arg(rest);
00392           if(session_root.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00393           if(session_root == "*") session_root="";
00394         }
00395         else if(command == "controldir") {
00396           central_control_dir=rest;
00397         }
00398         else if(command == "control") {
00399           std::string control_dir = config_next_arg(rest);
00400           if(control_dir.length() == 0) { config_close(cfile); if(cf) delete cf; return false; };
00401           if(control_dir == "*") control_dir="";
00402           for(;;) {
00403             std::string username = config_next_arg(rest);
00404             if(username.length() == 0) break;
00405             if(username == "*") {  /* add all gridmap users */
00406               if(!gridmap_user_list(rest)) { config_close(cfile); if(cf) delete cf; return false; };
00407               continue;
00408             };
00409             if(username == ".") username = "";
00410             JobUsers::iterator user=users.AddUser(username);
00411             if(user == users.end()) { config_close(cfile); if(cf) delete cf; return false; };
00412             user->substitute(control_dir);
00413             user->substitute(session_root);
00414             user->SetControlDir(control_dir);
00415             user->SetSessionRoot(session_root);
00416           };
00417         };
00418       };
00419     }; break;
00420 
00421     default: {
00422     }; break;
00423   };
00424   config_close(cfile);
00425   if(cf) delete cf;
00426   return true;
00427 }
00428