How do I set the destination filepath explicitly for every input file?
fpm isn't behaving in the way I expect it to!
Steps to reproduce:
$ fpm --name foo --package foo.deb -t deb -s dir --prefix /opt/foo bar/baz/foo
Created package {:path=>"foo.deb"}
Expected behavior:
$ dpkg -c foo.deb
drwx------ 0/0 0 2014-08-10 16:38 /
drwxrwxr-x 0/0 0 2014-08-10 16:38 /opt/
drwxrwxr-x 0/0 0 2014-08-10 16:38 /opt/foo/
-rw-rw-r-- 0/0 10 2014-08-10 16:37 /opt/foo/foo
$ sudo dpkg -i foo.deb
Selecting previously unselected package foo.
(Reading database ... 70063 files and directories currently installed.)
Preparing to unpack foo.deb ...
Unpacking foo (1.0) ...
Setting up foo (1.0) ...
$ find /opt/foo
/opt/foo
/opt/foo/foo
Actual behavior:
$ dpkg -c foo.deb
drwx------ 0/0 0 2014-08-10 16:38 ./
drwxrwxr-x 0/0 0 2014-08-10 16:38 ./opt/
drwxrwxr-x 0/0 0 2014-08-10 16:38 ./opt/foo/
drwxrwxr-x 0/0 0 2014-08-10 16:38 ./opt/foo/bar/
drwxrwxr-x 0/0 0 2014-08-10 16:38 ./opt/foo/bar/baz/
-rw-rw-r-- 0/0 10 2014-08-10 16:37 ./opt/foo/bar/baz/foo
$ sudo dpkg -i foo.deb
Selecting previously unselected package foo.
(Reading database ... 70063 files and directories currently installed.)
Preparing to unpack foo.deb ...
Unpacking foo (1.0) ...
Setting up foo (1.0) ...
$ find /opt/foo
/opt/foo
/opt/foo/bar
/opt/foo/bar/baz
/opt/foo/bar/baz/foo
That is, I expect the --prefix argument to fpm to be prefixed to the input
files, and I expect the local path to input files to be stripped out. Just
because my build system generates the file at ./bar/baz/foo, that doesn't mean
I want end-users to have bar/baz in the path to the files on their machines.
I would like a way to just give fpm a mapping from destination filepaths to local files that expresses where to find the files to put in the package, e.g.
{
"/opt/foo/foo" : "./bar/baz/foo"
}
would say, "for the filepath /opt/foo/foo in the package, use the local file ./bar/baz/foo.
Is there a way I can do that? I saw an option called --inputs but it doesn't
seem to have any documentation or examples. :-(
I've tried using .. in the --prefix argument, but this makes the behavior even more confusing:
$ fpm --name foo --package foo.deb -t deb -s dir --prefix /opt/foo/../.. bar/baz/foo
Created package {:path=>"foo.deb"}
$ dpkg -c foo.deb
drwx------ 0/0 0 2014-08-10 18:42 ./
drwxrwxr-x 0/0 0 2014-08-10 18:42 ./bar/
drwxrwxr-x 0/0 0 2014-08-10 18:42 ./bar/baz/
-rw-rw-r-- 0/0 10 2014-08-10 16:37 ./bar/baz/foo
drwxrwxr-x 0/0 0 2014-08-10 18:42 ./opt/
drwxrwxr-x 0/0 0 2014-08-10 18:42 ./opt/foo/
It's confusing, sorry about that. There's no real compromise between the two behaviors, so I recently added a 'path mapping' feature to solve it -
If you want bar/baz/foo as [prefix]/foo, then do:
fpm -s dir -t deb --name foo --prefix /opt/foo bar/baz/foo=bar/baz/foo
So instead of copying directories/files to the prefix, it places them specifically by path
@jordansissel thanks. I've actually chosen a simpler solution; or at least simpler to my mind: create a new directory, copy everything to the new directory at the appropriate place, then change directory to that directory before running fpm. Something like
$ mkdir tmp
$ cp bar/baz/foo tmp/foo
$ cd tmp
$ fpm --name foo --package foo.deb -t deb -s dir --prefix /opt/foo .
Not ideal, but it works.
You can also use -C to change directory before copying files.
fpm --name foo --package foo.deb -t deb -s dir --prefix /opt/foo -C bar/baz foo
Open to any suggestions on making this easier, again sorry for the confusion :)
Thank you for saving me from rpmbuild hell! Starting to believe the solution to the absurd state of package management isn't to make yet another one, but to subsume them all into an easy-to-use and portable tool like fpm.
Anyway, the "bar/baz/foo=bar/baz/foo" feature was exactly what I needed. It took a while to understand that it exists. Maybe make it more obvious in --help and use it in an example in the introduction at https://github.com/jordansissel/fpm/wiki.
Maybe this example will help others:
# Build an rpm to install the files in the "app" subdirectory into
# /etc/acme/mywebapp/ and install the files in scripts/web.d/ into
# /etc/acme/appserver/web.d/.
#
# Scripts are run pre and post install to restart the app server.
# - specifies "linux", so this rpm can be built on OSX.
# - need --rpm-auto-add-directories so /etc/acme/webapp/ is removed on uninstall
#
VERSION=0.1.0
PRODUCT_NAME=mywebapp
RPM_NAME=acme-${PRODUCT_NAME}
VENDOR=Acme
URL="http://www.example.com"
DESCRIPTION="The Acme mywebapp add-on for the acme-appserver
This software is Copyright 2014 by Acme. - All Rights Reserved.
"
WEBAPP_URL_PREFIX=/_admin/mywebapp/
fpm --rpm-os linux -s dir -t rpm \
-n ${RPM_NAME} -v ${VERSION} \
--vendor ${VENDOR} --description {DESCRIPTION} --url ${URL} \
--after-install scripts/service-appserver-restart.sh \
--after-remove scripts/service-appserver-restart.sh \
--before-remove scripts/service-appserver-stop.sh \
--rpm-auto-add-directories \
-x '.svn' -x '*/.gitkeep' -x '*/.idea' -x '*~' \
--depends "acme-appserver >= 3.1" \
--prefix=/etc/acme app/=${PRODUCT_NAME}${WEBAPP_URL_PREFIX} scripts/web.d/=acme-appserver/web.d/
Maybe I missed it elsewhere in the docs but I had to do some sleuthing in the issues to find this aliasing capability. Interested in a PR to improve this? If so where would you like it?
Most helpful comment
Thank you for saving me from rpmbuild hell! Starting to believe the solution to the absurd state of package management isn't to make yet another one, but to subsume them all into an easy-to-use and portable tool like fpm.
Anyway, the "bar/baz/foo=bar/baz/foo" feature was exactly what I needed. It took a while to understand that it exists. Maybe make it more obvious in --help and use it in an example in the introduction at https://github.com/jordansissel/fpm/wiki.
Maybe this example will help others: