This add a fine level of details about the created image including: - installed packages - source rpms used - licensing - dependencies - where disk space is used
Signed-off-by: Joey Boggs jboggs@redhat.com --- src/pylorax/treebuilder.py | 84 ++++++++++++++++++++++++++++++++++++++++++++++ src/sbin/livemedia-creator | 6 ++++ 2 files changed, 90 insertions(+)
diff --git a/src/pylorax/treebuilder.py b/src/pylorax/treebuilder.py index 2e7c43e..0311118 100644 --- a/src/pylorax/treebuilder.py +++ b/src/pylorax/treebuilder.py @@ -29,6 +29,7 @@ from base import DataHolder from ltmpl import LoraxTemplateRunner import imgutils from pylorax.executils import runcmd, runcmd_output +from subprocess import Popen, PIPE, STDOUT
templatemap = { 'i386': 'x86.tmpl', @@ -184,6 +185,88 @@ class TreeBuilder(object): def kernels(self): return findkernels(root=self.vars.inroot)
+ def collect_manifest(self, cmd, output_file, sort=False): + output = runcmd_output(cmd, root=self.vars.inroot) + with open(os.path.join(self.manifest_path, output_file), "w") as f: + if sort: + output = output.split("\n") + for line in sorted(set(output),key=str.lower): + if line: + f.write("%s\n" % line) + else: + f.write(output) + + def create_manifests(self): + self.manifest_path = os.path.join(self.vars.outroot, "isolinux") + env = os.environ.copy() + env['LC_ALL'] = 'C' + os.makedirs(self.manifest_path) + # collect installed packages information + cmd = ["rpm", "-qa", "--qf", + "%{name}-%{version}-%{release}.%{arch} (%{SIGPGP:pgpsig})\n"] + self.collect_manifest(cmd, "manifest-rpm.txt", True) + + # collect source rpms + cmd = ["rpm", "-qa", "--qf", "%{sourcerpm}\n"] + self.collect_manifest(cmd, "manifest-srpm.txt", True) + + # collect all included licenses rhbz#601927 + cmd = ["rpm", "-qa", "--qf", "%{license}\n"] + self.collect_manifest(cmd, "manifest-license.txt", True) + + # get individial file sizes + cmd = ["du", "-akx", "--exclude=/var/cache/yum", "/"] + self.collect_manifest(cmd, "manifest-file.txt", True) + + # get directory sizes + cmd = ["du", "-x", "--exclude=/var/cache/yum", "/"] + self.collect_manifest(cmd, "manifest-dir.txt", True) + + # find orphaned files + file_list = [] + cmd = ["rpm", "-qa"] + installed_rpms = runcmd_output(cmd).strip() + + for pkg in installed_rpms.split("\n"): + cmd = ["rpm", "-ql", pkg] + pkg_files = runcmd_output(cmd).strip() + for f in pkg_files.split("\n"): + file_list.append("%s##%s" % (f, pkg)) + + cmd = ["find", "/", "-xdev"] + fs_list = runcmd_output(cmd).strip() + + for f in fs_list.split("\n"): + file_list.append("%s##Not owned by any package." % f) + + final_list = {} + + for item in file_list: + f, owner = item.split("##") + if not f in final_list: + final_list[f] = owner + + output_file = os.path.join(self.manifest_path, "manifest-owns.txt") + with open(output_file, "w") as t: + for x in final_list.keys(): + t.write("%s\n%s\n" % (x, final_list[x])) + + # get dependency list + cmd = ["rpm", "-qa"] + output = runcmd_output(cmd, root=self.vars.inroot) + piped_cmd = ["xargs", "-n1", "rpm", "-e", "--test"] + run_cmd = Popen(piped_cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE) + stdout_data = run_cmd.communicate(input=output)[1] + deps_file = os.path.join(self.manifest_path, "manifest-deps.txt") + with open(deps_file, "w") as f: + f.write("%s\n" % stdout_data) + + # bzip large manufest files + for f in ["deps", "owns", "file", "dir" ]: + path = os.path.join(self.manifest_path, "manifest-%s.txt" % f) + cmd = ["bzip2", path] + runcmd(cmd) + def rebuild_initrds(self, add_args=[], backup="", prefix=""): '''Rebuild all the initrds in the tree. If backup is specified, each initrd will be renamed with backup as a suffix before rebuilding. @@ -269,6 +352,7 @@ def findkernels(root="/", kdir="boot"): r"(.(?P<flavor>{0}))?)$".format("|".join(flavors))) kernels = [] bootfiles = os.listdir(joinpaths(root, kdir)) + for f in bootfiles: match = kre.match(f) if match: diff --git a/src/sbin/livemedia-creator b/src/sbin/livemedia-creator index 9239445..61c4a5e 100755 --- a/src/sbin/livemedia-creator +++ b/src/sbin/livemedia-creator @@ -535,6 +535,9 @@ def make_livecd(opts, mount_dir, work_dir): log.info("dracut args = {0}".format(dracut_args)) tb.rebuild_initrds(add_args=dracut_args) log.info("Building boot.iso") + log.info("Generating Manifests") + if opts.create_manifests and opts.make_iso: + tb.create_manifests() tb.build()
return work_dir @@ -814,6 +817,9 @@ if __name__ == '__main__': parser.add_argument( "--volid", default=None, help="volume id") parser.add_argument( "--squashfs_args", help="additional squashfs args" ) + parser.add_argument( "--create-manifests", action="store_true", + help="Create file system manifests of image", + default=False )
opts = parser.parse_args()