Software ManagementLesson 3 of 4
Configuring repositories: remote, local and registered
Tell DNF where packages come from with a .repo file, build a local repository from an ISO or a folder, and fix the usual errors.
/etc/yum.repos.ddnf repolistdnf config-managercreaterepo_cdnf clean allsubscription-managermountrpm --import
After this lesson you can
- Write a .repo file with baseurl, enabled and gpgcheck for a remote or local repository.
- Mount an installation ISO persistently and use its BaseOS and AppStream as local repositories.
- Create a repository from a directory of RPMs, enable and disable repositories, and diagnose a repository that fails.
The idea
A repository is a directory (local, or served over HTTP, HTTPS or FTP) that holds RPM files plus a repodata/ folder of metadata. DNF learns where to look from files ending in .repo in /etc/yum.repos.d/. Each file may define several repositories; each repository is a section:
[exam-baseos]
name=Exam BaseOS
baseurl=http://content.example.com/rhel10/BaseOS
enabled=1
gpgcheck=0
| Setting | Meaning |
|---|---|
[exam-baseos] | The repository id: unique, no spaces, used with --enablerepo |
name= | A human-readable name shown in lists |
baseurl= | Where the repository is: http://..., https://... or file:///path |
enabled= | 1 use it, 0 ignore it |
gpgcheck= | 1 verify package signatures, 0 do not |
gpgkey= | Where the public key is (needed when gpgcheck=1) |
Note the three slashes in file:///mnt/dvd/BaseOS: two for the URL scheme and one for the root of the path.
RHEL is split into two repositories you will always meet: BaseOS (the core operating system) and AppStream (applications, languages and tools, most of what you install later). A usable system needs both.
Where repositories come from
- Registered systems.
subscription-manager register(orrhc connect) attaches the system to your Red Hat account, which generates/etc/yum.repos.d/redhat.repopointing to the Red Hat CDN (Content Delivery Network).subscription-manager repos --listshows what you can enable. This is the normal production setup. - A local source. The installation ISO contains both BaseOS and AppStream. Mounted at
/mnt/dvd, it is a complete offline repository. - A repository you build.
createrepo_c DIRwrites the metadata for a folder of RPMs, which is how you serve internal or downloaded packages.
The exam has no internet access, so it points you at an internal server or a mounted image. The task is nearly always the same: write the .repo file, make dnf repolist show it, and install something.
Signatures
gpgcheck=1 makes DNF refuse packages whose signature does not match an imported key. That protects you from tampered packages and is the right default. Import a key with rpm --import URL-or-file, or list gpgkey= in the .repo file so DNF offers to import it. Set gpgcheck=0 only for a repository you control, such as one you just built yourself, or when the task tells you the key is not available.
Try it
dnf repolist
repo id repo name
rhel-10-for-x86_64-appstream-rpms Red Hat Enterprise Linux 10 for x86_64 - AppStream (RPMs)
rhel-10-for-x86_64-baseos-rpms Red Hat Enterprise Linux 10 for x86_64 - BaseOS (RPMs)
Two remote repositories
sudo tee /etc/yum.repos.d/exam.repo <<'EOT'
[exam-baseos]
name=Exam BaseOS
baseurl=http://content.example.com/rhel10/BaseOS
enabled=1
gpgcheck=0
[exam-appstream]
name=Exam AppStream
baseurl=http://content.example.com/rhel10/AppStream
enabled=1
gpgcheck=0
EOT
dnf repolist
repo id repo name
exam-appstream Exam AppStream
exam-baseos Exam BaseOS
An ISO as a repository that survives a reboot
sudo mkdir -p /mnt/dvd
echo '/dev/sr0 /mnt/dvd iso9660 ro 0 0' | sudo tee -a /etc/fstab
sudo systemctl daemon-reload
sudo mount -a
findmnt /mnt/dvd
TARGET SOURCE FSTYPE OPTIONS
/mnt/dvd /dev/sr0 iso9660 ro,relatime,nojoliet,check=s,map=n,blocksize=2048
Then point two sections at file:///mnt/dvd/BaseOS and file:///mnt/dvd/AppStream. Test it with the others switched off, so you know the local repository works on its own:
sudo dnf --disablerepo='*' --enablerepo='dvd-*' install -y tree
Installed:
tree-2.1.0-6.el10.x86_64
Complete!
Build a repository from a folder
sudo dnf install -y createrepo_c
sudo mkdir -p /srv/localrepo
sudo dnf download --destdir /srv/localrepo tree
sudo createrepo_c /srv/localrepo
ls /srv/localrepo
Directory walk started
Directory walk done - 1 packages
Pool started (with 5 workers)
Pool finished
repodata tree-2.1.0-6.el10.x86_64.rpm
Enable, disable, clean
sudo dnf config-manager --set-disabled localrepo
sudo dnf config-manager --set-enabled localrepo
sudo dnf clean all
DNF caches repository metadata. After you edit a .repo file or add packages to a repository, run dnf clean all so the next command re-reads it.
Reading repository errors
| Error | Usual cause | Fix |
|---|---|---|
Cannot download repomd.xml / Cannot prepare internal mirrorlist | Wrong baseurl, no repodata, server unreachable | Check the URL with curl or ls; run createrepo_c |
Public key for ... is not installed | gpgcheck=1 and the key was never imported | rpm --import KEY, or set gpgkey= |
Repository X is listed more than once | The same id in two files | Make ids unique |
Nothing provides ... after adding a repo | Only one of BaseOS and AppStream is configured | Add the other |
| Old results after fixing a file | Cached metadata | dnf clean all |
Going further
dnf repoquery --repo localrepo lists what a single repository offers. A repository can also be served by a web server: createrepo_c the directory, put it under /var/www/html/repo, and others point baseurl= at it. Settings like priority=, exclude= and includepkgs= shape which repository wins, and repo_gpgcheck=1 verifies the metadata itself. In RHEL 10, system registration can also go through rhc connect, which additionally connects the host to Red Hat’s management services.
Practice
0 of 5 done
Do these on your own system. They get harder. Check each result, then tick it off.
- Warm-up
What repositories does this system use?
List the enabled repositories, then list all of them including disabled ones, and find the file that defines each. Count how many are enabled.
Check your result
dnf repolistprints repo id and name.dnf repolist allincludesdisabledentries. Definitions are under/etc/yum.repos.d/.Hint
ls /etc/yum.repos.dandgrep -H '^\[' /etc/yum.repos.d/*.repo.Solution
dnf repolist dnf repolist all | head ls /etc/yum.repos.d grep -H '^\[' /etc/yum.repos.d/*.repo - Practice
Configure two remote repositories
Your instructions say the system must use
http://content.example.com/rhel10/BaseOSandhttp://content.example.com/rhel10/AppStreamas its software sources. Create one file/etc/yum.repos.d/exam.repowith two repository sections namedexam-baseosandexam-appstream, both enabled. The signing key is not available, so GPG checking is off. Confirm DNF accepts the file (the URLs may not resolve in your lab).Check your result
dnf repolistlistsexam-baseosandexam-appstream(or fails with a download error for the host, proving DNF read the file).grep gpgcheck /etc/yum.repos.d/exam.reposhowsgpgcheck=0twice.Hint
Each section needs
[id],name=,baseurl=,enabled=1,gpgcheck=0. The id goes in square brackets and must be unique.Solution
sudo tee /etc/yum.repos.d/exam.repo <<'EOT' [exam-baseos] name=Exam BaseOS baseurl=http://content.example.com/rhel10/BaseOS enabled=1 gpgcheck=0 [exam-appstream] name=Exam AppStream baseurl=http://content.example.com/rhel10/AppStream enabled=1 gpgcheck=0 EOT dnf repolist - Practice
Use an ISO as a local repository, persistently
Attach the RHEL 10 installation ISO (or any ISO with
BaseOSandAppStreamfolders) as/dev/sr0. Mount it at/mnt/dvdread-only, make the mount survive a reboot, and write/etc/yum.repos.d/dvd.repowith two repositories pointing tofile:///mnt/dvd/BaseOSandfile:///mnt/dvd/AppStream. Show that you can install a package from it with all other repositories disabled.Check your result
findmnt /mnt/dvdshowsiso9660.mount -aproduces no error.sudo dnf --disablerepo='' --enablerepo='dvd-' install -y treesucceeds.Hint
/dev/sr0 /mnt/dvd iso9660 ro 0 0in/etc/fstab. For a plain file:loopin the options. Two repo sections, each with its ownbaseurl.Solution
sudo mkdir -p /mnt/dvd echo '/dev/sr0 /mnt/dvd iso9660 ro 0 0' | sudo tee -a /etc/fstab sudo systemctl daemon-reload sudo mount -a findmnt /mnt/dvd sudo tee /etc/yum.repos.d/dvd.repo <<'EOT' [dvd-baseos] name=DVD BaseOS baseurl=file:///mnt/dvd/BaseOS enabled=1 gpgcheck=0 [dvd-appstream] name=DVD AppStream baseurl=file:///mnt/dvd/AppStream enabled=1 gpgcheck=0 EOT sudo dnf --disablerepo='*' --enablerepo='dvd-*' install -y tree - Practice
Create a repository from a folder of RPMs
Make
/srv/localrepo, put the RPM fortreein it (dnf download --destdir), generate the repository metadata, add a repo definition and installtreefrom this repository only.Check your result
/srv/localrepo/repodata/repomd.xmlexists.dnf --disablerepo='*' --enablerepo=localrepo install -y treeworks.Hint
createrepo_c /srv/localrepo(packagecreaterepo_c). Usebaseurl=file:///srv/localrepo. Re-runcreaterepo_cwhenever the folder changes.Solution
sudo dnf install -y createrepo_c sudo mkdir -p /srv/localrepo sudo dnf download --destdir /srv/localrepo tree sudo createrepo_c /srv/localrepo sudo tee /etc/yum.repos.d/localrepo.repo <<'EOT' [localrepo] name=Local repository baseurl=file:///srv/localrepo enabled=1 gpgcheck=0 EOT sudo dnf --disablerepo='*' --enablerepo=localrepo install -y tree - Challenge
Repair a repository that fails
Break
localrepoin three different ways, one at a time, and read the error each time: a wrongbaseurlpath, a missingrepodatafolder, andgpgcheck=1with no key. For each, note the error text and the fix. Finish with a cleandnf clean allanddnf repolist.Check your result
The wrong path gives
Cannot download repomd.xmlorNo such file. The missing metadata gives the same message.gpgcheck=1givesPublic key for tree-... is not installedor a GPG check failure. After fixing all,dnf repolistlistslocalrepo.Hint
dnf clean allremoves cached metadata so the next command re-reads it. Fix GPG by importing the key (rpm --import) or, for a lab repo you trust,gpgcheck=0.Solution
sudo sed -i 's#file:///srv/localrepo#file:///srv/nowhere#' /etc/yum.repos.d/localrepo.repo sudo dnf clean all; dnf --disablerepo='*' --enablerepo=localrepo repolist sudo sed -i 's#nowhere#localrepo#' /etc/yum.repos.d/localrepo.repo sudo mv /srv/localrepo/repodata /srv/repodata.off sudo dnf clean all; dnf --disablerepo='*' --enablerepo=localrepo repolist sudo mv /srv/repodata.off /srv/localrepo/repodata sudo sed -i 's/gpgcheck=0/gpgcheck=1/' /etc/yum.repos.d/localrepo.repo sudo dnf --disablerepo='*' --enablerepo=localrepo install -y tree sudo sed -i 's/gpgcheck=1/gpgcheck=0/' /etc/yum.repos.d/localrepo.repo sudo dnf clean all; dnf repolist