Skip to content

Commit

Permalink
Merge pull request #199 from desultory/dev
Browse files Browse the repository at this point in the history
improve merge-usr symlinking, symlink resolution
  • Loading branch information
desultory authored Jan 24, 2025
2 parents d1e0e0d + ee9ca9c commit d7e4668
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 24 deletions.
35 changes: 21 additions & 14 deletions src/ugrd/base/core.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
__author__ = "desultory"
__version__ = "4.1.1"
__version__ = "4.1.3"

from pathlib import Path
from shutil import rmtree, which
Expand Down Expand Up @@ -112,22 +112,25 @@ def calculate_dependencies(self, binary: str) -> list[Path]:

@contains("merge_usr", "Skipping /usr merge", log_level=30)
def handle_usr_symlinks(self) -> None:
"""Adds symlinks for /usr/bin and /usr/sbin to /bin and /sbin.
"""
Adds symlinks for /bin and /sbin to /usr/bin
Adds a symlink for /usr/sbin to /usr/bin (-> bin)
Adds smlinks for /lib to /usr/lib and /lib64 to /usr/lib64
Warns if the symlink path is a directory on the host system.
"""
build_dir = self._get_build_path("/")
bin_dir = Path("bin")
sbin_dir = Path("sbin")
usr_sbin_dir = Path("usr/sbin")

for d in [bin_dir, sbin_dir, usr_sbin_dir]:
if d.is_dir() and not d.is_symlink():
self.logger.warning("Merged-usr symlink target is a directory: %s" % d)
bin_symlink = ("bin", "usr/bin")
sbin_symlink = ("sbin", "usr/bin")
usr_sbin_symlink = ("usr/sbin", "bin") # Make it relative
lib_symlink = ("lib", "usr/lib")
lib64_symlink = ("lib64", "usr/lib64")
symlinks = [bin_symlink, sbin_symlink, usr_sbin_symlink, lib_symlink, lib64_symlink]

for target, source in symlinks:
host_path = Path("/").joinpath(target)
if host_path.is_dir() and not host_path.is_symlink():
self.logger.warning("Host path is a directory: %s" % host_path)
self.logger.warning("Set `merge_usr = false` to disable /usr merge.")
build_d = build_dir / d
if not build_d.is_dir() and not build_d.is_symlink():
self.logger.log(5, "Creating merged-usr symlink to /usr/bin: %s" % build_d)
self._symlink("/usr/bin", d)
self._symlink(source, target)


def deploy_dependencies(self) -> None:
Expand Down Expand Up @@ -359,6 +362,10 @@ def _process_dependencies_multi(self, dependency: Union[Path, str]) -> None:
self["symlinks"][f"_auto_{dependency.name}"] = {"source": resolved_path, "target": dependency}
dependency = resolved_path

if dependency.is_symlink():
dependency = dependency.resolve()
self.logger.debug("Dependency target is a symlink, resolved to: %s" % dependency)

self.logger.debug("Added dependency: %s" % dependency)
self["dependencies"].append(dependency)

Expand Down
6 changes: 4 additions & 2 deletions src/ugrd/fs/cpio.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
__author__ = "desultory"
__version__ = "3.7.1"
__version__ = "3.7.2"

from pathlib import Path
from zenlib.util import contains, unset, colorize

from pycpio.cpio.symlink import CPIO_Symlink
from zenlib.util import colorize, contains, unset


@contains("check_cpio")
Expand Down Expand Up @@ -35,6 +36,7 @@ def _check_in_cpio(self, file, lines=[], quiet=False):
"""Checks that the file is in the CPIO archive, and it contains the specified lines."""
cpio = self._cpio_archive
file = str(file).lstrip("/") # Normalize as it may be a path
self.logger.debug("Checking CPIO for dependency: %s" % file)
if file not in cpio.entries:
fp = Path(file)
while str(fp) not in ["/", "."]:
Expand Down
20 changes: 12 additions & 8 deletions src/ugrd/generator_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from zenlib.util import pretty_print, colorize

__version__ = "1.5.3"
__version__ = "1.5.5"
__author__ = "desultory"


Expand All @@ -13,10 +13,12 @@ def get_subpath(path: Path, subpath: Union[Path, str]) -> Path:
if not isinstance(subpath, Path):
subpath = Path(subpath)

if subpath.is_relative_to(path):
return subpath

if subpath.is_absolute():
return path / subpath.relative_to("/")
else:
return path / subpath
subpath = subpath.relative_to("/")
return path / subpath


class GeneratorHelpers:
Expand Down Expand Up @@ -49,8 +51,9 @@ def _mkdir(self, path: Path, resolve_build=True) -> None:
else:
path_dir = path

if path_dir.is_symlink():
return self.logger.debug("Skipping symlink directory: %s" % path_dir)
while path_dir.is_symlink():
path_dir = self._get_build_path(path_dir.resolve())
self.logger.debug("[%s] Resolved directory symlink: %s" % (path, path_dir))

if not path_dir.parent.is_dir():
self.logger.debug("Parent directory does not exist: %s" % path_dir.parent)
Expand Down Expand Up @@ -122,7 +125,7 @@ def _copy(self, source: Union[Path, str], dest=None) -> None:

while dest_path.parent.is_symlink():
resolved_path = dest_path.parent.resolve() / dest_path.name
self.logger.debug("Resolved symlink: %s -> %s" % (dest_path.parent, resolved_path))
self.logger.debug("Resolved symlink: %s -> %s" % (dest_path, resolved_path))
dest_path = self._get_build_path(resolved_path)

if not dest_path.parent.is_dir():
Expand Down Expand Up @@ -159,7 +162,8 @@ def _symlink(self, source: Union[Path, str], target: Union[Path, str]) -> None:

while target.parent.is_symlink():
self.logger.debug("Resolving target parent symlink: %s" % target.parent)
target = self._get_build_path(target.parent.resolve() / target.name)
resolved_target = target.parent.resolve() / target.name
target = self._get_build_path(resolved_target)

if not target.parent.is_dir():
self.logger.debug("Parent directory for '%s' does not exist: %s" % (target.name, target.parent))
Expand Down

0 comments on commit d7e4668

Please sign in to comment.