CentOS 7からCentOS 8へのアップグレードは大変です💦

## 背景
つい最近導入したばかりのサーバがなぜかCentOS 7で、今後さらに５年以上使いたかったので、更新することになりました。

## 注意
CentOS8がリリースされてから１年くらい経つのですが、いまだに公式には7から8へのアップグレードの手段を提供していないです。
ただ、非公式にアップデートをしている例がいくつかあっただけです。

本番環境で実行するのはかなり危険です。今回は代用でほかのサーバを利用できるので実施しました。
また、ある程度のトラブルシューティングは必要です。初心者向けではありません。

## CentOS8の主要な更新点
- パッケージマネージャが`yum`から`dnf`への移行
- Linuxのカーネルの更新`3.10`から`4.18`
- その他、パッケージのバージョンの更新

フロントエンドがそのままだったりして、CentOS7から8へはあまり大きな影響はありません。（多分）

## アップデート手順
- `EPEL`リポジトリのインストール
- `yum-utils`のインストール
- `dnf`のインストール、パッケージの更新
- 競合の解決
- kernel coreの更新
- 確認

### EPELリポジトリのインストール
```
$ sudo yum install epel-release -y
```

### `yum-utils`などのインストール
```
$ sudo yum install yum-utils
$ sudo yum install rpmconf
```

```
$ sudo rpmconf -a
```

このとき、設定の更新を行うかどうかを確認されます。
以前の設定を使いたい場合は`N`と入れてください。

#### クリーンアップ
```
$ sudo package-cleanup --leaves
$ sudo package-cleanup --orphans
```




### dnfのインストールから更新まで
```
$ sudo yum install dnf
```

yumを消す必要があります。（その次のetcの中まで消す必要はないと思いますが一応）

```
$ sudo dnf -y remove yum yum-metadata-parser
$ sudo rm -Rf /etc/yum
```

パッケージを更新します。

```
$ sudo dnf upgrade
```

```
$ sudo dnf install http://mirror.centos.org/centos/8/BaseOS/x86_64/os/Packages/centos-repos-8.2-2.2004.0.1.el8.x86_64.rpm http://mirror.centos.org/centos/8/BaseOS/x86_64/os/Packages/centos-release-8.2-2.2004.0.1.el8.x86_64.rpm http://mirror.centos.org/centos/8/BaseOS/x86_64/os/Packages/centos-gpg-keys-8.2-2.2004.0.1.el8.noarch.rpm
```

```
$ sudo dnf -y upgrade https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
```

うまくいったら、クリーンアップします。

```
$ sudo dnf clean all
```

kernelの更新をしたいです。古いカーネルを消し去ります。

```
$ sudo rpm -e `rpm -q kernel`
```

次の手順で競合を起こすので最初に消しておきます。

```
$ sudo rpm -e --nodeps sysvinit-tools
```

CentOS8に`distro-sync`します。
最新の利用可能なバージョンへインストール済みパッケージを同期するという意味らしいです。

```
$ sudo dnf -y --releasever=8 --allowerasing --setopt=deltarpm=false distro-sync
```


### CentOS8へのアップグレード
カーネルを更新します。

```
$ sudo dnf -y install kernel-core
```

最小インストールで更新をかけます。

```
$ sudo dnf -y groupupdate "Core" "Minimal Install"
```

### CentOS 8へ更新できてるか確認
再起動後、`/etc/centos-release`が8.xxに更新されているかや、`uname -a`でLinuxのカーネルのバージョンを確認します。

```
$ sudo dnf update
```
で更新もちゃんとできるか確認しましょう。もし、更新ができずに競合解決しろって出たら、頑張りましょう。

私の場合はなぜかパッケージが破損していたらしくkernelがインストールできなかったので、再インストールしました。

### 補足：バージョンの競合が発生したら？
メッセージを忘れたので引用します。
https://superuser.com/questions/1517321/centos8-dnf-update-transaction-check-error より。

```
Error: transaction check vs depsolve:
(gcc >= 8 with gcc < 9) is needed by annobin-8.78-1.el8.x86_64
rpmlib(RichDependencies) <= 4.12.0-1 is needed by annobin-8.78-1.el8.x86_64
(annobin if gcc) is needed by redhat-rpm-config-120-1.el8.noarch
rpmlib(RichDependencies) <= 4.12.0-1 is needed by redhat-rpm-config-120-1.el8.noarch
To diagnose the problem, try running: 'rpm -Va --nofiles --nodigest'.
You probably have corrupted RPMDB, running 'rpm --rebuilddb' might fix the issue.
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'dnf clean packages'.
```

基本的にパッケージを削除し、後で再インストールします。

```
$ sudo dnf remove <package name here!>
```

また、それもできない場合はアップデートを実行します。

```
$ sudo dnf update <package name here!> --allowerase --best
```

それもできない場合は依存しているパッケージについて再帰的に競合を解決する必要があります。

gdbmで発生した場合はそれ自体がdnfで使われているらしくアップデートを行う必要があります。
アップグレードで発生した競合を手動で解決してください。

ちなみに依存関係はこのコマンドでチェックすることができます。
依存関係が適切でないとあらぬところでエラーが出るので注意が必要です。

```
$ sudo dnf check --dependencies
```

例えばこんな感じになることがあります。

```
$ sudo dnf check --dependencies
Modular dependency problems:

 Problem 1: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-App-cpanminus:1.7044:8010020191120175858:a9207fc6-0.x86_64
 Problem 2: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-DBD-MySQL:4.046:8010020191114030811:073fa5fe-0.x86_64
 Problem 3: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-DBD-SQLite:1.58:8010020191114033549:073fa5fe-0.x86_64
 Problem 4: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-DBI:1.641:8010020191113222731:16b3ab4d-0.x86_64
 Problem 5: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-FCGI:0.78:8010020191114031513:16b3ab4d-0.x86_64
 Problem 6: conflicting requests
  - nothing provides module(perl:5.26) needed by module perl-YAML:1.24:8010020191114031501:a5949e2e-0.x86_64

```

以下のコマンドで解決できました。

```
$ sudo dnf module enable perl:5.26
```

## 感想と独り言
CentOSはサポートが長いのですが、OSのアップデートは推奨されないのでしょうかね。Ubuntuとかだとサポートが半分しかありませんがLTSでアップデートできるように設計されています。

そして長く使いたいのになぜ古いバージョンのOSを入れたのか。それがもともとの主犯だと思ってます。

## 参考
- CentOS7 to CentOS8へのアップグレードについて　https://www.tecmint.com/upgrade-centos-7-to-centos-8/
- dnfの参考 https://www.atmarkit.co.jp/ait/articles/2001/10/news020.html
- perl の依存関係のエラーの参考 https://tech.godpress.net/?p=1168