Ubuntu. Автоматическое обновление

10.07.2023

Теги: LinuxUbuntuКонфигурацияНастройкаУстановка

Для автоматизации процесса установки обновлений в Ubuntu есть механизм Unattended Upgrades, который позволяет не только избавиться от ручной работы, но и достаточно тонко настроить эту процедуру. По умолчанию пакет unattended-upgrades уже установлен, так что нужно только настроить его под собственные потребности.

Файлы конфигурации

Основные настройки расположены в файле /etc/apt/apt.conf.d/50unattended-upgrades — сначада идут два списка, что нужно обновлять и что не нужно обновлять.

Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}";
    "${distro_id}:${distro_codename}-security";
    "${distro_id}ESMApps:${distro_codename}-apps-security";
    "${distro_id}ESM:${distro_codename}-infra-security";
};

Unattended-Upgrade::Package-Blacklist {
    // здесь пакеты, которые обновлять не нужно
};

Обновления безопасности пакет unattended-upgrades скачивает и устанавливает автоматически.

Дальше идут еще несколько настроек, которые могут быть полезны

// Если при попытке обновления возникают ошибки, то система может попытаться их исправить, это
// равносильно запуску команды dpkg --force-confold --configure -a. Обычно эта команда хорошо
// справляется со своими задачами, но такая ситуация является потенциально опасной.
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
// Разбить обновление на наименьшие возможные части, чтобы обновление можно было прервать
// с помощью сигнала SIGTERM. Это замедляет процесс обновления, зато дает возможность
// выключения компьютера во время обновления (с небольшой задержкой).
Unattended-Upgrade::MinimalSteps "true";
// Установить все обновления при завершении работы компьютера, вместо выполнения в фоновом
// режиме во время работы машины. Это (очевидно) замедлит выключение компьютера.
Unattended-Upgrade::InstallOnShutdown "false";
// Отправить сообщение электронной почты на этот адрес для устранения проблем или обновления
// пакетов. Если значение пустое или не задано, то сообщение электронной почты не отправляется.
Unattended-Upgrade::Mail "";

Для отправки почты должен быть установлен почтовый сервер. Но можно обойтись установкой и настройкой SSMTP для отправки писем через внешний почтовый сервер (см. здесь). В этом случае нужно изменить директиву, чтобы она имела следующий вид.

Unattended-Upgrade::Sender "somebody@somewhere.com";
// Когда отправлять сообщение на почту, возможные значения always, only-on-error или on-change
Unattended-Upgrade::MailReport "on-change";
// Удалить неиспользуемые автоматически установленные пакеты, связанные с ядром (образы, заголовки).
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
// Автоматическое удаление только новых неиспользуемых пакетов, установленных при обновления
Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
// Автоматическое удаление всех неиспользуемых зависимостей после обновления (эквивалентно apt autoremove)
Unattended-Upgrade::Remove-Unused-Dependencies "false";
// Если для полного применения изменений, внесенных установкой пакета или обновлением, требуется
// перезагрузка — создается файл /run/reboot-required. Эта директива предписывает выполнить
// перезагрузку немедленно, если после обновления обраружен файл /run/reboot-required.
Unattended-Upgrade::Automatic-Reboot "false";
// Автоматическая перезагрузка даже при наличии пользователей, вошедших в систему, когда
// для Unattended-Upgrade::Automatic-Reboot установлено значение true.
Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
// Если нужна перезагрузка и она разрешена, то выполнить перезагрузку в указанное время
// (значение по умолчанию — now, то есть немедленно).
Unattended-Upgrade::Automatic-Reboot-Time "now";

При эксплуатации виртуальных серверов в других локациях будет не лишним проверить, что на них правильно настроено время и часовой пояс, иначе можно получить перезагрузку совсем не тогда, когда она запланирована.

Теперь посмотрим второй файл конфигурации /etc/apt/apt.conf.d/20auto-upgrades — по умолчанию в нем всего две директивы.

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";

Они указывают как часто обновлять список пакетов и с какой периодичностью проводить обновления, число означает количество дней. С приведенными настройками обновления будут проверяться и устанавливаться ежедневно.

Для очистки кеша скачанных пакетов предназначена следующая директива — период очистки установлен в значение каждые 7 дней.

APT::Periodic::AutocleanInterval "7";

Также может быть интересна опция, позволяющая только скачивать обновления, без их установки — установка остается за администратором.

APT::Periodic::Download-Upgradeable-Packages "1";
Альтернативный способ активировать unattended-upgrades — создать файл /etc/apt/apt.conf.d/10periodic. Если оба эти файла существуют, настройки из 10periodic будут перезаписаны настройками из 20auto-upgrades. Смысла в этом нет, зачем это было сделано — об этом документация умалчивает.

Как это работает

В старых версиях Ubuntu запуск обновления был через cron — за это отвечал скрипт в директории /etc/cron.daily. Собственно, он и сейчас там есть, но в нем есть проверка — если есть Systemd, то ничего не делать.

$ cat /etc/cron.daily/apt-compat
# Systemd systems use a systemd timer unit which is preferable to
# run. We want to randomize the apt update and unattended-upgrade
# runs as much as possible to avoid hitting the mirrors all at the
# same time. The systemd time is better at this than the fixed
# cron.daily time
if [ -d /run/systemd/system ]; then
    exit 0
fi
# .....здесь еще какой-то код.....
exec /usr/lib/apt/apt.systemd.daily

Скрипт /usr/lib/apt/apt.systemd.daily использует механизм файловой метки, чтобы определить, когда запрошенное действие выполнялось в последний раз — и сравнивает это с интервалом, установленным для этого действия в APT::Periodic.

#!/bin/sh
#set -e
#
# This file understands the following apt configuration variables:
# Values here are the default.
# Create /etc/apt/apt.conf.d/10periodic file to set your preference.
#
# All of the n-days interval options also accept the suffixes
# s for seconds, m for minutes, h for hours, d for days or
# the "always" value to do the action for every job run,
# which can be used with systemd OnCalendar overrides to
# define custom schedules for the apt update/upgrade jobs.
#
#  Dir "/";
#  - RootDir for all configuration files
#
#  Dir::Cache "var/cache/apt/";
#  - Set apt package cache directory
#
#  Dir::Cache::Archives "archives/";
#  - Set package archive directory
#
#  APT::Periodic::Enable "1";
#  - Enable the update/upgrade script (0=disable)
#
#  APT::Periodic::BackupArchiveInterval "0";
#  - Backup after n-days if archive contents changed.(0=disable)
#
#  APT::Periodic::BackupLevel "3";
#  - Backup level.(0=disable), 1 is invalid.
#
#  Dir::Cache::Backup "backup/";
#  - Set periodic package backup directory
#
#  APT::Archives::MaxAge "0"; (old, deprecated)
#  APT::Periodic::MaxAge "0"; (new)
#  - Set maximum allowed age of a cache package file. If a cache 
#    package file is older it is deleted (0=disable)
#
#  APT::Archives::MinAge "2"; (old, deprecated)
#  APT::Periodic::MinAge "2"; (new)
#  - Set minimum age of a package file. If a file is younger it
#    will not be deleted (0=disable). Useful to prevent races
#    and to keep backups of the packages for emergency.
#
#  APT::Archives::MaxSize "0"; (old, deprecated)
#  APT::Periodic::MaxSize "0"; (new)
#  - Set maximum size of the cache in MB (0=disable). If the cache
#    is bigger, cached package files are deleted until the size
#    requirement is met (the oldest packages will be deleted 
#    first).
#
#  APT::Periodic::Update-Package-Lists "0";
#  - Do "apt-get update" automatically every n-days (0=disable)
#
#  APT::Periodic::Download-Upgradeable-Packages "0";
#  - Do "apt-get upgrade --download-only" every n-days (0=disable)
#
#  APT::Periodic::Download-Upgradeable-Packages-Debdelta "1";
#  - Use debdelta-upgrade to download updates if available (0=disable)
#
#  APT::Periodic::Unattended-Upgrade "0";
#  - Run the "unattended-upgrade" security upgrade script 
#    every n-days (0=disabled)
#    Requires the package "unattended-upgrades" and will write
#    a log in /var/log/unattended-upgrades
#
#  APT::Periodic::AutocleanInterval "0";
#  - Do "apt-get autoclean" every n-days (0=disable)
#
#  APT::Periodic::CleanInterval "0";
#  - Do "apt-get clean" every n-days (0=disable)
#
#  APT::Periodic::Verbose "0";
#  - Send report mail to root
#      0:  no report             (or null string)
#      1:  progress report       (actually any string)
#      2:  + command outputs     (remove -qq, remove 2>/dev/null, add -d)
#      3:  + trace on
#
# .....здесь еще какой-то код.....

В новых версиях Ubuntu за запуск обновления отвечают два таймера Systemd — apt-daily.timer (как apt update) и apt-daily-upgrade.timer (как apt upgrade). При этом, в файле 20auto-upgrades нужно использовать значение always, это означает — не использовать файловую метку, запускать всегда. И время запуска будет определяться только значениями в этих двух таймерах.

APT::Periodic::Update-Package-Lists "always";
APT::Periodic::Unattended-Upgrade "always";
APT::Periodic::AutocleanInterval "7";

$ systemctl cat apt-daily.timer
[Unit]
Description=Daily apt download activities

[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true

[Install]
WantedBy=timers.target
$ systemctl cat apt-daily-upgrade.timer
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer

[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true

[Install]
WantedBy=timers.target

Но эти два таймера только задают время запуска, а работу по обновлению выполняют apt-daily.service и apt-daily-upgrade.service.

$ sudo systemctl status apt-daily.service
○ apt-daily.service - Daily apt download activities
     Loaded: loaded (/lib/systemd/system/apt-daily.service; static)
     Active: inactive (dead) since Mon 2023-07-10 15:38:38 MSK; 47min ago
TriggeredBy: ● apt-daily.timer
       Docs: man:apt(8)
   Main PID: 38519 (code=exited, status=0/SUCCESS)
        CPU: 3.647s

июл 10 15:38:34 ubuntu-client systemd[1]: Starting Daily apt download activities...
июл 10 15:38:38 ubuntu-client systemd[1]: apt-daily.service: Deactivated successfully.
июл 10 15:38:38 ubuntu-client systemd[1]: Finished Daily apt download activities.
июл 10 15:38:38 ubuntu-client systemd[1]: apt-daily.service: Consumed 3.647s CPU time.
$ sudo systemctl status apt-daily-upgrade.service 
○ apt-daily-upgrade.service - Daily apt upgrade and clean activities
     Loaded: loaded (/lib/systemd/system/apt-daily-upgrade.service; static)
     Active: inactive (dead) since Mon 2023-07-10 09:44:29 MSK; 6h ago
TriggeredBy: ● apt-daily-upgrade.timer
       Docs: man:apt(8)
   Main PID: 3499 (code=exited, status=0/SUCCESS)
        CPU: 3.739s

июл 10 09:44:25 ubuntu-client systemd[1]: Starting Daily apt upgrade and clean activities...
июл 10 09:44:29 ubuntu-client systemd[1]: apt-daily-upgrade.service: Deactivated successfully.
июл 10 09:44:29 ubuntu-client systemd[1]: Finished Daily apt upgrade and clean activities.
июл 10 09:44:29 ubuntu-client systemd[1]: apt-daily-upgrade.service: Consumed 3.739s CPU time.

Давайте посмотрим, что делают эти две службы

$ systemctl cat apt-daily.service
[Unit]
Description=Daily apt download activities
Documentation=man:apt(8)
ConditionACPower=true
After=network.target network-online.target systemd-networkd.service NetworkManager.service connman.service

[Service]
Type=oneshot
ExecStartPre=-/usr/lib/apt/apt-helper wait-online
ExecStart=/usr/lib/apt/apt.systemd.daily update
$ systemctl cat apt-daily-upgrade.service
[Unit]
Description=Daily apt upgrade and clean activities
Documentation=man:apt(8)
ConditionACPower=true
After=apt-daily.service network.target network-online.target systemd-networkd.service NetworkManager.service connman.service

[Service]
Type=oneshot
ExecStartPre=-/usr/lib/apt/apt-helper wait-online
ExecStart=/usr/lib/apt/apt.systemd.daily install
KillMode=process
TimeoutStopSec=900

Теперь видим, что всю работу выполняет скрипт /usr/lib/apt/apt.systemd.daily, которому можно передать строку update или install.

Время запуска

Время запуска update

Чтобы изменить время запуска для проверки обновлений, нужно создать override-файл, который изменит некоторые директивы исходного юнит-файла.

$ sudo systemctl edit apt-daily.timer

Эта команда создает файл /etc/systemd/system/apt-daily.timer.d/override.conf и открывает его на редактирование.

[Timer]
# удалить старое значение
OnCalendar=
# установить новое значение
OnCalendar=*-*-* 7,19:00
# установить новое значение
RandomizedDelaySec=30m
В моем случае это не сработало, так что пришлось создавать директорию apt-daily.timer.d и файл override.conf вручную.

Поскольку допускается несколько директив OnCalendar, то нужно сперва удалить все старые значения, а потом добавить новое.

Сообщим Systemd о том, что внесли изменения в юнит-файл

$ $ sudo systemctl daemon-reload

Давайте посмотрим, что получилось в итоге

$ systemctl cat apt-daily.timer
# /lib/systemd/system/apt-daily.timer
[Unit]
Description=Daily apt download activities

[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true

[Install]
WantedBy=timers.target

# /etc/systemd/system/apt-daily.timer.d/override.conf
[Timer]
# удалить старое значение
OnCalendar=
# установить новое значение
OnCalendar=*-*-* 7,19:00
# установить новое значение
RandomizedDelaySec=30m

Мы установили запуск скачивания на 7:00 и 19:00 + случайная задержка в пределах 30 минут — давайте проверим, что так и есть.

$ systemctl status apt-daily.timer
● apt-daily.timer - Daily apt download activities
    Loaded: loaded (/lib/systemd/system/apt-daily.timer; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/apt-daily.timer.d
             └─override.conf
    Active: active (waiting) since Mon 2023-07-10 17:15:51 MSK; 23min ago
    Trigger: Mon 2023-07-10 19:25:55 MSK; 1h 36min left
    Triggers: ● apt-daily.service

июл 10 17:25:51 ubuntu-client systemd[1]: apt-daily.timer: Deactivated successfully.
июл 10 17:25:51 ubuntu-client systemd[1]: Stopped Daily apt download activities.
июл 10 17:25:51 ubuntu-client systemd[1]: Stopping Daily apt download activities...
июл 10 17:25:51 ubuntu-client systemd[1]: Started Daily apt download activities.

Время запуска upgrade

Чтобы изменить время запуска для обновления пакетов, нужно создать override-файл, который изменит некоторые директивы исходного юнит-файла.

$ sudo systemctl edit apt-daily-upgrade.timer

Эта команда создает файл /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf и открывает его на редактирование.

[Timer]
OnCalendar=
OnCalendar=*-*-* 7:00
RandomizedDelaySec=60s
В моем случае это не сработало, так что пришлось создавать директорию apt-daily-upgrade.timer.d и файл override.conf вручную.

Сообщим Systemd о том, что внесли изменения в юнит-файл

$ sudo systemctl daemon-reload

Давайте посмотрим, что получилось в итоге

$ systemctl cat apt-daily-upgrade.timer
# /lib/systemd/system/apt-daily-upgrade.timer
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer

[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true

[Install]
WantedBy=timers.target

# /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf
[Timer]
OnCalendar=
OnCalendar=*-*-* 7:00
RandomizedDelaySec=60s

Мы установили запуск обновления на 7:00 + случайная задержка в пределах 60 секунд — давайте проверим, что так и есть.

$ systemctl status apt-daily-upgrade.timer
● apt-daily-upgrade.timer - Daily apt upgrade and clean activities
    Loaded: loaded (/lib/systemd/system/apt-daily-upgrade.timer; enabled; vendor preset: enabled)
    Drop-In: /etc/systemd/system/apt-daily-upgrade.timer.d
             └─override.conf
    Active: active (waiting) since Mon 2023-07-10 09:18:06 MSK; 8h ago
    Trigger: Tue 2023-07-11 07:00:45 MSK; 13h left
    Triggers: ● apt-daily-upgrade.service

июл 10 09:18:06 ubuntu-client systemd[1]: Started Daily apt upgrade and clean activities.

Поиск: Linux • Ubuntu • Конфигурация • Настройка • Установка

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.