Skip to content

Commit 7d7c397

Browse files
authored
Merge pull request #301 from desultory/dev
improve logging when ldconfig cannot be used, musl detection
2 parents 0724741 + e8bb929 commit 7d7c397

File tree

1 file changed

+44
-22
lines changed

1 file changed

+44
-22
lines changed

src/ugrd/base/core.py

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
__author__ = "desultory"
2-
__version__ = "4.6.0"
2+
__version__ = "4.7.0"
33

44
from os import environ, makedev, mknod, uname
55
from pathlib import Path
@@ -28,6 +28,12 @@ class DecompressorError(Exception):
2828
pass
2929

3030

31+
class LDConfigError(Exception):
32+
"""Custom exception for ldconfig errors."""
33+
34+
pass
35+
36+
3137
def get_tmpdir(self) -> None:
3238
"""Reads TMPDIR from the environment, sets it as the temporary directory."""
3339
if tmpdir := environ.get("TMPDIR"):
@@ -303,35 +309,40 @@ def deploy_nodes(self) -> None:
303309
raise e
304310

305311

306-
@unset("musl_libc", "Skipping libgcc_s dependency resolution, musl_libc is enabled.", log_level=20)
307-
@contains("find_libgcc", "Skipping libgcc_s dependency resolution", log_level=20)
308-
def autodetect_libgcc(self) -> None:
309-
"""Finds libgcc.so, adds a 'dependencies' item for it.
310-
Adds the parent directory to 'library_paths'
311-
"""
312-
musl_warning = False
312+
def _get_ldconfig(self) -> list:
313+
"""Returns the ldconfig command if it exists, otherwise raise an LDConfigError."""
313314
try:
314315
cmd = self._run(["ldconfig", "-p"], fail_silent=True, fail_hard=False)
315316
except FileNotFoundError:
316-
musl_warning = True
317+
self.logger.warning("If musl libc is being used, `musl_libc = true` should be set in the config.")
318+
raise LDConfigError("ldconfig not found, unable to resolve libraries.")
317319

318-
if not musl_warning and b"Unimplemented option: -p" in cmd.stderr: # Probably musl libc
319-
musl_warning = True
320-
321-
if musl_warning:
322-
self.logger.warning(
323-
"This check can be disabled by setting `musl_libc = true` or `find_libgcc = false` in the configuration."
324-
)
325-
return self.logger.warning("Unable to run ldconfig -p, if glibc is being used, this is fatal!")
320+
if b"Unimplemented option: -p" in cmd.stderr: # Probably musl libc
321+
self.logger.warning("If musl libc is being used, `musl_libc = true` should be set in the config.")
322+
raise LDConfigError("ldconfig -p not supported, musl libc is likely in use.")
326323

327324
if cmd.returncode != 0:
328-
return self.logger.critical("Unable to run ldconfig -p, if glibc is being used, this is fatal!")
325+
raise LDConfigError("ldconfig failed to run: %s" % cmd.stderr.decode("utf-8"))
326+
327+
return cmd.stdout.decode("utf-8").splitlines()
329328

330-
ldconfig = cmd.stdout.decode("utf-8").splitlines()
329+
330+
@unset("musl_libc", "Skipping libgcc_s dependency resolution, musl_libc is enabled.", log_level=20)
331+
@contains("find_libgcc", "Skipping libgcc_s dependency resolution", log_level=20)
332+
def autodetect_libgcc(self) -> None:
333+
"""Finds libgcc.so, adds a 'dependencies' item for it.
334+
Adds the parent directory to 'library_paths'
335+
"""
336+
try:
337+
ldconfig = _get_ldconfig(self)
338+
except LDConfigError:
339+
self.logger.warning("Unable to run ldconfig -p, if glibc is being used, this is fatal!")
340+
self.logger.warning("If libgcc_s is not required, set `find_libgcc = false` in the configuration.")
341+
return
331342

332343
libgcc = [lib for lib in ldconfig if "libgcc_s" in lib and "(libc6," in lib][0]
333344
source_path = Path(libgcc.partition("=> ")[-1])
334-
self.logger.info("Source path for libgcc_s: %s" % source_path)
345+
self.logger.info(f"Source path for libgcc_s: {c_(source_path, 'green')}")
335346

336347
self["dependencies"] = source_path
337348
self["library_paths"] = str(source_path.parent)
@@ -344,15 +355,26 @@ def autodetect_musl(self) -> None:
344355
arch = uname().machine
345356
musl_path = Path(f"/etc/ld-musl-{arch}.path")
346357
if musl_path.exists():
347-
self.logger.info("Detected musl search path: %s" % c_(musl_path, "cyan"))
358+
self.logger.info(f"Detected musl search path: {c_(musl_path, 'green')}")
348359
self["dependencies"] = musl_path
349360
elif self["musl_libc"]:
350361
raise AutodetectError("Musl libc is enabled, but the musl search path was not found: %s" % musl_path)
351362

352363

353364
@unset("musl_libc", "Skipping ld.so.cache regeneration, musl_libc is enabled.", log_level=30)
354365
def regen_ld_so_cache(self) -> None:
355-
"""Regenerates the ld.so.cache file in the build dir. Uses defined library paths to generate the config"""
366+
"""
367+
Checks if a 'real' ldconfig is available, if so, regenerates the ld.so.cache file in the build dir.
368+
Uses defined library paths to generate the config file.
369+
370+
If ldconfig is not available, _get_ldconfiig will warn about setting `musl_libc` to true.
371+
Here, warn about this and that this is a fatal error if glibc is being used.
372+
"""
373+
try:
374+
_get_ldconfig(self)
375+
except LDConfigError:
376+
return self.logger.warning("Unable to run ldconfig -p, if glibc is being used, this is fatal!")
377+
356378
self.logger.info("Regenerating ld.so.cache")
357379
self._write("etc/ld.so.conf", self["library_paths"])
358380
build_path = self._get_build_path("/")

0 commit comments

Comments
 (0)