Skip to content
Open
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
3 changes: 3 additions & 0 deletions docs/cli-reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ General Options
* ``--deb-templates FILEPATH``
- (deb only) Add FILEPATH as debconf templates file.

* ``--deb-trigger FILEPATH``
- (deb only) Add FILEPATH as trigger script

* ``--deb-upstart FILEPATH``
- (deb only) Add FILEPATH as an upstart script

Expand Down
8 changes: 8 additions & 0 deletions docs/snippets.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Snippets For Argument Usage
=========

.. toctree::
:maxdepth: 1
:glob:

snippets/*
88 changes: 88 additions & 0 deletions docs/snippets/deb-trigger.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
Debian Triggers
===============

Debian packages can install commands to be run after installation and configuration of all packages.
Those commands are called triggers as other packages can ask the package manager to run those.

Sample trigger script
---------------------

This script defines two triggers. First the label based trigger `some-trigger` which runs `some-command`. Second the path based trigger `/etc/foobar` which runs a find-command.

::

for trigger in "$@"; do
case "$trigger" in
some-trigger)
some-command
;;
/etc/foobar)
find /etc/foobar -type f -ls
;;
esac
done

Install trigger
---------------

The following fpm command installs the trigger:

fpm --deb-trigger /path/to/triggers.sh

The resulting postinst-script in the packages looks like this:

::

#!/bin/sh

after_upgrade() {
:
}

after_install() {
:
}

triggered() {
:
for trigger in "$@"; do
case "$trigger" in
some-trigger)
some-command
;;
/etc/foobar)
find /etc/foobar -type f -ls
;;
esac
done
}

if [ "${1}" = "configure" -a -z "${2}" ] || \
[ "${1}" = "abort-remove" ]
then
# "after install" here
# "abort-remove" happens when the pre-removal script failed.
# In that case, this script, which should be idemptoent, is run
# to ensure a clean roll-back of the removal.
after_install
elif [ "${1}" = "configure" -a -n "${2}" ]
then
upgradeFromVersion="${2}"
# "after upgrade" here
# NOTE: This slot is also used when deb packages are removed,
# but their config files aren't, but a newer version of the
# package is installed later, called "Config-Files" state.
# basically, that still looks a _lot_ like an upgrade to me.
after_upgrade "${2}"
elif [ "${1}" = "triggered" ]
then
# "triggered" here
# NOTE: This slot allows implementing package triggers according to
# https://wiki.debian.org/DpkgTriggers
shift
triggered "${@}"
elif echo "${1}" | grep -E -q "(abort|fail)"
then
echo "Failed to install before the post-installation script was run." >&2
exit 1
fi
1 change: 0 additions & 1 deletion lib/fpm/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ def help(*args)
"Currently only supports deb, rpm and pacman packages." do |val|
File.expand_path(val) # Get the full path to the script
end # --before-upgrade

option "--template-scripts", :flag,
"Allow scripts to be templated. This lets you use ERB to template your " \
"packaging scripts (for --after-install, etc). For example, you can do " \
Expand Down
48 changes: 29 additions & 19 deletions lib/fpm/package/deb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class FPM::Package::Deb < FPM::Package
:after_install => "postinst",
:before_remove => "prerm",
:after_remove => "postrm",
:after_purge => "postrm",
} unless defined?(SCRIPT_MAP)

# The list of supported compression types. Default is gz (gzip)
Expand Down Expand Up @@ -200,6 +199,12 @@ class FPM::Package::Deb < FPM::Package
next File.expand_path(file)
end

option "--trigger", "FILE", "Add FILE as trigger script. " \
"See https://wiki.debian.org/DpkgTriggers and " \
"https://stackoverflow.com/questions/15276535/dpkg-how-to-use-trigger" do |file|
next File.expand_path(file)
end # --trigger

option "--upstart", "FILEPATH", "Add FILEPATH as an upstart script",
:multivalued => true do |file|
next File.expand_path(file)
Expand Down Expand Up @@ -527,23 +532,26 @@ def output(output_path)
attributes[:deb_systemd] << name
end

if script?(:before_upgrade) or script?(:after_upgrade) or attributes[:deb_systemd].any?
puts "Adding action files"
if script?(:before_install) or script?(:before_upgrade)
scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
end
if script?(:before_remove) or not attributes[:deb_systemd].empty?
scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
end
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd].any?
scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
end
if script?(:after_remove)
scripts[:after_remove] = template("deb/postrm_upgrade.sh.erb").result(binding)
end
if script?(:after_purge)
scripts[:after_purge] = template("deb/postrm_upgrade.sh.erb").result(binding)
end
if not attributes[:deb_trigger].nil?
scripts[:deb_trigger] = File.read(attributes[:deb_trigger])
end

if not attributes[:deb_after_purge].nil?
scripts[:after_purge] = File.read(attributes[:deb_after_purge])
end

puts "Adding action files"
if script?(:before_install) or script?(:before_upgrade)
scripts[:before_install] = template("deb/preinst_upgrade.sh.erb").result(binding)
end
if script?(:before_remove) or attributes[:deb_systemd].any?
scripts[:before_remove] = template("deb/prerm_upgrade.sh.erb").result(binding)
end
if script?(:after_install) or script?(:after_upgrade) or attributes[:deb_systemd].any? or script?(:deb_trigger)
scripts[:after_install] = template("deb/postinst_upgrade.sh.erb").result(binding)
end
if script?(:after_remove) or script?(:after_purge)
scripts[:after_remove] = template("deb/postrm_upgrade.sh.erb").result(binding)
end

# There are two changelogs that may appear:
Expand Down Expand Up @@ -593,7 +601,9 @@ def output(output_path)

if File.exists?(dest_changelog) and not File.exists?(dest_upstream_changelog)
# see https://www.debian.org/doc/debian-policy/ch-docs.html#s-changelogs
File.rename(dest_changelog, dest_upstream_changelog)
# to solve Lintian rule debian-changelog-file-missing-or-wrong-name the file
# is copied and not renamed
FileUtils.cp(dest_changelog, dest_upstream_changelog)
end

attributes.fetch(:deb_init_list, []).each do |init|
Expand Down
18 changes: 18 additions & 0 deletions templates/deb/postinst_upgrade.sh.erb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ $debsystemctl start <%= service %> >/dev/null || true
<% end -%>
}

triggered() {
<%# Making sure that at least one command is in the function -%>
<%# avoids a lot of potential errors, including the case that -%>
<%# the script is non-empty, but just whitespace and/or comments -%>
:
<%# if any trigger specified, loop through and start them -%>
<% if script?(:deb_trigger) -%>
<%= script(:deb_trigger) %>
<% end -%>
}

if [ "${1}" = "configure" -a -z "${2}" ] || \
[ "${1}" = "abort-remove" ]
then
Expand All @@ -77,6 +88,13 @@ then
# package is installed later, called "Config-Files" state.
# basically, that still looks a _lot_ like an upgrade to me.
after_upgrade "${2}"
elif [ "${1}" = "triggered" ]
then
# "triggered" here
# NOTE: This slot allows implementing package triggers according to
# https://wiki.debian.org/DpkgTriggers
shift
triggered "${@}"
elif echo "${1}" | grep -E -q "(abort|fail)"
then
echo "Failed to install before the post-installation script was run." >&2
Expand Down