-
Notifications
You must be signed in to change notification settings - Fork 541
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat (jkube-kit/config/service) : Add BuildPackBuildService (#2493)
+ Add new enum for buildpacks in JKubeBuildStrategy + Add BuildPackBuildService that would be activated when build strategy is set to buildpacks Signed-off-by: Rohan Kumar <rohaan@redhat.com>
- Loading branch information
1 parent
7b77750
commit ec1b92d
Showing
9 changed files
with
340 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
111 changes: 111 additions & 0 deletions
111
.../src/main/java/org/eclipse/jkube/kit/config/service/kubernetes/BuildPackBuildService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/* | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.config.service.kubernetes; | ||
|
||
import java.io.File; | ||
import java.net.MalformedURLException; | ||
import java.util.Objects; | ||
import java.util.Properties; | ||
|
||
import org.eclipse.jkube.kit.common.KitLogger; | ||
import org.eclipse.jkube.kit.common.RegistryConfig; | ||
import org.eclipse.jkube.kit.common.util.EnvUtil; | ||
import org.eclipse.jkube.kit.common.util.PropertiesUtil; | ||
import org.eclipse.jkube.kit.config.image.ImageConfiguration; | ||
import org.eclipse.jkube.kit.config.image.build.JKubeBuildStrategy; | ||
import org.eclipse.jkube.kit.config.service.AbstractImageBuildService; | ||
import org.eclipse.jkube.kit.config.service.BuildServiceConfig; | ||
import org.eclipse.jkube.kit.config.service.JKubeServiceException; | ||
import org.eclipse.jkube.kit.config.service.JKubeServiceHub; | ||
import org.eclipse.jkube.kit.service.buildpacks.BuildPackBuildOptions; | ||
import org.eclipse.jkube.kit.service.buildpacks.BuildPackCliDownloader; | ||
import org.eclipse.jkube.kit.service.buildpacks.controller.BuildPackCliController; | ||
|
||
import static org.apache.commons.lang3.StringUtils.strip; | ||
|
||
public class BuildPackBuildService extends AbstractImageBuildService { | ||
private static final String DEFAULT_BUILDER_IMAGE = "paketobuildpacks/builder:base"; | ||
private static final String PACK_CONFIG_DIR = ".pack"; | ||
private static final String PACK_CONFIG_FILE = "config.toml"; | ||
|
||
private final BuildServiceConfig buildServiceConfig; | ||
private final KitLogger kitLogger; | ||
private final Properties packProperties; | ||
|
||
public BuildPackBuildService(JKubeServiceHub jKubeServiceHub) { | ||
this(jKubeServiceHub, PropertiesUtil.getPropertiesFromResource(BuildPackBuildService.class.getResource("/META-INF/jkube/pack-cli.properties"))); | ||
} | ||
|
||
BuildPackBuildService(JKubeServiceHub jKubeServiceHub, Properties packProperties) { | ||
super(jKubeServiceHub); | ||
this.buildServiceConfig = Objects.requireNonNull(jKubeServiceHub.getBuildServiceConfig(), | ||
"BuildServiceConfig is required"); | ||
this.kitLogger = Objects.requireNonNull(jKubeServiceHub.getLog()); | ||
this.packProperties = packProperties; | ||
|
||
} | ||
|
||
@Override | ||
protected void buildSingleImage(ImageConfiguration imageConfiguration) { | ||
kitLogger.info("Delegating container image building process to BuildPacks"); | ||
doBuildPackBuild(imageConfiguration); | ||
} | ||
|
||
private void doBuildPackBuild(ImageConfiguration imageConfiguration) { | ||
BuildPackCliDownloader packCliDownloader = new BuildPackCliDownloader(kitLogger, packProperties); | ||
File packCli = packCliDownloader.getPackCLIIfPresentOrDownload(); | ||
kitLogger.info("Using pack %s", packCli.getAbsolutePath()); | ||
BuildPackCliController packCliController = new BuildPackCliController(packCli, kitLogger); | ||
BuildPackBuildOptions buildOptions = createBuildPackOptions(imageConfiguration); | ||
packCliController.build(buildOptions); | ||
} | ||
|
||
private BuildPackBuildOptions createBuildPackOptions(ImageConfiguration imageConfiguration) { | ||
Properties packConfigProperties = readLocalPackConfig(); | ||
String builderImage = strip(packConfigProperties.getProperty("default-builder-image", DEFAULT_BUILDER_IMAGE), "\""); | ||
BuildPackBuildOptions.BuildPackBuildOptionsBuilder buildOptionsBuilder = BuildPackBuildOptions.builder(); | ||
buildOptionsBuilder.imageName(imageConfiguration.getName()); | ||
buildOptionsBuilder.builderImage(builderImage); | ||
buildOptionsBuilder.creationTime("now"); | ||
return buildOptionsBuilder.build(); | ||
} | ||
|
||
private Properties readLocalPackConfig() { | ||
File packConfigDir = new File(EnvUtil.getUserHome(), PACK_CONFIG_DIR); | ||
if (packConfigDir.exists() && packConfigDir.isDirectory()) { | ||
File packConfig = new File(packConfigDir, PACK_CONFIG_FILE); | ||
try { | ||
return PropertiesUtil.getPropertiesFromResource(packConfig.toURI().toURL()); | ||
} catch (MalformedURLException e) { | ||
kitLogger.warn("Failure in reading pack local configuration : " + e.getMessage()); | ||
} | ||
} | ||
return new Properties(); | ||
} | ||
|
||
@Override | ||
protected void pushSingleImage(ImageConfiguration imageConfiguration, int retries, RegistryConfig registryConfig, boolean skipTag) throws JKubeServiceException { | ||
} | ||
|
||
@Override | ||
public boolean isApplicable() { | ||
return buildServiceConfig.getJKubeBuildStrategy() != null && | ||
buildServiceConfig.getJKubeBuildStrategy().equals(JKubeBuildStrategy.buildpacks); | ||
} | ||
|
||
@Override | ||
public void postProcess() { | ||
// NOOP | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
jkube-kit/config/service/src/main/resources/META-INF/jkube/build-service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
org.eclipse.jkube.kit.config.service.kubernetes.JibBuildService,100 | ||
org.eclipse.jkube.kit.config.service.kubernetes.BuildPackBuildService,110 | ||
org.eclipse.jkube.kit.config.service.openshift.OpenshiftBuildService,200 | ||
org.eclipse.jkube.kit.config.service.kubernetes.DockerBuildService,9999 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
183 changes: 183 additions & 0 deletions
183
.../test/java/org/eclipse/jkube/kit/config/service/kubernetes/BuildPackBuildServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
/* | ||
* Copyright (c) 2019 Red Hat, Inc. | ||
* This program and the accompanying materials are made | ||
* available under the terms of the Eclipse Public License 2.0 | ||
* which is available at: | ||
* | ||
* https://www.eclipse.org/legal/epl-2.0/ | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
* | ||
* Contributors: | ||
* Red Hat, Inc. - initial API and implementation | ||
*/ | ||
package org.eclipse.jkube.kit.config.service.kubernetes; | ||
|
||
import org.eclipse.jkube.kit.common.JKubeConfiguration; | ||
import org.eclipse.jkube.kit.common.KitLogger; | ||
import org.eclipse.jkube.kit.common.TestHttpStaticServer; | ||
import org.eclipse.jkube.kit.common.util.EnvUtil; | ||
import org.eclipse.jkube.kit.common.util.FileUtil; | ||
import org.eclipse.jkube.kit.config.image.ImageConfiguration; | ||
import org.eclipse.jkube.kit.config.image.build.BuildConfiguration; | ||
import org.eclipse.jkube.kit.config.image.build.JKubeBuildStrategy; | ||
import org.eclipse.jkube.kit.config.resource.RuntimeMode; | ||
import org.eclipse.jkube.kit.config.service.BuildServiceConfig; | ||
import org.eclipse.jkube.kit.config.service.JKubeServiceHub; | ||
|
||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Nested; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.io.TempDir; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.CsvSource; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Properties; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
import static org.mockito.Mockito.spy; | ||
import static org.mockito.Mockito.verify; | ||
|
||
class BuildPackBuildServiceTest { | ||
private KitLogger kitLogger; | ||
private JKubeServiceHub jKubeServiceHub; | ||
private static final String TEST_PACK_VERSION = "v0.32.1"; | ||
private ImageConfiguration imageConfiguration; | ||
private BuildServiceConfig buildServiceConfig; | ||
|
||
@TempDir | ||
private File temporaryFolder; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
kitLogger = spy(new KitLogger.SilentLogger()); | ||
buildServiceConfig = BuildServiceConfig.builder() | ||
.jKubeBuildStrategy(JKubeBuildStrategy.buildpacks) | ||
.build(); | ||
jKubeServiceHub = JKubeServiceHub.builder() | ||
.log(kitLogger) | ||
.platformMode(RuntimeMode.KUBERNETES) | ||
.buildServiceConfig(buildServiceConfig) | ||
.configuration(JKubeConfiguration.builder().build()) | ||
.build(); | ||
imageConfiguration = ImageConfiguration.builder() | ||
.name("foo/bar:latest") | ||
.build(BuildConfiguration.builder() | ||
.from("foo/base:latest") | ||
.build()) | ||
.build(); | ||
Map<String, String> properties = new HashMap<>(); | ||
properties.put("user.home", temporaryFolder.getAbsolutePath()); | ||
properties.put("os.name", System.getProperty("os.name")); | ||
properties.put("os.arch", System.getProperty("os.arch")); | ||
Map<String, String> env = new HashMap<>(); | ||
env.put("HOME", temporaryFolder.getAbsolutePath()); | ||
env.put("PATH", temporaryFolder.toPath().resolve("bin").toFile().getAbsolutePath()); | ||
EnvUtil.overrideEnvGetter(env::get); | ||
EnvUtil.overridePropertyGetter(properties::get); | ||
} | ||
|
||
@AfterEach | ||
void tearDown() { | ||
EnvUtil.overrideEnvGetter(System::getenv); | ||
EnvUtil.overridePropertyGetter(System::getProperty); | ||
} | ||
|
||
@ParameterizedTest | ||
@CsvSource({ | ||
"s2i,false", "jib,false", "docker,false", "buildpacks,true" | ||
}) | ||
void isApplicable_withGivenStrategy_shouldReturnTrueOnlyForBuildPackStrategy(String buildStrategyValue, boolean expectedResult) { | ||
// Given | ||
jKubeServiceHub = jKubeServiceHub.toBuilder() | ||
.buildServiceConfig(buildServiceConfig.toBuilder() | ||
.jKubeBuildStrategy(JKubeBuildStrategy.valueOf(buildStrategyValue)) | ||
.build()) | ||
.build(); | ||
// When | ||
final boolean result = new BuildPackBuildService(jKubeServiceHub).isApplicable(); | ||
// Then | ||
assertThat(result).isEqualTo(expectedResult); | ||
} | ||
|
||
|
||
@Nested | ||
@DisplayName("buildImage") | ||
class BuildImage { | ||
private TestHttpStaticServer server; | ||
private BuildPackBuildService buildPackBuildService; | ||
|
||
@BeforeEach | ||
void setUp() throws IOException { | ||
File remoteDirectory = new File(Objects.requireNonNull(getClass().getResource("/artifacts")).getFile()); | ||
File downloadArtifactsDir = temporaryFolder.toPath().resolve("download-artifacts").toFile(); | ||
FileUtil.copyDirectoryIfNotExists(remoteDirectory, downloadArtifactsDir); | ||
server = new TestHttpStaticServer(downloadArtifactsDir); | ||
Properties properties = new Properties(); | ||
properties.put("version", TEST_PACK_VERSION); | ||
properties.put("windows.binary-extension", "bat"); | ||
properties.put("linux.artifact", String.format("http://localhost:%d/pack-%s-linux.tgz", server.getPort(), TEST_PACK_VERSION)); | ||
properties.put("linux-arm64.artifact", String.format("http://localhost:%d/pack-%s-linux-arm64.tgz", server.getPort(), TEST_PACK_VERSION)); | ||
properties.put("macos.artifact", String.format("http://localhost:%d/pack-%s-macos.tgz", server.getPort(), TEST_PACK_VERSION)); | ||
properties.put("macos-arm64.artifact", String.format("http://localhost:%d/pack-%s-macos-arm64.tgz", server.getPort(), TEST_PACK_VERSION)); | ||
properties.put("windows.artifact", String.format("http://localhost:%d/pack-%s-windows.zip", server.getPort(), TEST_PACK_VERSION)); | ||
buildPackBuildService = new BuildPackBuildService(jKubeServiceHub, properties); | ||
} | ||
|
||
@AfterEach | ||
void tearDown() throws IOException { | ||
server.close(); | ||
} | ||
|
||
@Test | ||
@DisplayName("When default builder configured in .pack/config.toml, then use that builder image") | ||
void whenLocalPackConfigHasDefaultBuilderSet_thenUseThatBuilder() throws IOException { | ||
// Given | ||
givenLocalPackConfigExistsWithContent(temporaryFolder, String.format("default-builder-image=\"%s\"", "cnbs/sample-builder:bionic")); | ||
|
||
// When | ||
buildPackBuildService.buildSingleImage(imageConfiguration); | ||
|
||
// Then | ||
verify(kitLogger).info("[[s]]%s","build foo/bar:latest --builder cnbs/sample-builder:bionic --creation-time now"); | ||
} | ||
|
||
@Test | ||
@DisplayName("When .pack/config.toml invalid, then use opinionated builder image") | ||
void whenLocalPackConfigInvalid_thenUseOpinionatedBuilderImage() throws IOException { | ||
// Given | ||
givenLocalPackConfigExistsWithContent(temporaryFolder, "default-builder-image@@="); | ||
|
||
// When | ||
buildPackBuildService.buildSingleImage(imageConfiguration); | ||
|
||
// Then | ||
verify(kitLogger).info("[[s]]%s","build foo/bar:latest --builder paketobuildpacks/builder:base --creation-time now"); | ||
} | ||
|
||
@Test | ||
@DisplayName("When no default builder configured in .pack/config.toml, then use opinionated builder image") | ||
void whenLocalPackCLIAndNoDefaultBuilderInPackConfig_thenUseOpinionatedBuilderImage() { | ||
// When | ||
buildPackBuildService.buildSingleImage(imageConfiguration); | ||
|
||
// Then | ||
verify(kitLogger).info("[[s]]%s", "build foo/bar:latest --builder paketobuildpacks/builder:base --creation-time now"); | ||
} | ||
} | ||
|
||
private void givenLocalPackConfigExistsWithContent(File userHome, String content) throws IOException { | ||
File packHome = new File(userHome, ".pack"); | ||
Files.createDirectory(packHome.toPath()); | ||
File packConfig = new File(packHome, "config.toml"); | ||
Files.write(packConfig.toPath(), content.getBytes()); | ||
} | ||
} |
Oops, something went wrong.