You are not logged in.
From what I can tell, it is looking like the systemd timer doesn't get enabled on install of the program. The script runs once on install, but no further checks occur until the systemd timer gets enabled through a terminal or after boot. The timer is being enabled on boot and works correctly thereafter.
Thanks - I'll have to try a fresh install and see what happens.
I suppose the question is how to enable the systemctl timer on initial script run? Maybe something else in the postinst file of the .deb?
Yes, some more thought...
I often reboot my computer and the package does do a one-off run after install, so I must have missed that the timer wasn't being started. People whose machines are always up will not get the timer checks though.
OTOH things ought still to work even without the systemd timer, being triggered by dpkg runs, but let's sort out the timer first.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
The timer start thing is a bit tricky because it's a user timer, triggered 10 min after the user login. OTOH the package install process is running as root. Perhaps bl-run-broadcast could be run at install time in the package postinst script, as it already is to run an initial update check, but I feel there should be a simpler way...
Anyway, I've just confirmed that the systemd timer is not started after a fresh install of bunsen-apt-update-checker, although the check script itself is run.
Last edited by johnraff (2023-06-16 09:37:24)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Did a bit of research and found:
https://unix.stackexchange.com/question … ckage-alon
I rebuilt the package with debhelper as a dependency, and with that installed was able get a listing of the timer afterwards with:
systemctl --user list-timers --all
but was unable to enable/start the timer with systemctl enable --now in a terminal. My package name is different, but here is what I get for the timer after install but before reboot. I recognize I don't properly understand everthing here so just doing the best I can.
[sleekmason@ai2 ~]$systemctl --user list-timers --all
NEXT LEFT LAST PASSED UNIT ACTIVATES
- - - - ld-apt-update-checker.timer ld-apt-update-checker.service
1 timers listed.
[sleekmason@ai2 ~]$sudo systemctl enable --now ld-apt-update-checker.timer
[sudo] password for sleekmason:
Failed to enable unit: Unit file ld-apt-update-checker.timer does not exist.
[sleekmason@ai2 ~]$
I don't understand why the first statement is true but the second shows the timer to not exist. I can only assume I may be missing something important here.
but I feel there should be a simpler way...
What do you have in mind?
Offline
Made some progress.
Re: packaging a systemd timer, I think I was already doing it by the rules (as in the page you linked) and the timer was getting installed and enabled - but not started. The problem is one of logic - the package installation is done by root, but the timer is started by the user, on login and at intervals thereafter. So when the package is installed the user has already logged in, and the timer has missed its chance to be started. As @sleekmason noted, if you do a reboot (maybe even just logout/in) then the timer gets started and runs OK.
So what's needed for people who aren't going to reboot anytime soon after installing the package is to start the timer at installation time, from debian/postinst. After playing around it looks as if simply adding
bl-run-broadcast systemctl start bunsen-apt-update-checker.timer
should do the job. That translates the root-level process to a user-level command, and seems to work when I run it as root in a terminal. Starting the timer might also be enough to trigger the check script, but I have to do a test package build to find out.
Also bl-run-broadcast needed to pass along the environment variable XDG_RUNTIME_DIR for systemctl to follow the command. Revised bl-run-broadcast will go in the updated package:
#!/bin/bash
#
# bl-run-broadcast
# utility for root to run a command as all current X users
#
# Copyright: 2023 John Crawley <john@bunsenlabs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
HELP="bl-run-broadcast is a script for a root process
to run a command for all current X users.
For each user, and each DISPLAY, the command is run in a bash shell,
forked and disowned, so the parent process should not hang,
even if child processes continue running.
Usage: bl-run-broadcast <command> [<arguments>]
Optional arguments:
-h | --help Show this message
This script must be run as root.
NOTE Any command and arguments can be passed, but this utility was intended
for relatively short-lived notification applications like notify-send or yad.
Because the spawned processes are disowned, there will be no way to
check their return values on exit.
EXAMPLE:
bl-run-broadcast notify-send 'System Message' 'Something happened that you should know about.'
"
error_exit() {
echo "$0 error: $1" >&2
exit 1
}
case $1 in
--help|-h)
echo "$HELP"
exit
;;
'')
echo "${0}: no command was passed" >&2
exit 1
;;
esac
command -v "$1" >/dev/null || error_exit "cannot find command $1"
[[ $( id -u ) -eq 0 ]] || error_exit "This script must be run as root."
declare -A displays users
users=()
displays=()
for i in $(users);do # "users" command o/p
[[ $i = root ]] && continue
users[$i]=1
done # unique names
for u in "${!users[@]}"; do
for i in $(ps e -u "$u" | sed -rn 's/.* DISPLAY=(:[0-9]*).*/\1/p');do
displays[$i]=$u
done
done
for d in "${!displays[@]}";do
runuser -l "${displays[$d]}" --shell /usr/bin/bash -c "set -m; DISPLAY=${d} XDG_RUNTIME_DIR=/run/user/$(id -u ${displays[$d]}) $(printf '%q ' "$@" ) >/dev/null 2>&1 & disown; set +m;"
# runuser -u "${displays[$d]}" -- bash -c "set -m; DISPLAY=${d} $(printf '%q ' "$@" ) >/dev/null 2>&1 & disown; set +m;"
# sudo -u "${displays[$d]}" DISPLAY="$d" bash -c " $(printf '%q ' "$@" ) & "
done
exit
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
I rebuilt the package with debhelper as a dependency, and with that installed was able get a listing of the timer afterwards with:
systemctl --user list-timers --all
but was unable to enable/start the timer with systemctl enable --now in a terminal. My package name is different, but here is what I get for the timer after install but before reboot. I recognize I don't properly understand everthing here so just doing the best I can.
[sleekmason@ai2 ~]$systemctl --user list-timers --all NEXT LEFT LAST PASSED UNIT ACTIVATES - - - - ld-apt-update-checker.timer ld-apt-update-checker.service 1 timers listed. [sleekmason@ai2 ~]$sudo systemctl enable --now ld-apt-update-checker.timer [sudo] password for sleekmason: Failed to enable unit: Unit file ld-apt-update-checker.timer does not exist. [sleekmason@ai2 ~]$
The problem here was that ld-apt-update-checker.timer is a user timer, but your systemctl command was being run as root, and looking for a system timer of that name, which didn't exist.
Try:
systemctl --user status ld-apt-update-checker.timer
Replace 'status' with enable/start/stop/whatever
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
systemctl --user status ld-apt-update-checker.timer
That's the solution all right. I should have seen the missing --user in the second command. Jeez. Thanks for posting the updated script.)
*edit - Had a dialog for root pop up on install, but added --user to the line in bl-run-broadcast and all is well.)
bl-run-broadcast systemctl --user start bunsen-apt-update-checker.timer
Last edited by sleekmason (2023-06-17 15:21:02)
Offline
I've uploaded bunsen-apt-update-checker 12.1~test1-1 to the boron repository.
The code is here: https://github.com/BunsenLabs/bunsen-apt-update-checker
I'm hoping that this will now start bunsen-apt-update-checker.timer immediately on install, without waiting for a new login. The update check script should also be triggered then, if I'm reading the docs correctly: https://www.freedesktop.org/software/sy … timer.html
If a timer configured with OnBootSec= or OnStartupSec= is already in the past when the timer unit is activated, it will immediately elapse and the configured unit is started.
To test if this is working it's necessary to first purge the existing package (apt purge bunsen-apt-update-checker) to make sure all references to the existing timer have been removed, then reboot to clear out any residue before installing the new package.
Check if the timer is now running with
systemctl --user status bunsen-apt-update-checker.timer
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
^That package upgrade seems to start the systemd timer immediately on install, without waiting for a new login, and if there are already package upgrades the notification popup is triggered.
Is it working OK for everyone else? To test it you'd have to purge bunsen-apt-update-checker, wait till you knew your local apt was aware of some updates, then install the package and see if it notified you right away.
---
Second topic: a couple of weeks ago I tried disabling the systemd timer on my Beryllium main work machine to see if the apt updates alone would trigger the notification. For some time there were no new Bullseye upgrades, but some arrived today, and the notification was triggered, so that seems to be working too.
To disable the timer you can run:
sudo systemctl --global disable bunsen-apt-update-checker.timer
The notifications should still come - the timer is a belt-and-braces measure really.
I'd be interested to know, though, if some people are being passed over, like, is it still taking 10 days?
jr2 wrote:Just try ignoring it for a while. I have found it catches up eventually.
Yes, it did catch up finally, after ca 10 days and 20 - 25 hours of uptime without notifications, it notified me that there were 14 of them today.
---
Outline of the algorithm:
Today I booted my "Boron" and after three hours and no sign from the update-notifier I decided to run an update in terminal to see if there were some. And it was, 33 actually. Should not the update-notifier have notified me about this?
Even if you know updates are available (eg from the security mailing list, or looking directly at the repository, or from another computer) nothing will happen until your local apt updates its own database. You can do that manually with 'sudo apt update' but of course if you had to do that manually it would make the notifier package quite pointless!
What the package does is add a bit of apt configuration in /etc/apt/apt.conf.d/52aptupdates.bunsen:
// This should be enabled by default anyway.
APT::Periodic::Enable "1";
// Do "apt-get update" automatically every n-days (0=disable)
APT::Periodic::Update-Package-Lists "1";
// This option would require the package unattended-upgrades.
APT::Periodic::Unattended-Upgrade "0";
This tells apt to automatically update itself once a day. The exact time is not defined though - that is handled by some built-in apt scripts, so you can't determine exactly when the notification will arrive. When it does arrive, though, the notification will be should be triggered by this code in the same file:
// THESE COMMANDS ARE USED TO TRIGGER bl-apt-update-check
// WHENEVER UPDATE INFO MIGHT HAVE CHANGED
// Whenever dpkg is called we might have different updates
// i.e. if an user removes a package that had an update
DPkg::Post-Invoke {
"/usr/bin/test -x /usr/sbin/bl-run-broadcast && /usr/bin/test -x /usr/bin/bl-apt-update-check && /usr/sbin/bl-run-broadcast bl-apt-update-check || true";
};
// When Apt's cache is updated (i.e. apt-cache update)
APT::Update::Post-Invoke-Success {
"/usr/bin/test -x /usr/sbin/bl-run-broadcast && /usr/bin/test -x /usr/bin/bl-apt-update-check && /usr/sbin/bl-run-broadcast bl-apt-update-check || true";
};
So the systemd timer was added just in case the apt update happened at an inconvenient time.
To check if the apt auto-update has really been set, run:
apt-config dump | grep Periodic
You should see:
APT::Periodic "";
APT::Periodic::Enable "1";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "0";
NOTE
Just to be 100% clear, this is not going to do any kind of automatic upgrade! That has been thoroughly discussed here and everybody agreed that it would be a Bad Thing. It's just a utility to detect if upgrades are available and let you see what they are. What you do at that point is entirely up to you.
Last edited by johnraff (2023-07-07 07:04:58)
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
^Yes, got that exact same output as I should.
Offline
^thanks!
Just this morning a couple of webkit upgrades came in, and the notification appeared, even without the timer running, so that part seems to be OK.
'apt policy firefox' showed that data about the latest firefox update hadn't yet been downloaded. I guess apt will do its auto-update sometime in the next 24 hours and with luck the notification will appear then.
I'm subscribed to the Debian Security Mailing List, so I got a mail today about firefox-esr 102.13.0esr-1~deb11u1 (for Bullseye), but my local apt still thinks the latest version is 102.12.0esr-1~deb11u1. A run of 'sudo apt update' would probably fetch the latest data, but I want to leave it and see if it can do it by itself...
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Yes, the Firefox update notification came in the next day, followed by Thunderbird, so in fact the systemd timer seems to be quite optional. Does no harm though - people on systemd-less systems can just ignore it.
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline
Found a bug and a couple of places to polish up a bit.
Bug was, if the login window was left a long time without logging in, then lightdm sometimes tried to run bl-apt-update-checker. It left its own lockfile /tmp/bl-apt-update-check-lock and because it belonged to lightdm not to the user, it blocked the user from running bl-apt-update-checker until the next reboot when /tmp was emptied.
Then I realized that on a multi-user system each user might try to set the lockfile, blocking the other user.
Fix for both of those was not to use /tmp but to put each user's lockfile in /run/lock/<id>
Extra protection, don't allow bl-apt-update-checker to run for system users like lightdm (id under 1000) and don't allow bl-run-broadcast to send commands to system users (test for $(id -u).
Uploaded as bunsen-apt-update-checker 12.1-1, updated code on GitHub: https://github.com/BunsenLabs/bunsen-apt-update-checker
Changes: https://github.com/BunsenLabs/bunsen-ap … mits/boron
...elevator in the Brain Hotel, broken down but just as well...
( a boring Japan blog (currently paused), now on Bluesky, there's also some GitStuff )
Offline