Skip to content

Commit 4eed546

Browse files
aiutoapsaltis-ddog
andauthored
Implement pkg_install(symlink) (#979)
* Implement pkg_install(symlink) A first attempt at pgk_install of symlinks. It was pretty obvious code once I realized I needed os.lchmod() * fix use of cc_binary in the test because things changed under us * old python on buildkit * revert unintentional python reformating * Update pkg/private/install.py.tpl Co-authored-by: Andrew Psaltis <[email protected]> --------- Co-authored-by: Andrew Psaltis <[email protected]>
1 parent 28755e7 commit 4eed546

File tree

4 files changed

+38
-7
lines changed

4 files changed

+38
-7
lines changed

pkg/private/install.py.tpl

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,21 @@ class NativeInstaller(object):
9999
os.makedirs(dirname, int(mode, 8), exist_ok=True)
100100

101101
def _do_symlink(self, target, link_name, mode, user, group):
102-
raise NotImplementedError("symlinking not yet supported")
102+
logging.debug("SYMLINK %s <- %s", link_name, target)
103+
os.symlink(target, link_name)
104+
if mode:
105+
if hasattr(os, "lchmod"):
106+
logging.debug("CHMOD %s %s", mode, link_name)
107+
os.lchmod(link_name, int(mode, 8))
108+
else:
109+
logging.debug("CHMOD-NOT AVAILABLE %s %s", mode, link_name)
110+
if user or group:
111+
# Ownership can only be changed by sufficiently
112+
# privileged users.
113+
# TODO(nacl): This does not support windows
114+
if hasattr(os, "lchown") and os.getuid() == 0:
115+
logging.debug("CHOWN %s:%s %s", user, group, link_name)
116+
os.lchown(link_name, user, group)
103117

104118
def _maybe_make_unowned_dir(self, path):
105119
logging.debug("MKDIR (unowned) %s", path)
@@ -161,10 +175,8 @@ class NativeInstaller(object):
161175
self._chown_chmod(entry.dest, top_dir_mode, entry.user, entry.group)
162176

163177
def _install_symlink(self, entry):
164-
raise NotImplementedError("symlinking not yet supported")
165-
logging.debug("SYMLINK %s <- %s", entry.dest, entry.link_to)
166-
logging.debug("CHMOD %s %s", entry.dest, entry.mode)
167-
logging.debug("CHOWN %s.%s %s", entry.dest, entry.user, entry.group)
178+
self._maybe_make_unowned_dir(os.path.dirname(entry.dest))
179+
self._do_symlink(entry.src, entry.dest, entry.mode, entry.user, entry.group)
168180

169181
def include_manifest_path(self, path):
170182
with open(path, 'r') as fh:

tests/install/BUILD

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
load("@rules_python//python:defs.bzl", "py_test")
1616
load("//pkg:install.bzl", "pkg_install")
17-
load("//pkg:mappings.bzl", "pkg_attributes", "pkg_files", "pkg_mkdirs")
17+
load("//pkg:mappings.bzl", "pkg_attributes", "pkg_files", "pkg_mkdirs", "pkg_mklink")
1818
load("//tests/util:defs.bzl", "directory", "fake_artifact")
1919

2020
package(default_applicable_licenses = ["//:license"])
@@ -47,6 +47,8 @@ pkg_install(
4747
":artifact-in-owned-dir",
4848
":artifact-in-unowned-dir",
4949
":dirs",
50+
":fake_lib_link",
51+
":fake_so_in_lib",
5052
":generate_tree_pkg_files",
5153
],
5254
)
@@ -97,3 +99,19 @@ pkg_files(
9799
mode = "640",
98100
),
99101
)
102+
103+
fake_artifact(
104+
name = "fake.so.1.2.3",
105+
)
106+
107+
pkg_files(
108+
name = "fake_so_in_lib",
109+
srcs = [":fake.so.1.2.3"],
110+
prefix = "/lib",
111+
)
112+
113+
pkg_mklink(
114+
name = "fake_lib_link",
115+
link_name = "/lib/fake.so.1",
116+
target = "fake.so.1.2.3",
117+
)

tests/install/test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def assertEntryModeMatches(self, entry, actual_path,
8787
if os.name == 'nt':
8888
return
8989

90-
actual_mode = stat.S_IMODE(os.stat(actual_path).st_mode)
90+
actual_mode = stat.S_IMODE(os.stat(actual_path, follow_symlinks=False).st_mode)
9191
expected_mode = int(entry.mode, 8)
9292

9393
if (not is_tree_artifact_content and

tests/rpm/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
load("@bazel_skylib//rules:build_test.bzl", "build_test")
1717
load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
18+
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
1819
load("@rules_python//python:defs.bzl", "py_library", "py_test")
1920
load("@rules_shell//shell:sh_library.bzl", "sh_library")
2021
load(

0 commit comments

Comments
 (0)