#!/usr/bin/python3 import ctypes import ctypes.util import glob import optparse import os import re import shutil import struct import subprocess import tempfile try: import configparser except ImportError: import ConfigParser as configparser import dnf.rpm libc = ctypes.CDLL(ctypes.util.find_library('c')) CLONE_NEWNS = 0x00020000 CLONE_NEWCGROUP = 0x02000000 CLONE_NEWUTS = 0x04000000 CLONE_NEWIPC = 0x08000000 CLONE_NEWUSER = 0x10000000 CLONE_NEWPID = 0x20000000 PR_SET_NO_NEW_PRIVS = 38 PR_SET_DUMPABLE = 4 MS_RDONLY = 1 MS_REMOUNT = 32 MS_BIND = 4096 MS_REC = 16384 MS_PRIVATE = 1<<18 numregex = re.compile('([0-9]+)') def naturalize_string(key): """Analyzes string in a human way to enable natural sort :param nodename: The node name to analyze :returns: A structure that can be consumed by 'sorted' """ return [int(text) if text.isdigit() else text.lower() for text in re.split(numregex, key)] def natural_sort(iterable): """Return a sort using natural sort if possible :param iterable: :return: """ try: return sorted(iterable, key=naturalize_string) except TypeError: # The natural sort attempt failed, fallback to ascii sort return sorted(iterable) def get_kern_version(filename): with open(filename, 'rb') as kernfile: kernfile.seek(0x20e) offset = struct.unpack(' 1: pack_image(opts, args) def pack_image(opts, args): outdir = args[1] kerns = glob.glob(os.path.join(args[0], 'boot/vmlinuz-*')) kvermap = {} for kern in kerns: if 'rescue' in kern: continue kvermap[get_kern_version(kern)] = kern mostrecent = list(natural_sort(kvermap))[-1] initrdname = os.path.join(args[0], 'boot/initramfs-diskless-{0}.img'.format(mostrecent)) mkdirp(os.path.join(outdir, 'boot/efi/boot')) mkdirp(os.path.join(outdir, 'boot/initramfs')) shutil.copyfile(kvermap[mostrecent], os.path.join(outdir, 'boot/kernel')) shutil.copyfile(initrdname, os.path.join(outdir, 'boot/initramfs/distribution')) shutil.copyfile(os.path.join(args[0], 'boot/efi/EFI/BOOT/BOOTX64.EFI'), os.path.join(outdir, 'boot/efi/boot/BOOTX64.EFI')) grubbin = None for candidate in glob.glob(os.path.join(args[0], 'boot/efi/EFI/*')): if 'BOOT' not in candidate: grubbin = os.path.join(candidate, 'grubx64.efi') break shutil.copyfile(grubbin, os.path.join(outdir, 'boot/efi/boot/grubx64.efi')) subprocess.check_call(['mksquashfs', args[0], os.path.join(outdir, 'rootimg.sfs'), '-comp', 'xz']) if __name__ == '__main__': main()