/////////////////////////////////////////////////////////////////////////////// // throws : BadParameter void helper::check_scheme(saga::url& rm, bool local_ok) { std::string scheme(rm.get_scheme()); if (scheme == "rns") { std::cout << "RNS good" << std::endl; return; } if (scheme.empty() || scheme == "file") { if (local_ok) { SAGA_LOG_DEBUG("local file."); return; } else { SAGA_OSSTREAM strm; strm << "Could not initialize file for [" << rm << "]. " << "Only any:// and rns:// " << "schemes are supported."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } } //SRA : rns if (!(scheme == "irods" || scheme == "any")) { SAGA_OSSTREAM strm; strm << "Could not initialize file for [" << rm << "]. " << "Only any:// and rns:// " << "schemes are supported."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } }
// search all known sshfs's tto translate the URL If none scceeds, try to // create a new sshfs mount, and work on it saga::url filesystem_adaptor::translate (const saga::session & s, const saga::url & u) { saga::url ret; try { // FIXME: we would actually need the cpi's session here... sshfs_t sshfs = get_sshfs (s, u); ret = sshfs->translate (u); } catch ( const saga::exception & e ) { std::stringstream ss; ss << "Cannot handle URL 1" << u << ": cannot mount/translate into local file system : \n" << e.what () << "\n"; SAGA_ADAPTOR_THROW_NO_CONTEXT (ss.str (), saga::NoSuccess); } if ( ret == u ) { std::stringstream ss; ss << "Cannot handle URL 2" << u << ": cannot mount/translate into local file system"; SAGA_ADAPTOR_THROW_NO_CONTEXT (ss.str (), saga::NoSuccess); } return ret; }
file_transfer_ptr file_transfer_parser_impl::parse(std::string spec) const { std::string left, right; saga::adaptors::file_transfer_operator mode; if (!parse_file_transfer_specification(spec, left, mode, right)) { SAGA_OSSTREAM strm; strm << "Parse failed: " << "(FileTransfer entry: '" << spec << "')."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); throw; } #if 0 if (!check_filename(left) || !check_filename(right)) { SAGA_OSSTREAM strm; strm << "Cannot handle the specified URL " << "(FileTransfer entry: '" << spec << "')."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::IncorrectURL); } #endif file_transfer_ptr p; switch (mode) { case saga::adaptors::copy_local_remote: p = file_transfer_ptr(new file_transfer_impl(left, right, file_transfer::in)); break; case saga::adaptors::copy_remote_local: p = file_transfer_ptr(new file_transfer_impl(right, left, file_transfer::out)); break; case saga::adaptors::append_local_remote: case saga::adaptors::append_remote_local: { SAGA_OSSTREAM strm; strm << "Append operation is unsupported " << "(FileTransfer entry: '" << spec << "')."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::NotImplemented); } break; case saga::adaptors::unknown_mode: default: { // from condor SAGA_OSSTREAM strm; strm << "Unknown FileTransfer operator " << "(FileTransfer entry: '" << spec << "')."; SAGA_ADAPTOR_THROW_NO_CONTEXT(SAGA_OSSTREAM_GETSTRING(strm), saga::BadParameter); } break; } return p; }
saga::url filesystem_adaptor::translate_back (const saga::session & s, const saga::url & u) { std::string err; // std::cout << " mounted_.size(): trans 1 " << mounted_.size () << std::endl; std::map <std::string, TR1::shared_ptr <sshfs> > :: iterator begin = mounted_.begin (); std::map <std::string, TR1::shared_ptr <sshfs> > :: iterator end = mounted_.end (); std::map <std::string, TR1::shared_ptr <sshfs> > :: iterator it; for ( it = begin; it != end; it++ ) { try { // std::cout << " mounted_.size(): trans 2 " << mounted_.size () << std::endl; return (*it).second->translate_back (u); } catch ( const saga::exception & e ) { // try next one // std::cout << " mounted_.size(): trans 3 " << mounted_.size () << std::endl; err += e.get_message (); continue; } } // std::cout << " mounted_.size(): trans 4 " << mounted_.size () << std::endl; // could not translate back it seems - throw SAGA_ADAPTOR_THROW_NO_CONTEXT ((std::string ("Cannot handle URL 3: ") + err).c_str (), saga::BadParameter); // keep compiler happy return ""; }
/////////////////////////////////////////////////////////////////////////////// // // init() is called whenever the cpi's instance data have changed. In that // case, it re-initializes the proxy directory instance which points into the // locally mounted sshfs name spaces, or into the local file system in // general. // // init() will generally throw if the idata->location points elsewhere. // init() is however assumed to be atomic, so it either succeeds, or it fails // but then leaves the object state unchanged. That way, the individual // methods don't need to attempt to recover from a failed init. The only side // effect can be an additionally mounted sshfs, which is getting cleaned up by // the adaptor d'tor (that cleanup is optional though). // // The single argument, the url 'save', is used to restore state on failure // void dir_cpi_impl::init (void) { adaptor_instance_data_t adata (this); directory_instance_data_t idata (this); if ( idata->location_.get_scheme () != "ssh" && idata->location_.get_scheme () != "any" ) { SAGA_LOG_DEBUG ("sshfs can not handle url:"); SAGA_LOG_DEBUG (idata->location_.get_string ().c_str ()); std::stringstream ss; ss << "Cannot handle URL scheme " << idata->location_.get_scheme () << " - can only handle schemas 'ssh' or 'any'." << std::endl; SAGA_ADAPTOR_THROW_NO_CONTEXT (ss.str ().c_str (), saga::adaptors::AdaptorDeclined); } // create a new api object from the changed instance data. try { d_ = saga::filesystem::directory (adata->strip_session (s_), adata->try_translate (s_, idata->location_), idata->mode_); } catch ( const saga:: exception & e ) { std::stringstream ss; ss << "Cannot handle URL: \n\t" << e.what () << "\n"; SSH_ADAPTOR_RETHROW (e, ss.str ().c_str (), saga::BadParameter); } }
TR1::shared_ptr <sshfs> filesystem_adaptor::get_sshfs (const saga::session & s, const saga::url & u) { // only mount anything if the URL is ssh (or any) based if ( u.get_scheme () != "ssh" && u.get_scheme () != "any" ) { SAGA_ADAPTOR_THROW_NO_CONTEXT ("Cannot mount sshfs for non-ssh urls", saga::BadParameter); } return mount_sshfs (s, u); }
void dir_cpi_impl::set_dir_name () { // can we handle this type of URL ? if ( location.get_scheme () != "any" && location.get_scheme () != "sector" && !location.get_scheme().empty() ) { SAGA_LOG_DEBUG (location.get_string ().c_str ()); SAGA_ADAPTOR_THROW_NO_CONTEXT ("Cannot handle URL schema", saga::BadParameter); } resolve( location, dir_ ) ; }
////////////////////////////////////////////////////////////////////// // get exit state by tracejob through ssh // --- parse the results of "ssh server_host tracejob jobid" // std::string ssh::tracejob_get_exit_state(std::string id, std::string svr_name, std::ostringstream& os) { std::string ret_val(""); try { bp::command_line cl(command); cl.argument(svr_name); cl.argument("tracejob"); cl.argument(id); bp::launcher l; l.set_stdout_behavior(bp::redirect_stream); l.set_stderr_behavior(bp::redirect_stream); bp::child c = l.start(cl); bp::pistream& stdout = c.get_stdout(); // Find Exit_status std::string exit_state; boost::regex r("(Exit_status=)(\\d+)"); boost::smatch results; std::string line; while ( std::getline(stdout, line)) { boost::regex_search(line, results, r); if (!results.str().empty()){ exit_state = results.str(2); } } stdout.close(); bp::status s = c.wait(); if (s.exited() && s.exit_status() == EXIT_SUCCESS) { //std::cout << "exit_state = " << exit_state << std::endl; ret_val = exit_state; } else { //std::cout << "exit_state is empty..." << exit_state << std::endl; error_handling(c.get_stderr(), os); ret_val = ""; } } catch(std::exception const &e) { SAGA_ADAPTOR_THROW_NO_CONTEXT(e.what(), saga::NoSuccess); } return ret_val; }
////////////////////////////////////////////////////////////////////// // get PBS Job full status (qstat -f job_id) // jobstat_ptr qstat::get_full_status(std::string id, std::ostringstream& os) { //bp::command_line cl(command, command, path); jobstat_ptr ret_val; try { bp::command_line cl(command); cl.argument("-f"); // cl.argument("@nrg04.cc.kek.jp"); cl.argument(id); bp::launcher l; l.set_stdout_behavior(bp::redirect_stream); l.set_stderr_behavior(bp::redirect_stream); bp::child c = l.start(cl); bp::pistream& stdout = c.get_stdout(); // if(!stdout){ // std::cout << "pistream is empty" << std::endl; // } jobstat_ptr fullstat = builder.create(stdout); stdout.close(); bp::status s = c.wait(); if (s.exited() && s.exit_status() == EXIT_SUCCESS) { ret_val = fullstat; } else { error_handling(c.get_stderr(), os); jobstat_ptr empty_data; ret_val = empty_data; } } catch(std::exception const &e) { SAGA_ADAPTOR_THROW_NO_CONTEXT(e.what(), saga::NoSuccess); } return ret_val; }
sshfs_t filesystem_adaptor::mount_sshfs (const saga::session & s, const saga::url & u ) { saga::url tgt = u; // if url is any:// based, convert to ssh:// as expected by sshfs if ( tgt.get_scheme () == "any" ) { tgt.set_scheme ("ssh"); } std::string id = get_sshfs_id (tgt); // std::cout << " mounted_ mount : " << this << std::endl; // std::cout << " mounted_.size() mount 1: " << mounted_.size () << std::endl; // std::cout << " tested__.size() mount 1: " << tested__.size () << std::endl; // check if we have that mounted already if ( mounted_.find (id) != mounted_.end () ) { // make sure the fs is mounted mounted_[id]->mount (); return mounted_[id]; } // is not mounted, yet - try to mount it, store a new shared pointer, and // return it. SAGA_LOG_ALWAYS ("to mount new sshfs"); SAGA_LOG_ALWAYS (id.c_str ()); SAGA_LOG_ALWAYS (tgt.get_string ().c_str ()); TR1::shared_ptr <sshfs> ptr; try { ptr.reset (new sshfs (ini_, s, tgt)); } catch ( const saga::exception & e ) { SAGA_LOG_ERROR (e.what ()); std::stringstream ss; ss << "Could not mount sshfs for " << tgt << " : \n " << e.what () << std::endl; SAGA_ADAPTOR_THROW_NO_CONTEXT (ss.str ().c_str (), saga::BadParameter); } if ( ! ptr ) { // cannot mount the fs for some reason - throw a BadParameter SAGA_ADAPTOR_THROW_NO_CONTEXT ("sshfs mount failed for unknown reason", saga::NoSuccess); } // std::cout << " mounted_.size() mount 2: " << mounted_.size () << std::endl; // std::cout << " tested__.size() mount 2: " << tested__.size () << std::endl; // got the fs mounted - register it, and return the ptr mounted_[id] = ptr; tested__[id] = 1; SAGA_LOG_ALWAYS ("register mounted sshfs"); SAGA_LOG_ALWAYS (id.c_str ()); // std::cout << " === register mounted sshfs: " << id << std::endl; // std::cout << " mounted_.size() mount 3: " << mounted_.size () << std::endl; // std::cout << " tested__.size() mount 3: " << tested__.size () << std::endl; return ptr; }
////////////////////////////////////////////////////////////////////// // get PBS state (qstat job_id) // bool qstat::get_state(std::string id, std::string& pbs_state, std::ostringstream& os) { //bp::command_line cl(command, command, path); bool ret_val; try { bp::command_line cl(command); cl.argument(id); bp::launcher l; l.set_stdout_behavior(bp::redirect_stream); l.set_stderr_behavior(bp::redirect_stream); bp::child c = l.start(cl); bp::pistream& stdout = c.get_stdout(); if (!check_header(stdout)) { // TODO exception ? stdout.close(); ret_val = false; } // no list -- status deleted ? if (stdout.eof()) { pbs_state = "?"; // TODO stdout.close(); ret_val = true; } parser.reset(RE_QSTAT); std::vector<std::string> matched; std::string line; // TODO while ? if (std::getline(stdout, line)) { stdout.close(); if (parser.parse_line(line, matched)) { pbs_state = matched[7]; } else { // parse failed. // TODO exception ? ret_val = false; } } else { // read failed. stdout.close(); // TODO exception ? ret_val = false; } bp::status s = c.wait(); if (s.exited() && s.exit_status() == EXIT_SUCCESS) { ret_val = pbs_state.empty() ? false : true; } else { error_handling(c.get_stderr(), os); ret_val = false; } } catch(std::exception const &e) { SAGA_ADAPTOR_THROW_NO_CONTEXT(e.what(), saga::NoSuccess); } return ret_val; }
/////////////////////////////////////////////////////////////////////////////// // // init() is called whenever the cpi's instance data have changed. In that // case, it re-initializes the proxy directory instance which points into the // locally mounted sshfs name spaces, or into the local file system in // general. // // init() will generally throw if the idata->location points elsewhere. // init() is however assumed to be atomic, so it either succeeds, or it fails // but then leaves the object state unchanged. That way, the individual // methods don't need to attempt to recover from a failed init. The only side // effect can be an additionally mounted sshfs, which is getting cleaned up by // the adaptor d'tor (that cleanup is optional though). // // The single argument, the url 'save', is used to restore state on failure // void file_cpi_impl::init (void) { adaptor_instance_data_t adata (this); file_instance_data_t idata (this); if ( idata->location_.get_scheme () != "ssh" && idata->location_.get_scheme () != "any" ) { SAGA_LOG_DEBUG ("sshfs can not handle url:"); SAGA_LOG_DEBUG (idata->location_.get_string ().c_str ()); std::stringstream ss; ss << "Cannot handle URL scheme " << idata->location_.get_scheme () << " - can only handle schemas 'ssh' or 'any'." << std::endl; SAGA_ADAPTOR_THROW_NO_CONTEXT (ss.str ().c_str (), saga::adaptors::AdaptorDeclined); } // create a new api object from the changed instance data. bool success = false; saga::exception ex ("", saga::NoSuccess); saga::url new_url; try { new_url = adata->translate (s_, idata->location_); success = true; } catch ( const saga::exception & e ) { ex = e; } if ( success ) { try { f_ = saga::filesystem::file (adata->strip_session (s_), new_url, idata->mode_); } catch ( const saga::exception & e ) { std::stringstream ss; ss << "Cannot handle URL 5: \n\t" << e.what () << "\n"; SSH_ADAPTOR_RETHROW (e, ss.str ().c_str (), saga::BadParameter); } } else { try { new_url = adata->translate (s_, idata->location_); f_ = saga::filesystem::file (adata->strip_session (s_), new_url, idata->mode_); } catch ( const saga::exception & e ) { // FIXME: shouldn't we merge e and ex? std::stringstream ss; ss << "Cannot handle URL 6: \n\t" << ex.what () << "\n"; SSH_ADAPTOR_RETHROW (ex, ss.str ().c_str (), saga::BadParameter); } } }