CentOS 8のパッケージアップデートを自動化したい

# What's？

CentOS 8にインストールしたパッケージを、自動的に更新する方法はないのかな？ということで。

`yum`の時には`yum-cron`を使っていたそうなのですが、`dnf`になってからは？、と。

# dnf-automatic

`dnf`になってからは、この目的には`dnf-automatic`を使うようです。

[ソフトウェア更新の自動化](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html/configuring_basic_system_settings/managing-software-packages_configuring-basic-system-settings#automating-software-updates_updating-software-packages)

[dnf-automatic](https://man7.org/linux/man-pages/man8/dnf-automatic.8.html)

[DNF Automatic](https://dnf.readthedocs.io/en/latest/automatic.html)

以下のことができるようです。

- 更新パッケージのダウンロード
- 更新パッケージのインストール
- メールや標準出力による結果の報告、記録
- dnfの設定の上書き
- systemdのタイマーによって動作する

ちょっとインストールしてみましょう。

# 環境

今回の環境は、こちらです。

```shell
$ cat /etc/redhat-release
CentOS Linux release 8.4.2105


$ uname -srvmpio
Linux 4.18.0-240.22.1.el8_3.x86_64 #1 SMP Thu Apr 8 19:01:30 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```

# インストール

では、dnf-automaticをインストールしてみます。`dnf`でインストールできます。

```shell
$ sudo dnf install dnf-automatic
```

パッケージの情報。今回は、`4.4.2`がインストールされました。

```shell
$ rpm -qi dnf-automatic
Name        : dnf-automatic
Version     : 4.4.2
Release     : 11.el8
Architecture: noarch
Install Date: 2021年06月06日 22時52分14秒
Group       : Unspecified
Size        : 52588
License     : GPLv2+ and GPLv2 and GPL
Signature   : RSA/SHA256, 2021年03月12日 04時41分52秒, Key ID 05b555b38483c65d
Source RPM  : dnf-4.4.2-11.el8.src.rpm
Build Date  : 2021年03月12日 04時39分23秒
Build Host  : x86-01.mbox.centos.org
Relocations : (not relocatable)
Packager    : CentOS Buildsys <bugs@centos.org>
Vendor      : CentOS
URL         : https://github.com/rpm-software-management/dnf
Summary     : Package manager - automated upgrades
Description :
Systemd units that can periodically download package upgrades and apply them.
```

# デフォルト設定を確認する

まずは、デフォルト設定を確認してみましょう。`/etc/dnf/automatic.conf`が設定ファイルのようです。

```shell
$ grep -v '^#' /etc/dnf/automatic.conf
[commands]
upgrade_type = default
random_sleep = 0

network_online_timeout = 60


download_updates = yes

apply_updates = no


[emitters]

emit_via = stdio


[email]
email_from = root@example.com

email_to = root

email_host = localhost


[command]



[command_email]


email_from = root@example.com

email_to = root


[base]

debuglevel = 1
```


設定ファイルの内容は、こちらで確認します。

[DNF Automatic / Configuration File Format](https://dnf.readthedocs.io/en/latest/automatic.html#configuration-file-format)

これだけを見ていると、デフォルトでは以下の内容に見えますね。

- 更新可能なパッケージをすべて選択する
- 更新内容のダウンロードを行う
- 更新内容の適用はしない
- 結果は標準出力に書き出す

# dnf-automaticを有効化する

`dnf-automatic`を有効にしてみましょう。

以下のタイマーのいずれかを有効にします。

```shell
$ ll /usr/lib/systemd/system/dnf-automatic*.timer
-rw-r--r--. 1 root root 259 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-download.timer
-rw-r--r--. 1 root root 258 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-install.timer
-rw-r--r--. 1 root root 261 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-notifyonly.timer
-rw-r--r--. 1 root root 250 11月  9  2020 /usr/lib/systemd/system/dnf-automatic.timer
```

どのような実行コマンドかは、サービス定義を確認します。

```shell
$ ll /usr/lib/systemd/system/dnf-automatic*.service
-rw-r--r--. 1 root root 370 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-download.service
-rw-r--r--. 1 root root 348 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-install.service
-rw-r--r--. 1 root root 380 11月  9  2020 /usr/lib/systemd/system/dnf-automatic-notifyonly.service
-rw-r--r--. 1 root root 315 11月  9  2020 /usr/lib/systemd/system/dnf-automatic.service
```

これらの差は、オプション指定のみです。

```shell
$ grep ExecStart /usr/lib/systemd/system/dnf-automatic*.service
/usr/lib/systemd/system/dnf-automatic-download.service:ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer --downloadupdates --no-installupdates
/usr/lib/systemd/system/dnf-automatic-install.service:ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer --installupdates
/usr/lib/systemd/system/dnf-automatic-notifyonly.service:ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer --no-installupdates --no-downloadupdates
/usr/lib/systemd/system/dnf-automatic.service:ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer
```

`--installupdates`などの指定で`/etc/dnf/automatic.conf`の内容を上書きします。

今回は、`dnf-automatic-install.timer`を有効にしてパッケージのインストールも行う設定にしてみましょう。

```shell
$ sudo systemctl enable dnf-automatic-install.timer
Created symlink /etc/systemd/system/timers.target.wants/dnf-automatic-install.timer → /usr/lib/systemd/system/dnf-automatic-install.timer.
```

ユニット定義ファイルの中身も見てみます。

```shell:/usr/lib/systemd/system/dnf-automatic-install.service
[Unit]
Description=dnf automatic install updates
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
After=network-online.target

[Service]
Type=oneshot
Nice=19
IOSchedulingClass=2
IOSchedulingPriority=7
Environment="ABRT_IGNORE_PYTHON=1"
ExecStart=/usr/bin/dnf-automatic /etc/dnf/automatic.conf --timer --installupdates
```

タイマー側も。

```shell:/usr/lib/systemd/system/dnf-automatic-install.timer
[Unit]
Description=dnf-automatic-install timer
# See comment in dnf-makecache.service
ConditionPathExists=!/run/ostree-booted
Wants=network-online.target

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

[Install]
WantedBy=timers.target
```

どうやら、デフォルトでは6時に更新されるようです。

```shell
[Timer]
OnCalendar=*-*-* 6:00
```

あとは、必要に応じてカスタマイズですね。

なんとなく、使い方の雰囲気はわかりました。

# 更新対象を指定したい時は？

ところで、設定ファイルの内容からすると、対象のパッケージの選択方法は`upgrade_type`で指定する`default`と`security`のざっくり2パターンです。

> What kind of upgrades to look at. default signals looking for all available updates, security only those with an issued security advisory.

[commands section](https://dnf.readthedocs.io/en/latest/automatic.html#commands-section)

`security`＋指定パッケージ、とかにしたいな、とも思うのですが、どうしたらいいんでしょうね。

`dnf upgrade -y [パッケージ名]`みたいなsystemdタイマーを作ることになるんでしょうか？