Steve Langasek <vor...@debian.org> writes:
> On Wed, Jul 21, 2010 at 01:52:50PM -0700, Russ Allbery wrote:

>> +      Sometimes, a package requires another package to be unpacked
>> +      <em>and</em> configured before it can be unpacked.  In this
>> +      case, the dependent package must specify this dependency in
>> +      the <tt>Pre-Depends</tt> control field.

> I think "depending package" is clearer than "dependent package", since
> there's less possibility of confusion with "dependency".  (The usage
> "dependent package" does not currently exist elsewhere in Policy.)

Changed.

>> +          The package will not yet be unpacked, so
>> +          the <prgn>preinst</prgn> script cannot rely on any files
>> +          included in its package.  Only essential packages and
>> +          pre-dependencies (<tt>Pre-Depends</tt>) may be assumed to be
>> +          available.  Pre-dependencies will be at least unpacked.
>> +          They may be only unpacked or "Half-Configured", not
>> +          completely configured, but only if a previous version of the
>> +          pre-dependency was completely configured and the
>> +          pre-dependency had not been removed since then.
>>          </item>

> Maybe it would be clearer to write it this way?

>   Pre-dependencies will have been configured at least once, but at the
>   time the preinst is called they may only be in an unpacked or
>   "Half-Configured" state if a previous version of the pre-dependency
>   was completely configured and has not been removed (uninstalled?)
>   since then.

Yeah, that looks good to me.  Changed.

> Does dpkg provide any guarantee that the dependencies of the
> pre-dependency are also present at this point?  If it doesn't, I think
> that should be considered a bug in dpkg, since you may be invoking a
> command that links against a library whose soname has changed since the
> last time the pre-dep package was configured.  If it /does/ provide this
> guarantee, I think it should be documented in Policy.

I believe they can be in the same state as the pre-dependency itself for
exactly the same reasons, no?  Upgrades don't require deconfiguring
packages that depend on the package being upgraded, so if you abort in the
middle of upgrading a package the pre-dependency depends on, the
pre-dependency is still present and configured on the system, so dpkg will
treat the pre-dependency as satisfied.

I've not changed any wording in this area for this bug.

>> +          The files contained in the package will be unpacked.  All
>> +          package dependencies will at least be unpacked.  If there
>> +          are no circular dependencies involved, all package
>> +          dependencies will be configured.
>>          </item>

> Should this include a pointer to the section documenting the rules for
> breaking circular dependencies?

Added a reference.

>> +          unpacked in some error situations.<footnote>
>> +            For example, suppose packages foo and bar are installed
>> +            with foo depending on bar.  If an upgrade of bar were
>> +            started and then aborted, and then an attempt to remove
>> +            foo failed because its <prgn>prerm</prgn> script failed,
>> +            foo's <tt>postinst abort-remove</tt> would be called with
>> +            bar only "Half-Installed".
>> +          </footnote>
>>          </item>
>> -      </list>
>> +      </taglist>
>> +    </p>

> This footnote is interesting to me because although it accurately
> documents dpkg's behavior, I'm not sure what implications it has for how
> packages should guard against this case.  I think I've always ignored
> this possibility in my maintainer scripts, and will continue to do so on
> the grounds that any attempt to handle this gracefully is likely to
> introduce much greater complexity (and therefore bugs) with very little
> upside (when all is said and done, a package you were trying to remove
> is still installed, so do we care if it configures successfully?)

> If we can make a straightforward recommendation to maintainers for how
> to handle this case, I think we should include that in the footnote.
> Otherwise, if it shouldn't affect how we write maintainer scripts,
> perhaps it's better not to have this footnote at all since it would only
> lead to maintainers trying to be too clever and shooting themselves in
> the foot?

I think we should put it in the main text.  I've now added, after the
footnote and in the main text:

              The <prgn>postinst</prgn> should still attempt any actions
              for which its dependencies are required, since they will
              normally be available, but consider the correct error
              handling approach if those actions fail.  Aborting
              the <prgn>postinst</prgn> action if commands or facilities
              from the package dependencies are not available is often the
              best approach.

which I think is roughly what you're doing and what most people are doing
and which I think is the generally best approach.

>> +          The <prgn>postrm</prgn> script is called after the package's
>> +          files have been removed or replaced.  The package
>> +          whose <prgn>postrm</prgn> is being called may have
>> +          previously been deconfigured and only be unpacked, at which
>> +          point subsequent package changes do not consider its
>> +          dependencies.  Therefore, all <prgn>postrm</prgn> actions
>> +          may only rely on essential packages and cannot assume that
>> +          the package's dependencies are available.

> True as written, but less helpful than it should be.  There are a number
> of cases where postrm scripts still need to *try* to invoke
> non-essential functionality, and fail gracefully if it's unavailable;
> this should be explicitly encouraged so that maintainers don't come away
> thinking they shouldn't try to clean up after themselves.

> Ex.: if you have a package that manages a config file with ucf, you
> *must* call ucf --purge from "postrm purge" if ucf is present on the
> system at this point; failure to do so will give completely unintuitive
> handling of the config file on package purge && reinstall.

> Proposed wording (improvements requested):

>    Therefore, all <prgn>postrm</prgn> actions may only rely on essential
>    packages and must gracefully omit anything requiring the package's
>    dependencies when those dependencies are unavailable.

I now have, as the end of this paragraph:

              Therefore, all <prgn>postrm</prgn> actions
              may only rely on essential packages and must gracefully skip
              any actions that require the package's dependencies if those
              dependencies are unavailable.<footnote>
                This is often done by checking whether the command or
                facility the <prgn>postrm</prgn> intends to call is
                available before calling it.  For example:
<example>
if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
        . /usr/share/debconf/confmodule
        db_purge
fi
</example>
                in <prgn>postrm</prgn> purges the <prgn>debconf</prgn>
                configuration for the package
                if <package>debconf</package> is installed.
              </foonote>

>   --> Packages involved in circular dependencies may not be able to rely on
>       their dependencies being configured before they themselves are
>       configured, depending on which side of the break of the circular
>       dependency loop they happen to be on.

Fixed.

>>            <p>
>>              The <tt>Depends</tt> field should also be used if the
>> -            <prgn>postinst</prgn>, <prgn>prerm</prgn> or
>> -            <prgn>postrm</prgn> scripts require the package to be
>> -            present in order to run.  Note, however, that the
>> -            <prgn>postrm</prgn> cannot rely on any non-essential
>> -            packages to be present during the <tt>purge</tt>
>> -            phase.
>> +            <prgn>postinst</prgn> or <prgn>prerm</prgn> scripts
>> +            require the depended-on package to be unpacked or
>> +            configured in order to run.  In the case of <tt>postinst
>> +            configure</tt>, the depended-on packages will be unpacked
>> +            and configured first.  (If both packages are involved in a
>> +            dependency loop, this might not work as expected; see the
>> +            explanation a few paragraphs back.)  In the case
>> +            of <prgn>prerm</prgn> or other <prgn>postinst</prgn>
>> +            actions, the package dependencies will be at least
>> +            unpacked or "Half-Installed".
>> +          </p>
>>          </item>

> I disagree with this change.  If you are making use of non-essential
> packages in your postrm, you *should* use the Depends: field; you just
> *also* have to have a clean fallback plan if the dependency is not
> satisfied when the postrm is called.

> The normal use case is "whichever of the two packages is removed first
> must clean up".  While I can't think of a case where the cleanup
> interface called from the postrm isn't already a dependency for other
> reasons (e.g., for use in the postinst), I'd like this to be explicit
> all the same.

How about this?

              <p>
                The <tt>Depends</tt> field should also be used if the
                <prgn>postinst</prgn> or <prgn>prerm</prgn> scripts
                require the depended-on package to be unpacked or
                configured in order to run, or if the dependend-on package
                is desirable for cleanup done by <prgn>postrm</prgn>.  In
                the case of <tt>postinst configure</tt>, the depended-on
                packages will be unpacked and configured first.  (If both
                packages are involved in a dependency loop, this might not
                work as expected; see the explanation a few paragraphs
                back.)  In the case of <prgn>prerm</prgn> or
                other <prgn>postinst</prgn> actions, the package
                dependencies will normally be at least unpacked, but they
                may be only "Half-Installed" if a previous upgrade of the
                dependency failed.  In the case of <prgn>postrm</prgn>,
                there are no guarantees, but the depended-on package is
                more likely to be available if the package declares a
                dependency (particularly for <tt>postrm remove</tt>).
                The <prgn>postrm</prgn> script must cleanly skip actions
                that require a dependency if that dependency isn't
                available.
              </p>

-- 
Russ Allbery (r...@debian.org)               <http://www.eyrie.org/~eagle/>


-- 
To UNSUBSCRIBE, email to debian-dpkg-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org
Archive: http://lists.debian.org/87hbivvfts....@windlord.stanford.edu

Reply via email to