[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Taking over a previously diverted file

On Tue, Oct 17, 2006 at 09:05:46PM +0700, Theppitak Karoonboonyanan wrote:

> I wonder what is the best practice to remove a diversion from a package,
> when the new version will own the file itself, and no more steals it by a
> diversion.

> The situation is that my package (thailatex), has previously diverted
> a file from another package (tetex-base). But now tetex-base has
> moved the file from /usr/share/texmf to /usr/share/texmf-tetex,
> allowing my package to take over that file.

> Bug #393519 in my package, which breaks upgrading from sarge,
> is caused by an attempt to remove the diversion in preinst:

>  case "1" in
>    install|upgrade)
>      dpkg-divert --package thailatex  --remove --rename \
>             --divert /usr/share/texmf/tex/generic/babel/babel.sty.real \
>            /usr/share/texmf/tex/generic/babel/babel.sty
>      ...

> This causes an error like this:

>  Preparing to replace thailatex 0.3.2 (using .../thailatex_0.3.7-1_all.deb) 
>  ...
>  Removing `diversion of /usr/share/texmf/tex/generic/babel/babel.sty
> to /usr/share/texmf/tex/generic/babel/babel.sty.real by thailatex'
>  dpkg-divert: rename involves overwriting
> `/usr/share/texmf/tex/generic/babel/babel.sty' with
>    different file


> My guess is that at preinst stage, the diverted file is still owned by
> the package itself. So it's not allowed to be overwritten.

> But if I remove the old version before installing the new one, the
> old version's postrm will remove the diversion cleanly. And the new
> version just installs correctly.

> So, I got an idea to add Conflicts: with the old version of itself, hoping
> the sarge version to be removed before the new one being installed.
> But it doesn't behave as I thought. Rather, it just upgrades as usual,
> and causes the same error.

> So, my question is: how to completely take over the previously
> diverted file?

So the constraints are:

- the old version of tetex-base must be removed before the new thailatex is
  unpacked, otherwise you will have a file conflict
- there must be no /usr/share/texmf/tex/generic/babel/babel.sty in place
  when the diversion is removed, because dpkg-divert --remove will throw an
  error if the diverted-from file exists (whether or not the diverted-to
  file still exists)
- any actions taken in the preinst must be reversible on failure, so that
  the old package can be returned to installed state

Let's give this a try.  In the postinst:

  if [ -e $TEXDIR/babel.sty ]; then
      mv -i $TEXDIR/babel.sty $TEXDIR/babel.sty.undivert < /dev/null
  dpkg-divert --package thailatex  --remove --rename \
         --divert $TEXDIR/babel.sty.real \
  mv $TEXDIR/babel.sty.undivert $TEXDIR/babel.sty

and in debian/control:

  Package: thailatex
  Conflicts: tetex-base (<< $version)
  Replaces: tetex-base (<< $version)

This solution has the following properties.

- The version of tetex-base which contains $TEXDIR/babel.sty will always be
  removed from the system before the postinst for the new thailatex is run.
  (I chose this option over just Replaces:, because I'm not sure how
  Replaces: would interact with a diversion.)  This means that
  $TEXDIR/babel.sty.real will not exist when the postinst runs.
- The script is idempotent; we know that $TEXDIR/babel.sty will exist the
  *first* time the script is run, and that $TEXDIR/babel.sty.undivert should
  not exist, but we allow for the possibility that the postinst script fails
  later (before reverting the "mv") and that the user has manually fiddled
  with files in between -- if the user has manuall added $TEXDIR/babel.sty,
  the mv -i will silently fail, and the dpkg-divert --remove will /noisily/
- The diversion removal will always succeed unless the user has manually
  adjusted files.
- The final mv will always succeed unless the user has manually adjusted
  files, and as a result give us a $TEXDIR/babel.sty file that we're assured
  of being the copy from thailatex.
- By avoiding any use of the preinst, we also avoid any rollback

Completely untested in real-world conditions, let me know if you find I've
screwed something up :)

Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
vorlon@debian.org                                   http://www.debian.org/

Reply to: