4

Is it possible to create a binary .deb package with conditional files and directories installation (e.g. installation of an init script in /etc/init.d/ after being confirmed by the user)?

4
  • What is the point? Packages are installed with admin rights. Why another confirmation is needed? And how is it related to Ubuntu? – Pilot6 Jun 30 '15 at 19:13
  • @Pilot6 I would like to make some features optional for installation like creating a daemon. Sorry, my question is about Debian packaging and not Ubuntu (Would you suggest me to ask it elsewhere?). – KaBa Jun 30 '15 at 19:23
  • You can ask that at unix.stackexchange.com – Pilot6 Jun 30 '15 at 19:33
  • 3
    KaBa, I would suggesting installing the init script anyway, but enable/disable it after confirming with the user. @Pilot6 if either the packaging or the installation happens on Ubuntu, it's fine - since the Debian packaging system is also the primary system on Ubuntu. – muru Jul 1 '15 at 13:37
3

In order to interactively ask questions during package installation you should use debconf. To dynamically create and manage configuration files (and files in /etc/init.d/ are considered configuration files) ucf can be used.

A tutorial, on how to use debconf, may be found here:
http://www.fifi.org/doc/debconf-doc/tutorial.html

Minimal example

debconf template

Put this in the file debian/templates. It contains the text that is shown to the user during installation. Just be sure to replace demo-pkg with you actually package name!

Template: demo-pkg/install-init.d
Type: boolean
Default: false
Description: Would you like to install a service for this package?
 Services are really cool! They allow stuff to be started in the
 background without you having to start them manually!!!

Package configuration script

This is where you ask the user (interactively) about the things you need to know. This script is special since, when installing more than one package, all of these files of all packages are run before dpkg begins the actual installation process. This means that, if more than one package wants to ask the user something, all questions are asked at the beginning of installation for all packages, instead of later on for each package individually.

Just put the following stuff into a file named debian/config and mark it as executable (remember to replace demo-pkg with the correct package name):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

# Should an init job be installed?
db_input high demo-pkg/install-init.d || true
db_go

# You can also act upon the user's answers using `db_get`
#db_get demo-pkg/install-init.d
#[ "${RET}" = "false"] && echo "I don't think that was a wise decision..."

Maintainer scripts (postinst, prerm and postrm)

Here we do the actual magic and dynamically add and remove the configuration file/init script. For this to work you have to install your init script as regular file along with your package (I assumed /usr/share/demo-pkg/init-service in this example).

The debian/postinst file (called after all files were extracted by dpkg):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

if [ "$1" = "configure" ];
then
    # Check if the user decided the enable the service using `db_get`
    db_get demo-pkg/install-init.d
    if [ "${RET}" != "false" ];
    then
        # Install init script using `ucf`
        ucf /usr/share/demo-pkg/init-service /etc/init.d/demo-service

        # Register init script as service
        update-rc.d demo-service defaults

        # Start service
        invoke-rc.d demo-service start
    fi
fi

The debian/prerm file (called before files are removed by dpkg or the package is upgraded to a newer version):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

# Load debconf library
. /usr/share/debconf/confmodule

# Check if the user decided the enable the service using `db_get`
db_get demo-pkg/install-init.d
if [ "${RET}" != "false" ];
then
    # Stop the service before upgrade or removal
    invoke-rc.d demo-service stop

    if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ];
    then
        # Unregister service prior to removal
        update-rc.d -f demo-service remove
    fi
fi

The debian/postrm file (called after all files were removed by dpkg):

#!/bin/sh

# Make sure this script fails if any unexpected errors happen
set -e

if [ "$1" = "purge" ];
then
    # Remove service file using `ucf` (checking whether `ucf` is still available first)
    if type ucf >/dev/null 2>&1;
    then
        ucf --purge "/etc/init.d/demo-service"
    fi

    # Remove service file by hand (in case the above failed somehow)
    rm -f "/etc/init.d/demo-service"
fi

Final steps

  1. Add a Pre-Depends: dependency on debconf in the file debian/control
  2. Add a normal Depends: dependency on ucf in the file debian/control
  3. Make sure the file /usr/share/demo-pkg/init-service (or whatever you call it) gets installed properly
13
  • Don't forget to upvote and mark as accepted answer if this helped you! Please do ask for clarification if something doesn't make sense to you! – ntninja Jun 30 '15 at 20:47
  • Thanks for your answer! I will use it tomorrow and if there is any question, I will get back to you. Sure, I will mark it as accepted answer. – KaBa Jun 30 '15 at 21:11
  • Thanks! I just added some extra commands that make sure that the service is registered and started correctly. – ntninja Jun 30 '15 at 21:20
  • @KaBa: Please visit the Ask Ubuntu Tour to better understand how this site works, as it is a Q&A site and quite different from a forum... – Fabby Jul 1 '15 at 11:37
  • @KaBa Did you mark your debian/config file as executable (Right-click -> Properties -> Permissions -> Executable OR chmod +x "${filename}") ? Does the debian/config file include the shebang line ("#!/bin/sh")? – ntninja Jul 1 '15 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.