Skip to content

Commit

Permalink
Merge pull request #926 from stuartwdouglas/STONEBLD-1954
Browse files Browse the repository at this point in the history
STONEBLD-1954 assign each build attempt a unique ID
  • Loading branch information
stuartwdouglas authored Nov 20, 2023
2 parents fb4b3f6 + 1f67ceb commit cb92d1b
Show file tree
Hide file tree
Showing 12 changed files with 73 additions and 51 deletions.
2 changes: 2 additions & 0 deletions deploy/crds/base/jvmbuildservice.io_dependencybuilds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ spec:
- complete
- pipelineName
type: object
buildId:
type: string
buildRecipe:
properties:
additionalDownloads:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ require (
github.com/CycloneDX/cyclonedx-go v0.7.1
github.com/aws/aws-sdk-go v1.46.2
github.com/google/go-containerregistry v0.15.2
github.com/google/uuid v1.3.0
github.com/redhat-appstudio/image-controller v0.0.0-20231003082540-48893226ba8b
github.com/tektoncd/cli v0.31.1
go.uber.org/zap v1.24.0
Expand Down Expand Up @@ -70,7 +71,6 @@ require (
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.15.2 // indirect
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b // indirect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ public class ContainerTagCommand implements Runnable {
@CommandLine.Option(names = "--registry-prepend-tag", defaultValue = "")
String prependTag;

@CommandLine.Option(names = "--image-id", required = true)
String imageId;
@CommandLine.Option(names = "--image-digest", required = true)
String imageDigest;

@CommandLine.Parameters(split = ",")
List<String> gavs;
Expand All @@ -41,9 +41,9 @@ public void run() {

ContainerRegistryDeployer deployer = new ContainerRegistryDeployer(host, port, owner, token.orElse(""), repository,
insecure,
prependTag, imageId);
prependTag);
try {
deployer.tagArchive(gavs);
deployer.tagArchive(imageDigest, gavs);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ public class DeployCommand implements Runnable {
private static final String DOT_POM = ".pom";
private static final String DOT = ".";
private static final Set<String> ALLOWED_CONTAMINANTS = Set.of("-tests.jar");
public static final String IMAGE_DIGEST_OUTPUT = "Image Digest: ";
final BeanManager beanManager;
final ResultsUpdater resultsUpdater;

Expand Down Expand Up @@ -133,6 +134,8 @@ public class DeployCommand implements Runnable {
@CommandLine.Option(names = "--git-identity")
String gitIdentity;

@CommandLine.Option(names = "--build-id")
String buildId;
// Testing only ; used to disable image deployment
protected boolean imageDeployment = true;

Expand Down Expand Up @@ -214,7 +217,7 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
+ gav.getVersion(),
"rebuilt",
Map.of("scm-uri", scmUri, "scm-commit", commit, "hermetic",
Boolean.toString(hermetic))),
Boolean.toString(hermetic), "build-id", buildId)),
Files.newOutputStream(temp), false);
Files.delete(file);
Files.move(temp, file);
Expand Down Expand Up @@ -305,6 +308,9 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
} else {
Log.errorf("Skipped deploying from task run %s as all artifacts were contaminated", taskRun);
}
if (imageDigest != null) {
System.out.println(IMAGE_DIGEST_OUTPUT + "sha256:" + imageDigest);
}
if (taskRun != null) {

List<Contaminates> newContaminates = new ArrayList<>();
Expand Down Expand Up @@ -383,15 +389,15 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th
protected void doDeployment(Path sourcePath, Path logsPath, Set<String> gavs) throws Exception {
if (imageDeployment) {
ContainerRegistryDeployer deployer = new ContainerRegistryDeployer(host, port, owner, token.orElse(""), repository,
insecure, prependTag,
imageId);
deployer.deployArchive(deploymentPath, sourcePath, logsPath, gavs, new BiConsumer<String, String>() {
@Override
public void accept(String s, String hash) {
imageName = s;
imageDigest = hash;
}
});
insecure, prependTag);
deployer.deployArchive(deploymentPath, sourcePath, logsPath, gavs, imageId, buildId,
new BiConsumer<String, String>() {
@Override
public void accept(String s, String hash) {
imageName = s;
imageDigest = hash;
}
});
}
if (isNotEmpty(mvnRepo)) {
// Maven Repo Deployment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class DeployHermeticPreBuildImageCommand implements Runnable {
public void run() {
ContainerRegistryDeployer deployer = new ContainerRegistryDeployer(host, port, owner, token.orElse(""), repository,
insecure,
prependTag, "");
prependTag);
try {
deployer.deployHermeticPreBuildImage(builderImage, buildArtifactsPath, repositoryPath, imageSourcePath, imageName,
new BiConsumer<String, String>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public class DeployPreBuildImageCommand implements Runnable {
public void run() {
ContainerRegistryDeployer deployer = new ContainerRegistryDeployer(host, port, owner, token.orElse(""), repository,
insecure,
prependTag, "");
prependTag);
try {
deployer.deployPreBuildImage(builderImage, sourcePath, imageSourcePath, imageName,
new BiConsumer<String, String>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
Expand Down Expand Up @@ -56,16 +55,14 @@ public class ContainerRegistryDeployer {

private final Credential credential;

final String imageId;

public ContainerRegistryDeployer(
String host,
int port,
String owner,
String token,
String repository,
boolean insecure,
String prependTag, String imageId) {
String prependTag) {
if (insecure) {
System.setProperty("sendCredentialsOverHttp", "true");
}
Expand All @@ -76,7 +73,6 @@ public ContainerRegistryDeployer(
this.repository = repository;
this.insecure = insecure;
this.prependTag = prependTag;
this.imageId = imageId;
String fullName = host + (port == 443 ? "" : ":" + port) + "/" + owner + "/" + repository;
this.credential = ContainerUtil.processToken(fullName, token);

Expand All @@ -86,18 +82,18 @@ public ContainerRegistryDeployer(
Log.infof("Prepend tag is %s", prependTag);
}

public void deployArchive(Path deployDir, Path sourcePath, Path logsPath, Set<String> gavs,
public void deployArchive(Path deployDir, Path sourcePath, Path logsPath, Set<String> gavs, String imageId, String buildId,
BiConsumer<String, String> imageNameHashCallback) throws Exception {
Log.debugf("Using Container registry %s:%d/%s/%s", host, port, owner, repository);

// Read the tar to get the gavs and files
DeployData imageData = new DeployData(deployDir, gavs);

// Create the image layers
createImages(imageData, sourcePath, logsPath, imageNameHashCallback);
createImages(imageData, sourcePath, logsPath, imageId, buildId, imageNameHashCallback);
}

public void tagArchive(List<String> gavNames) throws Exception {
public void tagArchive(String imageDigest, List<String> gavNames) throws Exception {
if (gavNames.isEmpty()) {
throw new RuntimeException("Empty GAV list");
}
Expand All @@ -107,7 +103,7 @@ public void tagArchive(List<String> gavNames) throws Exception {
gavs.push(Gav.parse(i));
}
Gav first = gavs.pop();
String existingImage = createImageName(imageId);
String existingImage = createImageNameFromDigest(imageDigest);
RegistryImage existingRegistryImage = RegistryImage.named(existingImage);
RegistryImage registryImage = RegistryImage.named(createImageName(first.getTag()));
if (credential != null) {
Expand Down Expand Up @@ -221,17 +217,18 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO
}

private void createImages(DeployData imageData, Path sourcePath, Path logsPath,
BiConsumer<String, String> imageNameHashCallback)
String imageId, String buildId, BiConsumer<String, String> imageNameHashCallback)
throws InvalidImageReferenceException, InterruptedException, RegistryException, IOException,
CacheDirectoryCreationException, ExecutionException {

String imageName = createImageName();
String imageName = createImageName(buildId);
RegistryImage registryImage = RegistryImage.named(imageName);
if (credential != null) {
registryImage = registryImage.addCredentialRetriever(() -> Optional.of(credential));
}
Containerizer containerizer = Containerizer
.to(registryImage)
.withAdditionalTag(imageId)
.setAllowInsecureRegistries(insecure);
Log.infof("Deploying base image %s", imageName);

Expand Down Expand Up @@ -260,11 +257,6 @@ private void createImages(DeployData imageData, Path sourcePath, Path logsPath,
}
}

private String createImageName() {
String tag = imageId == null ? UUID.randomUUID().toString() : imageId;
return createImageName(tag);
}

private String createImageName(String tag) {
// As the tests utilise prependTag for uniqueness so check for that
// here to avoid reusing images when we want differentiation.
Expand All @@ -284,6 +276,15 @@ private String createImageName(String tag) {
+ ":" + tag;
}

private String createImageNameFromDigest(String digest) {
if (port == 443) {
return host + "/" + owner + "/" + repository
+ "@" + digest;
}
return host + ":" + port + "/" + owner + "/" + repository
+ "@" + digest;
}

private List<Path> getLayers(Path artifacts, Path source, Path logs) {
Log.debug("\n Container details:\n"
+ "\t layer 1 (source) " + source.toString() + "\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -81,6 +83,7 @@ public void testDeployArchive(QuarkusMainLauncher launcher) throws IOException {
"--image-id=test-image",
"--registry-host=" + container.getHost(),
"--registry-port=" + port,
"--build-id=test-id",
"--registry-owner=" + OWNER,
"--registry-repository=" + REPOSITORY,
"--source-path=" + source.toAbsolutePath().toString(),
Expand All @@ -92,18 +95,24 @@ public void testDeployArchive(QuarkusMainLauncher launcher) throws IOException {
Assertions.assertEquals(0, result.exitCode());
// Now we validate that the image and tags exist in the registry
ContainerRegistryDetails containerRegistryDetails = getContainerRegistryDetails();

Assertions.assertTrue(containerRegistryDetails.repoName.startsWith(OWNER + "/" + REPOSITORY));
Assertions.assertTrue(containerRegistryDetails.tags.contains("test-image"));
Assertions.assertTrue(containerRegistryDetails.tags.contains("test-id"));
Assertions.assertFalse(containerRegistryDetails.tags.contains(EXPECTED_TAG_1));
Assertions.assertFalse(containerRegistryDetails.tags.contains(EXPECTED_TAG_2));
System.out.println(result.getOutput());
Pattern p = Pattern.compile(DeployCommand.IMAGE_DIGEST_OUTPUT + "(.*)");
Matcher matcher = p.matcher(result.getOutput());
Assertions.assertTrue(matcher.find());
String digest = matcher.group(1);

result = launcher.launch("tag-container",
"--registry-host=" + container.getHost(),
"--registry-port=" + port,
"--registry-owner=" + OWNER,
"--registry-repository=" + REPOSITORY,
"--registry-insecure",
"--image-id=test-image",
"--image-digest=" + digest,
GROUP + ":" + FOO_BAR + ":" + VERSION + "," + GROUP + ":" + FOO_BAZ + ":" + VERSION);
containerRegistryDetails = getContainerRegistryDetails();
Assertions.assertTrue(containerRegistryDetails.tags.contains(EXPECTED_TAG_1));
Expand Down Expand Up @@ -184,6 +193,7 @@ private URL getRegistryURL(String path) throws IOException {

class ContainerRegistryDetails {
String repoName;
String digest;
List<String> tags;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ spec:
- complete
- pipelineName
type: object
buildId:
type: string
buildRecipe:
properties:
additionalDownloads:
Expand Down
5 changes: 3 additions & 2 deletions pkg/apis/jvmbuildservice/v1alpha1/dependencybuild_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ type DependencyBuildList struct {
}

type BuildAttempt struct {
Recipe *BuildRecipe `json:"buildRecipe,omitempty"`
Build *BuildPipelineRun `json:"build,omitempty"`
BuildId string `json:"buildId,omitempty"`
Recipe *BuildRecipe `json:"buildRecipe,omitempty"`
Build *BuildPipelineRun `json:"build,omitempty"`
}

type BuildPipelineRun struct {
Expand Down
Loading

0 comments on commit cb92d1b

Please sign in to comment.