jordansissel / fpm

Effing package management! Build packages for multiple platforms (deb, rpm, etc) with great ease and sanity.
http://fpm.readthedocs.io/en/latest/
Other
11.16k stars 1.07k forks source link

make it easier to target different distributions? #1826

Open Dieterbe opened 3 years ago

Dieterbe commented 3 years ago

Hello! First of all, thanks Jordan and other contributors for this fantastic tool. It certainly has helped me.

My main issue is keeping up with the various updates to linux distributions (debian, ubuntu, centos, etc) and their expectations and requirements. Sometimes they change init systems for example, and while fpm provides flags to help me include files to target certain init systems, the onus is still on me (and many other fpm users?) to keep up with the distributions release notes to find out if i should update my fpm commands/flags to accommodate new versions.

I have two suggestions:

1) the community could maintain a wiki page to cover distribution updates and marking which ones require any changes to fpm commands/flags. 2) some kind of abstraction to fpm, or a wrapper tool, where you can which (say) ubuntu versions you want to target, and it would invoke fpm the right way for all of them. It could possibly even generate a correct systemd (or whatever init system) config file. as most of my packages just contain one or a few binaries and some docs, fpm seems a bit too low level for such use case.

I'm making this post to gauge interest from others for either of these solutions, or perhaps i'm missing something? thanks, Dieter

jordansissel commented 3 years ago

I like this idea.

I'm not entirely sure what the interface would look like (that is, how would a user say "Target Ubuntu 20.04" to the fpm cli).

In working on pleaserun, I found some platform detections to be fairly straight forward while also allowing folks to be explicit, such as "Target Upstart 0.65" or something.

Documenting the per-platform specifics would be a good place to start. The fpm documentation files (in docs/) feels like the right place for now.

Sometimes they change init systems for example, and while fpm provides flags to help me include files to target certain init systems

Speaking of init systems, I don't know how often this part of fpm is used, but fpm can create a single package that targets many init systems at the same time. This is done with the -s pleaserun and uses pleaserun to generate them. When the package is removed, there is a removal script which cleans up any files generated at installation time.

% fpm -s pleaserun -t deb -n example-service /path/to/example
...

# What does this package when installed?
% ar p example-service_1.0_amd64.deb control.tar.gz | tar -zxf - -O ./postinst
#!/bin/sh

source="/usr/share/pleaserun/example"
exec sh "$source/install.sh"

# Let's try installing it
% sudo dpkg -i example-service_1.0_amd64.deb
Selecting previously unselected package example-service.
(Reading database ... 106351 files and directories currently installed.)
Preparing to unpack example-service_1.0_amd64.deb ...
Unpacking example-service (1.0) ...
Setting up example-service (1.0) ...
Platform systemd (default) detected. Installing service.
System has not been booted with systemd as init system (PID 1). Can't operate.
To start this service, use: systemctl start example

# See the systemd service file
% ls -l /etc/systemd/system/example.service
-rw-r--r-- 1 root root 584 Sep  4 16:17 /etc/systemd/system/example.service

# This file is cleaned up by the package when removed:
% sudo dpkg -r example-service
(Reading database ... 106398 files and directories currently installed.)
Removing example-service (1.0) ...
Running cleanup to remove service for package example-service

Basically, a "pleaserun" package generates an install script which detects the target system (when the package is installed) and installs the appropriate files necessary to run the service (/etc/init.d, systemd, upstart, etc).

jordansissel commented 3 years ago

@Dieterbe If you're most interested in init/servicei stuff, I think we're closer to a solution given my above comment about pleaserun and fpm's support for it. Let me know what you think :)

The idea with fpm -s pleaserun ... is that you have two packages -- one for your program/application and one for the service. One could depend on the other, so that apt-get install whatever-service would install your application and the service.

It might be desirable to make fpm produce a single package that contains both the application and the service management pieces provided by pleaserun. I haven't tried this myself within fpm.

For a similar example, Logstash includes the pleaserun library in the release packages in order to run pleaserun at package installation time:

Dieterbe commented 3 years ago

Seems like the fpm+pleaserun combo is a good step forward over just fpm where one has to provide the right init/run scripts and know how to include them.

The main considerations on my mind:

1) The init system detection is at runtime on the target system. I know of some end users who are not a fan of this sort of "magic" and would rather have little to no code execution during package install, and simply have all the files that will be installed, be declared by the package in the metadata. In theory this could be done by having pleaserun run in a short-lived test-VM (of same distro/version as the target), to do the detection, generate the files, store them in a static package, and then have a static package to deliver to the client. This is of course seems like a clunky process, but maybe it's automate-able with certain cloud providers. But if we had a simple text file describing, for each distro/version, what the init system used is, we don't have to do any detection and can always generate the correct files and include them in the package, not requiring any run-time magic. Such a text config file could be crowd sourced / community maintained.

By moving the magic from "runtime on target system" to package generation time, packages (and their generation) become also more testable and verifiable.

Of course, an advantage of the current approach is the "one distro package works on many versions [of that distro]". With my suggestion, you'd end up with more packages, possibly one per distro release (or at least one per "distro-init variation"), which would use more disk space and result in more costs.

2)

The idea with fpm -s pleaserun ... is that you have two packages -- one for your program/application and one for the service.

Is this in line with best practices ? Of which distributions? On Debian, for example the redis packages seem to include the service along with the server (but separate out admin tools), seems the redis server also includes the init scripts on centOS

I suspect most people would prefer a single package solution, which also seems simpler. But maybe i'm missing something.