From 31dbe34f10a772c47d2fde781e3ed9e0db268923 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Thu, 6 Jun 2013 13:59:58 -0400 Subject: [PATCH 1/2] feat(build_image): Record directories installed in stateful_partition During builds var_overlay is always mounted over /var. We want to do the same at run time but we also want to ensure everything expected to be there always does. After emerge completes gen_tmpfiles.py will scan /var for any .keep files that were installed and records their parent directories' permissions and ownership to /usr/lib/tmpfiles.d. On each boot systemd will automatically recreate anything that goes missing. This also means that going forward any ebuild that needs a directory in /var (or anywhere else the stateful partition is bound) can simply rely on the 'keepdir' ebuild function instead of adding things to coreos_startup. --- build_library/base_image_util.sh | 5 ++ gen_tmpfiles.py | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100755 gen_tmpfiles.py diff --git a/build_library/base_image_util.sh b/build_library/base_image_util.sh index 39d2da6bde..31b1eba012 100755 --- a/build_library/base_image_util.sh +++ b/build_library/base_image_util.sh @@ -203,6 +203,11 @@ create_base_image() { # trim the image size as much as possible. emerge_to_image --root="${root_fs_dir}" ${BASE_PACKAGE} + # Record directories installed to the stateful partition. + sudo "${SCRIPTS_DIR}/gen_tmpfiles.py" --root="${root_fs_dir}" \ + --output="${root_fs_dir}/usr/lib/tmpfiles.d/base_image.conf" \ + "${root_fs_dir}/var" + # Set /etc/lsb-release on the image. "${OVERLAY_CHROMEOS_DIR}/scripts/cros_set_lsb_release" \ --root="${root_fs_dir}" \ diff --git a/gen_tmpfiles.py b/gen_tmpfiles.py new file mode 100755 index 0000000000..d4f3a9f0d3 --- /dev/null +++ b/gen_tmpfiles.py @@ -0,0 +1,83 @@ +#!/usr/bin/python +'''Scan an existing directory tree and record installed directories. + +During build a number of directories under /var are created in the stateful +partition. We want to make sure that those are always there so create a record +of them using systemd's tempfiles config format so they are recreated during +boot if they go missing for any reason. +''' + +import optparse +import os +import stat +import sys +import pwd +import grp + +def main(): + keep = set() + parser = optparse.OptionParser(description=__doc__) + parser.add_option('--root', help='Remove root prefix from output') + parser.add_option('--output', help='Write output to the given file') + opts, args = parser.parse_args() + + if opts.root: + opts.root = os.path.abspath(opts.root) + + for path in args: + path = os.path.abspath(path) + if opts.root: + assert path.startswith(opts.root) + + for dirpath, dirnames, filenames in os.walk(path): + if any(f.startswith('.keep') for f in filenames): + keep.add(dirpath) + + # Add all parent directories too + for path in frozenset(keep): + split = [] + for pathbit in path.split('/'): + split.append(pathbit) + joined = '/'.join(split) + if not joined: + continue + if opts.root and not joined.startswith(opts.root): + continue + if opts.root == joined: + continue + keep.add(joined) + + config = [] + for path in sorted(keep): + if opts.root: + assert path.startswith(opts.root) + stripped = path[len(opts.root):] + assert len(stripped) > 1 + else: + stripped = path + + info = os.stat(path) + assert stat.S_ISDIR(info.st_mode) + mode = stat.S_IMODE(info.st_mode) + + try: + owner = pwd.getpwuid(info.st_uid).pw_name + except KeyError: + owner = str(info.st_uid) + try: + group = grp.getgrgid(info.st_gid).gr_name + except KeyError: + group = str(info.st_gid) + + config.append('d %-22s %04o %-10s %-10s - -' + % (stripped, mode, owner, group)) + + if opts.output: + fd = open(opts.output, 'w') + fd.write('\n'.join(config)) + fd.close() + else: + print '\n'.join(config) + +if __name__ == '__main__': + main() From dcd7b8e990ff0f3d29807be78d7d3967c6ad46c4 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Thu, 6 Jun 2013 14:22:40 -0400 Subject: [PATCH 2/2] fix(gen_tmpfiles): Add trailing newline --- gen_tmpfiles.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_tmpfiles.py b/gen_tmpfiles.py index d4f3a9f0d3..5d96f12c16 100755 --- a/gen_tmpfiles.py +++ b/gen_tmpfiles.py @@ -74,7 +74,7 @@ def main(): if opts.output: fd = open(opts.output, 'w') - fd.write('\n'.join(config)) + fd.write('\n'.join(config)+'\n') fd.close() else: print '\n'.join(config)