3 of 4

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.d
  • dnf repolist
  • dnf config-manager
  • createrepo_c
  • dnf clean all
  • subscription-manager
  • mount
  • rpm --import

50 min5 exercises

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
SettingMeaning
[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 (or rhc connect) attaches the system to your Red Hat account, which generates /etc/yum.repos.d/redhat.repo pointing to the Red Hat CDN (Content Delivery Network). subscription-manager repos --list shows 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 DIR writes 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

ErrorUsual causeFix
Cannot download repomd.xml / Cannot prepare internal mirrorlistWrong baseurl, no repodata, server unreachableCheck the URL with curl or ls; run createrepo_c
Public key for ... is not installedgpgcheck=1 and the key was never importedrpm --import KEY, or set gpgkey=
Repository X is listed more than onceThe same id in two filesMake ids unique
Nothing provides ... after adding a repoOnly one of BaseOS and AppStream is configuredAdd the other
Old results after fixing a fileCached metadatadnf 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.

  1. 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 repolist prints repo id and name. dnf repolist all includes disabled entries. Definitions are under /etc/yum.repos.d/.

    Hint

    ls /etc/yum.repos.d and grep -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
  2. Practice

    Configure two remote repositories

    Your instructions say the system must use http://content.example.com/rhel10/BaseOS and http://content.example.com/rhel10/AppStream as its software sources. Create one file /etc/yum.repos.d/exam.repo with two repository sections named exam-baseos and exam-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 repolist lists exam-baseos and exam-appstream (or fails with a download error for the host, proving DNF read the file). grep gpgcheck /etc/yum.repos.d/exam.repo shows gpgcheck=0 twice.

    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
  3. Practice

    Use an ISO as a local repository, persistently

    Attach the RHEL 10 installation ISO (or any ISO with BaseOS and AppStream folders) as /dev/sr0. Mount it at /mnt/dvd read-only, make the mount survive a reboot, and write /etc/yum.repos.d/dvd.repo with two repositories pointing to file:///mnt/dvd/BaseOS and file:///mnt/dvd/AppStream. Show that you can install a package from it with all other repositories disabled.

    Check your result

    findmnt /mnt/dvd shows iso9660. mount -a produces no error. sudo dnf --disablerepo='' --enablerepo='dvd-' install -y tree succeeds.

    Hint

    /dev/sr0 /mnt/dvd iso9660 ro 0 0 in /etc/fstab. For a plain file: loop in the options. Two repo sections, each with its own baseurl.

    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
  4. Practice

    Create a repository from a folder of RPMs

    Make /srv/localrepo, put the RPM for tree in it (dnf download --destdir), generate the repository metadata, add a repo definition and install tree from this repository only.

    Check your result

    /srv/localrepo/repodata/repomd.xml exists. dnf --disablerepo='*' --enablerepo=localrepo install -y tree works.

    Hint

    createrepo_c /srv/localrepo (package createrepo_c). Use baseurl=file:///srv/localrepo. Re-run createrepo_c whenever 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
  5. Challenge

    Repair a repository that fails

    Break localrepo in three different ways, one at a time, and read the error each time: a wrong baseurl path, a missing repodata folder, and gpgcheck=1 with no key. For each, note the error text and the fix. Finish with a clean dnf clean all and dnf repolist.

    Check your result

    The wrong path gives Cannot download repomd.xml or No such file. The missing metadata gives the same message. gpgcheck=1 gives Public key for tree-... is not installed or a GPG check failure. After fixing all, dnf repolist lists localrepo.

    Hint

    dnf clean all removes 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