diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2017-04-20 18:35:44 +0200 |
---|---|---|
committer | Vladimir Moskva <vladmos@google.com> | 2017-04-24 16:49:14 +0200 |
commit | 55928504a6c44629ebc1c54deef6282206def63f (patch) | |
tree | 4b7069a0ed7895cb8f8cd4251fb94e015c5c9260 /tools | |
parent | 2c4dd1f3176371473667c551cd5a5ae5992f8154 (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/BUILD | 10 | ||||
-rw-r--r-- | tools/build_defs/pkg/README.md | 66 | ||||
-rw-r--r-- | tools/build_defs/pkg/build_tar.py | 72 | ||||
-rwxr-xr-x | tools/build_defs/pkg/build_test.sh | 47 | ||||
-rw-r--r-- | tools/build_defs/pkg/pkg.bzl | 15 |
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) |