[Piuparts-devel] [Git][debian/piuparts][develop] 7 commits: Ignore /var/cache/debconf/tmp.ci/
Nicolas Dandrimont (@olasd)
gitlab at salsa.debian.org
Mon Mar 3 22:56:32 GMT 2025
Nicolas Dandrimont pushed to branch develop at Debian / piuparts
Commits:
7bfd92ba by Nicolas Dandrimont at 2025-03-03T21:52:00+01:00
Ignore /var/cache/debconf/tmp.ci/
Closes: #1092667
- - - - -
bffee51f by Nicolas Dandrimont at 2025-03-03T21:54:53+01:00
Extend allow-database policy-rc.d for firebird4.0
Closes: #1095408
- - - - -
12781170 by Nicolas Dandrimont at 2025-03-03T22:20:46+01:00
Support versioned provides in metapackage generation
This is especially important on packages that conflict with a virtual
package they're providing, such as sysvinit-utils=3.14-3
- - - - -
70f4ed2f by Nicolas Dandrimont at 2025-03-03T22:25:52+01:00
Clean up some string concatenations
Gbp-dch: ignore
- - - - -
60e839cf by Nicolas Dandrimont at 2025-03-03T23:31:27+01:00
Deduplicate checks whether a file is ignored
- - - - -
6c349734 by Nicolas Dandrimont at 2025-03-03T23:32:05+01:00
Record and ignore files affected by systemd-tmpfiles
Closes: #1036399
- - - - -
1db83cba by Nicolas Dandrimont at 2025-03-03T23:55:55+01:00
Always use --allow-remove-essential on removals
apt-get will only remove packages that have been explicitly listed for
removal, which takes care of Protected: yes and Important: yes packages.
piuparts won't actually attempt to remove Essential packages as they're
part of the base chroot (hopefully).
Closes: #1010967, #1084173
- - - - -
3 changed files:
- custom-scripts/scripts/post_remove_exceptions
- custom-scripts/scripts/pre_remove_exceptions
- piuparts.py
Changes:
=====================================
custom-scripts/scripts/post_remove_exceptions
=====================================
@@ -5,9 +5,6 @@ log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
-# cleanup from pre_remove_exceptions
-rm -fv /etc/apt/apt.conf.d/piuparts-allow-remove-essential
-
case ${PIUPARTS_OBJECTS%%=*} in
asclassic)
case "$PIUPARTS_DISTRIBUTION" in
=====================================
custom-scripts/scripts/pre_remove_exceptions
=====================================
@@ -60,32 +60,6 @@ case "$PIUPARTS_DISTRIBUTION" in
;;
esac
-case "$PIUPARTS_DISTRIBUTION" in
- lenny*|squeeze*|wheezy*|jessie*)
- # --allow-remove-essential was added in apt 1.1 (stretch)
- ;;
- *)
- case ${PIUPARTS_OBJECTS%%=*} in
- dracut*|\
- education-thin-client|\
- grub-efi-amd64-signed|\
- grub-efi-ia32-signed|\
- init|\
- ltsp-client-core-dbgsym|\
- ltsp-client-core|\
- ltsp-client)
- log_debug
- # requires removal of essential packages
- if [ ! -f /etc/apt/apt.conf.d/piuparts-allow-remove-essential ]
- then
- echo "Enabling APT::Get::allow-remove-essential"
- echo 'APT::Get::allow-remove-essential "true";' >> /etc/apt/apt.conf.d/piuparts-allow-remove-essential
- fi
- ;;
- esac
- ;;
-esac
-
# Allow removal of the kernel running on the host from the chroot.
UNAME_R="$(uname -r)"
echo "linux-image-$UNAME_R linux-image-$UNAME_R/prerm/removing-running-kernel-$UNAME_R boolean false" | debconf-set-selections
=====================================
piuparts.py
=====================================
@@ -48,7 +48,7 @@ import tempfile
import time
import traceback
import uuid
-from collections import namedtuple
+from collections import defaultdict, namedtuple
from contextlib import ExitStack
from signal import SIGALRM, SIGKILL, SIGTERM, alarm, signal
from typing import Dict
@@ -277,6 +277,7 @@ class Settings:
"/var/cache/debconf/templates.dat",
"/var/cache/debconf/templates.dat.old",
"/var/cache/debconf/templates.dat-old",
+ "/var/cache/debconf/tmp.ci/",
"/var/lib/apt/daily_lock",
"/var/lib/apt/extended_states",
"/var/lib/cdebconf/",
@@ -776,6 +777,7 @@ class Chroot:
self.mounts = []
self.initial_selections = None
self.avail_md5_history = []
+ self.systemd_tmpfiles: Dict[str, Tuple[str, str]] = {}
def create_temp_dir(self):
"""Create a temporary directory for the chroot."""
@@ -1148,6 +1150,7 @@ class Chroot:
policy += 'test "$1" = "postgresql-8.3" && exit 0\n'
policy += 'test "$1" = "firebird2.5-super" && exit 0\n'
policy += 'test "$1" = "firebird3.0" && exit 0\n'
+ policy += 'test "$1" = "firebird4.0" && exit 0\n'
policy += "exit 101\n"
create_file(full_name, policy)
os.chmod(full_name, 0o755)
@@ -1290,6 +1293,38 @@ class Chroot:
"""Remember initial selections to easily recognize mismatching chroot metadata"""
self.initial_selections = self.get_selections()
+ def remember_systemd_tmpfiles(self):
+ """Remember files potentially affected by systemd-tmpfiles. Only files and directories with some flags are ignored by piuparts."""
+ ignored_flags = (
+ "f", # Create file
+ "w", # Write file contents
+ "d", # Create directory
+ "D", # Create directory (and remove on --remove)
+ "p", # Create named pipe
+ "L", # Create symlink
+ "c", # Create character device
+ "b", # Create block device
+ "C", # Copy file or directory
+ )
+ (retcode, output) = self.run(["systemd-tmpfiles", "--cat-config"], ignore_errors=True)
+ if retcode != 0:
+ return
+
+ current_file = "unknown tmpfiles.d snippet"
+
+ for line in output.splitlines():
+ line = line.strip()
+ if not line:
+ continue
+ if line.startswith("#"):
+ if line.startswith("# /"):
+ if os.path.exists(self.relative(line[3:])):
+ current_file = line[2:]
+ continue
+ flag, filename, *_ = line.split()
+ if flag[0] in ignored_flags:
+ self.systemd_tmpfiles[filename] = (current_file, flag)
+
def upgrade_to_distros(self, distros, packages, apt_get_upgrade=False):
"""Upgrade a chroot installation to each successive distro."""
for distro in distros:
@@ -1353,7 +1388,7 @@ class Chroot:
def list_installed_files(self, pre_info, post_info):
"""List the new files installed, removed and modified between two dir trees.
Actually, it is a nice output of the funcion diff_meta_dat."""
- (new, removed, modified) = diff_meta_data(pre_info, post_info)
+ (new, removed, modified) = diff_meta_data(pre_info, post_info, self.is_ignored)
file_owners = self.get_files_owned_by_packages()
if new:
@@ -1643,7 +1678,8 @@ class Chroot:
"""Remove packages in a chroot."""
if packages:
self.run(
- ["apt-get", "remove"] + ["%s-" % x if x.endswith("+") else x for x in unqualify(packages)],
+ ["apt-get", "remove", "--allow-remove-essential"]
+ + ["%s-" % x if x.endswith("+") else x for x in unqualify(packages)],
ignore_errors=ignore_errors,
)
@@ -1929,20 +1965,27 @@ class Chroot:
if selinux_enabled():
self.mount("/sys/fs/selinux", self.selinuxfs_path(), opts=["bind", "ro"])
- def is_ignored(self, pathname, info="PATH"):
+ def is_ignored(self, pathname, info="PATH", quiet=False):
"""Is a file (or dir or whatever) to be ignored?"""
if pathname in settings.ignored_files:
return True
if ":" + pathname in settings.ignored_files:
- logging.info("IGNORED %s: %s" % (info, pathname))
+ if not quiet:
+ logging.info("IGNORED %s: %s" % (info, pathname))
+ return True
+ stripped_pathname = pathname.rstrip("/")
+ if stripped_pathname in self.systemd_tmpfiles:
+ snippet, flag = self.systemd_tmpfiles[stripped_pathname]
+ if not quiet:
+ logging.info("IGNORED %s: %s (flag %s systemd-tmpfiles snippet %s)", info, pathname, flag, snippet)
return True
for pattern in settings.ignored_patterns:
if pattern[0] == ":":
- verbose = True
+ verbose = not quiet
pattern = pattern[1:]
else:
verbose = False
- if re.search("^" + pattern + "$", pathname):
+ if re.fullmatch(pattern, pathname):
if verbose:
logging.info("IGNORED %s: %s" % (info, pathname))
return True
@@ -2178,50 +2221,22 @@ def format_object_attributes(obj):
return res
-def diff_meta_data(tree1, tree2, quiet=False):
+def diff_meta_data(tree1, tree2, is_ignored, quiet=False):
"""Compare two dir trees and return list of new files (only in 'tree2'),
removed files (only in 'tree1'), and modified files."""
tree1_c = tree1.copy()
tree2_c = tree2.copy()
- for name in settings.ignored_files:
- if name[0] == ":":
- verbose = not quiet
- name = name[1:]
- else:
- verbose = False
- if name in tree1_c:
- if verbose:
- logging.info("IGNORED PATH at 1: %s" % name)
+ for name in tree1:
+ if is_ignored(name, info="PATH at 1", quiet=quiet):
del tree1_c[name]
- if name in tree2_c:
- if verbose:
- logging.info("IGNORED PATH at 2: %s" % name)
+ for name in tree2:
+ if is_ignored(name, info="PATH at 2", quiet=quiet):
del tree2_c[name]
- for pattern in settings.ignored_patterns:
- if pattern[0] == ":":
- verbose = not quiet
- pattern = pattern[1:]
- else:
- verbose = False
- pat = re.compile(pattern)
- for name in tree1.keys():
- m = pat.search(name)
- if m and name in tree1_c:
- if verbose:
- logging.info("IGNORED PATH at 1: %s" % name)
- del tree1_c[name]
- for name in tree2.keys():
- m = pat.search(name)
- if m and name in tree2_c:
- if verbose:
- logging.info("IGNORED PATH at 2: %s" % name)
- del tree2_c[name]
-
modified = []
- for name in tree1.keys():
+ for name in tree1:
if name in tree1_c and name in tree2_c:
if objects_are_different(tree1[name], tree2[name]):
if not quiet:
@@ -2410,15 +2425,15 @@ def check_results(chroot, chroot_state, file_owners, deps_info=None):
current_info = chroot.get_tree_meta_data()
if settings.warn_on_others and deps_info is not None:
- (new, removed, modified) = diff_meta_data(reference_info, current_info)
- (depsnew, depsremoved, depsmodified) = diff_meta_data(reference_info, deps_info, quiet=True)
+ (new, removed, modified) = diff_meta_data(reference_info, current_info, chroot.is_ignored)
+ (depsnew, depsremoved, depsmodified) = diff_meta_data(reference_info, deps_info, chroot.is_ignored, quiet=True)
warnnew = prune_files_list(new, depsnew)
warnremoved = prune_files_list(removed, depsremoved)
warnmodified = prune_files_list(modified, depsmodified)
else:
- (new, removed, modified) = diff_meta_data(reference_info, current_info)
+ (new, removed, modified) = diff_meta_data(reference_info, current_info, chroot.is_ignored)
if new:
if settings.warn_on_leftovers_after_purge:
@@ -2525,9 +2540,14 @@ def install_purge_test(chroot, chroot_state, package_files, packages, extra_pack
arch = a
if arch != a:
logging.info("architecture mismatch: %s != %s)" % (arch, a))
+ unversioned_conflicts = defaultdict(list)
+ for conflict in conflicts:
+ unversioned_conflicts[conflict.split("(")[0].strip()].append(conflict)
for provided in provides:
- if provided in conflicts:
- conflicts.remove(provided)
+ unversioned_provide = provided.split("(")[0].strip()
+ if unversioned_provide in unversioned_conflicts:
+ for c in unversioned_conflicts[unversioned_provide]:
+ conflicts.remove(c)
all_depends = ", ".join(depends)
all_conflicts = ", ".join(conflicts)
metapackage = make_metapackage(
@@ -2572,6 +2592,8 @@ def install_purge_test(chroot, chroot_state, package_files, packages, extra_pack
chroot.run_scripts("post_install")
+ chroot.remember_systemd_tmpfiles()
+
if settings.install_purge_install:
file_owners = chroot.get_files_owned_by_packages()
chroot.restore_selections(chroot_state_with_deps, packages)
@@ -2878,7 +2900,7 @@ def parse_command_line():
"--apt",
action="store_true",
default=False,
- help="Command line arguments are package names " + "to be installed via apt.",
+ help="Command line arguments are package names to be installed via apt.",
)
parser.add_option(
@@ -2998,7 +3020,7 @@ def parse_command_line():
"-e",
"--existing-chroot",
metavar="DIR",
- help="Use DIR as the contents of the initial " + "chroot, instead of building a new one with " + "debootstrap",
+ help="Use DIR as the contents of the initial chroot, instead of building a new one with debootstrap",
)
parser.add_option(
@@ -3015,7 +3037,7 @@ def parse_command_line():
action="append",
metavar="FILENAME",
default=[],
- help="Add FILENAME to list of filenames to be " + "ignored when comparing changes to chroot."
+ help="Add FILENAME to list of filenames to be ignored when comparing changes to chroot."
"FILENAMES prefixed with ':' will be reported verbosely.",
)
@@ -3068,7 +3090,7 @@ def parse_command_line():
"--keep-sources-list",
action="store_true",
default=False,
- help="Don't modify the chroot's " + "etc/apt/sources.list.",
+ help="Don't modify the chroot's etc/apt/sources.list.",
)
parser.add_option(
@@ -3076,14 +3098,14 @@ def parse_command_line():
"--log-file",
"--logfile",
metavar="FILENAME",
- help="Write log file to FILENAME in addition to " + "the standard output.",
+ help="Write log file to FILENAME in addition to the standard output.",
)
parser.add_option(
"--list-installed-files",
action="store_true",
default=False,
- help="List files added to the chroot after the " + "installation of the package.",
+ help="List files added to the chroot after the installation of the package.",
)
parser.add_option(
@@ -3100,7 +3122,7 @@ def parse_command_line():
metavar="SNAPSHOT-SIZE",
action="store",
default="1G",
- help="Use SNAPSHOT-SIZE as snapshot size when creating " + "a new LVM snapshot (default: 1G)",
+ help="Use SNAPSHOT-SIZE as snapshot size when creating a new LVM snapshot (default: 1G)",
)
parser.add_option(
@@ -3165,7 +3187,7 @@ def parse_command_line():
"--no-ignores",
action="callback",
callback=forget_ignores,
- help="Forget all ignores set so far, including " + "built-in ones.",
+ help="Forget all ignores set so far, including built-in ones.",
)
parser.add_option(
@@ -3183,7 +3205,7 @@ def parse_command_line():
"--no-upgrade-test",
action="store_true",
default=False,
- help="Skip testing the upgrade from an existing version " + "in the archive.",
+ help="Skip testing the upgrade from an existing version in the archive.",
)
parser.add_option(
@@ -3232,7 +3254,7 @@ def parse_command_line():
"--pbuilder",
action="callback",
callback=set_basetgz_to_pbuilder,
- help="Use /var/cache/pbuilder/base.tgz as the base " + "tarball.",
+ help="Use /var/cache/pbuilder/base.tgz as the base tarball.",
)
parser.add_option(
@@ -3323,7 +3345,7 @@ def parse_command_line():
)
parser.add_option(
- "-t", "--tmpdir", metavar="DIR", help="Use DIR for temporary storage. Default is " + "$TMPDIR or /tmp."
+ "-t", "--tmpdir", metavar="DIR", help="Use DIR for temporary storage. Default is $TMPDIR or /tmp."
)
parser.add_option(
@@ -3555,7 +3577,7 @@ def parse_command_line():
exitcode = 1
if not args:
- logging.error("Need command line arguments: " + "names of packages or package files")
+ logging.error("Need command line arguments: names of packages or package files")
exitcode = 1
settings.testobjects = args
View it on GitLab: https://salsa.debian.org/debian/piuparts/-/compare/f50b3c7567248bdd7ab79f12a7b4aedb9772460f...1db83cba78a7742c782f3324fecf35adf7cdae20
--
View it on GitLab: https://salsa.debian.org/debian/piuparts/-/compare/f50b3c7567248bdd7ab79f12a7b4aedb9772460f...1db83cba78a7742c782f3324fecf35adf7cdae20
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/piuparts-devel/attachments/20250303/e00015bd/attachment-0001.htm>
More information about the Piuparts-devel
mailing list