createrepo_go is a pure-Go toolkit for creating, reading, modifying, and
merging RPM repository metadata. It provides command-line tools compatible with
the familiar createrepo_c, modifyrepo_c, mergerepo_c, and sqliterepo_c
workflows, plus a Go package for embedding repository metadata operations in
other applications.
The Go module path is:
github.com/define42/createrepo_go
- Generate
repodata/repomd.xmlwithprimary,filelists, andothermetadata from RPM packages. - Preserve or add extra repository metadata such as comps, modules, and updateinfo records.
- Generate yum-compatible SQLite metadata databases.
- Merge multiple repositories into one output repository.
- Load local or HTTP(S) repository metadata from Go code.
- Read and write common metadata compression formats:
gz,bz2,xz,zstd, andzck. - Generate optional
filelists-extand delta RPM metadata.
- Go 1.24 or newer.
No C library bindings are required.
From the repository root:
go build ./...To install all command-line tools into your configured Go binary directory:
go install ./cmd/...This installs:
createrepo_cmodifyrepo_cmergerepo_csqliterepo_c
Create repository metadata for a directory of RPMs:
createrepo_c /srv/repoWrite metadata to a separate output directory:
createrepo_c --outputdir /srv/repo-out /srv/rpmsGenerate SQLite metadata along with XML metadata:
createrepo_c --database /srv/repoUse a specific metadata compression format:
createrepo_c --compress-type gz /srv/repo
createrepo_c --zck /srv/repoUpdate an existing repository while preserving additional metadata:
createrepo_c --update /srv/repoAdd a comps/group metadata file:
createrepo_c --groupfile comps.xml /srv/repoAdd or replace additional metadata in an existing repodata directory:
modifyrepo_c --mdtype modules modules.yaml /srv/repo/repodataRemove an additional metadata record:
modifyrepo_c --remove modules /srv/repo/repodataMerge repositories:
mergerepo_c --repo /srv/repo-a --repo /srv/repo-b --outputdir /srv/mergedGenerate SQLite metadata for an existing repository:
sqliterepo_c /srv/repoRead packages in parallel and cache checksums between runs:
createrepo_c --workers 8 --cachedir /var/cache/createrepo /srv/repoWhen updating a repository, keep a few superseded metadata versions instead of deleting them all:
createrepo_c --update --retain-old-md 2 /srv/repoGenerate metadata for split media (one repository spanning several directories); package locations are prefixed with each volume's directory name:
createrepo_c --split --outputdir /srv/repo disc1 disc2 disc3Merge repositories, choosing how packages that share a name and architecture are
resolved (repo keeps the first repo's package, ts the newest build, nvr
the highest version):
mergerepo_c --method nvr --repo /srv/repo-a --repo /srv/repo-b --outputdir /srv/mergedMerge in Koji mode, which keeps every package version and records each
package's origin repository in pkgorigins metadata:
mergerepo_c --koji --repo /srv/repo-a --repo /srv/repo-b --outputdir /srv/mergedSkip unreadable packages and report a non-zero exit status, override a stale lock, or prune old metadata by age:
createrepo_c --error-exit-val --ignore-lock --retain-old-md-by-age 14d /srv/repoEach command supports --version. The following createrepo_c flags are
implemented: --workers, --cachedir, --skip-stat, --retain-old-md,
--retain-old-md-by-age, --split, --recycle-pkglist, --error-exit-val,
and --ignore-lock; and for mergerepo_c: --method, --koji, --pkgorigins,
--blocked, --all, --arch-expand, --nogroups, --noupdateinfo, and
--verbose.
--retain-old-md-by-age accepts an age such as 30 (seconds), 45s, 10m,
24h, 7d, or 2w. A few highly tool-specific flags remain accepted but
ignored (--noarch-repo and --simple for mergerepo_c, and --zck-dict-dir
for modifyrepo_c) so existing command lines keep working.
Import the public package:
import "github.com/define42/createrepo_go/pkg/createrepo"Create repository metadata:
err := createrepo.Create(ctx, createrepo.Options{
Directory: "/srv/repo",
Database: true,
Compression: createrepo.CompressionZstd,
Checksum: createrepo.ChecksumSHA256,
})Load repository metadata:
repo, err := createrepo.LoadMetadata(ctx, "https://example.com/repo/", createrepo.LoadOptions{
VerifyChecksums: true,
})
if err != nil {
return err
}
for _, pkg := range repo.Packages {
fmt.Println(pkg.Name, pkg.Version, pkg.Arch)
}Modify an existing repodata directory:
err := createrepo.Modify(ctx, createrepo.ModifyOptions{
MetadataPath: "/tmp/modules.yaml",
RepodataDir: "/srv/repo/repodata",
MetadataType: "modules",
Compress: true,
Compression: createrepo.CompressionZstd,
})The package can parse and emit the standard package metadata files:
primary.xmlfilelists.xmlfilelists-ext.xmlother.xmlrepomd.xmlupdateinfo.xml
Additional metadata records are preserved through create/update flows when requested.
Run the test suite with:
go test ./...Useful package layout:
cmd/contains the command-line entrypoints.internal/cli/contains flag parsing and command dispatch.pkg/createrepo/contains the public Go API and metadata implementation.tests/testdata/contains RPMs and repository fixtures used by tests.
This project is distributed under the GNU General Public License version 2. See
LICENSE for the full license text.