create local dnf repos
on a fedora system, we can create local dnf repos hosting packages built locally
via rpmbuild
; these local repos work nicely with remote repos that we normally
use;
creating a local dnf repo involves several steps:
-
create the repo dir;
there are some considerations when creating the repo dir: because the repo contains packages that are installed system-wide, it is recommended to protect the repo dir with root permission; also, a dnf repo hosts packages for a specific distro, release version and arch; ideally, the name of the repo reflects these properties;
here is what we do: we create this repo at
/opt/repo/fedora-31-x86_64
, with two subdirs for binary and source packages, respectively:$ sudo mkdir -p /opt/repo/fedora-31-x86_64/{RPMS,SRPMS} $ sudo chown -R root:root /opt/repo $ sudo chmod -R go-w,a-st /opt/repo
-
build rpm packages locally;
now we have the repo dir but not the packages; as we said, our local repo hosts packages built locally via
rpmbuild
; more specifically, we build these packages with:$ cd ~/rpmbuild $ rpmbuild -ba SPECS/{package}.spec
the built binary and source packages are left in
~/rpmbuild/RPMS
and~/rpmbuild/SRPMS
, respectively; -
fill the repo with packages;
this is just plain file copy:
$ sudo cp -r ~/rpmbuild/RPMS/* /opt/repo/fedora-31-x86_64/RPMS/ $ sudo cp -r ~/rpmbuild/SRPMS/* /opt/repo/fedora-31-x86_64/SRPMS/
it is unlikely that you built packages as root; did you? if you did, fix it; it is good habit not to abuse root privilege; so we assume the packages have normal user ownership; when we move them into the repo dir, we change their ownership and permission:
$ sudo chown -R root:root /opt/repo/fedora-31-x86_64 $ sudo chmod -R go-w,a-st /opt/repo/fedora-31-x86_64
now the
~/rpmbuild
dir is useless for our local repo; you can remove it if you want, or keep it if you need more from it; -
create repo metadata:
to actually make the dir a dnf repo, we need a tool
createrepo
:$ sudo dnf install createrepo
now create repo metadata with:
$ sudo createrepo /opt/repo/fedora-31-x86_64
this generates a subdir
repodata
containing repo metadata, turning the repo dir into a real dnf repo; -
add this repo to dnf:
now we need to make dnf aware of this repo; we can do this with dnf itself:
$ dnf config-manager --add-repo /opt/repo/fedora-31-x86_64
but this is not the most clever way of doing so; instead, we manually create a file
/etc/yum.repos.d/local.repo
:[Local] name=Local Repository baseurl=file:///opt/repo/fedora-$releasever-$basearch gpgcheck=0 priority=0 enabled=1
this allows several customizations:
-
in
baseurl
, we include variablesreleasever
andbasearch
, so that this file doesnt have to change if we have upgraded our system; -
we disable
gpgcheck
because this is a local repo managed by ourselves; -
we set
priority
to a very low value so that this local repo has higher priority over remote repos (the default priority is 99);
-
-
now we should be able to install packages from this local repo using dnf:
$ dnf install {package}
we issue the install command as usual; since our local repo has a higher priority, packages there will be preferred over those from remote repos;
-
to allow further changes to the repo, we can add a small maintenance script:
#!/bin/bash set -eo pipefail repo="/opt/repo" chown -R root:root "$repo" chmod -R go-w,a-st "$repo" createrepo "${repo}/fedora-31-x86_64"
run this script every time we add, modify or remove packages in this repo;