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
yumwithdnfa. Prepare
yuminstallationb. Install
dnfc. Remove
yum -
Use
dnfto 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.