Discussion:
[arch-projects] [dbscripts] [PATCH 2/3] db-update: die when trying to update a package without updating a pending rebuild
Eli Schwartz via arch-projects
2018-12-02 19:28:22 UTC
Permalink
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.

Signed-off-by: Eli Schwartz <***@archlinux.org>
---
db-functions | 21 +++++++++++++++++++++
db-update | 5 +++++
test/cases/db-update.bats | 13 +++++++++++++
3 files changed, 39 insertions(+)

diff --git a/db-functions b/db-functions
index 7aeedced..b47ad570 100644
--- a/db-functions
+++ b/db-functions
@@ -374,6 +374,27 @@ check_pkgrepos() {
return 0
}

+check_stagingrepos() {
+ local pkgfile=${1}
+ local pkgrepo=${2}
+ local pkgname=$(getpkgname "${pkgfile}")
+ local pkgarch=$(getpkgarch "${pkgfile}")
+ local candidate
+
+ if in_array "${pkgrepo}" "${STABLE_REPOS[@]}"; then
+ candidate=$(find_repo_for_package "${pkgname}" "${pkgarch}" "${TESTING_REPOS[@]}") || return 0
+ elif in_array "${pkgrepo}" "${TESTING_REPOS}"; then
+ candidate=$(find_repo_for_package "${pkgname}" "${pkgarch}" "${STAGING_REPOS[@]}") || return 0
+ fi
+
+ printf '%s\n' "${candidate%-*}"
+ for candidate in "${STAGING}/${candidate%-*}"/*${PKGEXTS}; do
+ [[ ${pkgname} = $(getpkgname "${candidate}" 2>/dev/null) ]] && return 0
+ done
+
+ return 1
+}
+
#usage: chk_license ${license[@]}"
chk_license() {
local l
diff --git a/db-update b/db-update
index 313fb999..f07a8a45 100755
--- a/db-update
+++ b/db-update
@@ -52,6 +52,11 @@ for repo in "${repos[@]}"; do
if ! check_pkgrepos "${pkg}"; then
die "Package %s already exists in another repository" "$repo/${pkg##*/}"
fi
+ set -x
+ 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
+ set +x
if ! check_packager "${pkg}"; then
die "Package %s does not have a valid packager" "$repo/${pkg##*/}"
fi
diff --git a/test/cases/db-update.bats b/test/cases/db-update.bats
index 9ee06321..f2e7fcab 100644
--- a/test/cases/db-update.bats
+++ b/test/cases/db-update.bats
@@ -87,6 +87,19 @@ load ../lib/common
checkPackage testing pkg-any-a 1-2
}

+@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 same any package to same repository fails" {
releasePackage extra pkg-any-a
db-update
--
2.19.2
Eli Schwartz via arch-projects
2018-12-02 19:28:23 UTC
Permalink
Don't allow anomalous testing packages floating around after a rebuild
which are older than stable.

Signed-off-by: Eli Schwartz <***@archlinux.org>
---
db-move | 9 +++++++++
test/cases/db-move.bats | 14 ++++++++++++++
test/lib/common.bash | 2 ++
3 files changed, 25 insertions(+)

diff --git a/db-move b/db-move
index 72aa0b35..7ded7de1 100755
--- a/db-move
+++ b/db-move
@@ -14,6 +14,11 @@ repo_to="${args[1]}"
ftppath_from="${FTP_BASE}/${repo_from}/os/"
ftppath_to="${FTP_BASE}/${repo_to}/os/"

+check_leapfrog=false
+if in_array "${repo_from}" "${STAGING_REPOS}" && in_array "${repo_to}" "${STABLE_REPOS}"; then
+ check_leapfrog=true
+fi
+
if ! check_repo_permission "$repo_to" || ! check_repo_permission "$repo_from"; then
die "You don't have permission to move packages from %s to %s" "$repo_from" "$repo_to"
fi
@@ -42,6 +47,10 @@ for pkgbase in "${args[@]:2}"; do
die "Could not read pkgver"
fi

+ if [[ ${check_leapfrog} = true ]] && leapfrog=$(find_repo_for_package "${pkgbase}" "${pkgarch}" "${TESTING_REPOS[@]}"); then
+ die "Package %s cannnot be moved from %s to %s while it exists in %s" "${pkgbase}" "${repo_from}" "${repo_to}" "${leapfrog}"
+ fi
+
for pkgname in "${pkgnames[@]}"; do
getpkgfile "${ftppath_from}/${pkgarch}/${pkgname}-${pkgver}-${vcsrepo_from##*-}"${PKGEXTS} >/dev/null
done
diff --git a/test/cases/db-move.bats b/test/cases/db-move.bats
index eb77ef9c..f4407168 100644
--- a/test/cases/db-move.bats
+++ b/test/cases/db-move.bats
@@ -39,6 +39,20 @@ load ../lib/common
done
}

+@test "move package from staging to extra while a testing package exists fails" {
+ releasePackage extra pkg-any-a
+ db-update
+ updatePackage pkg-any-a
+ releasePackage testing pkg-any-a
+ db-update
+ updatePackage pkg-any-a
+ releasePackage staging pkg-any-a
+ db-update
+
+ run db-move staging extra pkg-any-a
+ [ "$status" -ne 0 ]
+}
+
@test "move single-arch packages" {
local arches=('i686' 'x86_64')
local pkgs=('pkg-single-arch' 'pkg-simple-b')
diff --git a/test/lib/common.bash b/test/lib/common.bash
index a92a01ee..03089efc 100644
--- a/test/lib/common.bash
+++ b/test/lib/common.bash
@@ -25,6 +25,8 @@ __isGlobfile() {
[[ -f $1 ]]
}

+do:() { echo "${@@Q}"; "$@"; }
+
__buildPackage() {
local pkgdest=${1:-.}
local p
--
2.19.2
Loading...