in pkg/private/tar/build_tar.py [0:0]
def add_tree(self, tree_top, destpath, mode=None, ids=None, names=None):
"""Add a tree artifact to the tar file.
Args:
tree_top: the top of the tree to add
destpath: the path under which to place the files
mode: (int) force to set the specified posix mode (e.g. 0o755). The
default is derived from the source
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.
"""
# We expect /-style paths.
tree_top = os.path.normpath(tree_top).replace(os.path.sep, '/')
dest = destpath.strip('/') # redundant, dests should never have / here
if self.directory and self.directory != '/':
dest = self.directory.lstrip('/') + '/' + dest
# Again, we expect /-style paths.
dest = os.path.normpath(dest).replace(os.path.sep, '/')
if ids is None:
ids = (0, 0)
if names is None:
names = ('', '')
to_write = {}
for root, dirs, files in os.walk(tree_top):
# While `tree_top` uses '/' as a path separator, results returned by
# `os.walk` and `os.path.join` on Windows may not.
root = os.path.normpath(root).replace(os.path.sep, '/')
dirs = sorted(dirs)
rel_path_from_top = root[len(tree_top):].lstrip('/')
if rel_path_from_top:
dest_dir = dest + '/' + rel_path_from_top + '/'
else:
dest_dir = dest + '/'
for dir in dirs:
to_write[dest_dir + dir] = None
for file in sorted(files):
to_write[dest_dir + file] = root + '/' + file
for path in sorted(to_write.keys()):
content_path = to_write[path]
# If mode is unspecified, derive the mode from the file's mode.
if mode is None:
f_mode = 0o755 if os.access(content_path, os.X_OK) else 0o644
else:
f_mode = mode
if not content_path:
self.add_empty_file(
path,
mode=f_mode,
ids=ids,
names=names,
kind=tarfile.DIRTYPE)
else:
self.tarfile.add_file(
path,
file_content=content_path,
mode=f_mode,
uid=ids[0],
gid=ids[1],
uname=names[0],
gname=names[1])