CentOS 8.0 was released on September 24th, 2019 and 8.1 on January 15, 2020. This article describes how a CentOS 7 may be upgraded in place. The steps are captured in an Ansible role published on GitHub.
Theory of Operation
The steps to migrate a CentOS 7 instance to CentOS 8.1 are:
-
Replace
yum
withdnf
a. Prepare
yum
installationb. Install
dnf
c. Remove
yum
-
Use
dnf
to upgradea. Configure CentOS 8.1 packages
b. Install CentOS 8.1 (userland)
c. Install CentOS 8.1 kernel
Step #1 is necessitated because
dnf
has
replaced
yum
in
CentOS/RHEL 8 systems. The implementation is discussed in the next session.
Implementation
The following subsection describe the major steps of the upgrade.
Replace yum
with dnf
The first step is to replace yum
with dnf
. The implementation uses the
fact that /usr/bin/yum
is a regular file when yum
is installed and a
symbolic link to dnf-3
when dnf is installed.
- name: /usr/bin/yum
stat: path=/usr/bin/yum
register: yum
The condition yum.stat.isreg is defined and yum.stat.isreg
, if true,
indicates yum
was the package manager when Anisble was invoked. The
Ansible script takes advantage of this observation to provide idempotent
operation. package-cleanup(1)
is installed from
epel-release
and used to remove locally installed RPMs.
- name: epel-release
package:
name: epel-release
state: latest
when:
- yum.stat.isreg is defined and yum.stat.isreg
- name: yum-utils
package:
name: yum-utils
state: latest
when:
- yum.stat.isreg is defined and yum.stat.isreg
- name: package-cleanup
command:
cmd: "{{ item }}"
loop:
- package-cleanup --leaves
- package-cleanup --orphans
when:
- yum.stat.isreg is defined and yum.stat.isreg
The author’s use case is to upgrade a fresh install of CentOS 7. However,
if the upgrade is to be performed on a configured system, then rpmconf
should be invoked to determine if any configuration files need to be
preserved and/or migrated:
# yum -y install rpmconf
# rpmconf -a
dnf
is installed with yum
and then yum
is removed with the
corresponding dnf
request, /etc/yum
is removed, and dnf
is updated.
It is critical that these steps are completed so the system is not left in
an inconsistent state without a functioning yum
or dnf
.
- name: dnf
package:
name: dnf
state: latest
when:
- yum.stat.isreg is defined and yum.stat.isreg
- name: yum -> dnf
shell: |-
dnf -y remove yum yum-metadata-parser
rm -rf /etc/yum
dnf -y upgrade
args:
warn: false
when:
- yum.stat.isreg is defined and yum.stat.isreg
dnf
is now installed and available to use for an in-place upgrade.
Upgrade CentOS
CentOS 8 requires 3 CentOS RPMs plus the latest
epel-release
(obtained via RPM) which are installed
explicitly with dnf
. The conditional ansible_distribution_major_version
is version(releasever, "lt")
is leveraged to provide idempotent operation
and avoid re-running once CentOS 8 is installed.
- name: centos_packages
vars:
target: 8.1-1.1911.0.8.el8
arch: "{{ ansible_architecture }}"
releasever: "{{ target | regex_replace('^([0-9]+)[.].*$', '\\1') }}"
BaseOS: "http://mirror.centos.org/centos/{{ releasever }}/BaseOS"
Packages: "{{ BaseOS }}/{{ arch }}/os/Packages"
set_fact:
releasever: "{{ releasever }}"
centos_packages:
- "{{ Packages }}/centos-gpg-keys-{{ target }}.noarch.rpm"
- "{{ Packages }}/centos-release-{{ target }}.{{ arch }}.rpm"
- "{{ Packages }}/centos-repos-{{ target }}.{{ arch }}.rpm"
- "https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ releasever }}.noarch.rpm"
The system is now ready for the actual upgrade. The CentOS Upgrade script
has to run until reboot or the system will be left in an inconsistent state.
Unfortunately python
is replaced (and moved) so the Anisble client loses
communication during the process eliminating the possibility of using the
Anisble reboot
module. Instead, the administrator should reinvoke the
Ansible play once the update and reboot are complete.
- name: warn
debug:
msg: >-
Warning: CentOS Upgrade will install kernel and initiate reboot
when:
- ansible_distribution_major_version is version(releasever, "lt")
- name: CentOS Upgrade
shell: |-
dnf -y install {{ centos_packages | join(" ") }}
dnf clean all
rpm -e $(rpm -q kernel)
rpm -e --nodeps sysvinit-tools
dnf -y --releasever={{ releasever }} --allowerasing --setopt=deltarpm=false distro-sync
dnf -y install kernel-core
dnf -y groupupdate "Core" "Minimal Install"
shutdown -r now
args:
warn: false
when:
- ansible_distribution_major_version is version(releasever, "lt")
Post Upgrade Steps
The script allows for enabling the CentOS-Plus
repository and updating
installed packages after the reboot.
- name: Enable CentOS-Plus repository
ini_file:
dest: /etc/yum.repos.d/CentOS-centosplus.repo
create: no
section: centosplus
option: enabled
value: "1"
- name: package update
package:
name: "*"
state: latest
Summary
CentOS 7 installation may be upgraded to CentOS 8 in-place once yum
is
replaced by dnf
.