commit 2e9d842de164368abdc0261b3708363eb2f4f2c1
Merge: b36413d 3c59672
Author: Michael Vogt <mvo@debian.org>
Date: Mon Oct 26 09:51:39 2026 +0100
Merge pull request #436 from mvo5/drop-upgrade-between-snapshots
debian: fold upgrade-between-snapshots into existing tests
commit b36413d54c65a028d08a4ded5b8f1ec082eeaaf6
Author: Michael Vogt <michael@amutable.com>
Date: Mon Oct 26 08:01:34 2026 +0100
data: update Debian config for forky
Thanks to Daniel Lewart for suggesting this.
commit 1744c65eb181cc4542fe78cf6ddd6418e3082eb6
Merge: 8bfb4e4 b9f3b57
Author: Michael Vogt <mvo@debian.org>
Date: Mon Oct 26 07:58:37 2026 +0100
Merge pull request #418 from Fantu/add-italian-translation
Add Italian translation
commit 3c596723d8df000ac1a0c4d6659a8b037a92f387
Author: Michael Vogt <michael@amutable.com>
Date: Sun Oct 25 21:49:37 2026 +0100
test: use --no-install-recommends for slightly less package deps
commit a5fadc81c8345f0ab517f3687481ea74548c8d53
Author: Michael Vogt <michael@amutable.com>
Date: Sun Oct 25 21:50:32 2026 +0100
tests: drop unattended-upgrade --dry-run already covered by unit tests
commit 8bfb4e4c03bed93798fcd95e8e82a7142d3753aa
Author: Johan Walles <johan.walles@gmail.com>
Date: Wed Oct 21 23:18:38 2026 +0200
Add MinBatteryLevel option to upgrade on battery
Laptops that are only on battery while awake never get unattended
upgrades. Setting MinBatteryLevel to a percentage like "40" lets
unattended-upgrade run on battery while the system batteries are
charged at least that much. "0" runs regardless of power source, and
"ac-only" never runs on battery.
With MinimalSteps (the default), should_stop() runs before each
upgrade step, so a run on battery stops at the next step once the
charge drops below the threshold. The step itself always completes.
The charge is the average of all system batteries in
/sys/class/power_supply. Peripheral batteries and empty bays are
skipped. Averaging is exact for same-size batteries, which is the
common case. If any battery's charge can't be read,
unattended-upgrade stops, as before.
MinBatteryLevel replaces OnlyOnACPower in the example configs.
OnlyOnACPower still works as before, and is ignored with a warning if
both are set. An invalid MinBatteryLevel is treated as "ac-only" with
a warning, rather than falling back to OnlyOnACPower, which could be
less strict than intended. Empty values count as unset. If neither
option is set, the default is still to only run on AC power.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
commit ca07ce7ef26616e595f1e332e53197078dc80f46
Author: Michael Vogt <michael@amutable.com>
Date: Sun Oct 25 21:35:19 2026 +0100
debian: fold upgrade-between-snapshots into existing tests
The upgrade-between-snapshots test is silently broken for a while
now (2022ish) and the snapshot used is from 2020ish. The idea was
good but it requires constant work to keep it updated and its
expensive to run as it requires a chroot setup etc.
Instead fold the check (hold and blacklist) into the existing
upgrade-all-security and drop upgrade-between-snapshots.
commit b9f3b57f90de0405229f2632ad338c47472e6c67
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Tue Sep 29 21:26:58 2026 +0200
Complete and review the Italian translation
Translates the four messages that were missing or fuzzy, so all 87 are
now translated, and fixes typos and mistranslations in the others: for
example "Upgrade in minimal steps" and "Giving up on lockfile" had a
different meaning, and the strict whitelist was translated as the
normal one. The other messages are left as they were, apart from a few
small improvements.
The new message in the auto-removal log uses the same words as the
summary mail, which lists the same packages.
Uses the terms of the Italian apt translation for kept back ("mantenuti
alla versione attuale") and held ("bloccato") packages, and updates the
header with the translators.
Checked with msgfmt -c and in a Debian 13 container with
LANG=it_IT.UTF-8: --help, a dry-run and the summary mail are in Italian.
Assisted-by: Claude Code:claude-opus-5-5
commit 44dada81665b340eafe4c6ad57e1ff86f3999fdd
Author: Jarno Suni <8@iki.fi>
Date: Sun Oct 25 19:01:28 2026 +0100
README: document Remove-{Unused-Kernel-Packages,New-Unused-Dependencies}
Remove-Unused-Kernel-Packages was missing from the options reference.
And Remove-New-Unused-Dependencies needs tweaking as it only applies when
Remove-Unused-Dependencies is disabled.
Squashed from GH #247.
Co-Authored-By: Michael Vogt <michael@amutable.com>
commit 5e19766522ad6b72b4891212e17d589f3fd99087
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Tue Sep 29 21:00:18 2026 +0200
Import the Italian translation from Ubuntu
Taken from the source of language-pack-it-base 1:24.04+20260905 in
Ubuntu 24.04 (data/it/LC_MESSAGES/unattended-upgrades.po), exported from
Launchpad on 2026-09-05 and last revised in 2020. Launchpad terms of use
license translations made there under BSD.
The only change is a msgmerge with the current template: 83 messages
translated, 2 fuzzy and 2 untranslated. The review and the missing
messages follow in the next commit, so that its diff shows them.
Assisted-by: Claude Code:claude-opus-5-5
commit f951a730db16153eac6e1eb282335e1c1d711a05
Merge: 805fe39 97fddbe
Author: Michael Vogt <mvo@debian.org>
Date: Sun Oct 25 19:30:45 2026 +0100
Merge pull request #431 from Fantu/bts-translations
Apply the translations sent to the Debian BTS
commit 805fe395a6dada1a3cb58cdcdc8431aeddb8c323
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Sat Oct 24 14:17:56 2026 +0200
Add a NEWS entry about Package-Whitelist working again
The fix in cd5385f changes what gets upgraded on systems with a
non-strict whitelist, so warn about it. Also tell the users who enabled
Package-Whitelist-Strict, or wrote a blacklist of everything else, to
work around the bug that they can go back to a plain whitelist.
Assisted-by: Claude Code:claude-opus-5-5
commit b7f72b2235a3dc5794281b335a4de769ec5404d3
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Sat Oct 24 12:13:19 2026 +0200
Update POT file
Regenerated with "python3 setup.py build_i18n" from the current sources.
The template was last regenerated in 2019: it missed 14 messages, among
them the ones about kept back packages, and still had 4 that are no
longer used.
Assisted-by: Claude Code:claude-opus-5-5
commit 9057748041e391bec75abce007246aa627e9ddcd
Author: Jochen Sprickerhof <git@jochen.sprickerhof.de>
Date: Sat Feb 25 09:18:54 2023 +0100
Catch PermissionError when executing on_ac_power
Reproducible with:
$ touch /usr/bin/on_ac_power
and powermgmt-base not installed.
Ref: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1031880
commit c4290e498ba6a1aeba6d78b6bd3e7d1a68308f02
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Sat Oct 24 15:53:10 2026 +0200
Add the MailReport values "on-new-change" and "on-upgrade"
With MailReport "on-change" a mail is sent on every run while packages
are kept back, even when nothing was installed, upgraded or removed. On
a system that blacklists the kernel, for example, each run mails the
same kernel packages until they are upgraded by hand. Reporting kept
back packages is intended: blacklisted packages were added to the list
in #63, and in Debian bug #625847 Michael Vogt pointed out that a
package that did not get upgraded can mean an open security issue,
suggesting a separate option that keeps sending the mail by default
(https://bugs.debian.org/625847#25). The daily repetition, though, has
been a long-standing complaint: #24, #379 and the same Debian bug, which
Bálint Réczey considered not fully fixed in 2019
(https://bugs.debian.org/625847#64).
The default "on-change" keeps the current behaviour, and two new values
decide differently whether kept back packages alone are enough for a
mail:
- "on-new-change" sends a mail only for newly kept back packages or
versions: a package that stays kept back is reported once instead of
every day, a new version of it is reported again even if the previous
one was never installed, and so is a package that comes back after it
stopped being kept back;
- "on-upgrade" sends no mail just for kept back packages.
Mails sent for any other reason still list all the kept back packages,
and the motd notice is unchanged. These were first a separate
MailReport-Kept-Back option, which however only mattered with
"on-change": as values of MailReport they leave no combinations without
effect. An older unattended-upgrades that reads one of them treats it
like "on-change".
For "on-new-change" the reported name=version pairs are saved in
var/lib/unattended-upgrades/kept-back-mailed. The existing kept-back
file cannot be reused: it holds names only, and its format is read by
the motd snippet. KeptPkgs now also records the version found by
find_kept_packages(). The MailReport value is read by the new
get_mail_report_option(), and send_summary_mail() now gets the rootdir
and uses the new KeptBackMailState class, which keeps the mode, the
saved pairs and the current ones together, tells whether the kept back
packages are news and records them once mailed.
The new file is rewritten only after a successful run, and then only
after a successful mail or when there was nothing new to report: a
failed mail is retried on the next run, packages that are no longer kept
back are dropped, and a failed run, whose result does not include the
kept back packages, leaves it alone. Nothing is written in dry-run mode.
The file only saves mails, so an error reading or writing it is logged
and never stops the run: an unreadable file counts as empty.
README.md now describes every MailReport value, and the shipped
configuration files the two new ones; data/50unattended-upgrades.md5sum
gets their new checksums. As HACKING.md recommends for the templates,
this also folds in the "to chose" typo fix of #416, in the templates and
in a test fixture.
The new tests in test/test_mail.py run main() with run() mocked to
return a given result, and check "on-change", "on-new-change" (including
new versions and packages that are no longer kept back), "on-upgrade", a
failed mail, a failed run, a state file that can be neither read nor
written, and the recorded versions.
The same logic, still behind the separate option, was checked in a
Debian 13 container with unattended-upgrades 2.12 from the archive, the
patched script installed over it, a fake sendmail and a local repository
with one blacklisted package: the default mails on every run; "never"
(now "on-upgrade") sends nothing; "on-change" (now "on-new-change")
mails once, then stays quiet, also after a dry-run and after a run
failed on the dpkg lock, until a new version shows up; a failed mail is
retried on the next run; a mail sent for an upgrade records the kept
back packages it lists; a state file that is a directory only logs two
errors. The package built from that version was also installed over 2.12
in a Debian 13 VM with exim and pending security updates, blacklisting
linux-: the unmodified configuration file is replaced without a prompt,
a real run upgrades everything else and mails once, and later runs, also
through apt-daily-upgrade.service, stay quiet.
Co-authored-by: Michael Vogt <michael@amutable.com>
Assisted-by: Claude Code:claude-opus-5-5
commit 1f9bf808034f869547587a60e4fc4e805273fd91
Author: Michael Vogt <michael@amutable.com>
Date: Sat May 30 11:26:14 2026 +0200
debian: use os-release, drop lsb-release dependency
This commit switches to parse /etc/os-release for the lsb-release
information. This means we can drop the lsb-release dependency
and avoid the multile forks when getting the DISTRO_ID and friends.
commit 97fddbe3199fab081c6c6341dfc3d78cf00e646f
Author: Pedro Ribeiro <p.m42.ribeiro@gmail.com>
Date: Sat Oct 24 14:42:22 2026 +0200
Update the Portuguese translation
Translation sent in Debian bug #1102157 by the Portuguese translation
team, updating the one from 2012.
Closes: #1102157
commit 01d99b4fa5e80debecdf80a22d055b8bf7d454bd
Author: Baptiste Jammet <baptiste@mailoo.org>
Date: Sat Oct 24 14:40:34 2026 +0200
Update the French debconf translation
Translation sent in Debian bug #1121127, proofread by the
debian-l10n-french mailing list. It replaces the translation of the
program that was in debian/po/fr.po (moved to po/fr.po in the previous
commit), so the debconf question is shown in French again.
It also supersedes the earlier French debconf translation sent in Debian
bug #1104858, from the same team.
Closes: #1104858 #1121127
commit cd37366593e2a59f772394ec7bc6f8d3c0c4af5a
Author: Jean-Pierre Giraud <jean-pierregiraud@neuf.fr>
Date: Sat Oct 24 14:32:58 2026 +0200
Move the French translation of the program to po/fr.po
The translation sent in Debian bug #989635 is titled "French templates
translation" and was meant for debian/po/fr.po, but it translates the
messages of the program, not the debconf template: commit e6d291b put it
in debian/po/fr.po as asked, so it never reached po/fr.po and the
debconf template has not been translated since.
This copies it to po/fr.po, where it replaces the 2019 version it was
updated from. The debconf translation is restored in debian/po/fr.po in
the next commit.
commit 6483d382195865a4005809073d7ba77bfca2497f
Author: Daniel Lewart <lewart3@gmail.com>
Date: Fri Oct 23 23:16:47 2026 +0200
Update 50unattended-upgrades.Debian for trixie
Closes: #1115376
Co-authored-by: Michael Vogt <michael@amutable.com>
commit 719565a884fe841ff360414dbdbdbf2d59620a78
Author: Michael Vogt <michael@amutable.com>
Date: Fri Oct 23 22:37:29 2026 +0200
HACKING: add section about conffile&ucf
Small addition to codify when we need to be careful about the
default apt.conf.d configuration.
commit cd5385f998532432ab4734e2262e065b5b841613
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Thu Sep 17 14:11:26 2026 +0200
Fix Package-Whitelist being ignored unless the whitelist is strict
In calculate_upgradable_pkgs() the whitelist check ended up attached to
the wrong operand: since "and" binds tighter than "or", the condition
"pkg.is_upgradable or candidate_version_changed(pkg) and
is_pkgname_in_whitelist(...)" is evaluated as "pkg.is_upgradable or
(candidate_version_changed(pkg) and is_pkgname_in_whitelist(...))".
Every upgradable package satisfies the first operand, so
is_pkgname_in_whitelist() is never reached and all packages from the
allowed origins are upgraded, no matter what
Unattended-Upgrade::Package-Whitelist says.
That contradicts README.md, which states that only packages matching the
whitelist are marked for upgrade, and it also makes the documented
non-strict behaviour (whitelisted packages plus their dependencies)
unreachable. Package-Whitelist-Strict is not affected, because it works
through pinning and is_pkg_change_allowed() instead.
The missing parentheses were introduced in 4d0c9cd, first released in
1.16, when the Allow-downgrade handling was added to the condition; in
1.11.2 the check still read "pkg.is_upgradable and
is_pkgname_in_whitelist(...)". Restoring the grouping keeps the
downgrade case working: the whitelist is now applied to both ways a
package can be picked. An empty whitelist still matches everything, so
the default configuration is unchanged.
The new test in test/test_whitelist.py upgrades the root.rewind tree
with and without a whitelist; the second case fails without this fix,
picking test-package and test3-package as well.
Checked on a Debian 13.6 system with 125 pending upgrades and
unattended-upgrades 2.12 from the archive: with a whitelist of "unzip$"
the shipped version upgrades all 125 packages and the patched one
upgrades unzip alone, while the default configuration, a strict
whitelist and a blacklist give byte for byte the same package list
before and after the change.
Fixes #293
Closes: #1078049
Assisted-by: Claude Code:claude-opus-5
commit 149a298993c4b97b74cc22d20921d49a4b84ba7f
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Tue Sep 29 21:40:03 2026 +0200
Fix the log message for auto-removable packages that were not removed
do_auto_remove() logs the auto-removable packages that were kept
installed as "Packages that are kept back: %s". In apt terms "kept back"
means not upgraded, which is not what this list holds: it is the same
pkgs_kept_installed that the summary mail lists under "Packages that
were kept from being auto-removed:". The log line now uses the same
words.
Some translations followed the misleading wording (German and Dutch
translate it as held back packages); the new msgid lets translators fix
them.
Assisted-by: Claude Code:claude-opus-5-5
commit 0d518d9d41059f69fc6b3b1ce139bf11591b3b9f
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Tue Sep 29 21:38:06 2026 +0200
Fix the excuses logged for kept back packages with a whitelist
kept_package_excuse() never returned "Package %s is not whitelisted and
it is not a dependency of a whitelisted package.": that check sits in
the else branch of the strict whitelist check, where the package is
already known to be whitelisted, so it can never match. Since f3c6f13
(1.18) a package left out by a non-strict whitelist gets the generic
excuse "kept back because a related package is kept back or due to local
apt_preferences(5)" instead. Right now this only shows up together with
the fix in #412, because without it the non-strict whitelist does not
keep anything back.
The same "elif whitelist" branch also hides the next check whenever a
whitelist is configured: a whitelisted package from an untrusted origin
gets the generic excuse instead of "Package %s's origin is not
trusted.".
The whitelist branch now only handles packages that are not whitelisted,
with the strict or non-strict message, and every other package goes on
to the trust check.
The new test/test_kept_package_excuse.py covers every excuse; the
non-whitelisted and untrusted cases fail without this change. Also
checked in a Debian 13 container with a local repository: with #412
applied, a package left out by a non-strict whitelist is now logged as
not whitelisted, and whitelisted packages from an insecure repository as
not trusted; the strict whitelist messages do not change.
Assisted-by: Claude Code:claude-opus-5-5
commit 322edc724f1b1e179132cb94679a134f6264889a
Author: c99e <268417377+c99e@users.noreply.github.com>
Date: Sun Oct 11 22:23:02 2026 +0300
Fix development-release debug message on stable releases
Only log the development-release message when the returned release
matches the installed series. Preserve the existing release-window policy
and cover stable-series continuation with a regression test.
Fixes #420
Co-authored-by: Codex <codex@openai.com>
commit d798ed86a209472f707a0d1dc20a5ea116228f45
Author: Alexandre Detiste <alexandre.detiste@gmail.com>
Date: Wed Jan 15 23:44:51 2025 +0100
both usage of pycodestyle & pep8 has been removed
commit 5877bee20c58fda9111f8ef09eaefa0c4c2bbf92
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Tue Sep 29 20:38:45 2026 +0200
Move string formatting out of _() calls
Three messages were formatted before being passed to _(), so gettext
looked up the already formatted string and never found a translation.
"Unable to parse %s." is translated in 12 languages, but was always
logged in English. The same mistake was pointed out in the review of
#415.
Checked in a Debian 13 container with LANGUAGE=de and an Origins-Pattern
with an invalid placeholder: the log now says
"Unattended-Upgrade::Origins-Pattern kann nicht ausgewertet werden."
instead of the English message.
Assisted-by: Claude Code:claude-opus-5-5
commit c5001e74f8344f3f89d05fcb93c89cf062f78c6d
Author: Fabio Fantoni <fantonifabio@tiscali.it>
Date: Mon Sep 28 20:25:45 2026 +0200
Fix --dry-run deleting the list of kept-back packages
In dry-run mode find_kept_packages() returns an empty list on purpose
("The list of kept packages can't be calculated in dry-run mode."), but
main() still hands that result to update_kept_pkgs_file(), which deletes
var/lib/unattended-upgrades/kept-back when the list is empty. A manual
"unattended-upgrade --dry-run" therefore wipes the list written by the
last real run.
That file feeds the motd snippet installed as
/etc/update-motd.d/92-unattended-upgrades, so after a dry-run the "N
updates could not be installed automatically" notice disappears until
the next real run. Dry-run is the usual way to check a configuration, so
this is easy to hit on a system where some updates are waiting for a
manual upgrade.
Skip the update in dry-run mode, as the summary mail and the plugins'
postrun() already are a few lines below.
The new test in test/test_motd.py runs main() in dry-run mode on the
root.untrusted tree with an existing kept-back file; without this fix
the file is gone afterwards.
Checked in a Debian 13 chroot with unattended-upgrades 2.12 from the
archive and one blacklisted package pending: after a real run kept-back
lists that package, the shipped version deletes the file on --dry-run,
the patched one leaves it in place, and a following real run writes the
same list again.
Assisted-by: Claude Code:claude-opus-5-5
Automatic checks made by the Debian l10n team found some issues with the translations contained in this package. You should check the l10n status report for more information.
Issues can be things such as missing translations, problematic translated strings, outdated PO files, unknown languages, etc.