Skip to content

Commit

Permalink
db-update: die when trying to update a package without updating a pen…
Browse files Browse the repository at this point in the history
…ding rebuild

A semi-common pattern is for one maintainer to stage a rebuild of a
package due to e.g. cascading repository-wide python/boost/whatever
rebuilds, and then for the original maintainer of the package to not
notice and update the package in the stable repo, leaving an out of date
rebuild in staging or testing.

Then the the out of date package gets moved and ends up breaking things,
possibly via a package downgrade, possibly via breaking compatibility
with a much more targeted rebuild uploaded all at once. Ultimately,
Things Happen™ and the repository hierarchy gets broken.

Prevent this by enforcing for all packages that exist in
multiple levels of the repo: staging -> testing -> stable

That updates to one must come with an update to all the others.
  • Loading branch information
eli-schwartz committed Jan 10, 2019
1 parent 863818f commit 8804e63
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
25 changes: 25 additions & 0 deletions db-functions
Expand Up @@ -377,6 +377,31 @@ check_pkgrepos() {
return 0
}

check_stagingrepos() {
local pkgfile=${1}
local pkgrepo=${2}
local pkgname=$(getpkgname "${pkgfile}")
local pkgarch=$(getpkgarch "${pkgfile}")
local candidate candidates=()

if in_array "${pkgrepo}" "${STABLE_REPOS[@]}"; then
candidates+=($(find_repo_for_package "${pkgname}" "${pkgarch}" "${TESTING_REPOS[@]}"))
fi
if in_array "${pkgrepo}" "${STABLE_REPOS[@]}" "${TESTING_REPOS[@]}"; then
candidates+=($(find_repo_for_package "${pkgname}" "${pkgarch}" "${STAGING_REPOS[@]}"))
fi
(( ${#candidates[@]} == 0 )) && return 0

printf '%s\n' "${candidates[@]%-*}"
for candidate in "${candidates[@]}"; do
for candidate in "${STAGING}/${candidate%-*}"/*${PKGEXTS}; do
[[ ${pkgname} = $(getpkgname "${candidate}" 2>/dev/null) ]] && return 0
done
done

return 1
}

#usage: chk_license ${license[@]}"
chk_license() {
local l
Expand Down
3 changes: 3 additions & 0 deletions db-update
Expand Up @@ -52,6 +52,9 @@ for repo in "${repos[@]}"; do
if ! check_pkgrepos "${pkg}"; then
die "Package %s already exists in another repository" "$repo/${pkg##*/}"
fi
if ! missing_repo="$(check_stagingrepos "${pkg}" "${repo}")"; then
die "Package %s in %s needs to be updated in unstable repos as well: %s" "${pkg}" "${repo}" "${missing_repo}"
fi
if ! check_packager "${pkg}"; then
die "Package %s does not have a valid packager" "$repo/${pkg##*/}"
fi
Expand Down
27 changes: 27 additions & 0 deletions test/cases/db-update.bats
Expand Up @@ -94,6 +94,33 @@ load ../lib/common
[[ -f ${ARCHIVE_BASE}/packages/p/pkg-any-a/pkg-any-a-1-1-any${PKGEXT}.sig ]]
}

@test "update any package to stable repo without updating testing package fails" {
releasePackage extra pkg-any-a
db-update
updatePackage pkg-any-a
releasePackage testing pkg-any-a
db-update
updatePackage pkg-any-a
releasePackage extra pkg-any-a

run db-update
[ "$status" -ne 0 ]
}

@test "update any package to stable repo without updating staging package fails" {
releasePackage extra pkg-any-a
db-update
updatePackage pkg-any-a
releasePackage staging pkg-any-a
db-update
updatePackage pkg-any-a
releasePackage extra pkg-any-a

run db-update
echo "$output"
[ "$status" -ne 0 ]
}

@test "update same any package to same repository fails" {
releasePackage extra pkg-any-a
db-update
Expand Down
2 changes: 1 addition & 1 deletion test/lib/common.bash
Expand Up @@ -102,7 +102,7 @@ setup() {
ARCHIVE_BASE="${TMP}/archive"
ARCHIVEUSER=""
SVNREPO="file://${TMP}/svn-packages-repo"
PKGREPOS=('core' 'extra' 'testing')
PKGREPOS=('core' 'extra' 'testing' 'staging')
PKGPOOL='pool/packages'
SRCPOOL='sources/packages'
STAGING_REPOS=('staging')
Expand Down

0 comments on commit 8804e63

Please sign in to comment.