in genie-agent/src/main/java/com/netflix/genie/agent/execution/process/impl/JobProcessManagerImpl.java [87:164]
public void launchProcess(
final File jobDirectory,
final File jobScript,
final boolean interactive,
@Nullable final Integer timeout,
final boolean launchInJobDirectory
) throws JobLaunchException {
if (!this.launched.compareAndSet(false, true)) {
throw new IllegalStateException("Job already launched");
}
this.isInteractiveMode = interactive;
final ProcessBuilder processBuilder = new ProcessBuilder();
// Validate job running directory
if (jobDirectory == null) {
throw new JobLaunchException("Job directory is null");
} else if (!jobDirectory.exists()) {
throw new JobLaunchException("Job directory does not exist: " + jobDirectory);
} else if (!jobDirectory.isDirectory()) {
throw new JobLaunchException("Job directory is not a directory: " + jobDirectory);
} else if (!jobDirectory.canWrite()) {
throw new JobLaunchException("Job directory is not writable: " + jobDirectory);
}
if (jobScript == null) {
throw new JobLaunchException("Job script is null");
} else if (!jobScript.exists() || !jobScript.isFile()) {
throw new JobLaunchException("Job script is not a valid file");
} else if (!jobScript.canExecute()) {
throw new JobLaunchException("Job script is not executable");
}
this.initFailedFileRef.set(PathUtils.jobSetupErrorMarkerFilePath(jobDirectory).toFile());
log.info("Executing job script: {} (working directory: {})",
jobScript.getAbsolutePath(),
launchInJobDirectory ? jobDirectory : Paths.get("").toAbsolutePath().normalize().toString());
processBuilder.command(jobScript.getAbsolutePath());
if (launchInJobDirectory) {
processBuilder.directory(jobDirectory);
}
if (interactive) {
processBuilder.inheritIO();
} else {
processBuilder.redirectError(PathUtils.jobStdErrPath(jobDirectory).toFile());
processBuilder.redirectOutput(PathUtils.jobStdOutPath(jobDirectory).toFile());
}
final Span currentSpan = this.tracer.currentSpan();
if (currentSpan != null) {
processBuilder.environment().putAll(this.tracePropagator.injectForJob(currentSpan.context()));
}
if (this.killed.get()) {
log.info("Job aborted, skipping launch");
return;
}
log.info("Launching job");
try {
this.processReference.set(processBuilder.start());
if (timeout != null) {
// NOTE: There is a chance of a SLIGHT delay here between the process launch and the timeout
final Instant timeoutInstant = Instant.now().plusSeconds(timeout);
this.timeoutKillThread.set(
this.taskScheduler.schedule(new TimeoutKiller(this), timeoutInstant)
);
log.info("Scheduled timeout kill to occur {} second(s) from now at {}", timeout, timeoutInstant);
}
} catch (IOException | SecurityException e) {
throw new JobLaunchException("Failed to launch job: ", e);
}
log.info("Process launched (pid: {})", this.getPid(this.processReference.get()));
}