aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
authorGravatar Damien Martin-Guillerez <dmarting@google.com>2017-04-20 18:35:44 +0200
committerGravatar Vladimir Moskva <vladmos@google.com>2017-04-24 16:49:14 +0200
commit55928504a6c44629ebc1c54deef6282206def63f (patch)
tree4b7069a0ed7895cb8f8cd4251fb94e015c5c9260 /tools
parent2c4dd1f3176371473667c551cd5a5ae5992f8154 (diff)
Add possibility to set ownership of files on pkg_tar
Change-Id: Ic8c57c0ce78b5875135d5d1f19629ee40fd8f5f2 PiperOrigin-RevId: 153718869
Diffstat (limited to 'tools')
-rw-r--r--tools/build_defs/pkg/BUILD10
-rw-r--r--tools/build_defs/pkg/README.md66
-rw-r--r--tools/build_defs/pkg/build_tar.py72
-rwxr-xr-xtools/build_defs/pkg/build_test.sh47
-rw-r--r--tools/build_defs/pkg/pkg.bzl15
5 files changed, 191 insertions, 19 deletions
diff --git a/tools/build_defs/pkg/BUILD b/tools/build_defs/pkg/BUILD
index 266a2050ba..f735bdc272 100644
--- a/tools/build_defs/pkg/BUILD
+++ b/tools/build_defs/pkg/BUILD
@@ -51,7 +51,7 @@ py_binary(
visibility = ["//visibility:public"],
deps = [
":archive",
- "@bazel_tools//third_party/py/gflags",
+ "//third_party/py/gflags",
],
)
@@ -62,7 +62,7 @@ py_binary(
visibility = ["//visibility:public"],
deps = [
":archive",
- "@bazel_tools//third_party/py/gflags",
+ "//third_party/py/gflags",
],
)
@@ -72,7 +72,7 @@ py_binary(
srcs = ["make_rpm.py"],
visibility = ["//visibility:public"],
deps = [
- "@bazel_tools//third_party/py/gflags",
+ "//third_party/py/gflags",
],
)
@@ -106,6 +106,10 @@ genrule(
],
mode = "0644",
modes = {"usr/titi": "0755"},
+ owner = "42.24",
+ ownername = "titi.tata",
+ ownernames = {"etc/nsswitch.conf": "tata.titi"},
+ owners = {"etc/nsswitch.conf": "24.42"},
package_dir = "/",
strip_prefix = ".",
symlinks = {"usr/bin/java": "/path/to/bin/java"},
diff --git a/tools/build_defs/pkg/README.md b/tools/build_defs/pkg/README.md
index 4369777cd7..4777c79ba6 100644
--- a/tools/build_defs/pkg/README.md
+++ b/tools/build_defs/pkg/README.md
@@ -188,7 +188,71 @@ Creates a tar file from a list of inputs.
<p>
<code>
modes = {
- "tools/py/2to3.sh": "0755
+ "tools/py/2to3.sh": "0755",
+ ...
+ },
+ </code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>owner</code></td>
+ <td>
+ <code>String, default to '0.0'</code>
+ <p>
+ <code>UID.GID</code> to set the default numeric owner for all files
+ provided in <code>files</code>.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>owners</code></td>
+ <td>
+ <code>Dictionary, default to '{}'</code>
+ <p>
+ A string dictionary to change default owner of specific files from
+ <code>files</code>. Each key should be a path to a file before
+ appending the prefix <code>package_dir</code> and the corresponding
+ value the <code>UID.GID</code> numeric string for the owner of the
+ file. When determining owner ids, this attribute is looked first then
+ <code>owner</code>.
+ </p>
+ <p>
+ <code>
+ owners = {
+ "tools/py/2to3.sh": "42.24",
+ ...
+ },
+ </code>
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>ownername</code></td>
+ <td>
+ <code>String, optional</code>
+ <p>
+ <code>username.groupname</code> to set the default owner for all files
+ provided in <code>files</code> (by default there is no owner names).
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>ownernames</code></td>
+ <td>
+ <code>Dictionary, default to '{}'</code>
+ <p>
+ A string dictionary to change default owner of specific files from
+ <code>files</code>. Each key should be a path to a file before
+ appending the prefix <code>package_dir</code> and the corresponding
+ value the <code>username.groupname</code> string for the owner of the
+ file. When determining ownernames, this attribute is looked first then
+ <code>ownername</code>.
+ </p>
+ <p>
+ <code>
+ owners = {
+ "tools/py/2to3.sh": "leeroy.jenkins",
...
},
</code>
diff --git a/tools/build_defs/pkg/build_tar.py b/tools/build_defs/pkg/build_tar.py
index 650b901a1b..74edb588ea 100644
--- a/tools/build_defs/pkg/build_tar.py
+++ b/tools/build_defs/pkg/build_tar.py
@@ -53,6 +53,21 @@ gflags.DEFINE_multistring(
'Specific mode to apply to specific file (from the file argument),'
' e.g., path/to/file=0455.')
+gflags.DEFINE_multistring('owners', None,
+ 'Specify the numeric owners of individual files, '
+ 'e.g. path/to/file=0.0.')
+
+gflags.DEFINE_string('owner', '0.0',
+ 'Specify the numeric default owner of all files,'
+ ' e.g., 0.0')
+
+gflags.DEFINE_string('owner_name', None,
+ 'Specify the owner name of all files, e.g. root.root.')
+
+gflags.DEFINE_multistring('owner_names', None,
+ 'Specify the owner names of individual files, e.g. '
+ 'path/to/file=root.root.')
+
FLAGS = gflags.FLAGS
@@ -74,7 +89,7 @@ class TarFile(object):
def __exit__(self, t, v, traceback):
self.tarfile.close()
- def add_file(self, f, destfile, mode=None):
+ def add_file(self, f, destfile, mode=None, ids=None, names=None):
"""Add a file to the tar file.
Args:
@@ -82,6 +97,8 @@ class TarFile(object):
destfile: the name of the file in the layer
mode: force to set the specified mode, by
default the value from the source is taken.
+ ids: (uid, gid) for the file to set ownership
+ names: (username, groupname) for the file to set ownership.
`f` will be copied to `self.directory/destfile` in the layer.
"""
dest = destfile.lstrip('/') # Remove leading slashes
@@ -90,7 +107,18 @@ class TarFile(object):
# If mode is unspecified, derive the mode from the file's mode.
if mode is None:
mode = 0o755 if os.access(f, os.X_OK) else 0o644
- self.tarfile.add_file(dest, file_content=f, mode=mode)
+ if ids is None:
+ ids = (0, 0)
+ if names is None:
+ names = ('', '')
+ self.tarfile.add_file(
+ dest,
+ file_content=f,
+ mode=mode,
+ uid=ids[0],
+ gid=ids[1],
+ uname=names[0],
+ gname=names[1])
def add_tar(self, tar):
"""Merge a tar file into the destination tar file.
@@ -157,16 +185,46 @@ def main(unused_argv):
f = f[1:]
mode_map[f] = int(mode, 8)
+ default_ownername = ('', '')
+ if FLAGS.owner_name:
+ default_ownername = FLAGS.owner_name.split('.', 1)
+ names_map = {}
+ if FLAGS.owner_names:
+ for file_owner in FLAGS.owner_names:
+ (f, owner) = file_owner.split('=', 1)
+ (user, group) = owner.split('.', 1)
+ if f[0] == '/':
+ f = f[1:]
+ names_map[f] = (user, group)
+
+ default_ids = FLAGS.owner.split('.', 1)
+ default_ids = (int(default_ids[0]), int(default_ids[1]))
+ ids_map = {}
+ if FLAGS.owners:
+ for file_owner in FLAGS.owners:
+ (f, owner) = file_owner.split('=', 1)
+ (user, group) = owner.split('.', 1)
+ if f[0] == '/':
+ f = f[1:]
+ ids_map[f] = (int(user), int(group))
+
# Add objects to the tar file
with TarFile(FLAGS.output, FLAGS.directory, FLAGS.compression) as output:
for f in FLAGS.file:
(inf, tof) = f.split('=', 1)
mode = default_mode
- if tof[0] == '/' and (tof[1:] in mode_map):
- mode = mode_map[tof[1:]]
- elif tof in mode_map:
- mode = mode_map[tof]
- output.add_file(inf, tof, mode)
+ ids = default_ids
+ names = default_ownername
+ map_filename = tof
+ if tof[0] == '/':
+ map_filename = tof[1:]
+ if map_filename in mode_map:
+ mode = mode_map[map_filename]
+ if map_filename in ids_map:
+ ids = ids_map[map_filename]
+ if map_filename in names_map:
+ names = names_map[map_filename]
+ output.add_file(inf, tof, mode, ids, names)
for tar in FLAGS.tar:
output.add_tar(tar)
for deb in FLAGS.deb:
diff --git a/tools/build_defs/pkg/build_test.sh b/tools/build_defs/pkg/build_test.sh
index b4c3b16bae..ee8337cafa 100755
--- a/tools/build_defs/pkg/build_test.sh
+++ b/tools/build_defs/pkg/build_test.sh
@@ -25,6 +25,20 @@ function get_tar_listing() {
tar tvf "${test_data}" | sed -e 's/^.*:00 //'
}
+function get_tar_owner() {
+ local input=$1
+ local file=$2
+ local test_data="${TEST_DATA_DIR}/${input}"
+ tar tvf "${test_data}" | grep "00 $file\$" | cut -d " " -f 2
+}
+
+function get_numeric_tar_owner() {
+ local input=$1
+ local file=$2
+ local test_data="${TEST_DATA_DIR}/${input}"
+ tar --numeric-owner -tvf "${test_data}" | grep "00 $file\$" | cut -d " " -f 2
+}
+
function get_tar_permission() {
local input=$1
local file=$2
@@ -82,6 +96,29 @@ function get_changes() {
cat "${TEST_DATA_DIR}/${input}"
}
+function assert_content() {
+ local listing="./
+./etc/
+./etc/nsswitch.conf
+./usr/
+./usr/titi
+./usr/bin/
+./usr/bin/java -> /path/to/bin/java"
+ check_eq "$listing" "$(get_tar_listing $1)"
+ check_eq "-rwxr-xr-x" "$(get_tar_permission $1 ./usr/titi)"
+ check_eq "-rw-r--r--" "$(get_tar_permission $1 ./etc/nsswitch.conf)"
+ check_eq "24/42" "$(get_numeric_tar_owner $1 ./etc/)"
+ check_eq "24/42" "$(get_numeric_tar_owner $1 ./etc/nsswitch.conf)"
+ check_eq "42/24" "$(get_numeric_tar_owner $1 ./usr/)"
+ check_eq "42/24" "$(get_numeric_tar_owner $1 ./usr/titi)"
+ if [ -z "${2-}" ]; then
+ check_eq "tata/titi" "$(get_tar_owner $1 ./etc/)"
+ check_eq "tata/titi" "$(get_tar_owner $1 ./etc/nsswitch.conf)"
+ check_eq "titi/tata" "$(get_tar_owner $1 ./usr/)"
+ check_eq "titi/tata" "$(get_tar_owner $1 ./usr/titi)"
+ fi
+}
+
function test_tar() {
local listing="./
./etc/
@@ -91,13 +128,11 @@ function test_tar() {
./usr/bin/
./usr/bin/java -> /path/to/bin/java"
for i in "" ".gz" ".bz2" ".xz"; do
- check_eq "$listing" "$(get_tar_listing test-tar-${i:1}.tar$i)"
- check_eq "-rwxr-xr-x" "$(get_tar_permission test-tar-${i:1}.tar$i ./usr/titi)"
- check_eq "-rw-r--r--" "$(get_tar_permission test-tar-${i:1}.tar$i ./etc/nsswitch.conf)"
+ assert_content "test-tar-${i:1}.tar$i"
# Test merging tar files
- check_eq "$listing" "$(get_tar_listing test-tar-inclusion-${i:1}.tar)"
- check_eq "-rwxr-xr-x" "$(get_tar_permission test-tar-inclusion-${i:1}.tar ./usr/titi)"
- check_eq "-rw-r--r--" "$(get_tar_permission test-tar-inclusion-${i:1}.tar ./etc/nsswitch.conf)"
+ # We pass a second argument to not test for user and group
+ # names because tar merging ask for numeric owners.
+ assert_content "test-tar-inclusion-${i:1}.tar" "true"
done;
check_eq "./
diff --git a/tools/build_defs/pkg/pkg.bzl b/tools/build_defs/pkg/pkg.bzl
index b462fa3e66..43ca46c2d7 100644
--- a/tools/build_defs/pkg/pkg.bzl
+++ b/tools/build_defs/pkg/pkg.bzl
@@ -28,11 +28,18 @@ def _pkg_tar_impl(ctx):
"--output=" + ctx.outputs.out.path,
"--directory=" + ctx.attr.package_dir,
"--mode=" + ctx.attr.mode,
+ "--owner=" + ctx.attr.owner,
+ "--owner_name=" + ctx.attr.ownername,
]
args += ["--file=%s=%s" % (f.path, dest_path(f, data_path))
for f in ctx.files.files]
if ctx.attr.modes:
args += ["--modes=%s=%s" % (key, ctx.attr.modes[key]) for key in ctx.attr.modes]
+ if ctx.attr.owners:
+ args += ["--owners=%s=%s" % (key, ctx.attr.owners[key]) for key in ctx.attr.owners]
+ if ctx.attr.ownernames:
+ args += ["--owner_names=%s=%s" % (key, ctx.attr.ownernames[key])
+ for key in ctx.attr.ownernames]
if ctx.attr.extension:
dotPos = ctx.attr.extension.find('.')
if dotPos > 0:
@@ -154,11 +161,15 @@ pkg_tar = rule(
"files": attr.label_list(allow_files=True),
"mode": attr.string(default="0555"),
"modes": attr.string_dict(),
+ "owner": attr.string(default="0.0"),
+ "ownername": attr.string(default="."),
+ "owners": attr.string_dict(),
+ "ownernames": attr.string_dict(),
"extension": attr.string(default="tar"),
"symlinks": attr.string_dict(),
# Implicit dependencies.
"build_tar": attr.label(
- default=Label("@bazel_tools//tools/build_defs/pkg:build_tar"),
+ default=Label("//tools/build_defs/pkg:build_tar"),
cfg="host",
executable=True,
allow_files=True)
@@ -202,7 +213,7 @@ pkg_deb = rule(
"recommends": attr.string_list(default=[]),
# Implicit dependencies.
"make_deb": attr.label(
- default=Label("@bazel_tools//tools/build_defs/pkg:make_deb"),
+ default=Label("//tools/build_defs/pkg:make_deb"),
cfg="host",
executable=True,
allow_files=True)