From b082390e1950e8b41a09de8428e6044d18ba0a67 Mon Sep 17 00:00:00 2001 From: Stuart Douglas Date: Thu, 17 Jun 2021 15:09:21 +1000 Subject: [PATCH] Add the ability to re-use an existing native build This allows you to deploy something you have already built. --- .../java/io/quarkus/deployment/pkg/NativeConfig.java | 11 +++++++++++ .../deployment/pkg/steps/NativeImageBuildStep.java | 12 ++++++++++-- docs/src/main/asciidoc/container-image.adoc | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java index 7717fd5d137e1..d7faf57b3842f 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/NativeConfig.java @@ -229,6 +229,17 @@ public class NativeConfig { @ConfigItem public boolean reportErrorsAtRuntime; + /** + * Don't build a native image if it already exists. + * + * This is useful if you have already built an image and you want to use Quarkus to deploy it somewhere. + * + * Note that this is not able to detect if the existing image is outdated, if you have modified source + * or config and want a new image you must not use this flag. + */ + @ConfigItem(defaultValue = "false") + public boolean reuseExisting; + /** * Build time configuration options for resources inclusion in the native executable. */ diff --git a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java index f7f4b2bb6b95c..ab0508cd11c3a 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/NativeImageBuildStep.java @@ -149,6 +149,8 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa String nativeImageName = getNativeImageName(outputTargetBuildItem, packageConfig); String resultingExecutableName = getResultingExecutableName(nativeImageName, isContainerBuild); + Path generatedExecutablePath = outputDir.resolve(resultingExecutableName); + Path finalExecutablePath = outputTargetBuildItem.getOutputDirectory().resolve(resultingExecutableName); NativeImageBuildRunner buildRunner = getNativeImageBuildRunner(nativeConfig, outputDir, nativeImageName, resultingExecutableName); @@ -160,6 +162,14 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa } else { log.error("Unable to get GraalVM version from the native-image binary."); } + if (nativeConfig.reuseExisting) { + if (Files.exists(finalExecutablePath)) { + return new NativeImageBuildItem(finalExecutablePath, + new NativeImageBuildItem.GraalVMVersion(graalVMVersion.fullVersion, graalVMVersion.major, + graalVMVersion.minor, + graalVMVersion.distribution.name())); + } + } try { if (nativeConfig.cleanupServer) { @@ -189,8 +199,6 @@ public NativeImageBuildItem build(NativeConfig nativeConfig, NativeImageSourceJa if (exitCode != 0) { throw imageGenerationFailed(exitCode, nativeImageArgs); } - Path generatedExecutablePath = outputDir.resolve(resultingExecutableName); - Path finalExecutablePath = outputTargetBuildItem.getOutputDirectory().resolve(resultingExecutableName); IoUtils.copy(generatedExecutablePath, finalExecutablePath); Files.delete(generatedExecutablePath); if (nativeConfig.debug.enabled) { diff --git a/docs/src/main/asciidoc/container-image.adoc b/docs/src/main/asciidoc/container-image.adoc index 6691068a46159..0cfc429603571 100644 --- a/docs/src/main/asciidoc/container-image.adoc +++ b/docs/src/main/asciidoc/container-image.adoc @@ -106,6 +106,8 @@ To build a container image for your project, `quarkus.container-image.build=true ./mvnw clean package -Dquarkus.container-image.build=true ---- +NOTE: If you ever want to build a native container image and already have an existing native image you can set `-Dquarkus.native.reuse-existing=true` and the native image build will not be re-run. + == Pushing To push a container image for your project, `quarkus.container-image.push=true` needs to be set using any of the ways that Quarkus supports.