Add support for untrusted CNB builders
A `trustBuilder` configuration option has been added to the Maven and Gradle CNB integration image building goal and task. A known set of builders published by Paketo, Heroku, and Google are trusted by default, all other builders are untrusted by default. Closes gh-41352
This commit is contained in:
parent
c848a5e3ed
commit
224b06982e
|
@ -45,9 +45,20 @@ import org.springframework.util.Assert;
|
||||||
*/
|
*/
|
||||||
public class BuildRequest {
|
public class BuildRequest {
|
||||||
|
|
||||||
static final String DEFAULT_BUILDER_IMAGE_NAME = "paketobuildpacks/builder-jammy-tiny:latest";
|
static final String DEFAULT_BUILDER_IMAGE_NAME = "paketobuildpacks/builder-jammy-tiny";
|
||||||
|
|
||||||
private static final ImageReference DEFAULT_BUILDER = ImageReference.of(DEFAULT_BUILDER_IMAGE_NAME);
|
static final String DEFAULT_BUILDER_IMAGE_REF = DEFAULT_BUILDER_IMAGE_NAME + ":latest";
|
||||||
|
|
||||||
|
static final List<ImageReference> KNOWN_TRUSTED_BUILDERS = List.of(
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-tiny"),
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-base"),
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-full"),
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-buildpackless-tiny"),
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-buildpackless-base"),
|
||||||
|
ImageReference.of("paketobuildpacks/builder-jammy-buildpackless-full"),
|
||||||
|
ImageReference.of("gcr.io/buildpacks/builder"), ImageReference.of("heroku/builder"));
|
||||||
|
|
||||||
|
private static final ImageReference DEFAULT_BUILDER = ImageReference.of(DEFAULT_BUILDER_IMAGE_REF);
|
||||||
|
|
||||||
private final ImageReference name;
|
private final ImageReference name;
|
||||||
|
|
||||||
|
@ -55,6 +66,8 @@ public class BuildRequest {
|
||||||
|
|
||||||
private final ImageReference builder;
|
private final ImageReference builder;
|
||||||
|
|
||||||
|
private final Boolean trustBuilder;
|
||||||
|
|
||||||
private final ImageReference runImage;
|
private final ImageReference runImage;
|
||||||
|
|
||||||
private final Creator creator;
|
private final Creator creator;
|
||||||
|
@ -95,6 +108,7 @@ public class BuildRequest {
|
||||||
this.name = name.inTaggedForm();
|
this.name = name.inTaggedForm();
|
||||||
this.applicationContent = applicationContent;
|
this.applicationContent = applicationContent;
|
||||||
this.builder = DEFAULT_BUILDER;
|
this.builder = DEFAULT_BUILDER;
|
||||||
|
this.trustBuilder = null;
|
||||||
this.runImage = null;
|
this.runImage = null;
|
||||||
this.env = Collections.emptyMap();
|
this.env = Collections.emptyMap();
|
||||||
this.cleanCache = false;
|
this.cleanCache = false;
|
||||||
|
@ -118,7 +132,8 @@ public class BuildRequest {
|
||||||
ImageReference runImage, Creator creator, Map<String, String> env, boolean cleanCache,
|
ImageReference runImage, Creator creator, Map<String, String> env, boolean cleanCache,
|
||||||
boolean verboseLogging, PullPolicy pullPolicy, boolean publish, List<BuildpackReference> buildpacks,
|
boolean verboseLogging, PullPolicy pullPolicy, boolean publish, List<BuildpackReference> buildpacks,
|
||||||
List<Binding> bindings, String network, List<ImageReference> tags, Cache buildWorkspace, Cache buildCache,
|
List<Binding> bindings, String network, List<ImageReference> tags, Cache buildWorkspace, Cache buildCache,
|
||||||
Cache launchCache, Instant createdDate, String applicationDirectory, List<String> securityOptions) {
|
Cache launchCache, Instant createdDate, String applicationDirectory, List<String> securityOptions,
|
||||||
|
Boolean trustBuilder) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.applicationContent = applicationContent;
|
this.applicationContent = applicationContent;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
|
@ -139,6 +154,7 @@ public class BuildRequest {
|
||||||
this.createdDate = createdDate;
|
this.createdDate = createdDate;
|
||||||
this.applicationDirectory = applicationDirectory;
|
this.applicationDirectory = applicationDirectory;
|
||||||
this.securityOptions = securityOptions;
|
this.securityOptions = securityOptions;
|
||||||
|
this.trustBuilder = trustBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -151,7 +167,20 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, builder.inTaggedOrDigestForm(), this.runImage,
|
return new BuildRequest(this.name, this.applicationContent, builder.inTaggedOrDigestForm(), this.runImage,
|
||||||
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
||||||
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
||||||
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions);
|
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a new {@link BuildRequest} with an updated trust builder setting.
|
||||||
|
* @param trustBuilder {@code true} if the builder should be treated as trusted,
|
||||||
|
* {@code false} otherwise
|
||||||
|
* @return an updated build request
|
||||||
|
*/
|
||||||
|
public BuildRequest withTrustBuilder(boolean trustBuilder) {
|
||||||
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
|
this.applicationDirectory, this.securityOptions, trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,7 +192,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, runImageName.inTaggedOrDigestForm(),
|
return new BuildRequest(this.name, this.applicationContent, this.builder, runImageName.inTaggedOrDigestForm(),
|
||||||
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
this.creator, this.env, this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
||||||
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
||||||
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions);
|
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,7 +205,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -193,7 +222,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
|
||||||
Collections.unmodifiableMap(env), this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
Collections.unmodifiableMap(env), this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish,
|
||||||
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace, this.buildCache,
|
||||||
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions);
|
this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,7 +237,8 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator,
|
||||||
Collections.unmodifiableMap(updatedEnv), this.cleanCache, this.verboseLogging, this.pullPolicy,
|
Collections.unmodifiableMap(updatedEnv), this.cleanCache, this.verboseLogging, this.pullPolicy,
|
||||||
this.publish, this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace,
|
this.publish, this.buildpacks, this.bindings, this.network, this.tags, this.buildWorkspace,
|
||||||
this.buildCache, this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions);
|
this.buildCache, this.launchCache, this.createdDate, this.applicationDirectory, this.securityOptions,
|
||||||
|
this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -220,7 +250,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,7 +262,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,7 +274,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,7 +286,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -281,7 +311,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -306,7 +336,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -319,7 +349,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -342,7 +372,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -356,7 +386,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -369,7 +399,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -382,7 +412,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, launchCache, this.createdDate,
|
||||||
this.applicationDirectory, this.securityOptions);
|
this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -395,7 +425,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache,
|
||||||
parseCreatedDate(createdDate), this.applicationDirectory, this.securityOptions);
|
parseCreatedDate(createdDate), this.applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instant parseCreatedDate(String createdDate) {
|
private Instant parseCreatedDate(String createdDate) {
|
||||||
|
@ -420,7 +450,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
applicationDirectory, this.securityOptions);
|
applicationDirectory, this.securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -434,7 +464,7 @@ public class BuildRequest {
|
||||||
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
return new BuildRequest(this.name, this.applicationContent, this.builder, this.runImage, this.creator, this.env,
|
||||||
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
this.cleanCache, this.verboseLogging, this.pullPolicy, this.publish, this.buildpacks, this.bindings,
|
||||||
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
this.network, this.tags, this.buildWorkspace, this.buildCache, this.launchCache, this.createdDate,
|
||||||
this.applicationDirectory, securityOptions);
|
this.applicationDirectory, securityOptions, this.trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -464,6 +494,19 @@ public class BuildRequest {
|
||||||
return this.builder;
|
return this.builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the builder should be treated as trusted.
|
||||||
|
* @return the trust builder flag
|
||||||
|
* @since 3.4.0
|
||||||
|
*/
|
||||||
|
public boolean isTrustBuilder() {
|
||||||
|
return (this.trustBuilder != null) ? this.trustBuilder : isBuilderKnownAndTrusted();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isBuilderKnownAndTrusted() {
|
||||||
|
return KNOWN_TRUSTED_BUILDERS.stream().anyMatch((builder) -> builder.getName().equals(this.builder.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the run image that should be used, if provided.
|
* Return the run image that should be used, if provided.
|
||||||
* @return the run image
|
* @return the run image
|
||||||
|
|
|
@ -161,43 +161,104 @@ class Lifecycle implements Closeable {
|
||||||
if (this.request.isCleanCache()) {
|
if (this.request.isCleanCache()) {
|
||||||
deleteCache(this.buildCache);
|
deleteCache(this.buildCache);
|
||||||
}
|
}
|
||||||
run(createPhase());
|
if (this.request.isTrustBuilder()) {
|
||||||
|
run(createPhase());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
run(analyzePhase());
|
||||||
|
run(detectPhase());
|
||||||
|
if (!this.request.isCleanCache()) {
|
||||||
|
run(restorePhase());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.log.skippingPhase("restorer", "because 'cleanCache' is enabled");
|
||||||
|
}
|
||||||
|
run(buildPhase());
|
||||||
|
run(exportPhase());
|
||||||
|
}
|
||||||
this.log.executedLifecycle(this.request);
|
this.log.executedLifecycle(this.request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Phase createPhase() {
|
private Phase createPhase() {
|
||||||
Phase phase = new Phase("creator", isVerboseLogging());
|
Phase phase = new Phase("creator", isVerboseLogging());
|
||||||
phase.withDaemonAccess();
|
phase.withApp(this.applicationDirectory,
|
||||||
|
Binding.from(getCacheBindingSource(this.application), this.applicationDirectory));
|
||||||
|
phase.withPlatform(Directory.PLATFORM);
|
||||||
|
phase.withRunImage(this.request.getRunImage());
|
||||||
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
|
phase.withBuildCache(Directory.CACHE, Binding.from(getCacheBindingSource(this.buildCache), Directory.CACHE));
|
||||||
|
phase.withLaunchCache(Directory.LAUNCH_CACHE,
|
||||||
|
Binding.from(getCacheBindingSource(this.launchCache), Directory.LAUNCH_CACHE));
|
||||||
configureDaemonAccess(phase);
|
configureDaemonAccess(phase);
|
||||||
phase.withLogLevelArg();
|
|
||||||
phase.withArgs("-app", this.applicationDirectory);
|
|
||||||
phase.withArgs("-platform", Directory.PLATFORM);
|
|
||||||
phase.withArgs("-run-image", this.request.getRunImage());
|
|
||||||
phase.withArgs("-layers", Directory.LAYERS);
|
|
||||||
phase.withArgs("-cache-dir", Directory.CACHE);
|
|
||||||
phase.withArgs("-launch-cache", Directory.LAUNCH_CACHE);
|
|
||||||
phase.withArgs("-daemon");
|
|
||||||
if (this.request.isCleanCache()) {
|
if (this.request.isCleanCache()) {
|
||||||
phase.withArgs("-skip-restore");
|
phase.withSkipRestore();
|
||||||
}
|
}
|
||||||
if (requiresProcessTypeDefault()) {
|
if (requiresProcessTypeDefault()) {
|
||||||
phase.withArgs("-process-type=web");
|
phase.withProcessType("web");
|
||||||
}
|
}
|
||||||
phase.withArgs(this.request.getName());
|
phase.withImageName(this.request.getName());
|
||||||
phase.withBinding(Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
configureOptions(phase);
|
||||||
phase.withBinding(Binding.from(getCacheBindingSource(this.application), this.applicationDirectory));
|
configureCreatedDate(phase);
|
||||||
phase.withBinding(Binding.from(getCacheBindingSource(this.buildCache), Directory.CACHE));
|
return phase;
|
||||||
phase.withBinding(Binding.from(getCacheBindingSource(this.launchCache), Directory.LAUNCH_CACHE));
|
|
||||||
if (this.request.getBindings() != null) {
|
}
|
||||||
this.request.getBindings().forEach(phase::withBinding);
|
|
||||||
}
|
private Phase analyzePhase() {
|
||||||
phase.withEnv(PLATFORM_API_VERSION_KEY, this.platformVersion.toString());
|
Phase phase = new Phase("analyzer", isVerboseLogging());
|
||||||
if (this.request.getNetwork() != null) {
|
configureDaemonAccess(phase);
|
||||||
phase.withNetworkMode(this.request.getNetwork());
|
phase.withLaunchCache(Directory.LAUNCH_CACHE,
|
||||||
}
|
Binding.from(getCacheBindingSource(this.launchCache), Directory.LAUNCH_CACHE));
|
||||||
if (this.request.getCreatedDate() != null) {
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
phase.withEnv(SOURCE_DATE_EPOCH_KEY, Long.toString(this.request.getCreatedDate().getEpochSecond()));
|
phase.withRunImage(this.request.getRunImage());
|
||||||
|
phase.withImageName(this.request.getName());
|
||||||
|
configureOptions(phase);
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Phase detectPhase() {
|
||||||
|
Phase phase = new Phase("detector", isVerboseLogging());
|
||||||
|
phase.withApp(this.applicationDirectory,
|
||||||
|
Binding.from(getCacheBindingSource(this.application), this.applicationDirectory));
|
||||||
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
|
phase.withPlatform(Directory.PLATFORM);
|
||||||
|
configureOptions(phase);
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Phase restorePhase() {
|
||||||
|
Phase phase = new Phase("restorer", isVerboseLogging());
|
||||||
|
configureDaemonAccess(phase);
|
||||||
|
phase.withBuildCache(Directory.CACHE, Binding.from(getCacheBindingSource(this.buildCache), Directory.CACHE));
|
||||||
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
|
configureOptions(phase);
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Phase buildPhase() {
|
||||||
|
Phase phase = new Phase("builder", isVerboseLogging());
|
||||||
|
phase.withApp(this.applicationDirectory,
|
||||||
|
Binding.from(getCacheBindingSource(this.application), this.applicationDirectory));
|
||||||
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
|
phase.withPlatform(Directory.PLATFORM);
|
||||||
|
configureOptions(phase);
|
||||||
|
return phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Phase exportPhase() {
|
||||||
|
Phase phase = new Phase("exporter", isVerboseLogging());
|
||||||
|
configureDaemonAccess(phase);
|
||||||
|
phase.withApp(this.applicationDirectory,
|
||||||
|
Binding.from(getCacheBindingSource(this.application), this.applicationDirectory));
|
||||||
|
phase.withBuildCache(Directory.CACHE, Binding.from(getCacheBindingSource(this.buildCache), Directory.CACHE));
|
||||||
|
phase.withLaunchCache(Directory.LAUNCH_CACHE,
|
||||||
|
Binding.from(getCacheBindingSource(this.launchCache), Directory.LAUNCH_CACHE));
|
||||||
|
phase.withLayers(Directory.LAYERS, Binding.from(getCacheBindingSource(this.layers), Directory.LAYERS));
|
||||||
|
if (requiresProcessTypeDefault()) {
|
||||||
|
phase.withProcessType("web");
|
||||||
}
|
}
|
||||||
|
phase.withImageName(this.request.getName());
|
||||||
|
configureOptions(phase);
|
||||||
|
configureCreatedDate(phase);
|
||||||
return phase;
|
return phase;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,6 +299,7 @@ class Lifecycle implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureDaemonAccess(Phase phase) {
|
private void configureDaemonAccess(Phase phase) {
|
||||||
|
phase.withDaemonAccess();
|
||||||
if (this.dockerHost != null) {
|
if (this.dockerHost != null) {
|
||||||
if (this.dockerHost.isRemote()) {
|
if (this.dockerHost.isRemote()) {
|
||||||
phase.withEnv("DOCKER_HOST", this.dockerHost.getAddress());
|
phase.withEnv("DOCKER_HOST", this.dockerHost.getAddress());
|
||||||
|
@ -258,6 +320,22 @@ class Lifecycle implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configureCreatedDate(Phase phase) {
|
||||||
|
if (this.request.getCreatedDate() != null) {
|
||||||
|
phase.withEnv(SOURCE_DATE_EPOCH_KEY, Long.toString(this.request.getCreatedDate().getEpochSecond()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureOptions(Phase phase) {
|
||||||
|
if (this.request.getBindings() != null) {
|
||||||
|
this.request.getBindings().forEach(phase::withBinding);
|
||||||
|
}
|
||||||
|
if (this.request.getNetwork() != null) {
|
||||||
|
phase.withNetworkMode(this.request.getNetwork());
|
||||||
|
}
|
||||||
|
phase.withEnv(PLATFORM_API_VERSION_KEY, this.platformVersion.toString());
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isVerboseLogging() {
|
private boolean isVerboseLogging() {
|
||||||
return this.request.isVerboseLogging() && this.lifecycleVersion.isEqualOrGreaterThan(LOGGING_MINIMUM_VERSION);
|
return this.request.isVerboseLogging() && this.lifecycleVersion.isEqualOrGreaterThan(LOGGING_MINIMUM_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -269,7 +347,7 @@ class Lifecycle implements Closeable {
|
||||||
private void run(Phase phase) throws IOException {
|
private void run(Phase phase) throws IOException {
|
||||||
Consumer<LogUpdateEvent> logConsumer = this.log.runningPhase(this.request, phase.getName());
|
Consumer<LogUpdateEvent> logConsumer = this.log.runningPhase(this.request, phase.getName());
|
||||||
ContainerConfig containerConfig = ContainerConfig.of(this.builder.getName(), phase::apply);
|
ContainerConfig containerConfig = ContainerConfig.of(this.builder.getName(), phase::apply);
|
||||||
ContainerReference reference = createContainer(containerConfig);
|
ContainerReference reference = createContainer(containerConfig, phase.requiresApp());
|
||||||
try {
|
try {
|
||||||
this.docker.container().start(reference);
|
this.docker.container().start(reference);
|
||||||
this.docker.container().logs(reference, logConsumer::accept);
|
this.docker.container().logs(reference, logConsumer::accept);
|
||||||
|
@ -283,8 +361,8 @@ class Lifecycle implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContainerReference createContainer(ContainerConfig config) throws IOException {
|
private ContainerReference createContainer(ContainerConfig config, boolean requiresAppUpload) throws IOException {
|
||||||
if (this.applicationVolumePopulated) {
|
if (!requiresAppUpload || this.applicationVolumePopulated) {
|
||||||
return this.docker.container().create(config);
|
return this.docker.container().create(config);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
@ -339,8 +417,7 @@ class Lifecycle implements Closeable {
|
||||||
* <p>
|
* <p>
|
||||||
* Maps to the {@code <layers...>} concept in the
|
* Maps to the {@code <layers...>} concept in the
|
||||||
* <a href="https://github.com/buildpacks/spec/blob/master/buildpack.md">buildpack
|
* <a href="https://github.com/buildpacks/spec/blob/master/buildpack.md">buildpack
|
||||||
* specification</a> and the {@code -layers} argument from the reference lifecycle
|
* specification</a> and the {@code -layers} argument to lifecycle phases.
|
||||||
* implementation.
|
|
||||||
*/
|
*/
|
||||||
static final String LAYERS = "/layers";
|
static final String LAYERS = "/layers";
|
||||||
|
|
||||||
|
@ -367,8 +444,7 @@ class Lifecycle implements Closeable {
|
||||||
* <p>
|
* <p>
|
||||||
* Maps to the {@code <platform>/env} and {@code <platform>/#} concepts in the
|
* Maps to the {@code <platform>/env} and {@code <platform>/#} concepts in the
|
||||||
* <a href="https://github.com/buildpacks/spec/blob/master/buildpack.md">buildpack
|
* <a href="https://github.com/buildpacks/spec/blob/master/buildpack.md">buildpack
|
||||||
* specification</a> and the {@code -platform} argument from the reference
|
* specification</a> and the {@code -platform} argument to lifecycle phases.
|
||||||
* lifecycle implementation.
|
|
||||||
*/
|
*/
|
||||||
static final String PLATFORM = "/platform";
|
static final String PLATFORM = "/platform";
|
||||||
|
|
||||||
|
@ -377,8 +453,7 @@ class Lifecycle implements Closeable {
|
||||||
* image {@link BuildRequest#getName() name} being built, and is persistent across
|
* image {@link BuildRequest#getName() name} being built, and is persistent across
|
||||||
* invocations even if the application content has changed.
|
* invocations even if the application content has changed.
|
||||||
* <p>
|
* <p>
|
||||||
* Maps to the {@code -path} argument from the reference lifecycle implementation
|
* Maps to the {@code -path} argument to lifecycle phases.
|
||||||
* cache and restore phases
|
|
||||||
*/
|
*/
|
||||||
static final String CACHE = "/cache";
|
static final String CACHE = "/cache";
|
||||||
|
|
||||||
|
@ -387,8 +462,7 @@ class Lifecycle implements Closeable {
|
||||||
* based on the image {@link BuildRequest#getName() name} being built, and is
|
* based on the image {@link BuildRequest#getName() name} being built, and is
|
||||||
* persistent across invocations even if the application content has changed.
|
* persistent across invocations even if the application content has changed.
|
||||||
* <p>
|
* <p>
|
||||||
* Maps to the {@code -launch-cache} argument from the reference lifecycle
|
* Maps to the {@code -launch-cache} argument to lifecycle phases.
|
||||||
* implementation export phase
|
|
||||||
*/
|
*/
|
||||||
static final String LAUNCH_CACHE = "/launch-cache";
|
static final String LAUNCH_CACHE = "/launch-cache";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2022 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -24,6 +24,7 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
||||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
|
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
|
||||||
|
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,8 +38,6 @@ class Phase {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final boolean verboseLogging;
|
|
||||||
|
|
||||||
private boolean daemonAccess = false;
|
private boolean daemonAccess = false;
|
||||||
|
|
||||||
private final List<String> args = new ArrayList<>();
|
private final List<String> args = new ArrayList<>();
|
||||||
|
@ -51,6 +50,8 @@ class Phase {
|
||||||
|
|
||||||
private String networkMode;
|
private String networkMode;
|
||||||
|
|
||||||
|
private boolean requiresApp = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link Phase} instance.
|
* Create a new {@link Phase} instance.
|
||||||
* @param name the name of the phase
|
* @param name the name of the phase
|
||||||
|
@ -58,22 +59,65 @@ class Phase {
|
||||||
*/
|
*/
|
||||||
Phase(String name, boolean verboseLogging) {
|
Phase(String name, boolean verboseLogging) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.verboseLogging = verboseLogging;
|
withLogLevelArg(verboseLogging);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withApp(String path, Binding binding) {
|
||||||
|
withArgs("-app", path);
|
||||||
|
withBinding(binding);
|
||||||
|
this.requiresApp = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void withBuildCache(String path, Binding binding) {
|
||||||
|
withArgs("-cache-dir", path);
|
||||||
|
withBinding(binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this phase with Docker daemon access.
|
* Update this phase with Docker daemon access.
|
||||||
*/
|
*/
|
||||||
void withDaemonAccess() {
|
void withDaemonAccess() {
|
||||||
|
this.withArgs("-daemon");
|
||||||
this.daemonAccess = true;
|
this.daemonAccess = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void withImageName(ImageReference imageName) {
|
||||||
|
withArgs(imageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withLaunchCache(String path, Binding binding) {
|
||||||
|
withArgs("-launch-cache", path);
|
||||||
|
withBinding(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withLayers(String path, Binding binding) {
|
||||||
|
withArgs("-layers", path);
|
||||||
|
withBinding(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withPlatform(String path) {
|
||||||
|
withArgs("-platform", path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withProcessType(String type) {
|
||||||
|
withArgs("-process-type", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withRunImage(ImageReference runImage) {
|
||||||
|
withArgs("-run-image", runImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void withSkipRestore() {
|
||||||
|
withArgs("-skip-restore");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this phase with a debug log level arguments if verbose logging has been
|
* Update this phase with a debug log level arguments if verbose logging has been
|
||||||
* requested.
|
* requested.
|
||||||
|
* @param verboseLogging if verbose logging is requested
|
||||||
*/
|
*/
|
||||||
void withLogLevelArg() {
|
private void withLogLevelArg(boolean verboseLogging) {
|
||||||
if (this.verboseLogging) {
|
if (verboseLogging) {
|
||||||
this.args.add("-log-level");
|
this.args.add("-log-level");
|
||||||
this.args.add("debug");
|
this.args.add("debug");
|
||||||
}
|
}
|
||||||
|
@ -128,6 +172,10 @@ class Phase {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean requiresApp() {
|
||||||
|
return this.requiresApp;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.name;
|
return this.name;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,14 +27,18 @@ import java.time.ZoneId;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.io.TempDir;
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
|
||||||
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
import org.springframework.boot.buildpack.platform.docker.type.Binding;
|
||||||
|
import org.springframework.boot.buildpack.platform.docker.type.ImageName;
|
||||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||||
|
@ -64,7 +68,7 @@ class BuildRequestTests {
|
||||||
writeTestJarFile(jarFile);
|
writeTestJarFile(jarFile);
|
||||||
BuildRequest request = BuildRequest.forJarFile(jarFile);
|
BuildRequest request = BuildRequest.forJarFile(jarFile);
|
||||||
assertThat(request.getName()).hasToString("docker.io/library/my-app:0.0.1");
|
assertThat(request.getName()).hasToString("docker.io/library/my-app:0.0.1");
|
||||||
assertThat(request.getBuilder()).hasToString("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME);
|
assertThat(request.getBuilder()).hasToString("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_REF);
|
||||||
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
||||||
assertThat(request.getEnv()).isEmpty();
|
assertThat(request.getEnv()).isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -75,7 +79,7 @@ class BuildRequestTests {
|
||||||
writeTestJarFile(jarFile);
|
writeTestJarFile(jarFile);
|
||||||
BuildRequest request = BuildRequest.forJarFile(ImageReference.of("test-app"), jarFile);
|
BuildRequest request = BuildRequest.forJarFile(ImageReference.of("test-app"), jarFile);
|
||||||
assertThat(request.getName()).hasToString("docker.io/library/test-app:latest");
|
assertThat(request.getName()).hasToString("docker.io/library/test-app:latest");
|
||||||
assertThat(request.getBuilder()).hasToString("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_NAME);
|
assertThat(request.getBuilder()).hasToString("docker.io/" + BuildRequest.DEFAULT_BUILDER_IMAGE_REF);
|
||||||
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
||||||
assertThat(request.getEnv()).isEmpty();
|
assertThat(request.getEnv()).isEmpty();
|
||||||
}
|
}
|
||||||
|
@ -104,6 +108,7 @@ class BuildRequestTests {
|
||||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
||||||
.withBuilder(ImageReference.of("spring/builder"));
|
.withBuilder(ImageReference.of("spring/builder"));
|
||||||
assertThat(request.getBuilder()).hasToString("docker.io/spring/builder:latest");
|
assertThat(request.getBuilder()).hasToString("docker.io/spring/builder:latest");
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -113,6 +118,53 @@ class BuildRequestTests {
|
||||||
.of("spring/builder@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"));
|
.of("spring/builder@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"));
|
||||||
assertThat(request.getBuilder()).hasToString(
|
assertThat(request.getBuilder()).hasToString(
|
||||||
"docker.io/spring/builder@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
"docker.io/spring/builder@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withoutBuilderTrustsDefaultBuilder() throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withoutBuilderTrustsDefaultBuilderWithDifferentTag() throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
||||||
|
.withBuilder(ImageReference.of(ImageName.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME), "other"));
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withoutBuilderTrustsDefaultBuilderWithDigest() throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
||||||
|
.withBuilder(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)
|
||||||
|
.withDigest("sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d"));
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("trustedBuilders")
|
||||||
|
void withKnownTrustedBuilderTrustsBuilder(ImageReference builder) throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar")).withBuilder(builder);
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Stream<ImageReference> trustedBuilders() {
|
||||||
|
return BuildRequest.KNOWN_TRUSTED_BUILDERS.stream();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withoutTrustBuilderAndDefaultBuilderUpdatesTrustsBuilder() throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar")).withTrustBuilder(false);
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void withTrustBuilderAndBuilderUpdatesTrustBuilder() throws IOException {
|
||||||
|
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
||||||
|
.withBuilder(ImageReference.of("spring/builder"))
|
||||||
|
.withTrustBuilder(true);
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -86,7 +86,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -97,7 +97,7 @@ class BuilderTests {
|
||||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull());
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull());
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull());
|
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull());
|
||||||
then(docker.image()).should().load(archive.capture(), any());
|
then(docker.image()).should().load(archive.capture(), any());
|
||||||
|
@ -115,7 +115,7 @@ class BuilderTests {
|
||||||
.withBuilderRegistryTokenAuthentication("builder token")
|
.withBuilderRegistryTokenAuthentication("builder token")
|
||||||
.withPublishRegistryTokenAuthentication("publish token");
|
.withPublishRegistryTokenAuthentication("publish token");
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
|
@ -129,7 +129,7 @@ class BuilderTests {
|
||||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(),
|
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(),
|
||||||
|
@ -168,7 +168,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image-with-run-image-digest.json");
|
Image builderImage = loadImage("image-with-run-image-digest.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
.pull(eq(ImageReference
|
.pull(eq(ImageReference
|
||||||
|
@ -211,7 +211,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("example.com/custom/run:latest")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("example.com/custom/run:latest")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -231,11 +231,11 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME))))
|
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||||
.willReturn(builderImage);
|
.willReturn(builderImage);
|
||||||
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
||||||
.willReturn(runImage);
|
.willReturn(runImage);
|
||||||
|
@ -257,11 +257,11 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME))))
|
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||||
.willReturn(builderImage);
|
.willReturn(builderImage);
|
||||||
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
given(docker.image().inspect(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb"))))
|
||||||
.willReturn(runImage);
|
.willReturn(runImage);
|
||||||
|
@ -283,11 +283,11 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME))))
|
given(docker.image().inspect(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF))))
|
||||||
.willThrow(
|
.willThrow(
|
||||||
new DockerEngineException("docker://localhost/", new URI("example"), 404, "NOT FOUND", null, null))
|
new DockerEngineException("docker://localhost/", new URI("example"), 404, "NOT FOUND", null, null))
|
||||||
.willReturn(builderImage);
|
.willReturn(builderImage);
|
||||||
|
@ -313,7 +313,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -339,7 +339,7 @@ class BuilderTests {
|
||||||
.withBuilderRegistryTokenAuthentication("builder token")
|
.withBuilderRegistryTokenAuthentication("builder token")
|
||||||
.withPublishRegistryTokenAuthentication("publish token");
|
.withPublishRegistryTokenAuthentication("publish token");
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
|
@ -354,7 +354,7 @@ class BuilderTests {
|
||||||
assertThat(out.toString()).contains("Successfully created image tag 'docker.io/library/my-application:1.2.3'");
|
assertThat(out.toString()).contains("Successfully created image tag 'docker.io/library/my-application:1.2.3'");
|
||||||
|
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()));
|
||||||
then(docker.image()).should()
|
then(docker.image()).should()
|
||||||
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(),
|
.pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(),
|
||||||
|
@ -378,7 +378,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApi();
|
DockerApi docker = mockDockerApi();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image-with-bad-stack.json");
|
Image runImage = loadImage("run-image-with-bad-stack.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -395,7 +395,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApiLifecycleError();
|
DockerApi docker = mockDockerApiLifecycleError();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -413,7 +413,7 @@ class BuilderTests {
|
||||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||||
.withBuilderRegistryTokenAuthentication("builder token");
|
.withBuilderRegistryTokenAuthentication("builder token");
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||||
|
@ -431,7 +431,7 @@ class BuilderTests {
|
||||||
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
DockerConfiguration dockerConfiguration = new DockerConfiguration()
|
||||||
.withBuilderRegistryTokenAuthentication("builder token");
|
.withBuilderRegistryTokenAuthentication("builder token");
|
||||||
given(docker.image()
|
given(docker.image()
|
||||||
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(),
|
.pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(),
|
||||||
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
eq(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader())))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
Builder builder = new Builder(BuildLog.to(out), docker, dockerConfiguration);
|
||||||
|
@ -447,7 +447,7 @@ class BuilderTests {
|
||||||
DockerApi docker = mockDockerApiLifecycleError();
|
DockerApi docker = mockDockerApiLifecycleError();
|
||||||
Image builderImage = loadImage("image.json");
|
Image builderImage = loadImage("image.json");
|
||||||
Image runImage = loadImage("run-image.json");
|
Image runImage = loadImage("run-image.json");
|
||||||
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_NAME)), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of(BuildRequest.DEFAULT_BUILDER_IMAGE_REF)), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(builderImage));
|
.willAnswer(withPulledImage(builderImage));
|
||||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:base-cnb")), any(), isNull()))
|
||||||
.willAnswer(withPulledImage(runImage));
|
.willAnswer(withPulledImage(runImage));
|
||||||
|
@ -490,7 +490,7 @@ class BuilderTests {
|
||||||
private BuildRequest getTestRequest() {
|
private BuildRequest getTestRequest() {
|
||||||
TarArchive content = mock(TarArchive.class);
|
TarArchive content = mock(TarArchive.class);
|
||||||
ImageReference name = ImageReference.of("my-application");
|
ImageReference name = ImageReference.of("my-application");
|
||||||
return BuildRequest.of(name, (owner) -> content);
|
return BuildRequest.of(name, (owner) -> content).withTrustBuilder(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Image loadImage(String name) throws IOException {
|
private Image loadImage(String name) throws IOException {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -34,6 +34,7 @@ import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
import org.skyscreamer.jsonassert.JSONAssert;
|
import org.skyscreamer.jsonassert.JSONAssert;
|
||||||
|
|
||||||
|
@ -53,6 +54,7 @@ import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
|
||||||
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
||||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||||
import org.springframework.boot.buildpack.platform.json.SharedObjectMapper;
|
import org.springframework.boot.buildpack.platform.json.SharedObjectMapper;
|
||||||
|
import org.springframework.boot.testsupport.junit.BooleanValueSource;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -87,13 +89,23 @@ class LifecycleTests {
|
||||||
this.docker = mockDockerApi();
|
this.docker = mockDockerApi();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
createLifecycle().execute();
|
createLifecycle(trustBuilder).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +114,7 @@ class LifecycleTests {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withBindings(Binding.of("/host/src/path:/container/dest/path:ro"),
|
BuildRequest request = getTestRequest(true).withBindings(Binding.of("/host/src/path:/container/dest/path:ro"),
|
||||||
Binding.of("volume-name:/container/volume/path:rw"));
|
Binding.of("volume-name:/container/volume/path:rw"));
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-bindings.json"));
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-bindings.json"));
|
||||||
|
@ -114,48 +126,62 @@ class LifecycleTests {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
createLifecycle("builder-metadata-platform-api-0.3.json").execute();
|
createLifecycle(true, "builder-metadata-platform-api-0.3.json").execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-platform-api-0.3.json"));
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-platform-api-0.3.json"));
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeOnlyUploadsContentOnce() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeOnlyUploadsContentOnce(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
createLifecycle().execute();
|
createLifecycle(trustBuilder).execute();
|
||||||
assertThat(this.content).hasSize(1);
|
assertThat(this.content).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWhenAlreadyRunThrowsException() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWhenAlreadyRunThrowsException(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
Lifecycle lifecycle = createLifecycle();
|
Lifecycle lifecycle = createLifecycle(trustBuilder);
|
||||||
lifecycle.execute();
|
lifecycle.execute();
|
||||||
assertThatIllegalStateException().isThrownBy(lifecycle::execute)
|
assertThatIllegalStateException().isThrownBy(lifecycle::execute)
|
||||||
.withMessage("Lifecycle has already been executed");
|
.withMessage("Lifecycle has already been executed");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWhenBuilderReturnsErrorThrowsException() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWhenBuilderReturnsErrorThrowsException(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(9, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(9, null));
|
||||||
assertThatExceptionOfType(BuilderException.class).isThrownBy(() -> createLifecycle().execute())
|
assertThatExceptionOfType(BuilderException.class).isThrownBy(() -> createLifecycle(trustBuilder).execute())
|
||||||
.withMessage("Builder lifecycle 'creator' failed with status code 9");
|
.withMessage(
|
||||||
|
"Builder lifecycle '" + ((trustBuilder) ? "creator" : "analyzer") + "' failed with status code 9");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWhenCleanCacheClearsCache() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWhenCleanCacheClearsCache(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withCleanCache(true);
|
BuildRequest request = getTestRequest(trustBuilder).withCleanCache(true);
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-clean-cache.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-clean-cache.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter.json"));
|
||||||
|
assertThat(this.out.toString()).contains("Skipping restorer because 'cleanCache' is enabled");
|
||||||
|
}
|
||||||
VolumeName name = VolumeName.of("pack-cache-b35197ac41ea.build");
|
VolumeName name = VolumeName.of("pack-cache-b35197ac41ea.build");
|
||||||
then(this.docker.volume()).should().delete(name, true);
|
then(this.docker.volume()).should().delete(name, true);
|
||||||
}
|
}
|
||||||
|
@ -166,7 +192,7 @@ class LifecycleTests {
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(() -> createLifecycle("builder-metadata-unsupported-api.json").execute())
|
.isThrownBy(() -> createLifecycle(true, "builder-metadata-unsupported-api.json").execute())
|
||||||
.withMessageContaining("Detected platform API versions '0.2' are not included in supported versions");
|
.withMessageContaining("Detected platform API versions '0.2' are not included in supported versions");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,22 +202,32 @@ class LifecycleTests {
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(() -> createLifecycle("builder-metadata-unsupported-apis.json").execute())
|
.isThrownBy(() -> createLifecycle(true, "builder-metadata-unsupported-apis.json").execute())
|
||||||
.withMessageContaining("Detected platform API versions '0.1,0.2' are not included in supported versions");
|
.withMessageContaining("Detected platform API versions '0.1,0.2' are not included in supported versions");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWhenMultiplePlatformApisSupportedExecutesPhase() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWhenMultiplePlatformApisSupportedExecutesPhase(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
createLifecycle("builder-metadata-supported-apis.json").execute();
|
createLifecycle(trustBuilder, "builder-metadata-supported-apis.json").execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter.json"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void closeClearsVolumes() throws Exception {
|
void closeClearsVolumes() throws Exception {
|
||||||
createLifecycle().close();
|
createLifecycle(true).close();
|
||||||
then(this.docker.volume()).should().delete(VolumeName.of("pack-layers-aaaaaaaaaa"), true);
|
then(this.docker.volume()).should().delete(VolumeName.of("pack-layers-aaaaaaaaaa"), true);
|
||||||
then(this.docker.volume()).should().delete(VolumeName.of("pack-app-aaaaaaaaaa"), true);
|
then(this.docker.volume()).should().delete(VolumeName.of("pack-app-aaaaaaaaaa"), true);
|
||||||
}
|
}
|
||||||
|
@ -201,92 +237,163 @@ class LifecycleTests {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withNetwork("test");
|
BuildRequest request = getTestRequest(true).withNetwork("test");
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-network.json"));
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-network.json"));
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithCacheVolumeNamesExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithCacheVolumeNamesExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withBuildWorkspace(Cache.volume("work-volume"))
|
BuildRequest request = getTestRequest(trustBuilder).withBuildWorkspace(Cache.volume("work-volume"))
|
||||||
.withBuildCache(Cache.volume("build-volume"))
|
.withBuildCache(Cache.volume("build-volume"))
|
||||||
.withLaunchCache(Cache.volume("launch-volume"));
|
.withLaunchCache(Cache.volume("launch-volume"));
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-cache-volumes.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-cache-volumes.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-cache-volumes.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector-cache-volumes.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-cache-volumes.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder-cache-volumes.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-cache-volumes.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithCacheBindMountsExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithCacheBindMountsExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withBuildWorkspace(Cache.bind("/tmp/work"))
|
BuildRequest request = getTestRequest(trustBuilder).withBuildWorkspace(Cache.bind("/tmp/work"))
|
||||||
.withBuildCache(Cache.bind("/tmp/build-cache"))
|
.withBuildCache(Cache.bind("/tmp/build-cache"))
|
||||||
.withLaunchCache(Cache.bind("/tmp/launch-cache"));
|
.withLaunchCache(Cache.bind("/tmp/launch-cache"));
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-cache-bind-mounts.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-cache-bind-mounts.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-cache-bind-mounts.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector-cache-bind-mounts.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-cache-bind-mounts.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder-cache-bind-mounts.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-cache-bind-mounts.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithCreatedDateExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithCreatedDateExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withCreatedDate("2020-07-01T12:34:56Z");
|
BuildRequest request = getTestRequest(trustBuilder).withCreatedDate("2020-07-01T12:34:56Z");
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-created-date.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-created-date.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-created-date.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithApplicationDirectoryExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithApplicationDirectoryExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withApplicationDirectory("/application");
|
BuildRequest request = getTestRequest(trustBuilder).withApplicationDirectory("/application");
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-app-dir.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-app-dir.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector-app-dir.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder-app-dir.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-app-dir.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithSecurityOptionsExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithSecurityOptionsExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest().withSecurityOptions(List.of("label=user:USER", "label=role:ROLE"));
|
BuildRequest request = getTestRequest(trustBuilder)
|
||||||
|
.withSecurityOptions(List.of("label=user:USER", "label=role:ROLE"));
|
||||||
createLifecycle(request).execute();
|
createLifecycle(request).execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-security-opts.json", true));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-security-opts.json", true));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-security-opts.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-security-opts.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-security-opts.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithDockerHostAndRemoteAddressExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithDockerHostAndRemoteAddressExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest();
|
BuildRequest request = getTestRequest(trustBuilder);
|
||||||
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376")))
|
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376")))
|
||||||
.execute();
|
.execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-remote.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-remote.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-inherit-remote.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-inherit-remote.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-inherit-remote.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@ParameterizedTest
|
||||||
void executeWithDockerHostAndLocalAddressExecutesPhases() throws Exception {
|
@BooleanValueSource
|
||||||
|
void executeWithDockerHostAndLocalAddressExecutesPhases(boolean trustBuilder) throws Exception {
|
||||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||||
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
|
||||||
BuildRequest request = getTestRequest();
|
BuildRequest request = getTestRequest(trustBuilder);
|
||||||
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("/var/alt.sock")))
|
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("/var/alt.sock")))
|
||||||
.execute();
|
.execute();
|
||||||
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-local.json"));
|
if (trustBuilder) {
|
||||||
|
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-local.json"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer-inherit-local.json"));
|
||||||
|
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||||
|
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer-inherit-local.json"));
|
||||||
|
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||||
|
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter-inherit-local.json"));
|
||||||
|
}
|
||||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,14 +408,16 @@ class LifecycleTests {
|
||||||
return docker;
|
return docker;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BuildRequest getTestRequest() {
|
private BuildRequest getTestRequest(boolean trustBuilder) {
|
||||||
TarArchive content = mock(TarArchive.class);
|
TarArchive content = mock(TarArchive.class);
|
||||||
ImageReference name = ImageReference.of("my-application");
|
ImageReference name = ImageReference.of("my-application");
|
||||||
return BuildRequest.of(name, (owner) -> content).withRunImage(ImageReference.of("cloudfoundry/run"));
|
return BuildRequest.of(name, (owner) -> content)
|
||||||
|
.withRunImage(ImageReference.of("cloudfoundry/run"))
|
||||||
|
.withTrustBuilder(trustBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lifecycle createLifecycle() throws IOException {
|
private Lifecycle createLifecycle(boolean trustBuilder) throws IOException {
|
||||||
return createLifecycle(getTestRequest());
|
return createLifecycle(getTestRequest(trustBuilder));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lifecycle createLifecycle(BuildRequest request) throws IOException {
|
private Lifecycle createLifecycle(BuildRequest request) throws IOException {
|
||||||
|
@ -316,9 +425,9 @@ class LifecycleTests {
|
||||||
return createLifecycle(request, builder);
|
return createLifecycle(request, builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lifecycle createLifecycle(String builderMetadata) throws IOException {
|
private Lifecycle createLifecycle(boolean trustBuilder, String builderMetadata) throws IOException {
|
||||||
EphemeralBuilder builder = mockEphemeralBuilder(builderMetadata);
|
EphemeralBuilder builder = mockEphemeralBuilder(builderMetadata);
|
||||||
return createLifecycle(getTestRequest(), builder);
|
return createLifecycle(getTestRequest(trustBuilder), builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Lifecycle createLifecycle(BuildRequest request, ResolvedDockerHost dockerHost) throws IOException {
|
private Lifecycle createLifecycle(BuildRequest request, ResolvedDockerHost dockerHost) throws IOException {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2022 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -66,7 +66,7 @@ class PhaseTests {
|
||||||
Update update = mock(Update.class);
|
Update update = mock(Update.class);
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
then(update).should().withUser("root");
|
then(update).should().withUser("root");
|
||||||
then(update).should().withCommand("/cnb/lifecycle/test", NO_ARGS);
|
then(update).should().withCommand("/cnb/lifecycle/test", "-daemon");
|
||||||
then(update).should().withLabel("author", "spring-boot");
|
then(update).should().withLabel("author", "spring-boot");
|
||||||
then(update).shouldHaveNoMoreInteractions();
|
then(update).shouldHaveNoMoreInteractions();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,6 @@ class PhaseTests {
|
||||||
@Test
|
@Test
|
||||||
void applyWhenWithLogLevelArgAndVerboseLoggingUpdatesConfigurationWithLogLevel() {
|
void applyWhenWithLogLevelArgAndVerboseLoggingUpdatesConfigurationWithLogLevel() {
|
||||||
Phase phase = new Phase("test", true);
|
Phase phase = new Phase("test", true);
|
||||||
phase.withLogLevelArg();
|
|
||||||
Update update = mock(Update.class);
|
Update update = mock(Update.class);
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
then(update).should().withCommand("/cnb/lifecycle/test", "-log-level", "debug");
|
then(update).should().withCommand("/cnb/lifecycle/test", "-log-level", "debug");
|
||||||
|
@ -85,7 +84,6 @@ class PhaseTests {
|
||||||
@Test
|
@Test
|
||||||
void applyWhenWithLogLevelArgAndNonVerboseLoggingDoesNotUpdateLogLevel() {
|
void applyWhenWithLogLevelArgAndNonVerboseLoggingDoesNotUpdateLogLevel() {
|
||||||
Phase phase = new Phase("test", false);
|
Phase phase = new Phase("test", false);
|
||||||
phase.withLogLevelArg();
|
|
||||||
Update update = mock(Update.class);
|
Update update = mock(Update.class);
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
then(update).should().withCommand("/cnb/lifecycle/test");
|
then(update).should().withCommand("/cnb/lifecycle/test");
|
||||||
|
@ -133,7 +131,7 @@ class PhaseTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void applyWhenWithNetworkModeUpdatesConfigurationWithNetworkMode() {
|
void applyWhenWithNetworkModeUpdatesConfigurationWithNetworkMode() {
|
||||||
Phase phase = new Phase("test", true);
|
Phase phase = new Phase("test", false);
|
||||||
phase.withNetworkMode("test");
|
phase.withNetworkMode("test");
|
||||||
Update update = mock(Update.class);
|
Update update = mock(Update.class);
|
||||||
phase.apply(update);
|
phase.apply(update);
|
||||||
|
@ -145,7 +143,7 @@ class PhaseTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void applyWhenWithSecurityOptionsUpdatesConfigurationWithSecurityOptions() {
|
void applyWhenWithSecurityOptionsUpdatesConfigurationWithSecurityOptions() {
|
||||||
Phase phase = new Phase("test", true);
|
Phase phase = new Phase("test", false);
|
||||||
phase.withSecurityOption("option1=value1");
|
phase.withSecurityOption("option1=value1");
|
||||||
phase.withSecurityOption("option2=value2");
|
phase.withSecurityOption("option2=value2");
|
||||||
Update update = mock(Update.class);
|
Update update = mock(Update.class);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"/tmp/launch-cache:/launch-cache",
|
||||||
|
"/tmp/work-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"launch-volume:/launch-cache",
|
||||||
|
"work-volume-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/alt.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"DOCKER_HOST=tcp://192.168.1.2:2376",
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=user:USER",
|
||||||
|
"label=role:ROLE"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/analyzer",
|
||||||
|
"-daemon",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-run-image",
|
||||||
|
"docker.io/cloudfoundry/run:latest",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/builder",
|
||||||
|
"-app",
|
||||||
|
"/application",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-app-aaaaaaaaaa:/application",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/builder",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/tmp/work-app:/workspace",
|
||||||
|
"/tmp/work-layers:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/builder",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"work-volume-app:/workspace",
|
||||||
|
"work-volume-layers:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/builder",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/application",
|
"pack-app-aaaaaaaaaa:/application",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
"/host/src/path:/container/dest/path:ro",
|
"/host/src/path:/container/dest/path:ro",
|
||||||
"volume-name:/container/volume/path:rw"
|
"volume-name:/container/volume/path:rw"
|
||||||
],
|
],
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"/tmp/work-layers:/layers",
|
|
||||||
"/tmp/work-app:/workspace",
|
"/tmp/work-app:/workspace",
|
||||||
|
"/tmp/work-layers:/layers",
|
||||||
"/tmp/build-cache:/cache",
|
"/tmp/build-cache:/cache",
|
||||||
"/tmp/launch-cache:/launch-cache"
|
"/tmp/launch-cache:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"work-volume-layers:/layers",
|
|
||||||
"work-volume-app:/workspace",
|
"work-volume-app:/workspace",
|
||||||
|
"work-volume-layers:/layers",
|
||||||
"build-volume:/cache",
|
"build-volume:/cache",
|
||||||
"launch-volume:/launch-cache"
|
"launch-volume:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/alt.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/alt.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
||||||
],
|
],
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"NetworkMode": "test",
|
"NetworkMode": "test",
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -7,7 +7,13 @@
|
||||||
"author" : "spring-boot"
|
"author" : "spring-boot"
|
||||||
},
|
},
|
||||||
"HostConfig" : {
|
"HostConfig" : {
|
||||||
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace", "pack-cache-b35197ac41ea.build:/cache", "pack-cache-b35197ac41ea.launch:/launch-cache" ],
|
"Binds" : [
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
]
|
]
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=user:USER",
|
"label=user:USER",
|
||||||
|
|
|
@ -26,11 +26,11 @@
|
||||||
},
|
},
|
||||||
"HostConfig": {
|
"HostConfig": {
|
||||||
"Binds": [
|
"Binds": [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock",
|
|
||||||
"pack-layers-aaaaaaaaaa:/layers",
|
|
||||||
"pack-app-aaaaaaaaaa:/workspace",
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers",
|
||||||
"pack-cache-b35197ac41ea.build:/cache",
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
"pack-cache-b35197ac41ea.launch:/launch-cache"
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
],
|
],
|
||||||
"SecurityOpt" : [
|
"SecurityOpt" : [
|
||||||
"label=disable"
|
"label=disable"
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/detector",
|
||||||
|
"-app",
|
||||||
|
"/application",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-app-aaaaaaaaaa:/application",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/detector",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/tmp/work-app:/workspace",
|
||||||
|
"/tmp/work-layers:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/detector",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"work-volume-app:/workspace",
|
||||||
|
"work-volume-layers:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/detector",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"-platform",
|
||||||
|
"/platform"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/application",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-app-aaaaaaaaaa:/application",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"/tmp/work-app:/workspace",
|
||||||
|
"/tmp/build-cache:/cache",
|
||||||
|
"/tmp/launch-cache:/launch-cache",
|
||||||
|
"/tmp/work-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"work-volume-app:/workspace",
|
||||||
|
"build-volume:/cache",
|
||||||
|
"launch-volume:/launch-cache",
|
||||||
|
"work-volume-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8",
|
||||||
|
"SOURCE_DATE_EPOCH=1593606896"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/alt.sock:/var/run/docker.sock",
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"DOCKER_HOST=tcp://192.168.1.2:2376",
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=user:USER",
|
||||||
|
"label=role:ROLE"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/exporter",
|
||||||
|
"-daemon",
|
||||||
|
"-app",
|
||||||
|
"/workspace",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-launch-cache",
|
||||||
|
"/launch-cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers",
|
||||||
|
"docker.io/library/my-application:latest"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-app-aaaaaaaaaa:/workspace",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-cache-b35197ac41ea.launch:/launch-cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"/tmp/build-cache:/cache",
|
||||||
|
"/tmp/work-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"build-volume:/cache",
|
||||||
|
"work-volume-layers:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/alt.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"DOCKER_HOST=tcp://192.168.1.2:2376",
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=user:USER",
|
||||||
|
"label=role:ROLE"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"User": "root",
|
||||||
|
"Image": "pack.local/ephemeral-builder",
|
||||||
|
"Cmd": [
|
||||||
|
"/cnb/lifecycle/restorer",
|
||||||
|
"-daemon",
|
||||||
|
"-cache-dir",
|
||||||
|
"/cache",
|
||||||
|
"-layers",
|
||||||
|
"/layers"
|
||||||
|
],
|
||||||
|
"Env": [
|
||||||
|
"CNB_PLATFORM_API=0.8"
|
||||||
|
],
|
||||||
|
"Labels": {
|
||||||
|
"author": "spring-boot"
|
||||||
|
},
|
||||||
|
"HostConfig": {
|
||||||
|
"Binds": [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock",
|
||||||
|
"pack-cache-b35197ac41ea.build:/cache",
|
||||||
|
"pack-layers-aaaaaaaaaa:/layers"
|
||||||
|
],
|
||||||
|
"SecurityOpt" : [
|
||||||
|
"label=disable"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,6 +78,23 @@ class BootBuildImageIntegrationTests {
|
||||||
String projectName = this.gradleBuild.getProjectDir().getName();
|
String projectName = this.gradleBuild.getProjectDir().getName();
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
||||||
|
assertThat(result.getOutput()).contains("Running detector");
|
||||||
|
assertThat(result.getOutput()).contains("Running builder");
|
||||||
|
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||||
|
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
||||||
|
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||||
|
removeImages(projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestTemplate
|
||||||
|
void buildsImageWithTrustBuilder() throws IOException {
|
||||||
|
writeMainClass();
|
||||||
|
writeLongNameResource();
|
||||||
|
BuildResult result = this.gradleBuild.build("bootBuildImage");
|
||||||
|
String projectName = this.gradleBuild.getProjectDir().getName();
|
||||||
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||||
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
assertThat(result.getOutput()).contains("Network status: HTTP/2 200");
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||||
|
@ -146,10 +163,11 @@ class BootBuildImageIntegrationTests {
|
||||||
writeLongNameResource();
|
writeLongNameResource();
|
||||||
BuildResult result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT",
|
BuildResult result = this.gradleBuild.build("bootBuildImage", "--pullPolicy=IF_NOT_PRESENT",
|
||||||
"--imageName=example/test-image-cmd", "--builder=ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1",
|
"--imageName=example/test-image-cmd", "--builder=ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1",
|
||||||
"--runImage=paketobuildpacks/run-jammy-tiny", "--createdDate=2020-07-01T12:34:56Z",
|
"--trustBuilder", "--runImage=paketobuildpacks/run-jammy-tiny", "--createdDate=2020-07-01T12:34:56Z",
|
||||||
"--applicationDirectory=/application");
|
"--applicationDirectory=/application");
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
assertThat(result.getOutput()).contains("example/test-image-cmd");
|
assertThat(result.getOutput()).contains("example/test-image-cmd");
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack building");
|
||||||
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
|
||||||
Image image = new DockerApi().image().inspect(ImageReference.of("example/test-image-cmd"));
|
Image image = new DockerApi().image().inspect(ImageReference.of("example/test-image-cmd"));
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'org.springframework.boot' version '{version}'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.hasProperty('applyWarPlugin')) {
|
||||||
|
apply plugin: 'war'
|
||||||
|
}
|
||||||
|
|
||||||
|
bootBuildImage {
|
||||||
|
builder = "ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1"
|
||||||
|
trustBuilder = true
|
||||||
|
pullPolicy = "IF_NOT_PRESENT"
|
||||||
|
}
|
|
@ -118,9 +118,14 @@ The following table summarizes the available properties and their default values
|
||||||
|
|
||||||
| `builder`
|
| `builder`
|
||||||
| `--builder`
|
| `--builder`
|
||||||
| Name of the Builder image to use.
|
| Name of the builder image to use.
|
||||||
| `paketobuildpacks/builder-jammy-tiny:latest`
|
| `paketobuildpacks/builder-jammy-tiny:latest`
|
||||||
|
|
||||||
|
| `trustBuilder`
|
||||||
|
| `--trustBuilder`
|
||||||
|
| Whether to treat the builder as https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/concepts/trusted_builders/#what-is-a-trusted-builder[trusted].
|
||||||
|
| `true` if the builder is one of `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; false otherwise.
|
||||||
|
|
||||||
| `runImage`
|
| `runImage`
|
||||||
| `--runImage`
|
| `--runImage`
|
||||||
| Name of the run image to use.
|
| Name of the run image to use.
|
||||||
|
|
|
@ -91,6 +91,7 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||||
}
|
}
|
||||||
return ImageReference.of(imageName, projectVersion.get()).toString();
|
return ImageReference.of(imageName, projectVersion.get()).toString();
|
||||||
}));
|
}));
|
||||||
|
getTrustBuilder().convention((Boolean) null);
|
||||||
getCleanCache().convention(false);
|
getCleanCache().convention(false);
|
||||||
getVerboseLogging().convention(false);
|
getVerboseLogging().convention(false);
|
||||||
getPublish().convention(false);
|
getPublish().convention(false);
|
||||||
|
@ -131,6 +132,16 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||||
@Option(option = "builder", description = "The name of the builder image to use")
|
@Option(option = "builder", description = "The name of the builder image to use")
|
||||||
public abstract Property<String> getBuilder();
|
public abstract Property<String> getBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to treat the builder as trusted.
|
||||||
|
* @return whether to trust the builder
|
||||||
|
* @since 3.4.0
|
||||||
|
*/
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
@Option(option = "trustBuilder", description = "Consider the builder trusted")
|
||||||
|
public abstract Property<Boolean> getTrustBuilder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the run image that will be included in the built image. When {@code null},
|
* Returns the run image that will be included in the built image. When {@code null},
|
||||||
* the run image bundled with the builder will be used.
|
* the run image bundled with the builder will be used.
|
||||||
|
@ -348,13 +359,16 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||||
|
|
||||||
private BuildRequest customize(BuildRequest request) {
|
private BuildRequest customize(BuildRequest request) {
|
||||||
request = customizeBuilder(request);
|
request = customizeBuilder(request);
|
||||||
|
if (getTrustBuilder().isPresent()) {
|
||||||
|
request = request.withTrustBuilder(getTrustBuilder().get());
|
||||||
|
}
|
||||||
request = customizeRunImage(request);
|
request = customizeRunImage(request);
|
||||||
request = customizeEnvironment(request);
|
request = customizeEnvironment(request);
|
||||||
request = customizeCreator(request);
|
request = customizeCreator(request);
|
||||||
request = request.withCleanCache(getCleanCache().get());
|
request = request.withCleanCache(getCleanCache().get());
|
||||||
request = request.withVerboseLogging(getVerboseLogging().get());
|
request = request.withVerboseLogging(getVerboseLogging().get());
|
||||||
request = customizePullPolicy(request);
|
request = customizePullPolicy(request);
|
||||||
request = customizePublish(request);
|
request = request.withPublish(getPublish().get());
|
||||||
request = customizeBuildpacks(request);
|
request = customizeBuildpacks(request);
|
||||||
request = customizeBindings(request);
|
request = customizeBindings(request);
|
||||||
request = customizeTags(request);
|
request = customizeTags(request);
|
||||||
|
@ -406,11 +420,6 @@ public abstract class BootBuildImage extends DefaultTask {
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BuildRequest customizePublish(BuildRequest request) {
|
|
||||||
request = request.withPublish(getPublish().get());
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
private BuildRequest customizeBuildpacks(BuildRequest request) {
|
private BuildRequest customizeBuildpacks(BuildRequest request) {
|
||||||
List<String> buildpacks = getBuildpacks().getOrNull();
|
List<String> buildpacks = getBuildpacks().getOrNull();
|
||||||
if (!CollectionUtils.isEmpty(buildpacks)) {
|
if (!CollectionUtils.isEmpty(buildpacks)) {
|
||||||
|
|
|
@ -172,14 +172,24 @@ class BootBuildImageTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void whenNoBuilderIsConfiguredThenRequestHasDefaultBuilder() {
|
void whenNoBuilderIsConfiguredThenRequestHasDefaultBuilder() {
|
||||||
assertThat(this.buildImage.createRequest().getBuilder().getName())
|
BuildRequest request = this.buildImage.createRequest();
|
||||||
.isEqualTo("paketobuildpacks/builder-jammy-tiny");
|
assertThat(request.getBuilder().getName()).isEqualTo("paketobuildpacks/builder-jammy-tiny");
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void whenBuilderIsConfiguredThenRequestUsesSpecifiedBuilder() {
|
void whenBuilderIsConfiguredThenRequestUsesSpecifiedBuilder() {
|
||||||
this.buildImage.getBuilder().set("example.com/test/builder:1.2");
|
this.buildImage.getBuilder().set("example.com/test/builder:1.2");
|
||||||
assertThat(this.buildImage.createRequest().getBuilder().getName()).isEqualTo("test/builder");
|
BuildRequest request = this.buildImage.createRequest();
|
||||||
|
assertThat(request.getBuilder().getName()).isEqualTo("test/builder");
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenTrustBuilderIsEnabledThenRequestHasTrustBuilderEnabled() {
|
||||||
|
this.buildImage.getBuilder().set("example.com/test/builder:1.2");
|
||||||
|
this.buildImage.getTrustBuilder().set(true);
|
||||||
|
assertThat(this.buildImage.createRequest().isTrustBuilder()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -68,6 +68,8 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
|
||||||
assertThat(original).doesNotExist();
|
assertThat(original).doesNotExist();
|
||||||
assertThat(buildLog(project)).contains("Building image")
|
assertThat(buildLog(project)).contains("Building image")
|
||||||
.contains("docker.io/library/build-image:0.0.1.BUILD-SNAPSHOT")
|
.contains("docker.io/library/build-image:0.0.1.BUILD-SNAPSHOT")
|
||||||
|
.contains("Running detector")
|
||||||
|
.contains("Running builder")
|
||||||
.contains("---> Test Info buildpack building")
|
.contains("---> Test Info buildpack building")
|
||||||
.contains("---> Test Info buildpack done")
|
.contains("---> Test Info buildpack done")
|
||||||
.contains("Successfully built image");
|
.contains("Successfully built image");
|
||||||
|
@ -88,6 +90,8 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
|
||||||
assertThat(original).doesNotExist();
|
assertThat(original).doesNotExist();
|
||||||
assertThat(buildLog(project)).contains("Building image")
|
assertThat(buildLog(project)).contains("Building image")
|
||||||
.contains("docker.io/library/build-image-cmd-line:0.0.1.BUILD-SNAPSHOT")
|
.contains("docker.io/library/build-image-cmd-line:0.0.1.BUILD-SNAPSHOT")
|
||||||
|
.contains("Running detector")
|
||||||
|
.contains("Running builder")
|
||||||
.contains("---> Test Info buildpack building")
|
.contains("---> Test Info buildpack building")
|
||||||
.contains("---> Test Info buildpack done")
|
.contains("---> Test Info buildpack done")
|
||||||
.contains("Successfully built image");
|
.contains("Successfully built image");
|
||||||
|
@ -248,12 +252,14 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
|
||||||
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT")
|
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT")
|
||||||
.systemProperty("spring-boot.build-image.imageName", "example.com/test/cmd-property-name:v1")
|
.systemProperty("spring-boot.build-image.imageName", "example.com/test/cmd-property-name:v1")
|
||||||
.systemProperty("spring-boot.build-image.builder", "ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1")
|
.systemProperty("spring-boot.build-image.builder", "ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1")
|
||||||
|
.systemProperty("spring-boot.build-image.trustBuilder", "true")
|
||||||
.systemProperty("spring-boot.build-image.runImage", "paketobuildpacks/run-jammy-tiny")
|
.systemProperty("spring-boot.build-image.runImage", "paketobuildpacks/run-jammy-tiny")
|
||||||
.systemProperty("spring-boot.build-image.createdDate", "2020-07-01T12:34:56Z")
|
.systemProperty("spring-boot.build-image.createdDate", "2020-07-01T12:34:56Z")
|
||||||
.systemProperty("spring-boot.build-image.applicationDirectory", "/application")
|
.systemProperty("spring-boot.build-image.applicationDirectory", "/application")
|
||||||
.execute((project) -> {
|
.execute((project) -> {
|
||||||
assertThat(buildLog(project)).contains("Building image")
|
assertThat(buildLog(project)).contains("Building image")
|
||||||
.contains("example.com/test/cmd-property-name:v1")
|
.contains("example.com/test/cmd-property-name:v1")
|
||||||
|
.contains("Running creator")
|
||||||
.contains("---> Test Info buildpack building")
|
.contains("---> Test Info buildpack building")
|
||||||
.contains("---> Test Info buildpack done")
|
.contains("---> Test Info buildpack done")
|
||||||
.contains("Successfully built image");
|
.contains("Successfully built image");
|
||||||
|
@ -279,6 +285,22 @@ class BuildImageTests extends AbstractArchiveIntegrationTests {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestTemplate
|
||||||
|
void whenBuildImageIsInvokedWithTrustBuilder(MavenBuild mavenBuild) {
|
||||||
|
mavenBuild.project("dockerTest", "build-image-trust-builder")
|
||||||
|
.goals("package")
|
||||||
|
.systemProperty("spring-boot.build-image.pullPolicy", "IF_NOT_PRESENT")
|
||||||
|
.execute((project) -> {
|
||||||
|
assertThat(buildLog(project)).contains("Building image")
|
||||||
|
.contains("docker.io/library/build-image-v2-trust-builder:0.0.1.BUILD-SNAPSHOT")
|
||||||
|
.contains("Running creator")
|
||||||
|
.contains("---> Test Info buildpack building")
|
||||||
|
.contains("---> Test Info buildpack done")
|
||||||
|
.contains("Successfully built image");
|
||||||
|
removeImage("docker.io/library/build-image-v2-trust-builder", "0.0.1.BUILD-SNAPSHOT");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@TestTemplate
|
@TestTemplate
|
||||||
void whenBuildImageIsInvokedWithEmptyEnvEntry(MavenBuild mavenBuild) {
|
void whenBuildImageIsInvokedWithEmptyEnvEntry(MavenBuild mavenBuild) {
|
||||||
mavenBuild.project("dockerTest", "build-image-empty-env-entry")
|
mavenBuild.project("dockerTest", "build-image-empty-env-entry")
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>org.springframework.boot.maven.it</groupId>
|
||||||
|
<artifactId>build-image-v2-trust-builder</artifactId>
|
||||||
|
<version>0.0.1.BUILD-SNAPSHOT</version>
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>@java.version@</maven.compiler.source>
|
||||||
|
<maven.compiler.target>@java.version@</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>@project.groupId@</groupId>
|
||||||
|
<artifactId>@project.artifactId@</artifactId>
|
||||||
|
<version>@project.version@</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>build-image-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<image>
|
||||||
|
<builder>ghcr.io/spring-io/spring-boot-cnb-test-builder:0.0.1</builder>
|
||||||
|
<trustBuilder>true</trustBuilder>
|
||||||
|
</image>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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
|
||||||
|
*
|
||||||
|
* https://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 org.test;
|
||||||
|
|
||||||
|
public class SampleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
System.out.println("Launched");
|
||||||
|
synchronized(args) {
|
||||||
|
args.wait(); // Prevent exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -134,9 +134,14 @@ The following table summarizes the available parameters and their default values
|
||||||
|
|
||||||
| `builder` +
|
| `builder` +
|
||||||
(`spring-boot.build-image.builder`)
|
(`spring-boot.build-image.builder`)
|
||||||
| Name of the Builder image to use.
|
| Name of the builder image to use.
|
||||||
| `paketobuildpacks/builder-jammy-tiny:latest`
|
| `paketobuildpacks/builder-jammy-tiny:latest`
|
||||||
|
|
||||||
|
| `trustBuilder` +
|
||||||
|
(`spring-boot.build-image.trustBuilder`)
|
||||||
|
| Whether to treat the builder as https://buildpacks.io/docs/for-platform-operators/how-to/integrate-ci/pack/concepts/trusted_builders/#what-is-a-trusted-builder[trusted].
|
||||||
|
| `true` if the builder is one of `paketobuildpacks/builder-jammy-tiny`, `paketobuildpacks/builder-jammy-base`, `paketobuildpacks/builder-jammy-full`, `paketobuildpacks/builder-jammy-buildpackless-tiny`, `paketobuildpacks/builder-jammy-buildpackless-base`, `paketobuildpacks/builder-jammy-buildpackless-full`, `gcr.io/buildpacks/builder`, `heroku/builder`; false otherwise.
|
||||||
|
|
||||||
| `runImage` +
|
| `runImage` +
|
||||||
(`spring-boot.build-image.runImage`)
|
(`spring-boot.build-image.runImage`)
|
||||||
| Name of the run image to use.
|
| Name of the run image to use.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -118,6 +118,13 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo {
|
||||||
@Parameter(property = "spring-boot.build-image.builder", readonly = true)
|
@Parameter(property = "spring-boot.build-image.builder", readonly = true)
|
||||||
String imageBuilder;
|
String imageBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias for {@link Image#trustBuilder} to support configuration through command-line
|
||||||
|
* property.
|
||||||
|
*/
|
||||||
|
@Parameter(property = "spring-boot.build-image.trustBuilder", readonly = true)
|
||||||
|
Boolean trustBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for {@link Image#runImage} to support configuration through command-line
|
* Alias for {@link Image#runImage} to support configuration through command-line
|
||||||
* property.
|
* property.
|
||||||
|
@ -267,6 +274,9 @@ public abstract class BuildImageMojo extends AbstractPackagerMojo {
|
||||||
if (image.builder == null && this.imageBuilder != null) {
|
if (image.builder == null && this.imageBuilder != null) {
|
||||||
image.setBuilder(this.imageBuilder);
|
image.setBuilder(this.imageBuilder);
|
||||||
}
|
}
|
||||||
|
if (image.trustBuilder == null && this.trustBuilder != null) {
|
||||||
|
image.setTrustBuilder(this.trustBuilder);
|
||||||
|
}
|
||||||
if (image.runImage == null && this.runImage != null) {
|
if (image.runImage == null && this.runImage != null) {
|
||||||
image.setRunImage(this.runImage);
|
image.setRunImage(this.runImage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -49,6 +49,8 @@ public class Image {
|
||||||
|
|
||||||
String builder;
|
String builder;
|
||||||
|
|
||||||
|
Boolean trustBuilder;
|
||||||
|
|
||||||
String runImage;
|
String runImage;
|
||||||
|
|
||||||
Map<String, String> env;
|
Map<String, String> env;
|
||||||
|
@ -105,6 +107,18 @@ public class Image {
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the builder should be treated as trusted.
|
||||||
|
* @return {@code true} if the builder should be treated as trusted
|
||||||
|
*/
|
||||||
|
public Boolean getTrustBuilder() {
|
||||||
|
return this.trustBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setTrustBuilder(Boolean trustBuilder) {
|
||||||
|
this.trustBuilder = trustBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the run image to use to create the image.
|
* The name of the run image to use to create the image.
|
||||||
* @return the builder image name
|
* @return the builder image name
|
||||||
|
@ -221,6 +235,9 @@ public class Image {
|
||||||
if (StringUtils.hasText(this.builder)) {
|
if (StringUtils.hasText(this.builder)) {
|
||||||
request = request.withBuilder(ImageReference.of(this.builder));
|
request = request.withBuilder(ImageReference.of(this.builder));
|
||||||
}
|
}
|
||||||
|
if (this.trustBuilder != null) {
|
||||||
|
request = request.withTrustBuilder(this.trustBuilder);
|
||||||
|
}
|
||||||
if (StringUtils.hasText(this.runImage)) {
|
if (StringUtils.hasText(this.runImage)) {
|
||||||
request = request.withRunImage(ImageReference.of(this.runImage));
|
request = request.withRunImage(ImageReference.of(this.runImage));
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,11 +70,13 @@ class ImageTests {
|
||||||
BuildRequest request = new Image().getBuildRequest(createArtifact(), mockApplicationContent());
|
BuildRequest request = new Image().getBuildRequest(createArtifact(), mockApplicationContent());
|
||||||
assertThat(request.getName()).hasToString("docker.io/library/my-app:0.0.1-SNAPSHOT");
|
assertThat(request.getName()).hasToString("docker.io/library/my-app:0.0.1-SNAPSHOT");
|
||||||
assertThat(request.getBuilder().toString()).contains("paketobuildpacks/builder-jammy-tiny");
|
assertThat(request.getBuilder().toString()).contains("paketobuildpacks/builder-jammy-tiny");
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
assertThat(request.getRunImage()).isNull();
|
assertThat(request.getRunImage()).isNull();
|
||||||
assertThat(request.getEnv()).isEmpty();
|
assertThat(request.getEnv()).isEmpty();
|
||||||
assertThat(request.isCleanCache()).isFalse();
|
assertThat(request.isCleanCache()).isFalse();
|
||||||
assertThat(request.isVerboseLogging()).isFalse();
|
assertThat(request.isVerboseLogging()).isFalse();
|
||||||
assertThat(request.getPullPolicy()).isEqualTo(PullPolicy.ALWAYS);
|
assertThat(request.getPullPolicy()).isEqualTo(PullPolicy.ALWAYS);
|
||||||
|
assertThat(request.isPublish()).isFalse();
|
||||||
assertThat(request.getBuildpacks()).isEmpty();
|
assertThat(request.getBuildpacks()).isEmpty();
|
||||||
assertThat(request.getBindings()).isEmpty();
|
assertThat(request.getBindings()).isEmpty();
|
||||||
assertThat(request.getNetwork()).isNull();
|
assertThat(request.getNetwork()).isNull();
|
||||||
|
@ -86,6 +88,26 @@ class ImageTests {
|
||||||
image.builder = "springboot/builder:2.2.x";
|
image.builder = "springboot/builder:2.2.x";
|
||||||
BuildRequest request = image.getBuildRequest(createArtifact(), mockApplicationContent());
|
BuildRequest request = image.getBuildRequest(createArtifact(), mockApplicationContent());
|
||||||
assertThat(request.getBuilder()).hasToString("docker.io/springboot/builder:2.2.x");
|
assertThat(request.getBuilder()).hasToString("docker.io/springboot/builder:2.2.x");
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getBuildRequestWhenHasBuilderAndTrustBuilderUsesBuilderAndTrustBuilder() {
|
||||||
|
Image image = new Image();
|
||||||
|
image.builder = "springboot/builder:2.2.x";
|
||||||
|
image.trustBuilder = true;
|
||||||
|
BuildRequest request = image.getBuildRequest(createArtifact(), mockApplicationContent());
|
||||||
|
assertThat(request.getBuilder()).hasToString("docker.io/springboot/builder:2.2.x");
|
||||||
|
assertThat(request.isTrustBuilder()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void getBuildRequestWhenHasDefaultBuilderAndTrustBuilderUsesTrustBuilder() {
|
||||||
|
Image image = new Image();
|
||||||
|
image.trustBuilder = false;
|
||||||
|
BuildRequest request = image.getBuildRequest(createArtifact(), mockApplicationContent());
|
||||||
|
assertThat(request.getBuilder().toString()).contains("paketobuildpacks/builder-jammy-tiny");
|
||||||
|
assertThat(request.isTrustBuilder()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.testsupport.junit;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||||
|
import org.junit.platform.commons.util.Preconditions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link ArgumentsProvider} that provides {@code true} and {@code false} values.
|
||||||
|
*
|
||||||
|
* @author Scott Frederick
|
||||||
|
*/
|
||||||
|
class BooleanArgumentsProvider implements ArgumentsProvider {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
|
||||||
|
Method testMethod = context.getRequiredTestMethod();
|
||||||
|
Preconditions.condition(testMethod.getParameterCount() > 0, () -> String.format(
|
||||||
|
"@BooleanValueSource cannot provide arguments to method [%s]: the method does not declare any formal parameters.",
|
||||||
|
testMethod.toGenericString()));
|
||||||
|
|
||||||
|
return Stream.of(Arguments.arguments(false), Arguments.arguments(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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
|
||||||
|
*
|
||||||
|
* https://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 org.springframework.boot.testsupport.junit;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code @BooleanValueSource} is an {@link ArgumentsSource} which provides {@code true}
|
||||||
|
* and {@code false} values to the annotated {@code @ParameterizedTest} method.
|
||||||
|
*
|
||||||
|
* @author Scott Frederick
|
||||||
|
*/
|
||||||
|
@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
@ArgumentsSource(BooleanArgumentsProvider.class)
|
||||||
|
public @interface BooleanValueSource {
|
||||||
|
|
||||||
|
}
|
|
@ -48,7 +48,6 @@ import org.springframework.boot.image.junit.GradleBuildInjectionExtension;
|
||||||
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
|
import org.springframework.boot.testsupport.gradle.testkit.GradleBuild;
|
||||||
import org.springframework.boot.testsupport.gradle.testkit.GradleBuildExtension;
|
import org.springframework.boot.testsupport.gradle.testkit.GradleBuildExtension;
|
||||||
import org.springframework.boot.testsupport.gradle.testkit.GradleVersions;
|
import org.springframework.boot.testsupport.gradle.testkit.GradleVersions;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.entry;
|
import static org.assertj.core.api.Assertions.entry;
|
||||||
|
@ -85,6 +84,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -116,6 +116,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withCommand("--server.port=9090");
|
container.withCommand("--server.port=9090");
|
||||||
container.withExposedPorts(9090);
|
container.withExposedPorts(9090);
|
||||||
|
@ -133,6 +134,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -159,6 +161,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName, "assemble", "bootDistZip");
|
BuildResult result = buildImage(imageName, "assemble", "bootDistZip");
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -195,6 +198,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName, "assemble", "bootDistZip");
|
BuildResult result = buildImage(imageName, "assemble", "bootDistZip");
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -232,6 +236,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -264,6 +269,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -310,6 +316,7 @@ class PaketoBuilderTests {
|
||||||
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
ImageReference imageReference = ImageReference.of(ImageName.of(imageName));
|
||||||
BuildResult result = buildImage(imageName);
|
BuildResult result = buildImage(imageName);
|
||||||
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
|
||||||
|
assertThat(result.getOutput()).contains("Running creator");
|
||||||
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
try (GenericContainer<?> container = new GenericContainer<>(imageName)) {
|
||||||
container.withExposedPorts(8080);
|
container.withExposedPorts(8080);
|
||||||
container.waitingFor(Wait.forHttp("/test")).start();
|
container.waitingFor(Wait.forHttp("/test")).start();
|
||||||
|
@ -333,9 +340,11 @@ class PaketoBuilderTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
private BuildResult buildImage(String imageName, String... arguments) {
|
private BuildResult buildImage(String imageName, String... arguments) {
|
||||||
String[] buildImageArgs = { "bootBuildImage", "--imageName=" + imageName, "--pullPolicy=IF_NOT_PRESENT" };
|
List<String> args = new ArrayList<>(List.of(arguments));
|
||||||
String[] args = StringUtils.concatenateStringArrays(arguments, buildImageArgs);
|
args.add("bootBuildImage");
|
||||||
return this.gradleBuild.build(args);
|
args.add("--imageName=" + imageName);
|
||||||
|
args.add("--pullPolicy=IF_NOT_PRESENT");
|
||||||
|
return this.gradleBuild.build(args.toArray(new String[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeMainClass() throws IOException {
|
private void writeMainClass() throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue