-
Notifications
You must be signed in to change notification settings - Fork 202
Fix #825 : More flexible S2I binary build data format #1355
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* Copyright 2016 Red Hat, Inc. | ||
* | ||
* Red Hat licenses this file to you under the Apache License, version | ||
* 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
package io.fabric8.maven.core.service; | ||
|
||
import io.fabric8.maven.docker.config.ImageConfiguration; | ||
import io.fabric8.maven.docker.service.ServiceHub; | ||
|
||
import java.io.File; | ||
|
||
public interface BinaryInputArchiveBuilder { | ||
void createBinaryInput(ServiceHub hub, File targetDirectory, ImageConfiguration imageConfiguration) throws Fabric8ServiceException; | ||
File getBinaryInputTar(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/** | ||
* Copyright 2016 Red Hat, Inc. | ||
* | ||
* Red Hat licenses this file to you under the Apache License, version | ||
* 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
package io.fabric8.maven.core.service; | ||
|
||
import io.fabric8.maven.core.util.IoUtil; | ||
import io.fabric8.maven.docker.assembly.ArchiverCustomizer; | ||
import io.fabric8.maven.docker.config.ImageConfiguration; | ||
import io.fabric8.maven.docker.service.ServiceHub; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
import org.codehaus.plexus.archiver.tar.TarArchiver; | ||
|
||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.io.PrintWriter; | ||
import java.util.Map; | ||
|
||
public class DefaultBinaryInputArchiveBuilder implements BinaryInputArchiveBuilder { | ||
|
||
private BuildService.BuildServiceConfig config; | ||
private File binaryInputTar = null; | ||
|
||
public DefaultBinaryInputArchiveBuilder(BuildService.BuildServiceConfig config) { | ||
this.config = config; | ||
} | ||
|
||
@Override | ||
public void createBinaryInput(ServiceHub hub, File targetDir, ImageConfiguration imageConfiguration) throws Fabric8ServiceException { | ||
// Adding S2I artifacts such as environment variables in S2I mode | ||
ArchiverCustomizer customizer = getS2ICustomizer(imageConfiguration); | ||
|
||
try { | ||
// Create tar file with Docker archive | ||
if (customizer != null) { | ||
this.binaryInputTar = hub.getArchiveService().createDockerBuildArchive(imageConfiguration, config.getDockerMojoParameters(), customizer); | ||
} else { | ||
this.binaryInputTar = hub.getArchiveService().createDockerBuildArchive(imageConfiguration, config.getDockerMojoParameters()); | ||
} | ||
} catch (MojoExecutionException e) { | ||
throw new Fabric8ServiceException("Unable to create the build archive", e); | ||
} | ||
} | ||
|
||
private ArchiverCustomizer getS2ICustomizer(ImageConfiguration imageConfiguration) throws Fabric8ServiceException { | ||
try { | ||
if (imageConfiguration.getBuildConfiguration() != null && imageConfiguration.getBuildConfiguration().getEnv() != null) { | ||
String fileName = IoUtil.sanitizeFileName("s2i-env-" + imageConfiguration.getName()); | ||
final File environmentFile = new File(config.getBuildDirectory(), fileName); | ||
|
||
try (PrintWriter out = new PrintWriter(new FileWriter(environmentFile))) { | ||
for (Map.Entry<String, String> e : imageConfiguration.getBuildConfiguration().getEnv().entrySet()) { | ||
out.println(e.getKey() + "=" + e.getValue()); | ||
} | ||
} | ||
|
||
return new ArchiverCustomizer() { | ||
@Override | ||
public TarArchiver customize(TarArchiver tarArchiver) throws IOException { | ||
tarArchiver.addFile(environmentFile, ".s2i/environment"); | ||
return tarArchiver; | ||
} | ||
}; | ||
} else { | ||
return null; | ||
} | ||
} catch (IOException e) { | ||
throw new Fabric8ServiceException("Unable to add environment variables to the S2I build archive", e); | ||
} | ||
} | ||
|
||
public File getBinaryInputTar() { | ||
return binaryInputTar; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/** | ||
* Copyright 2016 Red Hat, Inc. | ||
* | ||
* Red Hat licenses this file to you under the Apache License, version | ||
* 2.0 (the "License"); you may not use this file except in compliance | ||
* with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | ||
* implied. See the License for the specific language governing | ||
* permissions and limitations under the License. | ||
*/ | ||
|
||
package io.fabric8.maven.core.service; | ||
|
||
import io.fabric8.maven.core.util.ResourceUtil; | ||
import io.fabric8.maven.docker.config.ImageConfiguration; | ||
import io.fabric8.maven.docker.service.ServiceHub; | ||
import org.apache.maven.plugin.MojoExecutionException; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
import java.nio.file.StandardCopyOption; | ||
|
||
public class WarBinaryInputArchiveBuilder implements BinaryInputArchiveBuilder { | ||
private BuildService.BuildServiceConfig config; | ||
private File binaryInputTar = null; | ||
|
||
public WarBinaryInputArchiveBuilder(BuildService.BuildServiceConfig config) { | ||
this.config = config; | ||
} | ||
|
||
@Override | ||
public void createBinaryInput(ServiceHub hub, File binaryInputDirectory, ImageConfiguration imageConfiguration) throws Fabric8ServiceException { | ||
try { | ||
File targetDirectory = new File(config.getBuildDirectory()); | ||
String[] jarOrWars = ResourceUtil.getFileListOfExtension(targetDirectory, ".war"); | ||
|
||
if(jarOrWars == null || jarOrWars.length == 0) { | ||
throw new MojoExecutionException("No war/jar built yet. Please ensure that the 'package' phase has run"); | ||
} | ||
|
||
File warFileLocation = ResourceUtil.getArchiveFile(targetDirectory, jarOrWars); | ||
File targetWarFileLocation = new File(binaryInputDirectory, warFileLocation.getName()); | ||
targetWarFileLocation.createNewFile(); | ||
Files.copy(Paths.get(warFileLocation.getAbsolutePath()), Paths.get(targetWarFileLocation.getAbsolutePath()), StandardCopyOption.REPLACE_EXISTING); | ||
} catch(IOException exception) { | ||
throw new Fabric8ServiceException("Cannot examine "+ binaryInputDirectory.getName() + " for the manifest"); | ||
} catch (MojoExecutionException mojoException) { | ||
throw new Fabric8ServiceException(mojoException); | ||
} | ||
} | ||
|
||
@Override | ||
public File getBinaryInputTar() { return binaryInputTar; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,9 +16,7 @@ | |
package io.fabric8.maven.core.service.openshift; | ||
|
||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.io.PrintWriter; | ||
import java.io.UnsupportedEncodingException; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
|
@@ -39,16 +37,16 @@ | |
import io.fabric8.kubernetes.client.Watcher; | ||
import io.fabric8.kubernetes.client.dsl.LogWatch; | ||
import io.fabric8.maven.core.config.OpenShiftBuildStrategy; | ||
import io.fabric8.maven.core.service.BinaryInputArchiveBuilder; | ||
import io.fabric8.maven.core.service.BuildService; | ||
import io.fabric8.maven.core.service.Fabric8ServiceException; | ||
import io.fabric8.maven.core.util.IoUtil; | ||
import io.fabric8.maven.core.util.FileUtil; | ||
import io.fabric8.maven.core.util.ResourceFileType; | ||
import io.fabric8.maven.core.util.kubernetes.KubernetesClientUtil; | ||
import io.fabric8.maven.core.util.kubernetes.KubernetesHelper; | ||
import io.fabric8.maven.core.util.kubernetes.KubernetesResourceUtil; | ||
import io.fabric8.maven.core.util.kubernetes.OpenshiftHelper; | ||
import io.fabric8.maven.docker.access.AuthConfig; | ||
import io.fabric8.maven.docker.assembly.ArchiverCustomizer; | ||
import io.fabric8.maven.docker.assembly.DockerAssemblyManager; | ||
import io.fabric8.maven.docker.config.AssemblyConfiguration; | ||
import io.fabric8.maven.docker.config.BuildImageConfiguration; | ||
|
@@ -87,27 +85,37 @@ public class OpenshiftBuildService implements BuildService { | |
private BuildServiceConfig config; | ||
private RegistryService.RegistryConfig registryConfig; | ||
private AuthConfigFactory authConfigFactory; | ||
private BinaryInputArchiveBuilder binaryInputArchiveBuilder; | ||
|
||
|
||
public OpenshiftBuildService(OpenShiftClient client, Logger log, ServiceHub dockerServiceHub, BuildServiceConfig config) { | ||
public OpenshiftBuildService(OpenShiftClient client, Logger log, ServiceHub dockerServiceHub, BuildServiceConfig config, BinaryInputArchiveBuilder binaryInputArchiveBuilder) { | ||
Objects.requireNonNull(client, "client"); | ||
Objects.requireNonNull(log, "log"); | ||
Objects.requireNonNull(dockerServiceHub, "dockerServiceHub"); | ||
Objects.requireNonNull(config, "config"); | ||
Objects.requireNonNull(binaryInputArchiveBuilder, "binaryInputArchiveBuilder"); | ||
|
||
this.client = client; | ||
this.log = log; | ||
this.dockerServiceHub = dockerServiceHub; | ||
this.config = config; | ||
this.binaryInputArchiveBuilder = binaryInputArchiveBuilder; | ||
} | ||
|
||
@Override | ||
public void build(ImageConfiguration imageConfig) throws Fabric8ServiceException { | ||
String buildName = null; | ||
try { | ||
ImageName imageName = new ImageName(imageConfig.getName()); | ||
// Create an empty directory | ||
File targetDir = createEmptyTargetDir(); | ||
|
||
// Fill the directory with the data in the right directory structure | ||
binaryInputArchiveBuilder.createBinaryInput(dockerServiceHub, targetDir, imageConfig); | ||
|
||
File dockerTar = createBuildArchive(imageConfig); | ||
// Create the tar archive by tarring the directory | ||
File dockerTar = binaryInputArchiveBuilder.getBinaryInputTar() != null ? binaryInputArchiveBuilder.getBinaryInputTar() : createTar(targetDir); | ||
|
||
ImageName imageName = new ImageName(imageConfig.getName()); | ||
|
||
KubernetesListBuilder builder = new KubernetesListBuilder(); | ||
|
||
|
@@ -144,49 +152,26 @@ public void build(ImageConfiguration imageConfig) throws Fabric8ServiceException | |
} | ||
} | ||
|
||
protected File createBuildArchive(ImageConfiguration imageConfig) throws Fabric8ServiceException { | ||
// Adding S2I artifacts such as environment variables in S2I mode | ||
ArchiverCustomizer customizer = getS2ICustomizer(imageConfig); | ||
|
||
try { | ||
// Create tar file with Docker archive | ||
File dockerTar; | ||
if (customizer != null) { | ||
dockerTar = dockerServiceHub.getArchiveService().createDockerBuildArchive(imageConfig, config.getDockerMojoParameters(), customizer); | ||
} else { | ||
dockerTar = dockerServiceHub.getArchiveService().createDockerBuildArchive(imageConfig, config.getDockerMojoParameters()); | ||
} | ||
return dockerTar; | ||
} catch (MojoExecutionException e) { | ||
throw new Fabric8ServiceException("Unable to create the build archive", e); | ||
private File createEmptyTargetDir() throws MojoExecutionException { | ||
File targetDir = new File(config.getBuildDirectory(), "s2i"); | ||
if (!targetDir.exists() && !targetDir.mkdirs()) { | ||
throw new MojoExecutionException("Can't create build working directory " + targetDir); | ||
} | ||
return targetDir; | ||
} | ||
|
||
private ArchiverCustomizer getS2ICustomizer(ImageConfiguration imageConfiguration) throws Fabric8ServiceException { | ||
try { | ||
if (imageConfiguration.getBuildConfiguration() != null && imageConfiguration.getBuildConfiguration().getEnv() != null) { | ||
String fileName = IoUtil.sanitizeFileName("s2i-env-" + imageConfiguration.getName()); | ||
final File environmentFile = new File(config.getBuildDirectory(), fileName); | ||
private File createTar(File targetDir) throws IOException, MojoExecutionException { | ||
TarArchiver tarArchiver = new TarArchiver(); | ||
tarArchiver.addDirectory(targetDir); | ||
|
||
try (PrintWriter out = new PrintWriter(new FileWriter(environmentFile))) { | ||
for (Map.Entry<String, String> e : imageConfiguration.getBuildConfiguration().getEnv().entrySet()) { | ||
out.println(e.getKey() + "=" + e.getValue()); | ||
} | ||
} | ||
// Delete previously existing tar files, if any | ||
FileUtil.deleteFilesInDirectory(targetDir, (file, s) -> { return s.endsWith(".tar"); }); | ||
|
||
return new ArchiverCustomizer() { | ||
@Override | ||
public TarArchiver customize(TarArchiver tarArchiver) throws IOException { | ||
tarArchiver.addFile(environmentFile, ".s2i/environment"); | ||
return tarArchiver; | ||
} | ||
}; | ||
} else { | ||
return null; | ||
} | ||
} catch (IOException e) { | ||
throw new Fabric8ServiceException("Unable to add environment variables to the S2I build archive", e); | ||
} | ||
File tarFile = File.createTempFile(config.getArtifactId().toString(), ".tar"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if I understand this: |
||
File destFile = new File(targetDir, config.getArtifactId() + ".tar"); | ||
tarArchiver.setDestFile(destFile); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also not sure that this works if you put the destination file into the directory that you tar up (as it would be tar up itself, too) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naiively I would expect a
and removing |
||
tarArchiver.createArchive(); | ||
return tarFile; | ||
} | ||
|
||
private File getImageStreamFile(BuildServiceConfig config) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's about adding a
File
return value to theBinaryInputArchiveBuilder
which then holds the the TAR archive ?Advantages:
createTar()
methodtargetDir
parameter. This just would be an implementation details.If you don't mind I would change it like this and push it to your branch (just to speed up things and to clarify my point).
@rohanKanojia would this be ok for you ?