aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--tools/build_defs/pkg/BUILD22
-rw-r--r--tools/build_defs/pkg/build_tar.py82
-rwxr-xr-xtools/build_defs/pkg/build_test.sh16
-rw-r--r--tools/build_defs/pkg/pkg.bzl6
4 files changed, 113 insertions, 13 deletions
diff --git a/tools/build_defs/pkg/BUILD b/tools/build_defs/pkg/BUILD
index 2f55d7fd0e..cae1a4a03a 100644
--- a/tools/build_defs/pkg/BUILD
+++ b/tools/build_defs/pkg/BUILD
@@ -174,6 +174,26 @@ pkg_tar(
},
)
+pkg_tar(
+ name = "test-tar-empty_files",
+ build_tar = ":build_tar",
+ empty_files = [
+ "/a",
+ "/b",
+ ],
+ mode = "0o777",
+)
+
+pkg_tar(
+ name = "test-tar-empty_dirs",
+ build_tar = ":build_tar",
+ empty_dirs = [
+ "/tmp",
+ "/pmt",
+ ],
+ mode = "0o777",
+)
+
pkg_deb(
name = "test-deb",
conffiles = [
@@ -205,6 +225,8 @@ sh_test(
":test-deb.deb",
":test-tar-.tar",
":test-tar-bz2.tar.bz2",
+ ":test-tar-empty_dirs.tar",
+ ":test-tar-empty_files.tar",
":test-tar-files_dict.tar",
":test-tar-gz.tar.gz",
":test-tar-inclusion-.tar",
diff --git a/tools/build_defs/pkg/build_tar.py b/tools/build_defs/pkg/build_tar.py
index a07fd43fb2..e5428041a3 100644
--- a/tools/build_defs/pkg/build_tar.py
+++ b/tools/build_defs/pkg/build_tar.py
@@ -30,6 +30,10 @@ gflags.DEFINE_multistring('file', [], 'A file to add to the layer')
gflags.DEFINE_string(
'mode', None, 'Force the mode on the added files (in octal).')
+gflags.DEFINE_multistring('empty_file', [], 'An empty file to add to the layer')
+
+gflags.DEFINE_multistring('empty_dir', [], 'An empty dir to add to the layer')
+
gflags.DEFINE_multistring('tar', [], 'A tar file to add to the layer')
gflags.DEFINE_multistring('deb', [], 'A debian package to add to the layer')
@@ -121,6 +125,56 @@ class TarFile(object):
uname=names[0],
gname=names[1])
+ def add_empty_file(self,
+ destfile,
+ mode=None,
+ ids=None,
+ names=None,
+ kind=tarfile.REGTYPE):
+ """Add a file to the tar file.
+
+ Args:
+ destfile: the name of the file in the layer
+ mode: force to set the specified mode, defaults to 644
+ ids: (uid, gid) for the file to set ownership
+ names: (username, groupname) for the file to set ownership.
+ kind: type of the file. tarfile.DIRTYPE for directory.
+
+ An empty file will be created as `destfile` in the layer.
+ """
+ dest = destfile.lstrip('/') # Remove leading slashes
+ # If mode is unspecified, assume read only
+ if mode is None:
+ mode = 0o644
+ if ids is None:
+ ids = (0, 0)
+ if names is None:
+ names = ('', '')
+ dest = os.path.normpath(dest)
+ self.tarfile.add_file(
+ dest,
+ content='' if kind == tarfile.REGTYPE else None,
+ kind=kind,
+ mode=mode,
+ uid=ids[0],
+ gid=ids[1],
+ uname=names[0],
+ gname=names[1])
+
+ def add_empty_dir(self, destpath, mode=None, ids=None, names=None):
+ """Add a directory to the tar file.
+
+ Args:
+ destpath: the name of the directory in the layer
+ mode: force to set the specified mode, defaults to 644
+ ids: (uid, gid) for the file to set ownership
+ names: (username, groupname) for the file to set ownership.
+
+ An empty file will be created as `destfile` in the layer.
+ """
+ self.add_empty_file(
+ destpath, mode=mode, ids=ids, names=names, kind=tarfile.DIRTYPE)
+
def add_tar(self, tar):
"""Merge a tar file into the destination tar file.
@@ -212,21 +266,23 @@ def main(unused_argv):
# Add objects to the tar file
with TarFile(FLAGS.output, FLAGS.directory, FLAGS.compression) as output:
+
+ def file_attributes(filename):
+ if filename[0] == '/':
+ filename = filename[1:]
+ return {
+ 'mode': mode_map.get(filename, default_mode),
+ 'ids': ids_map.get(filename, default_ids),
+ 'names': names_map.get(filename, default_ownername),
+ }
+
for f in FLAGS.file:
(inf, tof) = f.split('=', 1)
- mode = default_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)
+ output.add_file(inf, tof, **file_attributes(tof))
+ for f in FLAGS.empty_file:
+ output.add_empty_file(f, **file_attributes(f))
+ for f in FLAGS.empty_dir:
+ output.add_empty_dir(f, **file_attributes(f))
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 1322f5006d..99bae8e8fc 100755
--- a/tools/build_defs/pkg/build_test.sh
+++ b/tools/build_defs/pkg/build_test.sh
@@ -22,9 +22,17 @@ source ${DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; }
function get_tar_listing() {
local input=$1
local test_data="${TEST_DATA_DIR}/${input}"
+ # We strip unused prefixes rather than dropping "v" flag for tar, because we
+ # want to preserve symlink information.
tar tvf "${test_data}" | sed -e 's/^.*:00 //'
}
+function get_tar_verbose_listing() {
+ local input=$1
+ local test_data="${TEST_DATA_DIR}/${input}"
+ TZ="UTC" tar tvf "${test_data}"
+}
+
function get_tar_owner() {
local input=$1
local file=$2
@@ -147,6 +155,14 @@ function test_tar() {
check_eq "./
./not-etc/
./not-etc/mapped-filename.conf" "$(get_tar_listing test-tar-files_dict.tar)"
+ check_eq "drwxr-xr-x 0/0 0 1970-01-01 00:00 ./
+-rwxrwxrwx 0/0 0 1970-01-01 00:00 ./a
+-rwxrwxrwx 0/0 0 1970-01-01 00:00 ./b" \
+ "$(get_tar_verbose_listing test-tar-empty_files.tar)"
+ check_eq "drwxr-xr-x 0/0 0 1970-01-01 00:00 ./
+drwxrwxrwx 0/0 0 1970-01-01 00:00 ./tmp/
+drwxrwxrwx 0/0 0 1970-01-01 00:00 ./pmt/" \
+ "$(get_tar_verbose_listing test-tar-empty_dirs.tar)"
}
function test_deb() {
diff --git a/tools/build_defs/pkg/pkg.bzl b/tools/build_defs/pkg/pkg.bzl
index b12814dea7..24840eefbd 100644
--- a/tools/build_defs/pkg/pkg.bzl
+++ b/tools/build_defs/pkg/pkg.bzl
@@ -47,6 +47,10 @@ def _pkg_tar_impl(ctx):
if ctx.attr.ownernames:
args += ["--owner_names=%s=%s" % (key, ctx.attr.ownernames[key])
for key in ctx.attr.ownernames]
+ if ctx.attr.empty_files:
+ args += ["--empty_file=%s" % empty_file for empty_file in ctx.attr.empty_files]
+ if ctx.attr.empty_dirs:
+ args += ["--empty_dir=%s" % empty_dir for empty_dir in ctx.attr.empty_dirs]
if ctx.attr.extension:
dotPos = ctx.attr.extension.find('.')
if dotPos > 0:
@@ -175,6 +179,8 @@ _real_pkg_tar = rule(
"ownernames": attr.string_dict(),
"extension": attr.string(default="tar"),
"symlinks": attr.string_dict(),
+ "empty_files": attr.string_list(),
+ "empty_dirs": attr.string_list(),
# Implicit dependencies.
"build_tar": attr.label(
default=Label("//tools/build_defs/pkg:build_tar"),