为什么我的debian postinst脚本没有运行?

时间:2012-06-30 13:04:22

标签: package debian dpkg

我使用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一起运行?我该怎么做才能进一步调试呢?

3 个答案:

答案 0 :(得分:18)

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

我对自己的答案没有完全的信心,因为你的坏榜样 仍然在debian.org上,很难相信这样的错误可能会失误 通过

答案 1 :(得分:2)

我相信Alan Curry提供的答案是错误的,至少从2015年及以后开始 您的软件包的构建方式或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.

答案 2 :(得分:0)

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

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

https://wiki.debian.org/MaintainerScripts处,详细介绍了安装和卸载流程。

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

apt-get安装软件包 -它先运行预安装,然后后配置

apt-get删除软件包 -执行postrm remove,程序包将设置为“ 配置文件

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

apt-get清除程序包

这是我们下次安装软件包时能够运行预安装 postinst配置的唯一方法。