Skip to content

Commit

Permalink
feat: Adding support for --cacheFrom and --cacheTo buildX arguments
Browse files Browse the repository at this point in the history
Closes #1621

Signed-off-by: Bogdan Ilchyshyn <[email protected]>
  • Loading branch information
orange-buffalo authored and rohanKanojia committed Dec 3, 2023
1 parent 1b4dec5 commit c5cc4db
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 9 deletions.
4 changes: 4 additions & 0 deletions src/main/asciidoc/inc/build/_buildx.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ elements are ignored. If no platform architecture is specified, buildx is *not*
| The configuration of attestation modes. The `<provenance>` element may be set to `min`,
`max`, or `false`. The `<sbom>` element may be set to `true` or `false`. The `<provenance>`
element defaults to `min` and the `<sbom>` element defaults to `false`.
| *cacheFrom*
| A value to be passed through to the `--cache-from` option of `docker buildx build`. See https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-from[docker buildx reference docs].
| *cacheTo*
| A value to be passed through to the `--cache-to` option of `docker buildx build`. See https://docs.docker.com/engine/reference/commandline/buildx_build/#cache-to[docker buildx reference docs].
|===

.Examples
Expand Down
6 changes: 6 additions & 0 deletions src/main/asciidoc/inc/external/_property_configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ when a `docker.from` or a `docker.fromExt` is set.
| *docker.buildx.platform*
| Platform for multi-architecture image

| *docker.buildx.cacheFrom*
| Cache source for buildx builder

| *docker.buildx.cacheTo*
| Cache destination for buildx builder

| *docker.capAdd.idx*
| List of kernel capabilities to add to the container. See <<list-properties>>.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ public class BuildXConfiguration implements Serializable {
@Parameter
private String nodeName;

/**
* Value to be passed to {@code --cache-from} option of BuildX build.
*/
@Parameter
private String cacheFrom;

/**
* Value to be passed to {@code --cache-to} option of BuildX build.
*/
@Parameter
private String cacheTo;

public String getBuilderName() {
return builderName;
}
Expand All @@ -58,6 +70,14 @@ public String getNodeName() {
return nodeName;
}

public String getCacheFrom() {
return cacheFrom;
}

public String getCacheTo() {
return cacheTo;
}

public boolean isBuildX() {
return !getPlatforms().isEmpty();
}
Expand Down Expand Up @@ -127,5 +147,21 @@ public Builder attestations(AttestationConfiguration attestations) {
}
return this;
}

public Builder cacheFrom(String cacheFrom) {
config.cacheFrom = cacheFrom;
if (cacheFrom != null) {
isEmpty = false;
}
return this;
}

public Builder cacheTo(String cacheTo) {
config.cacheTo = cacheTo;
if (cacheTo != null) {
isEmpty = false;
}
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public enum ConfigKey {
BUILDX_DOCKERSTATEDIR("buildx.dockerStateDir"),
BUILDX_ATTESTATION_PROVENANCE("buildx.attestations.provenance"),
BUILDX_ATTESTATION_SBOM("buildx.attestations.sbom"),
BUILDX_CACHE_FROM("buildx.cacheFrom"),
BUILDX_CACHE_TO("buildx.cacheTo"),
CAP_ADD,
CAP_DROP,
SYSCTLS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ private BuildXConfiguration extractBuildx(BuildXConfiguration config, ValueProvi
.dockerStateDir(valueProvider.getString(BUILDX_DOCKERSTATEDIR, config.getDockerStateDir()))
.platforms(valueProvider.getList(BUILDX_PLATFORMS, config.getPlatforms()))
.attestations(extractAttestations(config.getAttestations(), valueProvider))
.cacheFrom(valueProvider.getString(BUILDX_CACHE_FROM, config.getCacheFrom()))
.cacheTo(valueProvider.getString(BUILDX_CACHE_TO, config.getCacheTo()))
.build();
}

Expand Down
11 changes: 10 additions & 1 deletion src/main/java/io/fabric8/maven/docker/service/BuildXService.java
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@ protected void buildX(List<String> buildX, String builderName, BuildDirs buildDi
cmdLine.add("--no-cache");
}

AttestationConfiguration attestations = buildConfiguration.getBuildX().getAttestations();
BuildXConfiguration buildXConfiguration = buildConfiguration.getBuildX();
AttestationConfiguration attestations = buildXConfiguration.getAttestations();
if (attestations != null) {
if (Boolean.TRUE.equals(attestations.getSbom())) {
cmdLine.add("--sbom=true");
Expand All @@ -197,6 +198,14 @@ protected void buildX(List<String> buildX, String builderName, BuildDirs buildDi
}
}

if (buildXConfiguration.getCacheFrom() != null) {
cmdLine.add("--cache-from=" + buildXConfiguration.getCacheFrom());
}

if (buildXConfiguration.getCacheTo() != null) {
cmdLine.add("--cache-to=" + buildXConfiguration.getCacheTo());
}

if (buildConfiguration.squash()) {
cmdLine.add("--squash");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import io.fabric8.maven.docker.access.AuthConfig;
import io.fabric8.maven.docker.util.DockerFileUtil;
import java.util.function.BiConsumer;
import org.apache.maven.plugin.MojoExecutionException;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -122,7 +123,7 @@ void testBuildNativePlatformWithForeign() throws Exception {
void testNoCacheIsPropagatedToBuildx(@TempDir File temporaryFolder) throws Exception {

//Given
buildNoCacheConfigUsingBuildx(temporaryFolder);
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildImage.noCache(true));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);
Expand All @@ -131,14 +132,67 @@ void testNoCacheIsPropagatedToBuildx(@TempDir File temporaryFolder) throws Excep
verifyBuildXArgumentPresentInExec("--no-cache");
}

private void buildNoCacheConfigUsingBuildx(File temporaryFolder) {
BuildXConfiguration buildXConfiguration = new BuildXConfiguration.Builder()
@Test
void testBuildXCacheFromIsNotPresentIfNotProvided(@TempDir File temporaryFolder) throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildX.cacheFrom(null));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentNotPresentInExec("--cache-from");
}

@Test
void testBuildXCacheFromIsPresentIfProvided(@TempDir File temporaryFolder) throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildX.cacheFrom("cacheFromSpec"));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentPresentInExec("--cache-from=cacheFromSpec");
}

@Test
void testBuildXCacheToIsNotPresentIfNotProvided(@TempDir File temporaryFolder) throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildX.cacheTo(null));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentNotPresentInExec("--cache-to");
}

@Test
void testBuildXCacheToIsPresentIfProvided(@TempDir File temporaryFolder) throws Exception {

//Given
buildConfigUsingBuildx(temporaryFolder, (buildX, buildImage) -> buildX.cacheTo("cacheToSpec"));

// When
buildx.build(projectPaths, imageConfig, configuredRegistry, authConfigList, buildArchive);

//Then
verifyBuildXArgumentPresentInExec("--cache-to=cacheToSpec");
}

private void buildConfigUsingBuildx(File temporaryFolder, BiConsumer<BuildXConfiguration.Builder, BuildImageConfiguration.Builder> spec) {
final BuildXConfiguration.Builder buildXConfigurationBuilder = new BuildXConfiguration.Builder()
.dockerStateDir(temporaryFolder.getAbsolutePath())
.platforms(Arrays.asList(NATIVE))
.build();
final BuildImageConfiguration buildImageConfig = new BuildImageConfiguration.Builder()
.buildx(buildXConfiguration)
.noCache(true)
.platforms(Arrays.asList(NATIVE));
final BuildImageConfiguration.Builder buildImageConfigBuilder = new BuildImageConfiguration.Builder();
spec.accept(buildXConfigurationBuilder, buildImageConfigBuilder);
final BuildXConfiguration buildxConfig = buildXConfigurationBuilder.build();
final BuildImageConfiguration buildImageConfig = buildImageConfigBuilder
.buildx(buildxConfig)
.build();
imageConfig = new ImageConfiguration.Builder()
.name("build-image")
Expand Down Expand Up @@ -235,4 +289,13 @@ private void verifyBuildXArgumentPresentInExec(String... args) throws Exception{
assertTrue(buildXArgCaptor.getValue().stream().anyMatch(passedArgument -> passedArgument.equalsIgnoreCase(arg)));
}
}

private void verifyBuildXArgumentNotPresentInExec(String... args) throws Exception{
ArgumentCaptor<List<String>> buildXArgCaptor = ArgumentCaptor.forClass(List.class);
Mockito.verify(exec).process(buildXArgCaptor.capture());
for (String arg: args) {
assertTrue(buildXArgCaptor.getValue().stream().noneMatch(passedArgument ->
passedArgument.toLowerCase().contains(arg.toLowerCase())));
}
}
}

0 comments on commit c5cc4db

Please sign in to comment.