【问题标题】:Why is my debian postinst script not being run?为什么我的 debian postinst 脚本没有运行?
【发布时间】:2012-06-30 13:04:21
【问题描述】:

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

【问题讨论】:

    标签: package debian dpkg


    【解决方案1】:

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

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

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

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

    apt-get 安装包 - 它运行preinst install,然后postinst configure

    apt-get 删除包 - 执行 postrm remove,包将设置为“Config Files

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

    apt-get purge 包

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

    【讨论】:

      【解决方案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.
      

      【讨论】:

      • 我并不完全清楚你在这里所说的关于“install 命令”的内容,但如果它有助于为任何人澄清事情,dpkg 将永远不会使用 $1 = 调用 postinst 脚本installupgrade。如果您愿意,没有什么能阻止您在 postinst 中支持额外的操作,但 dpkg 不会使用它们。原始问题中发布的脚本不起作用,因为它希望使用其中之一调用。也许这是fpm的错?我不知道。
      • @thepaul 我以为我很清楚。 The install command calls the configure option 。具体来说,它将使用 configure 和包的 version 调用 postinst 脚本,例如configure 6.4.0(根据我的经验,打包我自己的软件)
      【解决方案3】:

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

      我对我的回答没有完全的信心,因为你的坏榜样 仍然在 debian.org 上,很难相信这样的错误会溜走 通过。

      【讨论】:

      • 啊,根据 Debian Policy Manual 中的第 6.5 节,它看起来像是使用 configureinstall 运行的 preinst。安全 Debian 手册实际上谈到了“preinstpostinst”,因此他们的示例必须是针对 preinst 的。我会尝试重新排列。
      • 啊哈!现在说得通了。如果您已经在 preinst 中执行了取决于正在创建的用户的其他操作,请在 preinst 中执行此操作。否则 postinst 的 $1 = 配置分支。根据我对 /var/lib/dpkg/info/*.postinst 的快速扫描,这就是大多数包似乎都这样做的地方
      • 也许自 2012 年以来发生了一些变化,但我认为 postinsts 是在安装后运行的,也许只是在特定情况下。我在 Debian 服务器上安装 phpMyAdmin,安装虽然证明成功,但由于其 postinst 脚本而失败。这导致apt-get 认为它没有正确安装。一旦我调整了/var/lib/dpkg/info/phpmyadmin.postinst,它就起作用了。另外,我的系统有 277 个postinsts,只有 75 个preinsts,在我看来,安装后运行脚本比 删除 后更受欢迎。也许这只是一个维护不善的包。
      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 2013-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多