Skip to content

Commit

Permalink
NativeImageBuildRunner: Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
zakkak committed Feb 24, 2021
1 parent ea2159f commit 63fec3d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import java.util.List;
import java.util.stream.Stream;

import io.quarkus.deployment.util.ProcessUtil;

public class NativeImageBuildLocalRunner extends NativeImageBuildRunner {

private final String nativeImageExecutable;
Expand All @@ -17,10 +15,8 @@ public NativeImageBuildLocalRunner(String nativeImageExecutable) {

@Override
public void cleanupServer(File outputDir, boolean processInheritIODisabled) throws InterruptedException, IOException {
final ProcessBuilder pb = new ProcessBuilder(nativeImageExecutable, "--server-shutdown");
pb.directory(outputDir);
final Process process = ProcessUtil.launchProcess(pb, processInheritIODisabled);
process.waitFor();
final String[] cleanupCommand = { nativeImageExecutable, "--server-shutdown" };
runCommand(cleanupCommand, null, outputDir);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ protected void preBuild(List<String> buildArgs) throws InterruptedException, IOE
String[] createContainerCommand = buildCommand("create", containerRuntimeArgs, buildArgs);
log.info(String.join(" ", createContainerCommand).replace("$", "\\$"));
Process createContainerProcess = new ProcessBuilder(createContainerCommand).start();
createContainerProcess.waitFor();
if (createContainerProcess.waitFor() != 0) {
throw new RuntimeException("Failed to create builder container.");
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(createContainerProcess.getInputStream()))) {
containerId = reader.readLine();
}
String[] copyCommand = new String[] { containerRuntime.getExecutableName(), "cp", outputPath + "/.",
containerId + ":" + NativeImageBuildStep.CONTAINER_BUILD_VOLUME_PATH };
log.info(String.join(" ", copyCommand).replace("$", "\\$"));
Process copyProcess = new ProcessBuilder(copyCommand).start();
copyProcess.waitFor();
runCommand(copyCommand, "Failed to copy source-jar and libs from host to builder container", null);
super.preBuild(buildArgs);
}

Expand All @@ -47,22 +47,18 @@ protected String[] getBuildCommand(List<String> args) {

@Override
protected void postBuild() throws InterruptedException, IOException {
copy(nativeImageName);
copyFromBuilder(nativeImageName, "Failed to copy native image from container back to the host.");
if (nativeConfig.debug.enabled) {
copy("sources");
copyFromBuilder("sources", "Failed to copy sources from container back to the host.");
}
String[] removeCommand = new String[] { containerRuntime.getExecutableName(), "container", "rm", "--volumes",
containerId };
log.info(String.join(" ", removeCommand).replace("$", "\\$"));
Process removeProcess = new ProcessBuilder(removeCommand).start();
removeProcess.waitFor();
runCommand(removeCommand, "Failed to remove container: " + containerId, null);
}

private void copy(String path) throws IOException, InterruptedException {
private void copyFromBuilder(String path, String errorMsg) throws IOException, InterruptedException {
String[] copyCommand = new String[] { containerRuntime.getExecutableName(), "cp",
containerId + ":" + NativeImageBuildStep.CONTAINER_BUILD_VOLUME_PATH + "/" + path, outputPath };
log.info(String.join(" ", copyCommand).replace("$", "\\$"));
Process copyProcess = new ProcessBuilder(copyCommand).start();
copyProcess.waitFor();
runCommand(copyCommand, errorMsg, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public GraalVM.Version getGraalVMVersion() {
final GraalVM.Version graalVMVersion;
try {
String[] versionCommand = getGraalVMVersionCommand(Collections.singletonList("--version"));
log.debugf(String.join(" ", versionCommand).replace("$", "\\$"));
Process versionProcess = new ProcessBuilder(versionCommand)
.redirectErrorStream(true)
.start();
Expand Down Expand Up @@ -76,4 +77,41 @@ protected void preBuild(List<String> buildArgs) throws IOException, InterruptedE
protected void postBuild() throws InterruptedException, IOException {
}

/**
* Run {@code command} in {@code workingDirectory} and log error if {@code errorMsg} is not null.
*
* @param command The command to run
* @param errorMsg The error message to be printed in case of failure.
* If {@code null} the failure is ignored, but logged.
* @param workingDirectory The directory in which to run the command
*/
void runCommand(String[] command, String errorMsg, File workingDirectory) {
log.info(String.join(" ", command).replace("$", "\\$"));
Process process = null;
try {
final ProcessBuilder processBuilder = new ProcessBuilder(command);
if (workingDirectory != null) {
processBuilder.directory(workingDirectory);
}
process = processBuilder.start();
final int exitCode = process.waitFor();
if (exitCode != 0) {
if (errorMsg != null) {
log.error(errorMsg);
} else {
log.debugf("Command: " + String.join(" ", command) + " failed with exit code " + exitCode);
}
}
} catch (IOException | InterruptedException e) {
if (errorMsg != null) {
log.error(errorMsg);
} else {
log.debugf(e, "Command: " + String.join(" ", command) + " failed.");
}
} finally {
if (process != null) {
process.destroy();
}
}
}
}

0 comments on commit 63fec3d

Please sign in to comment.