int request_pipe_handler(Service*, int) { std::string* next_line; while ((next_line = request_buffer.GetNextLine()) != NULL) { dprintf (D_FULLDEBUG, "got work request: %s\n", next_line->c_str()); Gahp_Args args; // Parse the command... if (!(parse_gahp_command (next_line->c_str(), &args) && handle_gahp_command (args.argv, args.argc))) { dprintf (D_ALWAYS, "ERROR processing %s\n", next_line->c_str()); } // Clean up... delete next_line; } // check for an error in GetNextLine if (request_buffer.IsError() || request_buffer.IsEOF()) { dprintf (D_ALWAYS, "Request pipe closed. Exiting...\n"); DC_Exit (1); } return TRUE; }
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; }
int do_command_destroy_sandbox(void *arg, Stream*) { dprintf(D_ALWAYS, "FTGAHP: destroy 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]; std::string err; if(!destroy_sandbox(sid, err)) { // FAIL dprintf( D_ALWAYS, "BOSCO: destroy_sandbox error: %s\n", err.c_str()); write_to_pipe( ChildErrorPipe, err.c_str() ); return 1; } // SUCCEED return 0; }
int IOProcess::stdinPipeHandler() { char command[131072]; while( m_stdin_buffer.GetNextLine( command, sizeof( command ) ) ) { dprintf (D_FULLDEBUG, "got stdin: '%s'\n", command); Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print each result line // Print number of results printf("%s %d\n", GAHP_RESULT_SUCCESS, numOfResult()); fflush(stdout); startResultIteration(); char* next = NULL; while ((next = NextResult()) != NULL) { printf ("%s", next); fflush(stdout); deleteCurrentResult(); } m_new_results_signaled = false; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); io_process_exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { m_async_mode = true; m_new_results_signaled = false; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { m_async_mode = false; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_STATISTICS) == 0) { printf( "%s %d %d %d %d\n", GAHP_RESULT_SUCCESS, NumRequests, NumDistinctRequests, NumRequestsExceedingLimit, NumExpiredSignatures ); fflush( stdout ); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { StringList amazon_commands; int num_commands = 0; num_commands = allAmazonCommands(amazon_commands); num_commands += 7; const char *commands[num_commands]; int i = 0; commands[i++] = GAHP_RESULT_SUCCESS; commands[i++] = GAHP_COMMAND_ASYNC_MODE_ON; commands[i++] = GAHP_COMMAND_ASYNC_MODE_OFF; commands[i++] = GAHP_COMMAND_RESULTS; commands[i++] = GAHP_COMMAND_QUIT; commands[i++] = GAHP_COMMAND_VERSION; commands[i++] = GAHP_COMMAND_COMMANDS; amazon_commands.rewind(); char *one_amazon_command = NULL; while( (one_amazon_command = amazon_commands.next() ) != NULL ) { commands[i++] = one_amazon_command; } gahp_output_return (commands, i); } else { // got new command if( !addNewRequest(command) ) { gahp_output_return_error(); } else { gahp_output_return_success(); } } } else { gahp_output_return_error(); } } // check if GetNextLine() returned NULL because of an error or EOF if (m_stdin_buffer.IsError() || m_stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); io_process_exit(1); } return TRUE; }
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; }
int stdin_pipe_handler(Service*, int) { std::string* line; while ((line = stdin_buffer.GetNextLine()) != NULL) { const char * command = line->c_str(); // CREATE_CONDOR_SECURITY_SESSION contains sensitive data that // normally shouldn't be written to a publically-readable log. // We should conceal it unless GAHP_DEBUG_HIDE_SENSITIVE_DATA // says not to. if ( param_boolean( "GAHP_DEBUG_HIDE_SENSITIVE_DATA", true ) && strncmp( command, GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION, strlen( GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION ) ) == 0 ) { dprintf( D_ALWAYS, "got stdin: %s XXXXXXXX\n", GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION ); } else { dprintf (D_ALWAYS, "got stdin: %s\n", command); } Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print number of results std::string rn_buff; formatstr( rn_buff, "%d", result_list.number() ); const char * commands [] = { GAHP_RESULT_SUCCESS, rn_buff.c_str() }; gahp_output_return (commands, 2); // Print each result line char * next; result_list.rewind(); while ((next = result_list.next()) != NULL) { printf ("%s\n", next); fflush(stdout); dprintf(D_FULLDEBUG,"put stdout: %s\n",next); result_list.deleteCurrent(); } new_results_signaled = FALSE; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); dprintf(D_FULLDEBUG,"put stdout: S %s\n",version); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); DC_Exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { async_mode = TRUE; new_results_signaled = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { async_mode = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); return 0; // exit } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { const char * commands [] = { GAHP_RESULT_SUCCESS, GAHP_COMMAND_DOWNLOAD_SANDBOX, GAHP_COMMAND_UPLOAD_SANDBOX, GAHP_COMMAND_DESTROY_SANDBOX, GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION, GAHP_COMMAND_CONDOR_VERSION, GAHP_COMMAND_ASYNC_MODE_ON, GAHP_COMMAND_ASYNC_MODE_OFF, GAHP_COMMAND_RESULTS, GAHP_COMMAND_QUIT, GAHP_COMMAND_VERSION, GAHP_COMMAND_COMMANDS}; gahp_output_return (commands, 12); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_CREATE_CONDOR_SECURITY_SESSION) == 0) { ClaimIdParser claimid( args.argv[1] ); if ( !daemonCore->getSecMan()->CreateNonNegotiatedSecuritySession( DAEMON, claimid.secSessionId(), claimid.secSessionKey(), claimid.secSessionInfo(), CONDOR_PARENT_FQU, NULL, 0 ) ) { gahp_output_return_error(); } else { sec_session_id = claimid.secSessionId(); gahp_output_return_success(); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_CONDOR_VERSION) == 0) { peer_condor_version = args.argv[1]; const char *reply [] = { GAHP_RESULT_SUCCESS, escapeGahpString( CondorVersion() ) }; gahp_output_return( reply, 2 ); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DOWNLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_download_sandbox, (void*)strdup(command), NULL, download_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created download_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[2] = { "Worker thread failed", "NULL" }; enqueue_result(args.argv[1], res, 2); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_UPLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_upload_sandbox, (void*)strdup(command), NULL, upload_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created upload_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[1] = { "Worker thread failed" }; enqueue_result(args.argv[1], res, 1); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DESTROY_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_destroy_sandbox, (void*)strdup(command), NULL, destroy_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created destroy_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); const char * res[1] = { "Worker thread failed" }; enqueue_result(args.argv[1], res, 1); close( fds[0] ); } } else { // should never get here if verify does its job dprintf(D_ALWAYS, "FTGAHP: got bad command: %s\n", args.argv[0]); gahp_output_return_error(); } } else { gahp_output_return_error(); } delete line; } // check if GetNextLine() returned NULL because of an error or EOF if (stdin_buffer.IsError() || stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); DC_Exit (1); } return TRUE; }
int stdin_pipe_handler(Service*, int) { std::string* line; while ((line = stdin_buffer.GetNextLine()) != NULL) { const char * command = line->c_str(); dprintf (D_ALWAYS, "got stdin: %s\n", command); Gahp_Args args; if (parse_gahp_command (command, &args) && verify_gahp_command (args.argv, args.argc)) { // Catch "special commands first if (strcasecmp (args.argv[0], GAHP_COMMAND_RESULTS) == 0) { // Print number of results std::string rn_buff; formatstr( rn_buff, "%d", result_list.number() ); const char * commands [] = { GAHP_RESULT_SUCCESS, rn_buff.c_str() }; gahp_output_return (commands, 2); // Print each result line char * next; result_list.rewind(); while ((next = result_list.next()) != NULL) { printf ("%s\n", next); fflush(stdout); dprintf(D_FULLDEBUG,"put stdout: %s\n",next); result_list.deleteCurrent(); } new_results_signaled = FALSE; } else if (strcasecmp (args.argv[0], GAHP_COMMAND_VERSION) == 0) { printf ("S %s\n", version); fflush (stdout); dprintf(D_FULLDEBUG,"put stdout: S %s\n",version); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); DC_Exit(0); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_ON) == 0) { async_mode = TRUE; new_results_signaled = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_ASYNC_MODE_OFF) == 0) { async_mode = FALSE; gahp_output_return_success(); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_QUIT) == 0) { gahp_output_return_success(); return 0; // exit } else if (strcasecmp (args.argv[0], GAHP_COMMAND_COMMANDS) == 0) { const char * commands [] = { GAHP_RESULT_SUCCESS, GAHP_COMMAND_DOWNLOAD_SANDBOX, GAHP_COMMAND_UPLOAD_SANDBOX, GAHP_COMMAND_DESTROY_SANDBOX, GAHP_COMMAND_ASYNC_MODE_ON, GAHP_COMMAND_ASYNC_MODE_OFF, GAHP_COMMAND_RESULTS, GAHP_COMMAND_QUIT, GAHP_COMMAND_VERSION, GAHP_COMMAND_COMMANDS}; gahp_output_return (commands, 10); } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DOWNLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_download_sandbox, (void*)strdup(command), NULL, download_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created download_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_UPLOAD_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_upload_sandbox, (void*)strdup(command), NULL, upload_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created upload_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else if (strcasecmp (args.argv[0], GAHP_COMMAND_DESTROY_SANDBOX) == 0) { int fds[2]; if ( pipe( fds ) < 0 ) { EXCEPT( "Failed to create pipe!\n" ); } ChildErrorPipe = fds[1]; int tid = daemonCore->Create_Thread(do_command_destroy_sandbox, (void*)strdup(command), NULL, destroy_sandbox_reaper_id); close( fds[1] ); if( tid ) { dprintf (D_ALWAYS, "BOSCO: created destroy_sandbox thread, id: %i\n", tid); // this is a "success" in the sense that the gahp command was // well-formatted. whether or not the file transfer works or // not is not what we are reporting here. gahp_output_return_success(); SandboxEnt e; e.pid = tid; e.request_id = args.argv[1]; e.sandbox_id = args.argv[2]; e.error_pipe = fds[0]; // transfer started, record the entry in the map std::pair<int, struct SandboxEnt> p(tid, e); sandbox_map.insert(p); } else { dprintf (D_ALWAYS, "BOSCO: Create_Thread FAILED!\n"); gahp_output_return_success(); close( fds[0] ); } } else { // should never get here if verify does its job dprintf(D_ALWAYS, "FTGAHP: got bad command: %s\n", args.argv[0]); gahp_output_return_error(); } } else { gahp_output_return_error(); } delete line; } // check if GetNextLine() returned NULL because of an error or EOF if (stdin_buffer.IsError() || stdin_buffer.IsEOF()) { dprintf (D_ALWAYS, "stdin buffer closed, exiting\n"); DC_Exit (1); } return TRUE; }