aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2018-01-10 17:40:08 +0100
committerMichał Górny <mgorny@gentoo.org>2018-01-30 23:12:21 +0100
commit104635efa9b4c9e268832d9ac64ad39e44002df3 (patch)
tree3aec8f97d815a4d268d99de8fb19ea89053281d0
parentrsync: Fix *-verify-metamanifest boolean parsing (diff)
downloadportage-104635efa9b4c9e268832d9ac64ad39e44002df3.tar.gz
portage-104635efa9b4c9e268832d9ac64ad39e44002df3.tar.bz2
portage-104635efa9b4c9e268832d9ac64ad39e44002df3.zip
install-qa-check: New QA check/cleanup for empty directories
Warn about empty directories installed to /var in install-qa-check phase (that were not "filled" using keepdir), to help developers stop relying upon Portage preserving them. Those directories are rather unlikely to be false positives. Furthermore, remove all the empty directories if FEATURES=strict-keepdir is used to catch even more problems (intended for developers). Here warnings are not really suitable since there will be a high number of false positives. The PMS specifies the behavior upon merging empty directories as undefined, and specifically prohibits ebuilds from attempting to install empty directories. However, ebuilds occasionally still fall into the trap of relying on 'dodir' preserving the directory. Make the Portage behavior more strict in order to prevent that. Reviewed-by: Zac Medico <zmedico@gentoo.org>
-rw-r--r--bin/install-qa-check.d/95empty-dirs42
-rw-r--r--man/make.conf.54
-rw-r--r--pym/portage/const.py1
3 files changed, 47 insertions, 0 deletions
diff --git a/bin/install-qa-check.d/95empty-dirs b/bin/install-qa-check.d/95empty-dirs
new file mode 100644
index 000000000..8599db395
--- /dev/null
+++ b/bin/install-qa-check.d/95empty-dirs
@@ -0,0 +1,42 @@
+# Warn about and/or remove empty directories installed by ebuild.
+
+# Rationale: PMS prohibits ebuilds from installing empty directories.
+# Cleaning them up from the installation image provides an easy way
+# to make sure that ebuilds are not relying on it while making it easy
+# for users to override this if they need to.
+#
+# The ebuilds that need to preserve empty directories should use keepdir
+# as documented e.g.:
+# https://devmanual.gentoo.org/function-reference/install-functions/index.html
+#
+# For now, we emit QA warnings for empty directories in /var.
+# Additionally, if FEATURES=strict-keepdir is enabled we explicitly
+# remove *all* empty directories to trigger breakage.
+
+find_empty_dirs() {
+ local warn_dirs=()
+ local d striparg=
+
+ [[ ${FEATURES} == *strict-keepdir* ]] && striparg=-delete
+
+ while IFS= read -r -d $'\0' d; do
+ [[ ${d} == ${ED%/}/var/* ]] && warn_dirs+=( "${d}" )
+ done < <(find "${ED}" -depth -mindepth 1 -type d -empty -print0 ${striparg} | LC_COLLATE=C sort -z)
+
+ if [[ ${warn_dirs[@]} ]]; then
+ eqawarn "One or more empty directories installed to /var:"
+ eqawarn
+ for d in "${warn_dirs[@]}"; do
+ eqawarn " ${d#${ED%/}}"
+ done
+ eqawarn
+ eqawarn "If those directories need to be preserved, please make sure to create"
+ eqawarn "or mark them for keeping using 'keepdir'. Future versions of Portage"
+ eqawarn "will strip empty directories from installation image."
+ fi
+}
+
+find_empty_dirs
+: # guarantee successful exit
+
+# vim:ft=sh
diff --git a/man/make.conf.5 b/man/make.conf.5
index a81b497bd..cb0f00237 100644
--- a/man/make.conf.5
+++ b/man/make.conf.5
@@ -623,6 +623,10 @@ see \fBinstallsources\fR.
Have portage react strongly to conditions that have the potential to be
dangerous (like missing or incorrect digests for ebuilds).
.TP
+.B strict-keepdir
+Have portage strictly require keepdir calls in ebuilds. Empty
+directories installed without explicit keepdir will be removed.
+.TP
.B stricter
Have portage react strongly to conditions that may conflict with system
security provisions (for example textrels, executable stack). Read about
diff --git a/pym/portage/const.py b/pym/portage/const.py
index e5fa4b67c..655be82b1 100644
--- a/pym/portage/const.py
+++ b/pym/portage/const.py
@@ -184,6 +184,7 @@ SUPPORTED_FEATURES = frozenset([
"split-elog",
"split-log",
"strict",
+ "strict-keepdir",
"stricter",
"suidctl",
"test",