int do_command_upload_sandbox(void *arg, Stream*) { dprintf(D_ALWAYS, "FTGAHP: upload sandbox\n"); Gahp_Args args; parse_gahp_command ((char*)arg, &args); // first two args: result id and sandbox id: std::string rid = args.argv[1]; std::string sid = args.argv[2]; // third arg: job ad ClassAd ad; classad::ClassAdParser my_parser; if (!(my_parser.ParseClassAd(args.argv[3], ad))) { // FAIL write_to_pipe( ChildErrorPipe, "Failed to parse job ad" ); return 1; } // rewrite the IWD to the actual sandbox dir std::string iwd; define_sandbox_path(sid, iwd); ad.Assign(ATTR_JOB_IWD, iwd.c_str()); char ATTR_SANDBOX_ID[] = "SandboxId"; ad.Assign(ATTR_SANDBOX_ID, sid.c_str()); // directory was created, let's set up the FileTransfer object FileTransfer ft; if (!ft.Init(&ad)) { // FAIL write_to_pipe( ChildErrorPipe, "Failed to initialize FileTransfer" ); return 1; } // lookup ATTR_VERSION and set it. this changes the wire // protocol and it is important that this happens before // calling UploadFiles. char* peer_version = NULL; ad.LookupString(ATTR_VERSION, &peer_version); ft.setPeerVersion(peer_version); free (peer_version); dprintf(D_ALWAYS, "BOSCO: calling upload files\n"); // the "true" param to UploadFiles here means blocking (i.e. "in the foreground") if (!ft.UploadFiles(true)) { // FAIL write_to_pipe( ChildErrorPipe, ft.GetInfo().error_desc.Value() ); return 1; } // SUCCEED return 0; }
bool create_sandbox_dir(std::string sid, std::string &iwd) { define_sandbox_path(sid, iwd); dprintf(D_ALWAYS, "BOSCO: create, sandbox path: %s\n", iwd.c_str()); // who are we? need to change priv? if (mkdir_and_parents_if_needed(iwd.c_str(), 0700)) { return true; } else { return false; } }
// IT IS legitimate for the command DESTROY_SANDBOX to happen while a file // transfer is currently happening. so, tear it down properly to avoid any // memory leaks. this means looking it up in our map, which should be O(1), // and then removing the actual filesystem portion. bool destroy_sandbox(std::string sid, std::string &err) { dprintf(D_ALWAYS, "BOSCO: destroy, sandbox id: %s\n", sid.c_str()); std::string iwd; define_sandbox_path(sid, iwd); dprintf(D_ALWAYS, "BOSCO: destroy, sandbox path: %s\n", iwd.c_str()); // remove (rm -rf) the sandbox dir char *buff = condor_dirname( iwd.c_str() ); std::string parent_dir = buff; free( buff ); buff = condor_dirname( parent_dir.c_str() ); std::string gparent_dir = buff; free( buff ); dprintf( D_FULLDEBUG, "parent_dir: %s\n", parent_dir.c_str() ); dprintf( D_FULLDEBUG, "gparent_dir: %s\n", gparent_dir.c_str() ); Directory d( parent_dir.c_str() ); if ( !d.Remove_Full_Path( iwd.c_str() ) ) { dprintf(D_ALWAYS, "Failed to remove %s\n", iwd.c_str()); // TODO Should we return failure? } d.Rewind(); if ( d.Next() == NULL ) { dprintf(D_FULLDEBUG, "Removing empty directory %s\n", parent_dir.c_str()); Directory d2( gparent_dir.c_str() ); if ( !d2.Remove_Full_Path( parent_dir.c_str() ) ) { dprintf(D_ALWAYS, "Failed to remove %s\n", parent_dir.c_str()); // TODO Should we return failure? } d2.Rewind(); if ( d2.Next() == NULL ) { dprintf(D_FULLDEBUG, "Removing empty directory %s\n", gparent_dir.c_str()); if ( !d2.Remove_Full_Path( gparent_dir.c_str() ) ) { dprintf(D_ALWAYS, "Failed to remove %s\n", gparent_dir.c_str()); // TODO Should we return failure? } } } err = "NULL"; return true; }
int download_sandbox_reaper(Service*, int pid, int status) { // map pid to the SandboxEnt stucture we have recorded SandboxMap::iterator i; i = sandbox_map.find(pid); SandboxEnt e = i->second; if (status == 0) { std::string path; define_sandbox_path(e.sandbox_id, path); const char * res[2] = { "NULL", path.c_str() }; enqueue_result(e.request_id, res, 2); } else { char *err_msg = NULL; read_from_pipe( e.error_pipe, &err_msg ); if ( err_msg == NULL || err_msg[0] == '\0' ) { free( err_msg ); err_msg = strdup( "Worker thread failed" ); } const char * res[2] = { err_msg, "NULL" }; enqueue_result(e.request_id, res, 2); free( err_msg ); } close( e.error_pipe ); // remove from the map sandbox_map.erase(pid); return 0; }
int do_command_upload_sandbox(void *arg, Stream*) { dprintf(D_ALWAYS, "FTGAHP: upload sandbox\n"); Gahp_Args args; parse_gahp_command ((char*)arg, &args); // first two args: result id and sandbox id: std::string rid = args.argv[1]; std::string sid = args.argv[2]; // third arg: job ad ClassAd ad; classad::ClassAdParser my_parser; if (!(my_parser.ParseClassAd(args.argv[3], ad))) { // FAIL write_to_pipe( ChildErrorPipe, "Failed to parse job ad" ); return 1; } // rewrite the IWD to the actual sandbox dir std::string iwd; define_sandbox_path(sid, iwd); ad.Assign(ATTR_JOB_IWD, iwd.c_str()); char ATTR_SANDBOX_ID[] = "SandboxId"; ad.Assign(ATTR_SANDBOX_ID, sid.c_str()); // directory was created, let's set up the FileTransfer object FileTransfer ft; if (!ft.Init(&ad)) { // FAIL write_to_pipe( ChildErrorPipe, "Failed to initialize FileTransfer" ); return 1; } // Set the Condor version of our peer, as given by the CONDOR_VERSION // command. // If we don't have a version, then assume it's pre-8.1.0. // In 8.1, the file transfer protocol changed and we added // the CONDOR_VERSION command. if ( !peer_condor_version.empty() ) { ft.setPeerVersion( peer_condor_version.c_str() ); } else { CondorVersionInfo ver( 8, 0, 0 ); ft.setPeerVersion( ver ); } if ( !sec_session_id.empty() ) { ft.setSecuritySession( sec_session_id.c_str() ); } dprintf(D_ALWAYS, "BOSCO: calling upload files\n"); // the "true" param to UploadFiles here means blocking (i.e. "in the foreground") if (!ft.UploadFiles(true)) { // FAIL write_to_pipe( ChildErrorPipe, ft.GetInfo().error_desc.Value() ); return 1; } // SUCCEED return 0; }