Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix wrong ordering of files in rpm when using feature to generate intermediate directories #90

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions src/it/test19-intermediate-directories-collect/verify.groovy
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
def dump() {
Process proc = ('rpm -q --dump -p ' + basedir + "/target/*.rpm").execute()
def verifyFileInodes() {
Process proc = ['rpm', '-q', '--queryformat', '[%{FILEINODES} %{FILEMODES:perms} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]', basedir.path + '/target/*.rpm'].execute() | 'sort -n'.execute()
proc.waitFor()
return proc.in.getText().trim()
}

def actual = dump()
println "Dump:\n" + actual
def actual = verifyFileInodes()
println "Verify file inodes:\n" + actual

def expected = """\
/opt/mycompany/myapp 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b/x/y/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100555 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/c 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/c/d 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/c/d/x 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/c/d/x/y 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/c/d/x/y/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100555 myuser mygroup 0 0 0 X""".stripIndent()
1 drwxrwxrwx myuser mygroup /opt/mycompany/myapp
2 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/a
3 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/a/b
4 -r-xr-xr-x myuser mygroup /opt/mycompany/myapp/a/b/x/y/foobar
5 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/c
6 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/c/d
7 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/c/d/x
8 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/c/d/x/y
9 -r-xr-xr-x myuser mygroup /opt/mycompany/myapp/c/d/x/y/foobar""".stripIndent()

if (actual != expected) {
System.out.format("RPM dump doesn't match - actual:%n%s%nexpected:%n%s%n", actual, expected);
System.out.format("RPM file inodes doesn't match - actual:%n%s%nexpected:%n%s%n", actual, expected);
return false;
}

Expand Down
8 changes: 4 additions & 4 deletions src/it/test19-intermediate-directories/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,13 @@

<entries>
<entry>
<name>/opt/mycompany/myapp/a/b/c/foobar</name>
<file>${project.basedir}/src/main/data/foobar</file>
<name>/opt/mycompany/myapp</name>
<directory>true</directory>
<ruleset>my-default</ruleset>
</entry>
<entry>
<name>/opt/mycompany/myapp</name>
<directory>true</directory>
<name>/opt/mycompany/myapp/a/b/c/foobar</name>
<file>${project.basedir}/src/main/data/foobar</file>
<ruleset>my-default</ruleset>
</entry>
<entry>
Expand Down
27 changes: 14 additions & 13 deletions src/it/test19-intermediate-directories/verify.groovy
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
def dump() {
Process proc = ('rpm -q --dump -p ' + basedir + "/target/*.rpm").execute()
def verifyFileInodes() {
Process proc = ['rpm', '-q', '--queryformat', '[%{FILEINODES} %{FILEMODES:perms} %-13{FILEUSERNAME} %-14{FILEGROUPNAME} %{FILENAMES}\n]', basedir.path + '/target/*.rpm'].execute() | 'sort -n'.execute()
proc.waitFor()
return proc.in.getText().trim()
}

def actual = dump()
println "Dump:\n" + actual
def actual = verifyFileInodes()
println "Verify file inodes:\n" + actual

def expected = """\
/etc/mycompany/myapp 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040755 root root 0 0 0 X
/etc/mycompany/myapp/defaults 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040755 root root 0 0 0 X
/opt/mycompany/myapp 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b/c 0 1230807600 0000000000000000000000000000000000000000000000000000000000000000 040777 myuser mygroup 0 0 0 X
/opt/mycompany/myapp/a/b/c/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100555 myuser mygroup 0 0 0 X
/opt/mycompany/otherapp/a/b/c/foobar 0 1230807600 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0100111 mygeneraluser mygeneralgroup 0 0 0 X""".stripIndent()
1 drwxrwxrwx myuser mygroup /opt/mycompany/myapp
2 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/a
3 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/a/b
4 drwxrwxrwx myuser mygroup /opt/mycompany/myapp/a/b/c
5 -r-xr-xr-x myuser mygroup /opt/mycompany/myapp/a/b/c/foobar
6 drwxr-xr-x root root /etc/mycompany/myapp
7 drwxr-xr-x root root /etc/mycompany/myapp/defaults
8 ---x--x--x mygeneraluser mygeneralgroup /opt/mycompany/otherapp/a/b/c/foobar""".stripIndent()

if (actual != expected) {
System.out.format("RPM dump doesn't match - actual:%n%s%nexpected:%n%s%n", actual, expected);
System.out.format("RPM file inodes doesn't match - actual:%n%s%nexpected:%n%s%n", actual, expected);
return false;
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,51 +11,78 @@
package de.dentrassi.rpm.builder;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.packager.rpm.build.BuilderContext;
import org.eclipse.packager.rpm.build.FileInformationProvider;

public class MissingDirectoryTracker implements BuilderContextListener {
public class MissingDirectoryGeneratorInterceptor implements BuilderContext {

private final BuilderContext builderContext;

// keep track of explicit added directories
private final Set<String> explicitAddedDirectories;
// keep track of all missing directories which should be added after processing (without explicit added directories)
private final Map<String, FileInformationProvider<Object>> missingDirectories;
// base directories (prefixes) for which the intermediate directories should be generated
private final List<String> baseDirectories;
// keep track of explicit added directories
private final Set<String> explicitAddedDirectories;
// keep track of all additionally generated and added directories
private final Set<String> generatedDirectories;

public MissingDirectoryTracker(List<String> baseDirectories) {
this.explicitAddedDirectories = new HashSet<>();
this.missingDirectories = new HashMap<>();
public MissingDirectoryGeneratorInterceptor(BuilderContext builderContext, List<String> baseDirectories) {
this.builderContext = builderContext;
this.baseDirectories = baseDirectories;
explicitAddedDirectories = new HashSet<>();
generatedDirectories = new HashSet<>();
}

@Override
public void setDefaultInformationProvider(FileInformationProvider<Object> provider) {
builderContext.setDefaultInformationProvider(provider);
}

@Override
public FileInformationProvider<Object> getDefaultInformationProvider() {
return builderContext.getDefaultInformationProvider();
}

@Override
public void notifyFileAdded(String targetName, FileInformationProvider<Object> provider) {
public void addFile(String targetName, Path source, FileInformationProvider<? super Path> provider) throws IOException {
addMissingDirectoriesFromPath(targetName, provider);
builderContext.addFile(targetName, source, provider);
}

@Override
public void notifyDirectoryAdded(String targetName, FileInformationProvider<Object> provider) {
explicitAddedDirectories.add(targetName);
missingDirectories.remove(targetName);
public void addFile(String targetName, InputStream source, FileInformationProvider<Object> provider) throws IOException {
addMissingDirectoriesFromPath(targetName, provider);
builderContext.addFile(targetName, source, provider);
}

@Override
public void notifySymbolicLinkAdded(String targetName, FileInformationProvider<Object> provider) {
public void addFile(String targetName, ByteBuffer source, FileInformationProvider<Object> provider) throws IOException {
addMissingDirectoriesFromPath(targetName, provider);
builderContext.addFile(targetName, source, provider);
}

private void addMissingDirectoriesFromPath(String targetName, FileInformationProvider<Object> provider) {
@Override
public void addDirectory(String targetName, FileInformationProvider<? super Directory> provider) throws IOException {
addMissingDirectoriesFromPath(targetName, provider);
builderContext.addDirectory(targetName, provider);
explicitAddedDirectories.add(targetName);
}

@Override
public void addSymbolicLink(String targetName, String linkTo, FileInformationProvider<? super SymbolicLink> provider) throws IOException {
addMissingDirectoriesFromPath(targetName, provider);
builderContext.addSymbolicLink(targetName, linkTo, provider);
}

private void addMissingDirectoriesFromPath(String targetName, FileInformationProvider<?> provider) throws IOException {
if (provider instanceof MojoFileInformationProvider) {
MojoFileInformationProvider mojoProvider = (MojoFileInformationProvider) provider;

Expand All @@ -76,15 +103,17 @@ private void addMissingDirectoriesFromPath(String targetName, FileInformationPro
}
}

private void addIfIsMissingDirectory(String intermediateDirectory, MojoFileInformationProvider mojoProvider) {
if (startsPathWithPrefix(intermediateDirectory) && !explicitAddedDirectories.contains(intermediateDirectory)) {
missingDirectories.computeIfAbsent(intermediateDirectory,
(String directory) -> new MojoFileInformationProvider(
private void addIfIsMissingDirectory(String intermediateDirectory, MojoFileInformationProvider mojoProvider) throws IOException {
if (startsPathWithPrefix(intermediateDirectory)
&& !explicitAddedDirectories.contains(intermediateDirectory)
&& !generatedDirectories.contains(intermediateDirectory)) {
builderContext.addDirectory(intermediateDirectory, new MojoFileInformationProvider(
mojoProvider.getRulesetEval(),
mojoProvider.getRuleId(),
null,
mojoProvider.getLogger(),
mojoProvider.getTimestamp()));
generatedDirectories.add(intermediateDirectory);
}
}

Expand All @@ -96,12 +125,6 @@ private boolean startsPathWithPrefix(String directory) {
return baseDirectories.stream().anyMatch(directory::startsWith);
}

public void addMissingIntermediateDirectoriesToContext(BuilderContext ctx) throws IOException {
for (Map.Entry<String, FileInformationProvider<Object>> missingEntry : missingDirectories.entrySet()) {
ctx.addDirectory(missingEntry.getKey(), missingEntry.getValue());
}
}

private List<String> getIntermediateDirectories(String targetName) {
ArrayList<String> intermediateDirectories = new ArrayList<>();
Path path = Paths.get(targetName);
Expand Down
14 changes: 6 additions & 8 deletions src/main/java/de/dentrassi/rpm/builder/RpmMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -1104,9 +1104,12 @@ protected void fillPayload(final RpmBuilder builder) throws MojoFailureException
return;
}

final ListenableBuilderContext ctx = new ListenableBuilderContext(builder.newContext());
final MissingDirectoryTracker missingDirectoryTracker = new MissingDirectoryTracker(this.generateIntermediateDirectories);
ctx.registerListener(missingDirectoryTracker);
final BuilderContext ctx;
if (this.generateIntermediateDirectories.isEmpty()) {
ctx = builder.newContext();
} else {
ctx = new MissingDirectoryGeneratorInterceptor(builder.newContext(), this.generateIntermediateDirectories);;
}

this.logger.debug("Building payload:");

Expand All @@ -1121,11 +1124,6 @@ protected void fillPayload(final RpmBuilder builder) throws MojoFailureException
fillFromEntry(ctx, entry);
}
}

ctx.removeListener(missingDirectoryTracker);
if (!generateIntermediateDirectories.isEmpty()) {
missingDirectoryTracker.addMissingIntermediateDirectoriesToContext(ctx);
}
}

private void customizeHeader(final RpmBuilder builder) {
Expand Down