From aa41f7501b90b050fed441e4421147039e320e83 Mon Sep 17 00:00:00 2001 From: Rohan Kumar Date: Tue, 5 Dec 2023 21:28:57 +0530 Subject: [PATCH] feat (jkube-kit/build/service/buildpacks) : Add BuildPackCliController (#2453) Signed-off-by: Rohan Kumar --- jkube-kit/build/service/buildpacks/pom.xml | 8 ++ .../buildpacks/BuildPackBuildOptions.java | 33 ++++++ .../controller/BuildPackCliController.java | 73 ++++++++++++ .../controller/BuildPackController.java | 21 ++++ .../BuildPackCliControllerTest.java | 104 ++++++++++++++++++ 5 files changed, 239 insertions(+) create mode 100644 jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackBuildOptions.java create mode 100644 jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackCliController.java create mode 100644 jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackController.java create mode 100644 jkube-kit/build/service/buildpacks/src/test/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackCliControllerTest.java diff --git a/jkube-kit/build/service/buildpacks/pom.xml b/jkube-kit/build/service/buildpacks/pom.xml index aaaa882d12..6bf5c3b47b 100644 --- a/jkube-kit/build/service/buildpacks/pom.xml +++ b/jkube-kit/build/service/buildpacks/pom.xml @@ -33,6 +33,10 @@ org.eclipse.jkube jkube-kit-build-api + + org.projectlombok + lombok + org.eclipse.jkube jkube-kit-common @@ -52,6 +56,10 @@ org.assertj assertj-core + + org.apache.commons + commons-lang3 + diff --git a/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackBuildOptions.java b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackBuildOptions.java new file mode 100644 index 0000000000..d2aece9da6 --- /dev/null +++ b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackBuildOptions.java @@ -0,0 +1,33 @@ +/* + * 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.service.buildpacks; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Builder(toBuilder = true) +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Setter +@EqualsAndHashCode +public class BuildPackBuildOptions { + private String builderImage; + private String imageName; + private String creationTime; +} \ No newline at end of file diff --git a/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackCliController.java b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackCliController.java new file mode 100644 index 0000000000..f9cf4023bc --- /dev/null +++ b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackCliController.java @@ -0,0 +1,73 @@ +/* + * 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.service.buildpacks.controller; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.jkube.kit.common.KitLogger; +import org.eclipse.jkube.kit.service.buildpacks.BuildPackBuildOptions; +import org.eclipse.jkube.kit.service.buildpacks.BuildPackCommand; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +public class BuildPackCliController implements BuildPackController { + private final File pack; + private final KitLogger kitLogger; + + public BuildPackCliController(File binaryFile, KitLogger kitLogger) { + this.pack = binaryFile; + this.kitLogger = kitLogger; + } + + @Override + public void build(BuildPackBuildOptions buildOptions) { + BuildPackCommand buildPackCommand = new BuildPackCommand(kitLogger, pack, + createBuildCommandArguments(buildOptions), + l -> kitLogger.info("[[s]]%s", l)); + try { + buildPackCommand.execute(); + } catch (IOException e) { + throw new IllegalStateException("Process Existed With : " + buildPackCommand.getExitCode() + " [" + e.getMessage() + "]", e); + } + } + + @Override + public String version() { + AtomicReference versionRef = new AtomicReference<>(); + BuildPackCommand versionCommand = new BuildPackCommand(kitLogger, pack, Collections.singletonList("--version"), versionRef::set); + try { + versionCommand.execute(); + } catch (IOException e) { + kitLogger.warn(e.getMessage()); + } + if (StringUtils.isNotBlank(versionRef.get())) { + return versionRef.get(); + } + return null; + } + + private List createBuildCommandArguments(BuildPackBuildOptions buildOptions) { + List buildArgs = new ArrayList<>(); + buildArgs.add("build"); + buildArgs.add(buildOptions.getImageName()); + buildArgs.addAll(Arrays.asList("--builder", buildOptions.getBuilderImage())); + buildArgs.addAll(Arrays.asList("--creation-time", buildOptions.getCreationTime())); + return buildArgs; + } +} diff --git a/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackController.java b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackController.java new file mode 100644 index 0000000000..e1e2e364ab --- /dev/null +++ b/jkube-kit/build/service/buildpacks/src/main/java/org/eclipse/jkube/kit/service/buildpacks/controller/BuildPackController.java @@ -0,0 +1,21 @@ +/* + * 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.service.buildpacks.controller; + +import org.eclipse.jkube.kit.service.buildpacks.BuildPackBuildOptions; + +public interface BuildPackController { + void build(BuildPackBuildOptions buildOptions); + String version(); +} diff --git a/jkube-kit/build/service/buildpacks/src/test/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackCliControllerTest.java b/jkube-kit/build/service/buildpacks/src/test/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackCliControllerTest.java new file mode 100644 index 0000000000..9dd2b08019 --- /dev/null +++ b/jkube-kit/build/service/buildpacks/src/test/java/org/eclipse/jkube/kit/service/buildpacks/BuildPackCliControllerTest.java @@ -0,0 +1,104 @@ +/* + * 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.service.buildpacks; + +import org.eclipse.jkube.kit.common.KitLogger; +import org.eclipse.jkube.kit.common.util.EnvUtil; +import org.eclipse.jkube.kit.service.buildpacks.controller.BuildPackCliController; +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 java.io.File; +import java.util.Objects; + +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +class BuildPackCliControllerTest { + private KitLogger kitLogger; + private BuildPackCliController buildPackCliController; + private BuildPackBuildOptions buildOptions; + private File pack; + + @BeforeEach + void setUp() { + kitLogger = spy(new KitLogger.SilentLogger()); + String validPackBinary = EnvUtil.isWindows() ? "pack.bat" : "pack"; + pack = new File(Objects.requireNonNull(getClass().getResource(String.format("/%s", validPackBinary))).getFile()); + buildPackCliController = new BuildPackCliController(pack, kitLogger); + buildOptions = BuildPackBuildOptions.builder() + .imageName("foo/bar:latest") + .builderImage("foo/builder:base") + .creationTime("now") + .build(); + } + + @Nested + @DisplayName("pack command succeeds") + class CommandSucceeds { + @Test + @DisplayName("build, BuildPackBuildOptions passes as commandline arguments") + void build_whenInvoked_thenBuildPackBuildOptionsPassedAsCommandLineArguments() { + // When + buildPackCliController.build(buildOptions); + + // Then + verify(kitLogger).info("[[s]]%s", "build foo/bar:latest --builder foo/builder:base --creation-time now"); + } + + @Test + @DisplayName("version, should get pack version") + void version() { + // When + String version = buildPackCliController.version(); + + // Then + assertThat(version).isEqualTo("0.32.1+git-b14250b.build-5241"); + } + } + + @Nested + @DisplayName("pack command fails") + class CommandFails { + @BeforeEach + void setUp() { + String invalidPackBinary = EnvUtil.isWindows() ? "invalid-pack.bat" : "invalid-pack"; + pack = new File(Objects.requireNonNull(BuildPackCliControllerTest.class.getResource(String.format("/%s", invalidPackBinary))).getFile()); + buildPackCliController = new BuildPackCliController(pack, kitLogger); + } + + @Test + @DisplayName("build, throws exception") + void build_whenCommandFailed_thenThrowException() { + // When + Then + assertThatIllegalStateException() + .isThrownBy(() -> buildPackCliController.build(buildOptions)) + .withMessageContaining("Process Existed With : 1"); + } + + @Test + @DisplayName("version, returns null on failure") + void version_whenCommandFailed_thenReturnNull() { + // When + String version = buildPackCliController.version(); + + // Then + assertThat(version).isNull(); + } + } +}