fix: use --ignore instead of separate provider call to prevent init conflict

Using --ignore=elogind-dinit (and alphabetically-before providers for
other inits) prevents pacman --noconfirm from resolving init-logind
to the wrong provider. This is more robust than installing the
provider separately, which can fail if base's deps are missing.
This commit is contained in:
2026-07-05 21:41:53 +02:00
parent 4e32d1de61
commit fe4e86257b
2 changed files with 26 additions and 10 deletions
+10 -5
View File
@@ -97,12 +97,17 @@ make_rootfs() {
args+=(-P)
fi
# Install init-logind provider BEFORE base to avoid pacman picking
# the wrong one alphabetically (elogind-dinit < elogind-openrc),
# which pulls in dinit -> dinit-rc and conflicts with openrc.
basestrap "${basestrap_args[@]}" "${args[@]}" "${rootfs}" "elogind-${INITSYS}" --overwrite='*'
# Ignore init-logind providers alphabetically before the selected
# init to prevent pacman --noconfirm from pulling in the wrong one
# (elogind-dinit < elogind-openrc) and its conflicting deps.
local ignore_args=()
case "${INITSYS}" in
openrc) ignore_args=("--ignore=elogind-dinit") ;;
runit) ignore_args=("--ignore=elogind-dinit" "--ignore=elogind-openrc") ;;
s6) ignore_args=("--ignore=elogind-dinit" "--ignore=elogind-openrc" "--ignore=elogind-runit") ;;
esac
basestrap "${basestrap_args[@]}" "${args[@]}" "${rootfs}" "${packages[@]}" --overwrite='*'
basestrap "${basestrap_args[@]}" "${args[@]}" "${rootfs}" "${packages[@]}" --overwrite='*' "${ignore_args[@]}"
copy_overlay "${root_overlay}" "${rootfs}"
@@ -343,6 +343,20 @@ class PMPacman(PackageManager):
# Don't report download progress for each file
command.append("--noprogressbar")
# Ignore init-logind providers that come alphabetically before
# the selected one, preventing pacman --noconfirm from picking
# the wrong one and pulling in a conflicting init system.
if libcalamares.globalstorage.contains("baseInit"):
base_init = libcalamares.globalstorage.value("baseInit")
provider = libcalamares.globalstorage.value("initProvider")
if base_init and provider:
sorted_inits = ["dinit", "openrc", "runit", "s6"]
if provider in sorted_inits:
idx = sorted_inits.index(provider)
for p in sorted_inits[:idx]:
ignore_pkg = f"{base_init}-{p}"
command.append(f"--ignore={ignore_pkg}")
if self.pacman_needed_only:
command.append("--needed")
@@ -542,12 +556,9 @@ def run():
if provider in known_inits:
init_pkg = "-".join([base_init, provider])
libcalamares.utils.debug("Init provider package added: {!s}".format(init_pkg))
# Install init-logind provider BEFORE base so pacman doesn't
# pick the wrong one alphabetically (elogind-dinit comes before
# elogind-openrc), which would pull in dinit+dinit-rc and
# conflict with openrc via the init-rc virtual.
operations.insert(0, {"install": [init_pkg]})
operations[0]["install"].append(init_pkg)
libcalamares.globalstorage.insert("initProvider", provider)
libcalamares.globalstorage.insert("baseInit", base_init)
break
libcalamares.globalstorage.insert("packageOperationsBasestrap", operations)