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

How to modify rpm file listing to not manage all directories #59

Open
cwalker67 opened this issue Oct 15, 2014 · 15 comments
Open

How to modify rpm file listing to not manage all directories #59

cwalker67 opened this issue Oct 15, 2014 · 15 comments
Labels

Comments

@cwalker67
Copy link

I'm kind of having a hard time trying to figure out how to configure an rpm to only manage a subset of directories being installed. for example:

buildRpm {
    into('/opt/test')
    from(war.outputs.files) {
        into('warDir')
        user 'testuser'
        groupPermission 'testgroup'
    } 
}

when you copy the rpm out to a linux box and query the list of files managed shows:

rpm -qpl testwar.rpm
/opt/test
/opt/test/warDir
/opt/test/warDir/test.war

Installation will cause the /opt/test directory ownership to be testuser:testgroup even if the directory already exists. The install will also fail if the /opt/test directory is managed by another rpm with a 'file conflict' error

What I would like to see from the rpm is:

rpm -qpl testwar.rpm
/opt/test/warDir
/opt/test/warDir/test.war

But I can't figure out the correct combination of configuration to get it to work. Has anyone else ran into this?

@quidryan
Copy link
Contributor

Have you tried setting addParentDirs=false?

On Wed, Oct 15, 2014 at 1:38 PM, Charles Walker [email protected]
wrote:

I'm kind of having a hard time trying to figure out how to configure an
rpm to only manage a subset of directories being installed. for example:

buildRpm {
into('/opt/test')
from(war.outputs.files) {
into('warDir')
user 'testuser'
groupPermission 'testgroup'
}
}

when you copy the rpm out to a linux box and query the list of files
managed shows:

rpm -qpl testwar.rpm
/opt/test
/opt/test/warDir
/opt/test/warDir/test.war

Installation will cause the /opt/test directory ownership to be
testuser:testgroup even if the directory already exists. The install will
also fail if the /opt/test directory is managed by another rpm with a
'file conflict' error

What I would like to see from the rpm is:

rpm -qpl testwar.rpm
/opt/test/warDir
/opt/test/warDir/test.war

But I can't figure out the correct combination of configuration to get it
to work. Has anyone else ran into this?


Reply to this email directly or view it on GitHub
#59.

@cwalker67
Copy link
Author

yes, and at best i ended up with something like:

rpm -qpl testwar.rpm
/opt/test/warDir/test.war

which upon removal of the rpm does not delete the /opt/test/warDir directory which ends up being owned by root

@merscwog
Copy link
Contributor

So /opt/test is considered "built-in" then on your system.

There was a recent enhancement just made to the underlying redline-rpm library that makes it safe to specify built-in directories on a per Contents basis:

craigwblake/redline@062a56d

Not available as a feature within the ospackage-plugin yet, but should be straight-forward to add. Technically if you don't mind the "/opt/test" directory considered built-in for all rpm tasks within a build, you can call Contents.addBuiltinDirectory('/opt/test') currently in your build file during the configuration phase and it will do what you desire.

Maybe I'll find time to start working on gradle-related things again and enhance the gradle-ospackage-plugin with this change, but I don't believe that's going to happen in the next month or so.

@cwalker67
Copy link
Author

Spencer,
Could you elaborate on how to call Contents.addBuiltinDirectory('/opt/test') in the current configuration?

@merscwog
Copy link
Contributor

Outside of any tasks:

import org.redline_rpm.payload.Contents
Contents.addBuiltinDirectory('opt/test')

Warning. In the future, this will break with newer versions of redline-rpm (yet to be released) which remove the static method.

@cwalker67
Copy link
Author

Thanks spencer but i was not able to get this working (using gradle 2.0.1).

  • I changed the import to be 'org.freecompany.redline.payload.Contents' since thats what the plugin uses
  • I needed to add the redline library as a classpath dependency

At this point, i could execute the task but it seemed to be ignoring the "built in" directory i added

@cwalker67
Copy link
Author

I wanted to elaborate a little further on this as a possible bug. take the following full example:

plugins {
    id "nebula.os-package" version "2.0.2"
}

repositories {
    mavenCentral()
}

configurations {
    test
}

dependencies {
    test 'org.apache.anakia:anakia:1.0@pom'
}

group = 'org.test.package'
version = "1.0.0"

ospackage {
    os = LINUX
    arch = NOARCH
}

task fooRpm(type: Rpm) {
    packageName 'foo'
    into('/opt/test')

    from(configurations.test.getSingleFile()) {
        user 'nobody'
        permissionGroup 'nobody'
        into('bin')
    } 
}

task barRpm(type: Rpm) {
    packageName 'bar'
    into('/opt/test')

    from(configurations.test.getSingleFile()) {
        user 'adm'
        permissionGroup 'adm'
        into('test')
    } 
}

Using gradle 2.0.1 and executing gradle clean fooRpm barRpm produces two rpms. if you try to install both packages (on a recent linux version), it will fail with a file conflict on /opt/test

Both rpms try to take ownership of /opt/test even though the above configuration doesn't seem to represent that. Adding addParentDirs=false will allow the install to occur but all directories created are then owned by root and not removed when the rpm in uninstalled

@merscwog
Copy link
Contributor

Ah. Forgot that it's using an older version of the redline classes.

This used to work in some of the gradle 1.x versions (at least 1.10 and prior).

It's possible that due to some better classloader isolation that you are seeing a different Contents class instance.

Not sure when I'll be able to look more into this, but that's my best guess without creating an example myself with a newer gradle instance.

-Spencer


From: Charles Walker [email protected]
To: nebula-plugins/gradle-ospackage-plugin [email protected]
Cc: Spencer Allain [email protected]
Sent: Thursday, October 16, 2014 12:29 PM
Subject: Re: [gradle-ospackage-plugin] How to modify rpm file listing to not manage all directories (#59)

Thanks spencer but i was not able to get this working (using gradle 2.0.1).

  • I changed the import to be 'org.freecompany.redline.payload.Contents' since thats what the plugin uses
  • I needed to add the redline library as a classpath dependency
    At this point, i could execute the task but it seemed to be ignoring the "built in" directory i added


Reply to this email directly or view it on GitHub.

@cwalker67
Copy link
Author

Could this be escalated to "Bug" status?

@bmuschko
Copy link
Contributor

@cwalker67 Could you please provide a pull request containing an integration test that reproduces the issue? We can then take it from there.

@cwalker67
Copy link
Author

I created a test which fails on the issue. I think the main issue is that there is no (easy) way to specify a directory as "built-in". while diving in, i did manage to come up with a workaround (documented in a second test) where you create all directories with the "directory" command and then specify "addParentDirs false" when copying files.

@ubhatta33
Copy link

@cwalker67 Does your latest workaround (second test) handle the uninstall scenario. I have a similar issue and was using the addParentsDir false as a workaround, but the uninstall is not deleting the leaf folders? Were you able to get around that (without using the postUnistall script)?

@cwalker67
Copy link
Author

@ubhatta33 Yes. The basic gist is that you use the directory command to specify ALL rpm managed directories. Then you can copy files and specify the addParentDirs false attribute. here is a (contrived) example:

Note that /opt/test/foo and it's subdirectories are the only directories managed by the rpm. if /opt/test/ does not exist, it will be created but not considered owned by the rpm

plugins {
    id "nebula.os-package" version "2.2.6"
}

repositories {
    mavenCentral()
}

configurations {
    test
}

dependencies {
    test 'org.apache.anakia:anakia:1.0@jar'
}

group = 'org.test.package'
version = "1.0.0"

ospackage {
    os = LINUX
    arch = NOARCH
}

task fooRpm(type: Rpm) {
    packageName 'foo'

    user 'nobody'
    permissionGroup 'nobody'
    directory('/opt/test/foo')

    FileTree fileTree = zipTree(configurations.test.getSingleFile()).getAsFileTree()
    fileTree.visit { FileVisitDetails fileVisitDetails ->
        if (fileVisitDetails.isDirectory()) {
            directory('/opt/test/foo/' + fileVisitDetails.relativePath)
        }
    }

    from(zipTree(configurations.test.getSingleFile())) {
        addParentDirs false
        into('/opt/test/foo')
    } 
}

rpm -qpl foo-1.0.0.noarch.rpm now properly shows

[vagrant@localhost vagrant]$ rpm -qlp foo-1.0.0.noarch.rpm
/opt/test/foo
/opt/test/foo/META-INF
/opt/test/foo/META-INF/LICENSE
/opt/test/foo/META-INF/MANIFEST.MF
/opt/test/foo/META-INF/NOTICE
/opt/test/foo/org
/opt/test/foo/org/apache
/opt/test/foo/org/apache/anakia
/opt/test/foo/org/apache/anakia/AnakiaElement.class
/opt/test/foo/org/apache/anakia/AnakiaJDOMFactory.class
/opt/test/foo/org/apache/anakia/AnakiaTask$Context.class
/opt/test/foo/org/apache/anakia/AnakiaTask.class
/opt/test/foo/org/apache/anakia/Escape.class
/opt/test/foo/org/apache/anakia/NodeList$1.class
/opt/test/foo/org/apache/anakia/NodeList$AttributeXMLOutputter.class
/opt/test/foo/org/apache/anakia/NodeList.class
/opt/test/foo/org/apache/anakia/OutputWrapper.class
/opt/test/foo/org/apache/anakia/TreeWalker.class
/opt/test/foo/org/apache/anakia/XPathCache.class
/opt/test/foo/org/apache/anakia/XPathTool.class

@cwalker67 cwalker67 reopened this Aug 7, 2015
@cwalker67
Copy link
Author

sorry, clicked the wrong button.

@Hubbitus
Copy link

Hubbitus commented Feb 9, 2016

Sorry, is there solution except add all directories as builtin?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants