Skip to content

Commit

Permalink
Add support for hashed mode to Poudriere
Browse files Browse the repository at this point in the history
Creates the repo with hash-based filenames to allow use of a CDN
  • Loading branch information
allanjude committed Oct 31, 2021
1 parent d4d4074 commit 30c4b23
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 6 deletions.
11 changes: 11 additions & 0 deletions src/etc/poudriere.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,14 @@ DISTFILES_CACHE=/usr/ports/distfiles
# be fetched.
# Default: everything
#PACKAGE_FETCH_WHITELIST="gcc* rust llvm*"

# Have pkg create the repo such that each package is named with the short hash
# if its file contents in the package filename, with symlinks to the traditional
# package filenames. The packagesite.yaml file will point to the hashed version
# of these files. By using hashed pkg filenames, this allows users to lazily
# cache packages without conflicting with the existing packages, or serving stale
# packages from a cache. Once the packages are synced the much
# smaller meta files can then be synced. Allowing a near atomic update of the repo.
# On caching CDNs this means a need to purge 2-5 files instead of all pkgs that
# have been updated.
#PKG_HASH="no"
10 changes: 6 additions & 4 deletions src/man/poudriere-bulk.8
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
.\"
.\" Note: The date here should be updated whenever a non-trivial
.\" change is made to the manual page.
.Dd September 9, 2021
.Dd October 31, 2021
.Dt POUDRIERE-BULK 8
.Os
.Sh NAME
Expand All @@ -38,7 +38,7 @@
.Nm
.Fl a
.Fl j Ar name
.Op Fl CcFIikNnRrSTtvw
.Op Fl CcFHIikNnRrSTtvw
.Op Fl b Ar name
.Op Fl B Ar name
.Op Fl J Ar maxjobs Ns Op Cm \&: Ns Ar prebuildmaxjobs
Expand All @@ -48,7 +48,7 @@
.Nm
.Fl f Ar file Op Oo Fl f Ar file2 Oc Ar ...
.Fl j Ar name
.Op Fl CcFIikNnRrSTtvw
.Op Fl CcFHIikNnRrSTtvw
.Op Fl b Ar name
.Op Fl B Ar name
.Op Fl J Ar maxjobs Ns Op Cm \&: Ns Ar prebuildmaxjobs
Expand All @@ -57,7 +57,7 @@
.Op Fl z Ar set
.Nm
.Fl j Ar name
.Op Fl CcFIikNnRrSTtvw
.Op Fl CcFHIikNnRrSTtvw
.Op Fl b Ar name
.Op Fl B Ar name
.Op Fl J Ar maxjobs Ns Op Cm \&: Ns Ar prebuildmaxjobs
Expand Down Expand Up @@ -228,6 +228,8 @@ Fetch only from the original
Skip
.Fx
mirrors.
.It Fl H
Create a repository where the package filenames contain the short hash of the contents.
.It Fl I
Advanced interactive mode.
.Pp
Expand Down
7 changes: 6 additions & 1 deletion src/share/poudriere/bulk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ Options:
-f file. Implies -c for -a.
-c -- Clean all the previously built binary packages and logs.
-F -- Only fetch from original master_site (skip FreeBSD mirrors)
-H -- Create a repository where the package filenames contain the
short hash of the contents.
-I -- Advanced Interactive mode. Leaves jail running with ports
installed after test.
-i -- Interactive mode. Enter jail for interactive testing and
Expand Down Expand Up @@ -98,7 +100,7 @@ COMMIT=1

[ $# -eq 0 ] && usage

while getopts "ab:B:CcFf:iIj:J:knNO:p:RrSTtvwz:" FLAG; do
while getopts "ab:B:CcFf:HiIj:J:knNO:p:RrSTtvwz:" FLAG; do
case "${FLAG}" in
a)
ALL=1
Expand Down Expand Up @@ -126,6 +128,9 @@ while getopts "ab:B:CcFf:iIj:J:knNO:p:RrSTtvwz:" FLAG; do
OPTARG="${SAVED_PWD}/${OPTARG}"
LISTPKGS="${LISTPKGS:+${LISTPKGS} }${OPTARG}"
;;
H)
PKG_REPO_FLAGS="${PKG_REPO_FLAGS} --hash --symlink"
;;
I)
INTERACTIVE_MODE=2
;;
Expand Down
22 changes: 21 additions & 1 deletion src/share/poudriere/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8211,12 +8211,16 @@ sign_pkg() {
}

build_repo() {
local origin pkg_repo_list_files
local origin pkg_repo_list_files hashcmd

msg "Creating pkg repository"
if [ ${DRY_RUN} -eq 1 ]; then
return 0
fi
if [ ${PKG_HASH} != "no" ]; then
hashcmd="--hash --symlink"
PKG_REPO_FLAGS="${PKG_REPO_FLAGS:+${PKG_REPO_FLAGS} }$hashcmd"
fi
bset status "pkgrepo:"
ensure_pkg_installed force_extract || \
err 1 "Unable to extract pkg."
Expand All @@ -8231,11 +8235,19 @@ build_repo() {
install -m 0400 "${PKG_REPO_META_FILE}" \
${MASTERMNT}/tmp/pkgmeta
fi

# Remount rw
# mount_nullfs does not support mount -u
umount ${UMOUNT_NONBUSY} ${MASTERMNT}/packages || \
umount -f ${MASTERMNT}/packages
mount_packages

mkdir -p ${MASTERMNT}/tmp/packages
if [ -n "${PKG_REPO_SIGNING_KEY}" ]; then
install -m 0400 ${PKG_REPO_SIGNING_KEY} \
${MASTERMNT}/tmp/repo.key
injail ${PKG_BIN} repo \
${PKG_REPO_FLAGS} \
${pkg_repo_list_files} \
-o /tmp/packages \
${PKG_META} \
Expand All @@ -8246,12 +8258,14 @@ build_repo() {
# using SSH with DNSSEC as older hosts don't support
# it.
${MASTERMNT}${PKG_BIN} repo \
${PKG_REPO_FLAGS} \
${pkg_repo_list_files} \
-o ${MASTERMNT}/tmp/packages ${PKG_META_MASTERMNT} \
${MASTERMNT}/packages \
${SIGNING_COMMAND:+signing_command: ${SIGNING_COMMAND}}
else
JNETNAME="n" injail ${PKG_BIN} repo \
${PKG_REPO_FLAGS} \
${pkg_repo_list_files} \
-o /tmp/packages ${PKG_META} /packages \
${SIGNING_COMMAND:+signing_command: ${SIGNING_COMMAND}}
Expand All @@ -8266,6 +8280,11 @@ build_repo() {
sign_pkg pubkey "${PACKAGES}/Latest/pkg.${PKG_EXT}"
fi
fi

# Remount ro
umount ${UMOUNT_NONBUSY} ${MASTERMNT}/packages || \
umount -f ${MASTERMNT}/packages
mount_packages -o ro
}

calculate_size_in_mb() {
Expand Down Expand Up @@ -8784,6 +8803,7 @@ INTERACTIVE_MODE=0
: ${FLAVOR_DEFAULT_ALL:=no}
: ${NULLFS_PATHS:="/rescue /usr/share /usr/tests /usr/lib32"}
: ${PACKAGE_FETCH_URL:="pkg+http://pkg.FreeBSD.org/\${ABI}"}
: ${PKG_HASH:=no}

: ${POUDRIERE_TMPDIR:=$(command mktemp -dt poudriere)}
: ${SHASH_VAR_PATH_DEFAULT:=${POUDRIERE_TMPDIR}}
Expand Down
5 changes: 5 additions & 0 deletions src/share/poudriere/include/pkg.sh
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ delete_pkg() {
[ $# -ne 1 ] && eargs delete_pkg pkg
local pkg="$1"

# If ${pkg} is a symlink, delete the target as well
[ -L "${pkg}" ] && unlink $(realpath "${pkg}")

# Delete the package and the depsfile since this package is being deleted,
# which will force it to be recreated
unlink "${pkg}"
Expand All @@ -339,6 +342,8 @@ delete_pkg_xargs() {
# Delete the package and the depsfile since this package is being deleted,
# which will force it to be recreated
{
# If ${pkg} is a symlink, delete the target as well
[ -L "${pkg}" ] && echo $(realpath "${pkg}")
echo "${pkg}"
echo "${pkg_cache_dir}"
} >> "${listfile}"
Expand Down
5 changes: 5 additions & 0 deletions src/share/poudriere/pkgclean.sh
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,16 @@ for file in ${PACKAGES}/All/*; do
pkgname="${pkgname%.*}"
if ! pkg_get_origin origin "${file}"; then
msg_verbose "Found corrupt package: ${file}"
[ -L "${file}" ] && echo "$(realpath ${file})" >> ${BADFILES_LIST}
echo "${file}" >> ${BADFILES_LIST}
elif shash_remove pkgname-forbidden "${pkgname}" \
forbidden; then
msg_verbose "Found forbidden package (${forbidden}): ${file}"
[ -L "${file}" ] && echo "$(realpath ${file})" >> ${BADFILES_LIST}
echo "${file}" >> ${BADFILES_LIST}
elif ! pkgbase_is_needed "${pkgname}"; then
msg_verbose "Found unwanted package: ${file}"
[ -L "${file}" ] && echo "$(realpath ${file})" >> ${BADFILES_LIST}
echo "${file}" >> ${BADFILES_LIST}
else
echo "${file} ${origin}" >> ${FOUND_ORIGINS}
Expand All @@ -208,6 +211,7 @@ for file in ${PACKAGES}/All/*; do
;&
*)
msg_verbose "Found incorrect format file: ${file}"
[ -L "${file}" ] && echo "$(realpath ${file})" >> ${BADFILES_LIST}
echo "${file}" >> ${BADFILES_LIST}
;;
esac
Expand Down Expand Up @@ -257,6 +261,7 @@ END {
for pkg in $packages; do
pkgversion="${pkg##*-}"
pkgversion="${pkgversion%.*}"
pkgversion="${pkgversion%~*}"

if [ -z "${lastpkg}" ]; then
lastpkg="${pkg}"
Expand Down

0 comments on commit 30c4b23

Please sign in to comment.