From 4b03362015e6835bc7e4a239fc7e56c65c2533dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Mon, 21 Feb 2022 18:06:02 +0100 Subject: [PATCH] [KARAF-7367] add Reproducible Builds support --- pom.xml | 2 +- tooling/karaf-maven-plugin/pom.xml | 4 +-- .../src/it/test-kar-packaging/pom.xml | 4 +++ .../src/it/test-kar-packaging/verify.bsh | 26 ++++++++++++++++--- .../org/apache/karaf/tooling/KarMojo.java | 17 ++++++++++-- 5 files changed, 45 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 2cf3ba8150a..61e6503bfa4 100644 --- a/pom.xml +++ b/pom.xml @@ -315,7 +315,7 @@ 0.5.0 2.0 - 3.2.1 + 3.3.0 1.7.32 1.2.2 diff --git a/tooling/karaf-maven-plugin/pom.xml b/tooling/karaf-maven-plugin/pom.xml index cd12a982ba1..46594660696 100644 --- a/tooling/karaf-maven-plugin/pom.xml +++ b/tooling/karaf-maven-plugin/pom.xml @@ -165,12 +165,12 @@ org.apache.maven maven-archiver - 2.6 + 3.5.2 org.codehaus.plexus plexus-archiver - 3.6.0 + 4.2.7 org.apache.felix diff --git a/tooling/karaf-maven-plugin/src/it/test-kar-packaging/pom.xml b/tooling/karaf-maven-plugin/src/it/test-kar-packaging/pom.xml index ce2c53adef1..2100e958c6e 100644 --- a/tooling/karaf-maven-plugin/src/it/test-kar-packaging/pom.xml +++ b/tooling/karaf-maven-plugin/src/it/test-kar-packaging/pom.xml @@ -26,6 +26,10 @@ 1.0-SNAPSHOT kar + + 12 + + diff --git a/tooling/karaf-maven-plugin/src/it/test-kar-packaging/verify.bsh b/tooling/karaf-maven-plugin/src/it/test-kar-packaging/verify.bsh index 5de530cbc4e..02a05e205d1 100644 --- a/tooling/karaf-maven-plugin/src/it/test-kar-packaging/verify.bsh +++ b/tooling/karaf-maven-plugin/src/it/test-kar-packaging/verify.bsh @@ -19,11 +19,31 @@ import java.io.*; import java.lang.*; +import java.util.*; +import java.util.zip.*; // check if the kar archive has been pushed to the repository File generated = new File(basedir, "target/test-kar-packaging-1.0-SNAPSHOT.kar"); -if (generated.exists()) { - return true; +if (!generated.exists()) { + return false; } -return false; \ No newline at end of file +// check Reproducible Builds outputTimestamp +ZipFile zipFile = new ZipFile(generated); +Enumeration entries = zipFile.entries(); +long timestamp = -1; + +while(entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + long t = entry.getTime(); + if (timestamp == -1) { + timestamp = t; + } + if (t != timestamp) { + System.out.println(entry.getName() + " entry last modified = " + t + ", expected " + timestamp); + return false; + } +} +zipFile.close(); + +return true; \ No newline at end of file diff --git a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java index ad29b904fb6..75b96aa6fe8 100644 --- a/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java +++ b/tooling/karaf-maven-plugin/src/main/java/org/apache/karaf/tooling/KarMojo.java @@ -124,6 +124,16 @@ public class KarMojo extends MojoSupport { @Parameter(defaultValue = "${repositoryPath}") private String repositoryPath = "repository/"; + /** + * Timestamp for reproducible output archive entries, either formatted as ISO 8601 + * yyyy-MM-dd'T'HH:mm:ssXXX or as an int representing seconds since the epoch (like + * SOURCE_DATE_EPOCH). + * + * @since 4.4.0 + */ + @Parameter(defaultValue = "${project.build.outputTimestamp}") + private String outputTimestamp; + private static final Pattern mvnPattern = Pattern.compile("mvn:([^/ ]+)/([^/ ]+)/([^/ ]*)(/([^/ ]+)(/([^/ ]+))?)?"); @@ -246,10 +256,13 @@ private File createArchive(List bundles, File featuresFile, String gro File archiveFile = getArchiveFile(outputDirectory, finalName, classifier); MavenArchiver archiver = new MavenArchiver(); + archiver.setCreatedBy("Kar Maven Plugin", "org.apache.karaf.tooling", "karaf-maven-plugin"); MavenArchiveConfiguration configuration = new MavenArchiveConfiguration(); configuration.addManifestEntries(archive.getManifestEntries()); archiver.setArchiver(jarArchiver); archiver.setOutputFile(archiveFile); + // configure for Reproducible Builds based on outputTimestamp value + archiver.configureReproducible(outputTimestamp); try { //TODO should .kar be a bundle? @@ -270,7 +283,7 @@ private File createArchive(List bundles, File featuresFile, String gro // archive.addManifestEntry(Constants.BUNDLE_SYMBOLICNAME, project.getArtifactId()); //include the feature.xml - Artifact featureArtifact = factory.createArtifactWithClassifier(groupId, artifactId, version, "xml", KarArtifactInstaller.FEATURE_CLASSIFIER); + Artifact featureArtifact = factory.createArtifactWithClassifier(groupId, artifactId, version, "xml", KarArtifactInstaller.FEATURE_CLASSIFIER); jarArchiver.addFile(featuresFile, repositoryPath + layout.pathOf(featureArtifact)); if (featureArtifact.isSnapshot()) { @@ -347,7 +360,7 @@ private File createArchive(List bundles, File featuresFile, String gro if (resourcesDir.isDirectory()) { archiver.getArchiver().addDirectory(resourcesDir); } - archiver.createArchive(project, archive); + archiver.createArchive(mavenSession, project, archive); return archiveFile; } catch (Exception e) {