Skip to content

Commit

Permalink
fix(quarkusio#7712): S2i build no longer renames artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
iocanel committed Mar 12, 2020
1 parent edec6a4 commit c224346
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.time.Duration;
import java.util.List;
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
Expand All @@ -12,6 +13,7 @@ public class S2iConfig {

public static final String DEFAULT_BASE_JVM_IMAGE = "fabric8/s2i-java:2.3";
public static final String DEFAULT_BASE_NATIVE_IMAGE = "quay.io/quarkus/ubi-quarkus-native-binary-s2i:19.3.0";
public static final String DEFAULT_NATIVE_TARGET_FILENAME = "application";

/**
* The base image to be used when a container image is being produced for the jar build
Expand All @@ -38,18 +40,32 @@ public class S2iConfig {
public List<String> nativeArguments;

/**
* The path to where the jar is added during the assemble phase.
* The directory where the jar is added during the assemble phase.
* This is dependant on the s2i image and should be supplied if a non default image is used.
*/
@ConfigItem(defaultValue = "/deployments/application${quarkus.package.runner-suffix}.jar")
public String jarPath;
@ConfigItem(defaultValue = "/deployments/")
public String jarDirectory;

/**
* The path to where the native binary is added during the assemble phase.
* This is dependant on the s2i image and should be supplied if a non default image is used.
* The resulting filename of the jar in the s2i image.
* This option may be used if the selected s2i image uses a fixed name for the jar.
*/
@ConfigItem
public Optional<String> jarFileName;

/**
* The directory where the native binary is added during the assemble phase.
* This is dependant on the s2i image and should be supplied if a non-default image is used.
*/
@ConfigItem(defaultValue = "/home/quarkus/")
public String nativeBinaryDirectory;

/**
* The resulting filename of the native binary in the s2i image.
* This option may be used if the selected s2i image uses a fixed name for the native binary.
*/
@ConfigItem(defaultValue = "/home/quarkus/application")
public String nativeBinaryPath;
@ConfigItem
public Optional<String> nativeBinaryFileName;

/**
* The build timeout.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@
public class S2iProcessor {

private static final String S2I = "s2i";
private static final String JAR_ARTIFACT_FORMAT = "%s%s.jar";
private static final String NATIVE_ARTIFACT_FORMAT = "%s%s";
private static final String BUILD_CONFIG_NAME = "openshift.io/build-config.name";
private static final String RUNNING = "Running";

Expand All @@ -77,18 +75,27 @@ public void s2iRequirementsJvm(S2iConfig s2iConfig,
CurateOutcomeBuildItem curateOutcomeBuildItem,
OutputTargetBuildItem out,
PackageConfig packageConfig,
JarBuildItem jarBuildItem,
BuildProducer<BaseImageInfoBuildItem> builderImageProducer,
BuildProducer<KubernetesCommandBuildItem> commandProducer) {

final List<AppDependency> appDeps = curateOutcomeBuildItem.getEffectiveModel().getUserDependencies();

String outputJarFileName = jarBuildItem.getPath().getFileName().toString();

String classpath = appDeps.stream()
.map(d -> Paths.get(s2iConfig.jarPath).getParent().resolve("lib")
.resolve(d.getArtifact().getGroupId() + "." + d.getArtifact().getPath().getFileName()).toAbsolutePath()
.map(d -> String.valueOf(d.getArtifact().getGroupId() + "." + d.getArtifact().getPath().getFileName()))
.map(s -> Paths.get(s2iConfig.jarDirectory).resolve("lib").resolve(s).toAbsolutePath()
.toString())
.collect(Collectors.joining(File.pathSeparator));

String jarFileName = s2iConfig.jarFileName.orElse(outputJarFileName);
String pathToJar = Paths.get(s2iConfig.jarDirectory).resolve(jarFileName)
.toAbsolutePath()
.toString();

List<String> args = new ArrayList<>();
args.addAll(Arrays.asList("-jar", s2iConfig.jarPath, "-cp", classpath));
args.addAll(Arrays.asList("-jar", pathToJar, "-cp", classpath));
args.addAll(s2iConfig.jvmArguments);

if (!s2iConfig.hasDefaultBaseJvmImage()) {
Expand All @@ -102,11 +109,30 @@ public void s2iRequirementsNative(S2iConfig s2iConfig,
CurateOutcomeBuildItem curateOutcomeBuildItem,
OutputTargetBuildItem out,
PackageConfig packageConfig,
NativeImageBuildItem nativeImage,
BuildProducer<BaseImageInfoBuildItem> builderImageProducer,
BuildProducer<KubernetesCommandBuildItem> commandProducer) {

boolean usingDefaultBuilder = ImageUtil.getRepository(S2iConfig.DEFAULT_BASE_NATIVE_IMAGE)
.equals(ImageUtil.getRepository(s2iConfig.baseNativeImage));
String outputNativeBinaryFileName = nativeImage.getPath().getFileName().toString();

String nativeBinaryFileName = null;

//The default s2i builder for native builds, renames the native binary.
//To make things easier for the user, we need to handle it.
if (usingDefaultBuilder && !s2iConfig.nativeBinaryFileName.isPresent()) {
nativeBinaryFileName = S2iConfig.DEFAULT_NATIVE_TARGET_FILENAME;
} else {
nativeBinaryFileName = s2iConfig.nativeBinaryFileName.orElse(outputNativeBinaryFileName);
}

String pathToNativeBinary = Paths.get(s2iConfig.nativeBinaryDirectory).resolve(nativeBinaryFileName)
.toAbsolutePath()
.toString();

builderImageProducer.produce(new BaseImageInfoBuildItem(s2iConfig.baseNativeImage));
commandProducer.produce(new KubernetesCommandBuildItem(s2iConfig.nativeBinaryPath,
commandProducer.produce(new KubernetesCommandBuildItem(pathToNativeBinary,
s2iConfig.nativeArguments.toArray(new String[s2iConfig.nativeArguments.size()])));
}

Expand Down Expand Up @@ -138,18 +164,7 @@ public void s2iBuildFromJar(S2iConfig s2iConfig, ContainerImageConfig containerI
.filter(r -> r.getName().endsWith("kubernetes/openshift.yml"))
.findFirst().orElseThrow(() -> new IllegalStateException("Could not find kubernetes/openshift.yml"));

Path artifactPath = out.getOutputDirectory()
.resolve(String.format(JAR_ARTIFACT_FORMAT, out.getBaseName(), packageConfig.runnerSuffix));
Path applicationJarPath = out.getOutputDirectory()
.resolve(String.format(JAR_ARTIFACT_FORMAT, "application", packageConfig.runnerSuffix));

try {
Files.copy(artifactPath, applicationJarPath, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
throw new RuntimeException("Error preparing the s2i build archive.", e);
}

createContainerImage(kubernetesClient, openshiftYml, s2iConfig, out.getOutputDirectory(), applicationJarPath,
createContainerImage(kubernetesClient, openshiftYml, s2iConfig, out.getOutputDirectory(), jar.getPath(),
out.getOutputDirectory().resolve("lib"));
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "jar-container", Collections.emptyMap()));
containerImageResultProducer.produce(
Expand All @@ -166,7 +181,7 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain
Optional<ContainerImagePushRequestBuildItem> pushRequest,
BuildProducer<ArtifactResultBuildItem> artifactResultProducer,
BuildProducer<ContainerImageResultBuildItem> containerImageResultProducer,
NativeImageBuildItem nativeImageBuildItem) {
NativeImageBuildItem nativeImage) {

if (!containerImageConfig.build && !containerImageConfig.push && !buildRequest.isPresent()
&& !pushRequest.isPresent()) {
Expand All @@ -184,21 +199,10 @@ public void s2iBuildFromNative(S2iConfig s2iConfig, ContainerImageConfig contain
.filter(r -> r.getName().endsWith("kubernetes/openshift.yml"))
.findFirst().orElseThrow(() -> new IllegalStateException("Could not find kubernetes/openshift.yml"));

Path artifactPath = out.getOutputDirectory()
.resolve(String.format(NATIVE_ARTIFACT_FORMAT, out.getBaseName(), packageConfig.runnerSuffix));
Path applicationImagePath = out.getOutputDirectory()
.resolve(String.format(NATIVE_ARTIFACT_FORMAT, "application", packageConfig.runnerSuffix));

try {
Files.copy(artifactPath, applicationImagePath, StandardCopyOption.REPLACE_EXISTING);
} catch (Exception e) {
throw new RuntimeException("Error preparing the s2i build archive.", e);
}

createContainerImage(kubernetesClient, openshiftYml, s2iConfig, out.getOutputDirectory(), applicationImagePath);
createContainerImage(kubernetesClient, openshiftYml, s2iConfig, out.getOutputDirectory(), nativeImage.getPath());
artifactResultProducer.produce(new ArtifactResultBuildItem(null, "native-container", Collections.emptyMap()));
containerImageResultProducer.produce(
new ContainerImageResultBuildItem(S2I, null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
containerImageResultProducer
.produce(new ContainerImageResultBuildItem(S2I, null, ImageUtil.getRepository(image), ImageUtil.getTag(image)));
}

public static void createContainerImage(KubernetesClientBuildItem kubernetesClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ public void build(ApplicationInfoBuildItem applicationInfo,
Optional<KubernetesCommandBuildItem> commandBuildItem,
Optional<KubernetesHealthLivenessPathBuildItem> kubernetesHealthLivenessPathBuildItem,
Optional<KubernetesHealthReadinessPathBuildItem> kubernetesHealthReadinessPathBuildItem,
BuildProducer<GeneratedFileSystemResourceBuildItem> generatedResourceProducer,
BuildProducer<FeatureBuildItem> featureProducer) {
BuildProducer<GeneratedFileSystemResourceBuildItem> generatedResourceProducer) {

if (kubernetesPortBuildItems.isEmpty()) {
log.debug("The service is not an HTTP service so no Kubernetes manifests will be generated");
Expand Down Expand Up @@ -223,7 +222,11 @@ public void build(ApplicationInfoBuildItem applicationInfo,
} catch (IOException e) {
log.debug("Unable to delete temporary directory " + root, e);
}
featureProducer.produce(new FeatureBuildItem(FeatureBuildItem.KUBERNETES));
}

@BuildStep
FeatureBuildItem produceFeature() {
return new FeatureBuildItem(FeatureBuildItem.KUBERNETES);
}

/**
Expand Down

0 comments on commit c224346

Please sign in to comment.