This directory contains packaging for the Fedora family of distributions.
The package can be built using a rootless podman container.
The entire snapd tree is exposed as /src inside the container, this is done
with the first -v switch. The .build directory is exposed as the /build
directory. This is where most of the build actually happens. This is where we
copy the built packages from the container back to the container host. The Z
option applies the right SELinux context.
The --rm switch removes the container so that it doesn't linger after each
build. The --interactive switch allows us to pass a script to bash on stdin.
The --userns host option maps the ID of the calling user to root inside the
container.
The BASH_XTRACEFD environment variable is preserved, along with the file
descriptor. This allows the outer script to differentiate trace output from
stderr for better clarity.
Several named volumes are used to avoid network operations on subsequent runs.
snapd-fedora-dnf-cacheis mapped to/var/cache/libdnf5snapd-gomod-cacheis mapped to/var/cache/gomod
GOMODCACHE is exported early in the container script so every subsequent go
invocation picks it up. This volume is shared with other distributions that use
the same approach.
DNF discards downloaded packages after installation by default, so all dnf install calls pass --setopt=keepcache=True to retain the RPMs in the volume.
podman run \
--rm \
--interactive \
--attach stdin \
--attach stdout \
--attach stderr \
--preserve-fd="${BASH_XTRACEFD-}" \
--userns host \
-e BASH_XTRACEFD="${BASH_XTRACEFD-}" \
-e SKIP_TESTS="${SKIP_TESTS-}" \
-v "../../:/src:ro,Z" \
-v ".build/:/build:Z" \
-v "snapd-fedora-dnf-cache:/var/cache/libdnf5:Z" \
-v "snapd-gomod-cache:/var/cache/gomod:Z" \
-w /build \
registry.fedoraproject.org/fedora:latest \
/bin/bash -x -e -uThe small host script creates the .build directory with the structure expected
by rpmbuild. This directory is shared with the container and can be used to
access resulting packages and build logs.
rm -rf .build
mkdir -p .build/{SRPMS,RPMS,SOURCES,SPECS}The build script has several sections. As a part of the process we are creating
two source tarballs (one without vendored dependencies and one with only the
vendored dependencies), and combining them with the snapd.spec file from this
directory.
# Show the sizes of persistent caches to verify volumes are populated across runs.
echo "DNF cache: $(du -sh /var/cache/libdnf5 2>/dev/null | cut -f1 || echo empty)"
echo "Go module cache: $(du -sh /var/cache/gomod 2>/dev/null | cut -f1 || echo empty)"
# Allow both root and the builder user to read and write the Go module cache.
chmod 1777 /var/cache/gomod
export GOMODCACHE=/var/cache/gomod
# Install bootstrap packages.
BASH_XTRACEFD= dnf --assumeyes install --setopt=install_weak_deps=False --setopt=keepcache=True \
bash coreutils findutils gawk git gzip make rpm-build \
rpm-devel systemd-rpm-macros tar xz golang
# Copy packaging files to the build directory.
install -t /build/SPECS/ /src/packaging/fedora/snapd.spec
# Determine the version of the package.
version=$(rpmspec -q --qf "%{VERSION}\n" /build/SPECS/snapd.spec | head -n1)
# Copy the source tree to a temporary location, so that we can call go mod vendor.
mkdir -p /src-rw
tar -C /src -c \
--exclude='./vendor/*' \
--exclude='./c-vendor/squashfuse' \
--exclude='.git' \
--exclude='.git/*' \
--exclude='.image-garden/*' \
--exclude='./packaging/*/.build/*' \
--exclude='./built-snap/*' \
--exclude='./*.snap' \
. | tar -C /src-rw -x
# Vendor Go modules that are needed.
( cd /src-rw && go mod vendor )
# Create the no-vendor and only-vendor source archives.
( cd /src-rw && ./packaging/pack-source -v "$version" -o /build/SOURCES )
# Discover and install build dependencies.
rpmspec -q --buildrequires /build/SPECS/snapd.spec >/tmp/buildreqs.txt
BASH_XTRACEFD= xargs -r -d "\n" dnf --assumeyes install --setopt=keepcache=True </tmp/buildreqs.txt
# Create a non-root build user.
useradd -m builder
# Transfer ownership of the work directory to the build user.
# When exiting, restore root ownership. Root in the container
# is mapped to the calling host user.
chown -R builder /build
trap 'chown -R root /build' EXIT
# Build the binary package.
su builder -c 'cd /build && BASH_XTRACEFD= GOMODCACHE=/var/cache/gomod rpmbuild -ba /build/SPECS/snapd.spec --define "_topdir /build"'"${SKIP_TESTS:+ --nocheck}"