ctron / rpm-builder

Maven RPM builder plugin

Home Page:https://ctron.github.io/rpm-builder

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add option to preserve file permissions when collecting files for RPM from a POSIX file system

bsnote opened this issue · comments

It's quite annoying to explicitly specify file permissions when building an RPM, especially when files are collected from multiple sources maintained by different teams or there are many executable files in a directory, but not all of them. The problem is not only in having a long list of rules/entries, but also in having to track new files or file permission changes in all the sources.

The following is stated in the documentation:

This information is not read from the filesystem, since this may not work on some platforms. RPM does assume a POSIX like system, so building on a Windows system may not provide enough information to properly fill out all required information in the file.

which is a bit odd given that building RPM packages on Windows or on any other non-POSIX systems is quite rare. So I don't quite see why file permissions are not preserved if possible, by default.

It is suggested to make preserving file permissions the default behaviour on POSIX systems. Alternatively, there should be a global or an entry level configuration option (or both), for example:

<entry>
    ...
    <mode>original</mode>
    ...
</entry>

That is actually on purpose, as the docs try to explain. And I don't think it is different when building RPMs using the rpm-build command, as one specifies all the information there too, just in a different format.

The problem with reading it from the file system is that this might just not be reproducible, and might lead to completely random results depending on where you run it. Even between different Linux installations. And I am not even talking about stuff like NFS.

My proposal would be have a directory structure, and leverage the rules system to keep it simple. Like creating a rule for /opt/my-app/bin and putting all binaries into that directory, having a single rule for this. Which is basically what rpm-build is doing.

And while I am normally not against adding something that benefits someone, having a feature like this feels like causing more harm than doing good. Enabling such a behavior by default is a real bad idea IMHO, as this might actually break things for existing users and will lead to totally unexpected outcomes for some.

But I also don't want to reject the idea in general (with the exception of making this default). So if you want to work on this, I think it would make sense to outline/discuss/describe how this should work in general? Where all the information (owner, flags) comes from, and how this would work in different environments (non-POSIX) where the information might not be available.

I still have the feeling in your case, you would be better off creating some rules that match your file system structure.

Remember that you can define your own rules, which will greatly help to define suitable defaults for ownership, permission and also RPM flags like configuration, etc.

If you follow the usual *nix directory layout of <prefix>/bin, <prefix>/lib, etc. will you be able to write them very generic and define/distribute them in a parent POM so that you do not need to redefine the default rule set all the time.

For example:

              <defaultRuleset>default</defaultRuleset>
              <rulesets combine.children="append">
                <ruleset>
                  <id>default</id>
                  <rules>
                    <!-- default ownership -->
                    <rule>
                      <user>root</user>
                      <group>root</group>
                    </rule>
                    <!-- default directory permissions -->
                    <rule>
                      <when>
                        <type>directory</type>
                      </when>
                      <mode>0750</mode> <!-- u=rwx,g=rx -->
                    </rule>
                    <rule>
                      <when>
                        <type>file</type>
                      </when>
                      <mode>0440</mode> <!-- u=r,g=r -->
                    </rule>
                    <rule>
                      <when>
                        <prefix>/opt/${project.name}/etc</prefix>
                        <type>file</type>
                      </when>
                      <configuration>true</configuration>
                      <noreplace>true</noreplace>
                      <mode>0644</mode> <!-- u=rw,g=r,o=r -->
                    </rule>
                  </rules>
                </ruleset>
              </rulesets>