UNIX / Linux keyboard.

Migrate a Linux System from Red Hat Enterprise to CentOS

Manually Migrating from RHEL to CentOS

Here is how I started with a system with the Workstation edition of Red Hat Enterprise Linux 7 and converted that to CentOS. If you are planning in advance to use CentOS, just install CentOS in the beginning. If you do want to start with Red Hat and change to CentOS, it probably would be be best to archive your data and re-install using CentOS. But maybe you really want or need to migrate from RHEL to CentOS, so here is how to do that. We will go from RHEL 7.0 Workstation to CentOS 7.1.1503.

Make and test that archive of your data before going any further.

There is no guarantee that the following will do anything more than destroy your system.

Seriously. Don't continue with this unless you are very certain of what you are doing and you have a way to get out of whatever problems this gets you into.

We must get all the Red Hat branded components off the system and replaced by the equivalent CentOS components. We will see that some packages have "redhat" in their name in both distributions, but the ones from the Red Hat media must be replaced with those of the same package name and version number (but different non-branded content) from CentOS. This takes more than simply pointing at a CentOS repository and running an upgrade as that leaves you with a mixture including Red-Hat-licensed content.

This takes four major steps: The first one from RHEL 7.0 to CentOS 7.0.1406 is the big one. Second, an upgrade to CentOS 7.1.1503. At this point the system is still mostly based on Red Hat packages. Third, an automated re-installation of all current packages, replacing almost all remaining Red Hat packages with the CentOS equivalents. Finally, a cleanup of a few remaining but no longer needed packages left over from the initial Red Hat installation.

The Situation

The system has RHEL 7 installed, in particular redhat-release-workstation-7.0-1.el7.x86_64. In the installation I selected "Development and Creative Workstation" then added some package groups for a total of 1,941 RPM packages.

How
Linux
Boots

The system has UEFI firmware and is set up for UEFI booting, not the "BIOS legacy compatibility" mode. Make sure you understand how Linux boots as knowledge of some of the details of that will be crucial along the way. If you aren't intimidated yet, we need to know how UEFI booting works in support of Secure Boot because we will have to fix our system at some point so it once again can boot.

Yes, the UEFI — shim — GRUB2 — Linux — systemd booting chain will broken and repaired by the time we finish this project.

As we will see below, this is running on top of VMware Workstation and so it isn't really UEFI firmware, it's VMware's emulation of UEFI. You put firmware="efi" into the *.vmx file to make that happen. But the fact that this is on top of VMware virtualization has no effect on how it works. It does allow me to easily re-image the system and start over, something I had to do several times to figure out the following procedure.

The Requirements

YUM repository on the network.

Rescue boot media.

Keyboard and the ability to use it. This involves lots of long commands and command pipelines, and command substitution. Accurate typing is crucial as we must reconfigure the firmware and the boot loader.

I have two CentOS 7 YUM repos set up on another system on which I installed CentOS 7 to start with. These are CentOS 7.0.1406 and 7.1.1503, equivalent to RHEL 7.0 and 7.1. I created the repos by copying the contents of the entire CentOS 7 "everything" ISO images into /var/www/html/CentOS-7.0.1406/ and /var/www/html/CentOS-7.1.1503/ and then enabling and starting httpd, the Apache web server. On my system to be upgraded I have the following in /etc/yum.repos.d/centos.repo, specifying my YUM server's IP address in the URL:

[CentOS]
name=CentOS 7.0.1406
baseurl=http://10.1.1.200/CentOS-7.0.1406/
enabled=1
gpgcheck=1 

I have added the CentOS PGP key to the RPM database and verified that yum can find the repo. If you don't do the first of those two steps, you can't do the second as long has you have gpgcheck enabled. And you should.

# rpm --import http://10.1.1.200/CentOS-7.0.1406/RPM-GPG-KEY-CentOS-7
# yum repoinfo
# yum repolist 

That shows me that the CentOS 7.0.1406 is enabled with 8,465 packages available. It also reminds me that the initial RHEL installation is still pestering me to register with Red Hat Network. We will start by removing the related packages.

Remove the Red Hat Subscription and RHN Components

We will start by removing the subscription-manager, yum-rhn-plugin, redhat-support, and redhat-access packages. To do that we must also remove a number of other packages that depend on them:

# rpm --erase $( rpm -qa | egrep 'subscription-manager|rhn|redhat-support|redhat-access' )

Forcibly Change from redhat-release-workstation to centos-release

OK, here we go... Let's see where we're starting from:

# lsb_release -idr
Distributor ID: RedHatEnterpriseWorkstation
Description:    Red Hat Enterprise Linux Workstation release 7.0 (Maipo)
Release:        7.0
# rpm -qa | grep release
redhat-release-workstation-7.0-1.el7.x86_64
# rpm -qa | wc
   1941    1941   64536 

Everything beyond this point is dangerous.

We need to change the release package from redhat-release-workstation to centos-release. Notice that I am using the --nodeps option to tell rpm to ignore the dependencies that we normally want it to enforce. You need to have a really really good reason (and trusted backups) to use the --nodeps option or its equally if not more dangerous cousin --force. Make sure that you remove those directories, that step is surprisingly critical in getting the following installation to work! They are two empty directories that previously held copies of the GNU Public Licence and the End User License Agreement, but the new package fails to completely install if they are there, leaving you with a mess.

# rpm --erase --nodeps redhat-release-workstation
# rmdir /usr/share/doc/redhat-release /usr/share/redhat-release
# yum install centos-release
# mv /etc/yum.repos.d/CentOS-* /root 

I don't want to use the CentOS repos on the Internet, I want to use the local one I have created from the ISO images. So I move them somewhere safe so I have a copy to use in the future. Later steps will reinstall those twice, so I can simply remove the additional copies when that happens.

Let's see what has happened:

# lsb_release -idr
Distributor ID: CentOS
Description:    CentOS Linux release 7.0.1406 (Core) 
Release:        7.0.1406
# rpm -qa | grep release
centos-release-7-0.1406.el7.centos.2.3.x86_64
# rpm -qa | wc
   1929    1929   64090
# rpm -qai | grep -c '^Vendor.*Red'
1927 

The release package has been changed, but that is all. That last command shows that all but two of the packages specify Red Hat as the vendor. Let's see which two those are:

# for PKG in $( rpm -qa )
> do
>   echo $PKG $( rpm -qi $PKG | grep -c '^Vendor' ) | grep -v '1$'
> done
centos-release-7-0.1406.el7.centos.2.3.x86_64 0
gpg-pubkey-f4a80eb5-53a7ff4b 0 

Replace Many Packages with yum upgrade

Now let's do an upgrade. This will replace three very specific Red Hat packages, redhat-bookmarks, redhat-indexhtml, and redhat-logos with their CentOS equivalents and update 74 other packages. This runs in less than a minute and a half:

# yum upgrade 

Reconfigure the Firmware and Boot Loader

You must immediately fix the firmware and boot loader, as the updates to the shim and grub2-efi packages did not finish the job.

Let's see where the boot loader components are and how the UEFI firmware is configured. The problems are highlighted in yellow.

# tree /boot/efi
/boot/efi/
`-- EFI
    |-- BOOT
    |   |-- BOOTX64.EFI
    |   `-- fallback.efi
    |-- centos
    |   |-- BOOT.CSV
    |   |-- fonts
    |   |   `-- unicode.pf2
    |   |-- gcdx64.efi
    |   |-- grubx64.efi
    |   |-- MokManager.efi
    |   |-- shim.efi
    |   `-- shim-redhat.efi
    `-- redhat
	`-- grub.cfg

# rpm -qf /boot/efi/EFI/centos/grubx64.efi /boot/efi/EFI/centos/shim* /boot/efi/EFI/redhat/grub.cfg 
grub2-efi-2.02-0.2.10.el7.centos.1.x86_64
shim-0.7-5.2.el7.centos.2.x86_64
shim-0.7-5.2.el7.centos.2.x86_64
file /boot/efi/EFI/redhat/grub.cfg is not owned by any package

# efibootmgr -v
BootCurrent: 0005
Timeout: 10 seconds
BootOrder: 0002,0005,0000,0001,0003,0004
Boot0000* EFI VMware Virtual SATA Hard Drive (0.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00000000000000
Boot0001* EFI VMware Virtual SATA Hard Drive (2.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00020000000000
Boot0002* EFI VMware Virtual SATA CDROM Drive (1.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00010000000000
Boot0003* EFI Network	ACPI(a0341d0,0)PCI(14,0)MAC(000c29e98e4f,0)
Boot0004* EFI Internal Shell (Unsupported option)	MM(b,bee94000,bf21efff)
Boot0005* Red Hat Enterprise Linux	HD(1,800,64000,59895477-f628-4e59-8dbf-67b6ebd1478b)File(\EFI\redhat\shim.efi)

5 directories, 10 files 

The UEFI firmware has not been updated and the GRUB boot loader configuration file has not been moved. We must fix these two problems. The resulting changes are in yellow. We must create a new boot target, which will automatically be inserted as the first. Then we will specify a new boot order to try the CD/DVD drive first, then our new distro-specific shim file. The shim program calls the GRUB program which expects to find its configuration file in its directory, so we must move that file.

# efibootmgr -c -d /dev/sda -p 1 -l '\EFI\centos\shim.efi' -L 'CentOS'

# efibootmgr -v
BootCurrent: 0005
Timeout: 10 seconds
BootOrder: 0006,0002,0005,0000,0001,0003,0004
Boot0000* EFI VMware Virtual SATA Hard Drive (0.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00000000000000
Boot0001* EFI VMware Virtual SATA Hard Drive (2.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00020000000000
Boot0002* EFI VMware Virtual SATA CDROM Drive (1.0)	ACPI(a0341d0,0)PCI(11,0)PCI(5,0)03120a00010000000000
Boot0003* EFI Network	ACPI(a0341d0,0)PCI(14,0)MAC(000c29e98e4f,0)
Boot0004* EFI Internal Shell (Unsupported option)	MM(b,bee94000,bf21efff)
Boot0005* Red Hat Enterprise Linux	HD(1,800,64000,59895477-f628-4e59-8dbf-67b6ebd1478b)File(\EFI\redhat\shim.efi)
Boot0006* CentOS        HD(1,800,64000,59895477-f628-4e59-8dbf-67b6ebd1478b)File(\EFI\centos\shim.efi)

5 directories, 10 files

# efibootmgr -o 2,6
BootCurrent: 0005
Timeout: 10 seconds
BootOrder: 0002,0006
Boot0000* EFI VMware Virtual SATA Hard Drive (0.0)
Boot0001* EFI VMware Virtual SATA Hard Drive (2.0)
Boot0002* EFI VMware Virtual SATA CDROM Drive (1.0)
Boot0003* EFI Network
Boot0004* EFI Internal Shell (Unsupported option)
Boot0005* Red Hat Enterprise Linux
Boot0006* CentOS

# mv /boot/efi/EFI/redhat/grub.cfg /boot/efi/EFI/centos

# rpm -qf /boot/efi/EFI/centos/grub.cfg 
grub2-efi-2.02-0.2.10.el7.centos.1.x86_64

Now let's reboot and make sure that everything works.

Progress So Far

A quick glance suggests that we have migrated a Red Hat system to CentOS, but not really. Yes, we have run an update off a CentOS YUM repo, the system reports a CentOS release, and the graphical desktop shows a CentOS logo instead of a Red Hat logo. But it is still based almost entirely on Red Hat packages:

# rpm -qa | wc
   1930    1930   64692
# rpm -qai | grep -c 'Vendor.*Red'
1850 

If our goal was this version of CentOS, we would need to do the reinstallation described further down. But we also want to move to a newer release of CentOS, so let's do that first and let it take care of some more of the migration work.

Upgrade to a Newer CentOS Release

This is easy. Modify /etc/yum.repos.d/centos.repo to point to the newer repo and run an upgrade. This upgrades 690 packages and installs 9 (plus 27 dependent packages), and ran in about 11.5 minutes.

# cat /etc/yum.repos.d/centos.repo
[CentOS]
name=CentOS 7.1.1503
baseurl=http://10.1.1.200/CentOS-7.1503/
enabled=1
gpgcheck=1
		
# yum upgrade

That will have re-installed those CentOS repository definitions. Move those to the side.

# mv /etc/yum.repos.d/CentOS-* /root 

Let's check our progress. We're on the 7.1.1503 release, down from 1,850 to 1,223 Red Hat packages, and a newer kernel has been installed. It is based on the same 3.10.0 release, but Red Hat will have made patches and maybe some additions. The Linux kernel is open source so Red Hat is obligated to release their changes. But they simply release the modified source code, not the patches that would be more helpful. See Oracle's RedPatch project for the missing patch files.

# lsb_release -idr
Distributor ID: CentOS
Description:    CentOS Linux release 7.1.1503 (Core) 
Release:        7.1.1503

# rpm -qa | wc
   1964    1964   66474

# rpm -qai | grep -c '^Vendor.*Red'
1223

# rpm -qa | sort | grep kernel
abrt-addon-kerneloops-2.1.11-19.el7.centos.0.3.x86_64
kernel-3.10.0-123.el7.x86_64
kernel-3.10.0-229.el7.x86_64
kernel-devel-3.10.0-123.el7.x86_64
kernel-devel-3.10.0-229.el7.x86_64
kernel-headers-3.10.0-229.el7.x86_64
kernel-tools-3.10.0-229.el7.x86_64
kernel-tools-libs-3.10.0-229.el7.x86_64 

Let's check the UEFI firmware and the boot loader again. A change has been made, but it won't cause problems. That upgrade has added more boot target definitions with duplicate entries for the disks, network, and the UEFI internal shell, and added them to the end of the boot order. As long as it starts with our CD/DVD followed by the CentOS shim program, we have what we need.

# efibootmgr -v
BootCurrent: 0006
Timeout: 10 seconds
BootOrder: 0002,0006,0007,0008,0009,000A
Boot0000* EFI VMware Virtual SATA Hard Drive (0.0)      ACPI(a0341d0,0)PCI(11,0)PCI(5,0)SATA(0,0,0)
Boot0001* EFI VMware Virtual SATA Hard Drive (2.0)      ACPI(a0341d0,0)PCI(11,0)PCI(5,0)SATA(2,0,0)
Boot0002* EFI VMware Virtual SATA CDROM Drive (1.0)     ACPI(a0341d0,0)PCI(11,0)PCI(5,0)SATA(1,0,0)
Boot0003* EFI Network   ACPI(a0341d0,0)PCI(14,0)MAC(MAC(000c29e98e4f,0)
Boot0004* EFI Internal Shell (Unsupported option)       MM(b,bee94000,bf21efff)FvFile(c57ad6b7-0515-40a8-9d21-551652854e37)
Boot0005* Red Hat Enterprise Linux      HD(1,800,64000,59895477-f628-4e59-8dbf-67b6ebd1478b)File(\EFI\redhat\shim.efi)
Boot0006* CentOS        HD(1,800,64000,59895477-f628-4e59-8dbf-67b6ebd1478b)File(\EFI\centos\shim.efi)
Boot0007* EFI VMware Virtual SATA Hard Drive (0.0)      ACPI(a0341d0,0)PCI(11,0)PCI(5,0)SATA(0,0,0)
Boot0008* EFI VMware Virtual SATA Hard Drive (2.0)      ACPI(a0341d0,0)PCI(11,0)PCI(5,0)SATA(2,0,0)
Boot0009* EFI Network   ACPI(a0341d0,0)PCI(14,0)MAC(MAC(000c29e98e4f,0)
Boot000A* EFI Internal Shell (Unsupported option)       MM(b,bee94000,bf21efff)FvFile(c57ad6b7-0515-40a8-9d21-551652854e37) 

Let's reboot to run the newer kernel and to test that everything has gone correctly so far. We will now see three choices at the GRUB menu: the new 3.10.0-229 release has been inserted as the default first entry.

Log in, become root, and remove the two unneeded kernel packages. Don't worry about the warnings. This gets rid of two from the original Red Hat installation.

# rpm -qa | sort | grep kernel
abrt-addon-kerneloops-2.1.11-19.el7.centos.0.3.x86_64
kernel-3.10.0-123.el7.x86_64
kernel-3.10.0-229.el7.x86_64
kernel-devel-3.10.0-123.el7.x86_64
kernel-devel-3.10.0-229.el7.x86_64
kernel-headers-3.10.0-229.el7.x86_64
kernel-tools-3.10.0-229.el7.x86_64
kernel-tools-libs-3.10.0-229.el7.x86_64

# rpm -qa | grep 'kernel.*3.10.0-123'
kernel-3.10.0-123.el7.x86_64
kernel-devel-3.10.0-123.el7.x86_64

# rpm --erase $( rpm -qa | grep 'kernel.*3.10.0-123' )
warning: file /lib/modules/3.10.0-123.el7.x86_64/modules.softdep: remove failed: No such file or directory
warning: file /lib/modules/3.10.0-123.el7.x86_64/modules.devname: remove failed: No such file or directory 

Reinstall All Current Packages Available in the CentOS Repository

This is the largest yum operation of the entire project. This reinstalls all of the currently installed packages. Based on package name and version, it seems like a lot of work for no real accomplishment. But the repository is CentOS and so this replaces almost all of the remaining Red Hat packages with their CentOS equivalents. This will download and install 1,955 packages. We recently determined that we have 1,964 packages on the system, of which 1,223 are from Red Hat. This takes almost 20 minutes.

# yum repository-packages CentOS move-to 

Clean Up the Remaining Red Hat Packages

We are nearly done:

# rm /etc/yum.repos.d/CentOS-*

# rpm -qa | wc
   1962    1962   66410

# rpm -qai | grep -c 'Vendor.*Red'
5

# rpm -qai | egrep '^Name|^Vendor' | grep -B 1 Red
Vendor      : CentOS
Name        : Red_Hat_Enterprise_Linux-Release_Notes-7-en-US
Vendor      : Red Hat, Inc.
--
Name        : libertas-usb8388-firmware
Vendor      : Red Hat, Inc.
--
Vendor      : CentOS
Name        : Red_Hat_Enterprise_Linux-Release_Notes-7-fr-FR
Vendor      : Red Hat, Inc.
--
Name        : libertas-sd8787-firmware
Vendor      : Red Hat, Inc.
--
Name        : libertas-sd8686-firmware
Vendor      : Red Hat, Inc. 

The only Red Hat data remaining on the system are the Release Notes and three firmware packages for Marvell Libertas hardware — the USB 8388, SD 8686, and SD 8787 Network Adapters. We can erase all of those:

# rpm -qa | egrep 'Release_Notes|libertas'
Red_Hat_Enterprise_Linux-Release_Notes-7-en-US-0-2.el7.noarch
libertas-usb8388-firmware-20140213-0.3.git4164c23.el7.noarch
Red_Hat_Enterprise_Linux-Release_Notes-7-fr-FR-0-3.el7.noarch
libertas-sd8787-firmware-20140213-0.3.git4164c23.el7.noarch
libertas-sd8686-firmware-20140213-0.3.git4164c23.el7.noarch

# rpm --erase $( rpm -qa | egrep 'Release_Notes|libertas' ) 

Finished!

I have migrated a Red Hat Enterprise Linux system to CentOS without a complete reinstallation.

Be extremely careful if you try any of this!