]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Use --keep-directory-symlink from cp 9.5 onwards
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 23 Feb 2024 10:48:11 +0000 (11:48 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 23 Feb 2024 13:27:23 +0000 (14:27 +0100)
--keep-directory-symlink instructs cp to not fail when trying to
copy a directory onto a symlink but to follow the symlink instead.

The patch to introduce it was merged into coreutils and will be
available from coreutils 9.5 onwards.

--copy-contents has to be added as well to make
--keep-directory-symlink work. --copy-contents is generally harmless
for our use cases and won't change anything.

We also make sure gpg creates its sockets in /run instead of the
gpg homedir so they don't become part of the image. gpg automatically
uses /run if /run/user/uid exists so we create /run/user/0 to satisfy
that check.

Fixes #2168

mkosi/sandbox.py
mkosi/tree.py

index 15bf449f309a02b8d81df68dcbcba57cdc499641..f716effad16332bc068e1c2b6ad48bb758a0c08c 100644 (file)
@@ -202,6 +202,8 @@ def apivfs_cmd(root: Path) -> list[PathString]:
         "--dev", root / "dev",
         # Make sure /etc/machine-id is not overwritten by any package manager post install scripts.
         "--ro-bind-try", root / "etc/machine-id", root / "etc/machine-id",
+        # Nudge gpg to create its sockets in /run by making sure /run/user/0 exists.
+        "--dir", root / "run/user/0",
         *finalize_passwd_mounts(root),
         "sh", "-c",
         f"chmod 1777 {root / 'tmp'} {root / 'var/tmp'} {root / 'dev/shm'} && "
index e744909dddac2840ad23c56bf04787665ea6741a..a6af3a171bfae46c5eea78cd8d6ea501d240c02d 100644 (file)
@@ -14,6 +14,7 @@ from mkosi.run import find_binary, run
 from mkosi.sandbox import SandboxProtocol, nosandbox
 from mkosi.types import PathString
 from mkosi.util import flatten
+from mkosi.versioncomp import GenericVersion
 
 
 def statfs(path: Path, *, sandbox: SandboxProtocol = nosandbox) -> str:
@@ -25,6 +26,10 @@ def is_subvolume(path: Path, *, sandbox: SandboxProtocol = nosandbox) -> bool:
     return path.is_dir() and statfs(path, sandbox=sandbox) == "btrfs" and path.stat().st_ino == 256
 
 
+def cp_version() -> GenericVersion:
+    return GenericVersion(run(["cp", "--version"], stdout=subprocess.PIPE).stdout.splitlines()[0].split()[3])
+
+
 def make_tree(
     path: Path,
     *,
@@ -92,8 +97,12 @@ def copy_tree(
         "--dereference" if dereference else "--no-dereference",
         f"--preserve=mode,links{',timestamps,ownership,xattr' if preserve else ''}",
         "--reflink=auto",
+        "--copy-contents",
         src, dst,
     ]
+    if cp_version() >= "9.5":
+        copy += ["--keep-directory-symlink"]
+
     options: list[PathString] = ["--ro-bind", src, src, "--bind", dst.parent, dst.parent]
 
     # If the source and destination are both directories, we want to merge the source directory with the