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

Re: Run script after package install, update



On Sun, Jun 15, 2025 at 1:15 PM David Wright <deblis@lionunicorn.co.uk> wrote:
>
> On Sun 15 Jun 2025 at 11:33:09 (-0400), Greg Wooledge wrote:
> > On Sun, Jun 15, 2025 at 11:07:41 -0400, Boyan Penkov wrote:
> > > So ultimately, my problem is addressed; however, the larger question
> > > is still open: is there in fact a straightforward way for a user, not
> > > the package maintainer, to tell the package management system: "If and
> > > only if your operation touched package x, also do this one thing
> > > locally."?  I can think of about a million use cases for this: "if you
> > > touched maildir-utils, run mu  index." "if you touched offlineimap,
> > > run offlineimap" "if you touched etckeeper, re-commit the /etc files"
> > > and so on ...
> >
> > Since the apt documentation is such complete rubbish, the only ways
> > to actually figure out how anything *works* are source diving and
> > experimenting.  I do not feel like trying to source-dive through apt
> > and its libraries, so I tried an experiment.
> >
> > According to the apt.conf(5) man page:
> >
> >        Pre-Invoke, Post-Invoke
> >            This is a list of shell commands to run before/after invoking
> >            dpkg(1). Like options this must be specified in list notation. The
> >            commands are invoked in order using /bin/sh; should any fail APT
> >            will abort.
> >
> > That's clear as mud.  What is "list notation"?  Again, I had to experiment.
> > I tried looking for examples, learned that the
> > /usr/share/doc/apt/examples/configure-index.gz file documented at the end
> > of the man page does not exist, discovered that the file
> > /usr/share/doc/apt/examples/configure-index exists instead, read that, and
> > found nothing helpful in deciphering what an apt.conf.d/* file should
> > look like.
> >
> > I looked at other files in /etc/apt/apt.conf.d/ for inspiration, and
> > tried searching for the word "list" in the man page, but ultimately it
> > came down to experimenting until I got it right.
> >
> > Here's what I did:
> >
> > 1) I created the file /etc/apt/apt.conf.d/99localexperiment with the
> > following contents:
> >
> > ====================================================================
> > DPkg::Post-Invoke { /usr/local/sbin/dpkg-experiment; };
> > ====================================================================
> >
> > 2) I created the script /usr/local/sbin/dpkg-experiment with the following
> > contents:
> >
> > ====================================================================
> > #!/bin/sh
> > exec > /var/tmp/dpkg-experiment
> > printf '%s args' "$#"
> > if test "$#" != 0; then
> >     printf :
> >     printf ' <%s>' "$@"
> > fi
> > echo; echo
> > ps -fp "$$,$PPID"
> > echo
> > env
> > ====================================================================
> >
> > and gave it 755 permissions.
> >
> > 3) I installed a package by running "sudo apt-get install sl".
> >
> > Here's the /var/tmp/dpkg-experiment file that was created as a result:
> >
> > ====================================================================
> > 0 args
> >
> > UID          PID    PPID  C STIME TTY          TIME CMD
> > root      487061  487060  0 11:19 pts/27   00:00:00 sh -c /usr/local/sbin/dpkg-experiment
> > root      487062  487061  0 11:19 pts/27   00:00:00 /bin/sh /usr/local/sbin/dpkg-experiment
> >
> > SUDO_GID=1000
> > DPKG_FRONTEND_LOCKED=true
> > MAIL=/var/mail/root
> > LC_TIME=C
> > USER=root
> > HOME=/root
> > COLORTERM=rxvt-xpm
> > SUDO_UID=1000
> > LOGNAME=root
> > TERM=rxvt-unicode-256color
> > PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
> > DISPLAY=:0
> > LANG=en_US.utf8
> > XAUTHORITY=/home/greg/.Xauthority
> > LS_COLORS=ln=31:ex=35:cd=44;37:bd=44;37:pi=32
> > SUDO_COMMAND=/usr/bin/apt-get install sl
> > SHELL=/bin/bash
> > SUDO_USER=greg
> > PWD=/tmp
> > ====================================================================
> >
> > Conclusion: there is nothing at all in the environment or arguments
> > passed to the Post-Invoke script(s) that indicate what has been done.
> > Any such scripts created by the local sysadmin will have to take their
> > own investigative steps to try to figure out what happened, and what
> > they should do about it.
> >
> > Unless of course there's some *other* hook that we don't know about
> > because the documentation is so poor.
>
> Well, I just plagiarised /etc/apt/apt.conf.d/99needrestart:
>
>   $ cat /etc/apt/apt.conf.d/99redogrub
>   DPkg::Post-Invoke {"test -x /var/local/bin/redo && /var/local/bin/redo || true"; };
>   $
>
> and wrote /var/local/bin/redo:
>
>   $ cat /var/local/bin/redo
>   #!/bin/sh
>   if [ "/boot/grub/grub.cfg" -nt "/var/local/bin/redo" ]; then
>     grub-mkconfig -o /boot/grub/grub.cfg
>   fi
>   touch "/var/local/bin/redo"
>   #
>   $
>
> Then with:
>
>   $ ls -l /boot/grub/grub.cfg /var/local/bin/redo
>   -rw-r--r-- 1 root root  10634 May 22 21:27 /boot/grub/grub.cfg
>   -rwxr--r-- 1 root staff   143 Jun 15 11:31 /var/local/bin/redo
>   $
>
> uninstalling bash-doc and reinstalling it, nothing happened. But after:
>
>   # touch /boot/grub/grub.cfg
>   #
>
> then we get:
>
>   # apt-get remove bash-doc
>   Reading package lists... Done
>   Building dependency tree... Done
>   Reading state information... Done
>   The following packages will be REMOVED:
>     bash-doc
>   0 upgraded, 0 newly installed, 1 to remove and 1 not upgraded.
>   After this operation, 3318 kB disk space will be freed.
>   Do you want to continue? [Y/n]
>   (Reading database ... 327723 files and directories currently installed.)
>   Removing bash-doc (5.1-2+deb11u1) ...
>   Processing triggers for install-info (6.7.0.dfsg.2-6) ...
>   Processing triggers for doc-base (0.11.1) ...
>   Processing 2 removed doc-base files...
>   Invalid format pdf for bash (Bash Manual Page)
>   Invalid format pdf for bash (Bash Manual Page)
>   Registering documents with dhelp...
>   Generating grub configuration file ...                ← voilà
>   Found linux image: /boot/vmlinuz-5.10.0-35-amd64
>   Found initrd image: /boot/initrd.img-5.10.0-35-amd64
>   Found linux image: /boot/vmlinuz-5.10.0-34-amd64
>   Found initrd image: /boot/initrd.img-5.10.0-34-amd64
>   Warning: os-prober will be executed to detect other bootable partitions.
>   Its output will be used to detect bootable binaries on them and create new boot entries.
>   Found Debian GNU/Linux 10 (buster) on /dev/sda4
>   Adding boot menu entry for UEFI Firmware Settings ...
>   done
>   # apt-get -o Acquire::http::Proxy="http://192.168.1.14:3142/"; install bash-doc
>   Reading package lists... Done
>   Building dependency tree... Done
>   Reading state information... Done
>   The following NEW packages will be installed:
>     bash-doc
>   0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
>   Need to get 0 B/1931 kB of archives.
>   After this operation, 3318 kB of additional disk space will be used.
>   Retrieving bug reports... Done
>   Parsing Found/Fixed information... Done
>   Selecting previously unselected package bash-doc.
>   (Reading database ... 327642 files and directories currently installed.)
>   Preparing to unpack .../bash-doc_5.1-2+deb11u1_all.deb ...
>   Unpacking bash-doc (5.1-2+deb11u1) ...
>   Setting up bash-doc (5.1-2+deb11u1) ...
>   Processing triggers for install-info (6.7.0.dfsg.2-6) ...
>   Processing triggers for doc-base (0.11.1) ...
>   Processing 2 added doc-base files...
>   Registering documents with dhelp...
>   Scanning processes...
>   Scanning processor microcode...
>   Scanning linux images...
>   Running kernel seems to be up-to-date.
>   The processor microcode seems to be up-to-date.
>   No services need to be restarted.
>   No containers need to be restarted.
>   No user sessions are running outdated binaries.
>   #
>
> So the script runs whenever grub.cfg gets updated. Note that
> grub-install does not update grub.cfg, IIRC, but the script
> can be triggered manually whenever necessary (as I did above).
>
> Cheers,
> David.
>

Hey David - yes, this is basically the general mechanism I was looking
for, super (and it's somewhat silly that I had totally forgotten about
needrestart, despite seeing it every time...).

If someone points me to where to record this knowledge more
permanently, I'd be glad to do it, with the appropriate credit to
David...

Super stuff...

-- 
Boyan Penkov


Reply to: