7

我使用fpm制作了.deb我的应用程序:

fpm -s dir -t deb -n myapp -v 9 -a all -x "*.git" -x "*.bak" -x "*.orig" \
--after-remove debian/postrm  --after-install debian/postinst \
--description "Automated build." -d mysql-client -d python-virtualenv home

除其他外,该postinst脚本应该为应用程序创建一个用户:

#!/bin/sh

    set -e

    APP_NAME=myapp

    case "$1" in
        configure)
            virtualenv /home/$APP_NAME/local
            #supervisorctl start $APP_NAME
        ;;

    # http://www.debian.org/doc/manuals/securing-debian-howto/ch9.en.html#s-bpp-lower-privs
       install|upgrade)

       # If the package has default file it could be sourced, so that
       # the local admin can overwrite the defaults

       [ -f "/etc/default/$APP_NAME" ] && . /etc/default/$APP_NAME

       # Sane defaults:

       [ -z "$SERVER_HOME" ] && SERVER_HOME=/home/$APP_NAME
       [ -z "$SERVER_USER" ] && SERVER_USER=$APP_NAME
       [ -z "$SERVER_NAME" ] && SERVER_NAME=""
       [ -z "$SERVER_GROUP" ] && SERVER_GROUP=$APP_NAME

       # Groups that the user will be added to, if undefined, then none.
       ADDGROUP=""

       # create user to avoid running server as root
       # 1. create group if not existing
       if ! getent group | grep -q "^$SERVER_GROUP:" ; then
          echo -n "Adding group $SERVER_GROUP.."
          addgroup --quiet --system $SERVER_GROUP 2>/dev/null ||true
          echo "..done"
       fi
       # 2. create homedir if not existing
       test -d $SERVER_HOME || mkdir $SERVER_HOME
       # 3. create user if not existing
       if ! getent passwd | grep -q "^$SERVER_USER:"; then
         echo -n "Adding system user $SERVER_USER.."
         adduser --quiet \
                 --system \
                 --ingroup $SERVER_GROUP \
                 --no-create-home \
                 --disabled-password \
                 $SERVER_USER 2>/dev/null || true
         echo "..done"
       fi

       # … and a bunch of other stuff.

似乎postinst脚本是用 调用的configure,但不是用调用的,install我试图理解为什么。在/var/log/dpkg.log中,我看到了我期望的行:

2012-06-30 13:28:36 configure myapp 9 9
2012-06-30 13:28:36 status unpacked myapp 9
2012-06-30 13:28:36 status half-configured myapp 9
2012-06-30 13:28:43 status installed myapp 9

我检查了/etc/default/myapp不存在。该文件/var/lib/dpkg/info/myapp.postinst存在,如果我使用install第一个参数手动运行它,它会按预期工作。

为什么postinst脚本没有运行install?我能做些什么来进一步调试呢?

4

3 回答 3

18

我认为您复制的示例脚本是完全错误的。postinst不应该用任何installupgrade参数调用,永远。dpkg 格式的权威定义是 Debian Policy Manual。当前版本postinst第 6 章中进行了描述, 并且仅列出了configureabort-upgradeabort-removeabort-removeabort-deconfigure作为可能的第一个参数。

我对我的回答没有完全的信心,因为你的坏例子仍然在 debian.org 上,很难相信这样的错误会漏掉。

于 2012-07-04T05:05:05.640 回答
4

我相信艾伦库里提供的答案是不正确的,至少在 2015 年及以后。您的包的构建方式或文件中的错误导致您的问题
一定有一些错误。您可以通过在命令行中添加 (debug) 选项来 调试您的安装,即:postinst
-D

sudo dpkg -D2 -i yourpackage_name_1.0.0_all.deb

-D2应该解决这类问题

作为记录,调试级别如下:

          Number   Description
               1   Generally helpful progress information
               2   Invocation and status of maintainer scripts
              10   Output for each file processed
             100   Lots of output for each file processed
              20   Output for each configuration file
             200   Lots of output for each configuration file
              40   Dependencies and conflicts
             400   Lots of dependencies/conflicts output
           10000   Trigger activation and processing
           20000   Lots of output regarding triggers
           40000   Silly amounts of output regarding triggers
            1000   Lots of drivel about e.g. the dpkg/info dir
            2000   Insane amounts of drivel

install命令调用该configure选项,根据我的经验,该postinst脚本将始终运行。可能会让您感到困惑的一件事是postrm“旧”版本的脚本,如果升级包,将您当前的包preinst脚本之后运行,如果您没有意识到发生了什么,这可能会造成严重破坏。
从 dpkg 手册页: 安装包括以下步骤:

          1. Extract the control files of the new package.

          2.  If  another version of the same package was installed before
          the new installation, execute prerm script of the old package.

          3. Run preinst script, if provided by the package.

          4. Unpack the new files, and at the same time back  up  the  old
          files, so that if something goes wrong, they can be restored.

          5.  If  another version of the same package was installed before
          the new installation, execute the postrm script of the old pack‐
          age.  Note that this script is executed after the preinst script
          of the new package, because new files are written  at  the  same
          time old files are removed.

          6.  Configure the package. 

          Configuring consists of the following steps:

          1.  Unpack  the  conffiles, and at the same time back up the old
          conffiles, so that they can be restored if something goes wrong.

          2. Run postinst script, if provided by the package.
于 2016-03-20T09:10:43.590 回答
1

这是一个已经解决的老问题,但在我看来,公认的解决方案并不完全正确,我认为有必要为像我一样遇到同样问题的人提供信息。

第 6.5 章详细介绍了调用 preinst 和 postinst 文件的所有参数

https://wiki.debian.org/MaintainerScripts有详细的安装和卸载流程。

观察在以下情况下会发生什么:

apt-get install package - 它运行preinst install然后postinst configure

apt-get remove package - 执行 postrm remove 并且包将被设置为“ Config Files

要使包实际处于“未安装”状态,必须使用它:

apt-get 清除包

这是我们下次安装软件包时能够运行preinst installpostinst configure的唯一方法。

于 2020-04-29T15:22:54.923 回答