コード例 #1
0
ファイル: pkgm.py プロジェクト: sonicwalker/Customizer-SW
def main():
    common.check_filesystem()

    pkgmngr = None
    for sfile in ('aptitude', 'aptitude-curses', 'synaptic', 'apper'):
        for sdir in ('bin', 'sbin', 'usr/bin', 'usr/sbin'):
            full_file = misc.join_paths(config.FILESYSTEM_DIR, sdir, sfile)
            if os.path.exists(full_file) and os.access(full_file, os.X_OK):
                pkgmngr = misc.join_paths(sdir, sfile)
                message.sub_debug('Package manager detected', sfile)

    if not pkgmngr:
        raise (message.exception('No package manager available'))

    if not pkgmngr.startswith('aptitude'):
        try:
            message.sub_info('Allowing local access to X-server')
            misc.system_command((misc.whereis('xhost'), '+local:'))

            message.sub_info('Executing package manager')
            misc.chroot_exec((pkgmngr))

        finally:
            message.sub_info('Blocking local access to X-server')
            misc.system_command((misc.whereis('xhost'), '-local:'))
    else:
        message.sub_info('Executing package manager')
        misc.chroot_exec((pkgmngr))
コード例 #2
0
ファイル: xnest.py プロジェクト: clearkimura/Customizer
def main():
    common.check_filesystem()

    message.sub_info('Detecting available sessions')
    xsession = None
    for sfile in misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, \
        'usr/share/xsessions')):
        if sfile.endswith('.desktop'):
            xsession = common.get_value(sfile, 'Exec=')
            message.sub_debug('Session detected', xsession)

    if not xsession:
        raise(message.exception('No session available'))

    # FIXME: race condition between session and Xephyr - if session
    # starts before Xephyr it fails saying it does not find the DISPLAY
    message.sub_info('Starting Xephyr')
    x = subprocess.Popen((misc.whereis('Xephyr'), '-ac', '-screen', \
        config.RESOLUTION, '-br', ':13'))
    x.poll()
    if x.returncode is not None and x.returncode > 0:
        raise(message.exception('Failed to start Xephyr', x.returncode))

    try:
        message.sub_info('Allowing local access to X-server')
        misc.system_command((misc.whereis('xhost'), '+local:13'))

        message.sub_info('Starting nested X session', xsession)
        misc.chroot_exec((xsession), xnest=True)

        message.sub_info('Blocking local access to X-server')
        misc.system_command((misc.whereis('xhost'), '-local:13'))
    finally:
        message.sub_info('Terminating Xephyr')
        x.terminate()
コード例 #3
0
ファイル: pkgm.py プロジェクト: clearkimura/Customizer
def main():
    common.check_filesystem()

    pkgmngr = None
    for sfile in ('aptitude', 'aptitude-curses', 'synaptic', 'apper'):
        for sdir in ('bin', 'sbin', 'usr/bin', 'usr/sbin'):
            full_file = misc.join_paths(config.FILESYSTEM_DIR, sdir, sfile)
            if os.path.exists(full_file) and os.access(full_file, os.X_OK):
                pkgmngr = misc.join_paths(sdir, sfile)
                message.sub_debug('Package manager detected', sfile)

    if not pkgmngr:
        raise(message.exception('No package manager available'))

    if not pkgmngr.startswith('aptitude'):
        try:
            message.sub_info('Allowing local access to X-server')
            misc.system_command((misc.whereis('xhost'), '+local:'))

            message.sub_info('Executing package manager')
            misc.chroot_exec((pkgmngr))

        finally:
            message.sub_info('Blocking local access to X-server')
            misc.system_command((misc.whereis('xhost'), '-local:'))
    else:
        message.sub_info('Executing package manager')
        misc.chroot_exec((pkgmngr))
コード例 #4
0
ファイル: xnest.py プロジェクト: seabirdzh/Customizer
def main():
    common.check_filesystem()

    message.sub_info('Detecting available sessions')
    xsession = None
    for sfile in misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, \
        'usr/share/xsessions')):
        if sfile.endswith('.desktop'):
            xsession = common.get_value(sfile, 'Exec=')
            message.sub_debug('Session detected', xsession)

    if not xsession:
        raise (message.exception('No session avaialable'))

    # FIXME: race condition between session and Xephyr - if session
    # starts before Xephyr it fails saying it does not find the DISPLAY
    message.sub_info('Starting Xephyr')
    x = subprocess.Popen((misc.whereis('Xephyr'), '-ac', '-screen', \
        config.RESOLUTION, '-br', ':13'))
    x.poll()
    if x.returncode > 0:
        raise (message.exception('Failed to start Xephyr', x.returncode))

    try:
        message.sub_info('Allowing local access to X-server')
        misc.system_command((misc.whereis('xhost'), '+local:13'))

        message.sub_info('Starting nested X session', xsession)
        misc.chroot_exec((xsession), xnest=True)

        message.sub_info('Blocking local access to X-server')
        misc.system_command((misc.whereis('xhost'), '-local:13'))
    finally:
        message.sub_info('Terminating Xephyr')
        x.terminate()
コード例 #5
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def copy_file(source, destination):
    if FILE_DEBUG:
        message.sub_debug('File {} copied to'.format(source), destination)
    base = os.path.dirname(destination)
    if not os.path.isdir(base):
        os.makedirs(base)
    shutil.copyfile(source, destination)
コード例 #6
0
def append_file(sfile, content):
    if FILE_DEBUG: message.sub_debug('Appending data to', sfile)
    dirname = os.path.dirname(sfile)
    if not os.path.isdir(dirname):
        os.makedirs(dirname)

    afile = open(sfile, 'a')
    afile.write(content)
    afile.close()
コード例 #7
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def append_file(sfile, content):
    if FILE_DEBUG: message.sub_debug('Appending data to', sfile)
    dirname = os.path.dirname(sfile)
    if not os.path.isdir(dirname):
        os.makedirs(dirname)

    afile = open(sfile, 'a')
    afile.write(content)
    afile.close()
コード例 #8
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def list_files(directory):
    if FILE_DEBUG: message.sub_debug('Listing files in', directory)
    slist = []
    if not os.path.exists(directory):
        return slist
    for root, subdirs, files in os.walk(directory):
        for sfile in files:
            slist.append(os.path.join(root, sfile))
    return slist
コード例 #9
0
def list_files(directory):
    if FILE_DEBUG: message.sub_debug('Listing files in', directory)
    slist = []
    if not os.path.exists(directory):
        return slist
    for root, subdirs, files in os.walk(directory):
        for sfile in files:
            slist.append(os.path.join(root, sfile))
    return slist
コード例 #10
0
def detect_boot():
    global initrd, vmlinuz
    initrd = None
    vmlinuz = None

    for sfile in sorted(misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, 'boot'))):
        if 'initrd.img' in sfile:
            initrd = sfile
            message.sub_debug('Initrd detected', sfile)
        elif 'vmlinuz' in sfile:
            vmlinuz = sfile
            message.sub_debug('Vmlinuz detected', sfile)
コード例 #11
0
def check_filesystem():
    message.sub_info('Checking')
    corrupted = False
    for sdir in ('bin', 'sbin', 'usr/bin', 'usr/sbin', 'etc', 'lib', 'usr/lib'):
        full_dir = misc.join_paths(config.FILESYSTEM_DIR, sdir)
        if not os.path.isdir(full_dir):
            message.sub_debug('Non-existing path', full_dir)
            corrupted = True
            break

    if corrupted:
        raise(message.exception('Filesystem is missing or corrupted'))
コード例 #12
0
def check_filesystem():
    message.sub_info('Checking')
    corrupted = False
    for sdir in ('bin', 'sbin', 'usr/bin', 'usr/sbin', 'etc', 'lib',
                 'usr/lib'):
        full_dir = misc.join_paths(config.FILESYSTEM_DIR, sdir)
        if not os.path.isdir(full_dir):
            message.sub_debug('Non-existing path', full_dir)
            corrupted = True
            break

    if corrupted:
        raise (message.exception('Filesystem is missing or corrupted'))
コード例 #13
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def write_file(sfile, content):
    if FILE_DEBUG: message.sub_debug('Writing data to', sfile)
    dirname = os.path.dirname(sfile)
    if not os.path.isdir(dirname):
        os.makedirs(dirname)

    original = None
    if os.path.isfile(sfile):
        original = read_file(sfile)
    wfile = open(sfile, 'w')
    try:
        wfile.write(content)
    except:
        if original:
            wfile.write(original)
        raise
    finally:
        wfile.close()
コード例 #14
0
def main():
    common.check_filesystem()

    if not os.path.isfile(config.HOOK):
        raise(message.exception('HOOK does not exists', config.HOOK))

    message.sub_info('Copying HOOK file')
    hook_file = misc.join_paths(config.FILESYSTEM_DIR, 'hook')
    if os.path.isfile(hook_file):
        message.sub_debug('Removing', hook_file)
        os.unlink(hook_file)
    misc.copy_file(config.HOOK, hook_file)

    message.sub_info('Making HOOK executable')
    os.chmod(hook_file, stat.S_IEXEC)

    message.sub_info('Running HOOK')
    misc.chroot_exec(('/hook'))
コード例 #15
0
def write_file(sfile, content):
    if FILE_DEBUG: message.sub_debug('Writing data to', sfile)
    dirname = os.path.dirname(sfile)
    if not os.path.isdir(dirname):
        os.makedirs(dirname)

    original = None
    if os.path.isfile(sfile):
        original = read_file(sfile)
    wfile = open(sfile, 'w')
    try:
        wfile.write(content)
    except:
        if original:
            wfile.write(original)
        raise
    finally:
        wfile.close()
コード例 #16
0
ファイル: deb.py プロジェクト: kostyll/Customizer
def main():
    common.check_filesystem()

    if not os.path.isfile(config.DEB):
        raise(message.exception('DEB does not exists', config.DEB))
    elif not config.DEB.endswith('.deb'):
        raise(message.exception('File is not DEB', config.DEB))

    message.sub_info('Copying DEB file')
    deb_file = misc.join_paths(config.FILESYSTEM_DIR, 'temp.deb')
    if os.path.isfile(deb_file):
        message.sub_debug('Removing', deb_file)
        os.unlink(deb_file)
    misc.copy_file(config.DEB, deb_file)

    message.sub_info('Installing DEB')
    misc.chroot_exec(('dpkg', '-i', '/temp.deb'))
    message.sub_info('Installing dependencies')
    misc.chroot_exec(('apt-get', 'install', '-f', '-y'))
コード例 #17
0
def system_command(command, shell=False, cwd=None, env=None):
    if CMD_DEBUG: message.sub_debug('Executing system command', command)
    if not cwd:
        cwd = dir_current()
    elif not os.path.isdir(cwd):
        cwd = '/'
    if not env:
        env = os.environ
    if isinstance(command, str) and not shell:
        command = shlex.split(command)
    if CATCH:
        pipe = subprocess.Popen(command, stderr=subprocess.PIPE, \
            shell=shell, cwd=cwd, env=env)
        pipe.wait()
        if pipe.returncode != 0:
            raise(Exception(pipe.communicate()[1].strip()))
        return pipe.returncode
    else:
        return subprocess.check_call(command, shell=shell, cwd=cwd, env=env)
コード例 #18
0
def main():
    common.check_filesystem()

    if not os.path.isfile(config.DEB):
        raise (message.exception('DEB does not exists', config.DEB))
    elif not config.DEB.endswith('.deb'):
        raise (message.exception('File is not DEB', config.DEB))

    message.sub_info('Copying DEB file')
    deb_file = misc.join_paths(config.FILESYSTEM_DIR, 'temp.deb')
    if os.path.isfile(deb_file):
        message.sub_debug('Removing', deb_file)
        os.unlink(deb_file)
    misc.copy_file(config.DEB, deb_file)

    message.sub_info('Installing DEB')
    misc.chroot_exec(('dpkg', '-i', '/temp.deb'))
    message.sub_info('Installing dependencies')
    misc.chroot_exec(('apt-get', 'install', '-f', '-y'))
コード例 #19
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def system_command(command, shell=False, cwd=None, env=None):
    if CMD_DEBUG: message.sub_debug('Executing system command', command)
    if not cwd:
        cwd = dir_current()
    elif not os.path.isdir(cwd):
        cwd = '/'
    if not env:
        env = os.environ
    if isinstance(command, str) and not shell:
        command = shlex.split(command)
    if CATCH:
        pipe = subprocess.Popen(command, stderr=subprocess.PIPE, \
            shell=shell, cwd=cwd, env=env)
        pipe.wait()
        if pipe.returncode != 0:
            raise (Exception(pipe.communicate()[1].strip()))
        return pipe.returncode
    else:
        return subprocess.check_call(command, shell=shell, cwd=cwd, env=env)
コード例 #20
0
def clean_work_dirs():
    # ensure that nothing is mounted to the working directories before cleanup,
    # see https://github.com/clearkimura/Customizer/issues/82
    if os.path.exists('/proc/mounts'):
        for line in misc.readlines_file('/proc/mounts'):
            # spaces are recorded as "\\040", handle them unconditionally
            # TODO: test if this actually works with special characters
            mpoint = line.split()[1].replace('\\040', ' ')
            if mpoint.startswith((config.FILESYSTEM_DIR, config.ISO_DIR)):
                message.sub_info('Unmounting', mpoint)
                misc.system_command((misc.whereis('umount'), '-f', '-l', mpoint))
    else:
        message.sub_debug('/proc/mounts does not exists!')

    if os.path.isdir(config.FILESYSTEM_DIR):
        message.sub_info('Removing', config.FILESYSTEM_DIR)
        shutil.rmtree(config.FILESYSTEM_DIR)

    if os.path.isdir(config.ISO_DIR):
        message.sub_info('Removing', config.ISO_DIR)
        shutil.rmtree(config.ISO_DIR)
コード例 #21
0
ファイル: hook.py プロジェクト: mgrechukh/Customizer
def main():
    common.check_filesystem()

    if not os.path.isfile(config.HOOK):
        raise (message.exception("HOOK does not exists", config.HOOK))

    message.sub_info("Copying HOOK file")
    hook_file = misc.join_paths(config.FILESYSTEM_DIR, "hook")
    if os.path.isfile(hook_file):
        message.sub_debug("Removing", hook_file)
        os.unlink(hook_file)
    misc.copy_file(config.HOOK, hook_file)

    try:
        message.sub_info("Making HOOK executable")
        os.chmod(hook_file, stat.S_IEXEC)

        message.sub_info("Running HOOK")
        misc.chroot_exec(("/hook"))
    finally:
        if os.path.isfile(hook_file):
            os.unlink(hook_file)
コード例 #22
0
def clean_work_dirs():
    # ensure that nothing is mounted to the working directories before cleanup,
    # see https://github.com/clearkimura/Customizer/issues/82
    if os.path.exists('/proc/mounts'):
        for line in misc.readlines_file('/proc/mounts'):
            # spaces are recorded as "\\040", handle them unconditionally
            # TODO: test if this actually works with special characters
            mpoint = line.split()[1].replace('\\040', ' ')
            if mpoint.startswith((config.FILESYSTEM_DIR, config.ISO_DIR)):
                message.sub_info('Unmounting', mpoint)
                misc.system_command(
                    (misc.whereis('umount'), '-f', '-l', mpoint))
    else:
        message.sub_debug('/proc/mounts does not exists!')

    if os.path.isdir(config.FILESYSTEM_DIR):
        message.sub_info('Removing', config.FILESYSTEM_DIR)
        shutil.rmtree(config.FILESYSTEM_DIR)

    if os.path.isdir(config.ISO_DIR):
        message.sub_info('Removing', config.ISO_DIR)
        shutil.rmtree(config.ISO_DIR)
コード例 #23
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def chroot_exec(command,
                prepare=True,
                mount=True,
                output=False,
                xnest=False,
                shell=False,
                cwd=None):
    if CHROOT_DEBUG:
        message.sub_debug('Trying to set up chroot command', command)
    out = None
    resolv = '{}/etc/resolv.conf'.format(config.FILESYSTEM_DIR)
    hosts = '{}/etc/hosts'.format(config.FILESYSTEM_DIR)
    inhibit = '{}/usr/sbin/policy-rc.d'.format(config.FILESYSTEM_DIR)
    mount = whereis('mount')
    umount = whereis('umount')
    chroot = whereis('chroot')
    if isinstance(command, str):
        chroot_command = '{} {} {}'.format(chroot, config.FILESYSTEM_DIR,
                                           command)
    else:
        chroot_command = [chroot, config.FILESYSTEM_DIR]
        chroot_command.extend(command)
    try:
        if prepare:
            if CHROOT_DEBUG:
                message.sub_debug(
                    'Preparing chroot environment for networking')
            if os.path.isfile(
                    '/etc/resolv.conf') and not os.path.islink(resolv):
                copy_file('/etc/resolv.conf', resolv)
            elif os.path.islink(resolv):
                # usually /run/resolvconf/resolv.conf
                resolv = os.path.realpath(resolv)
                rdir = os.path.dirname(resolv)
                if not os.path.isdir(rdir):
                    os.makedirs(rdir)
                copy_file('/etc/resolv.conf', resolv)
            if os.path.isfile('/etc/hosts'):
                if os.path.isfile(hosts):
                    copy_file(hosts, '{}.backup'.format(hosts))
                copy_file('/etc/hosts', hosts)

        if mount:
            if CHROOT_DEBUG: message.sub_debug('Mounting paths inside chroot')
            pseudofs = [
                '/proc', '/dev', '/dev/pts', '/dev/shm', '/sys', '/tmp',
                '/var/lib/dbus'
            ]
            if os.path.islink(config.FILESYSTEM_DIR + '/var/run'):
                pseudofs.append('/run/dbus')
            else:
                pseudofs.append('/var/run/dbus')
            for s in pseudofs:
                if not os.path.exists(s):
                    continue
                sdir = config.FILESYSTEM_DIR + s
                if not os.path.ismount(sdir):
                    if not os.path.isdir(sdir):
                        os.makedirs(sdir)
                    if MOUNT_DEBUG:
                        message.sub_debug('Mounting --bind {}'.format(s), sdir)
                    system_command((mount, '--bind', s, sdir))

        if prepare:
            if MOUNT_DEBUG: message.sub_debug('Creating mtab inside chroot')
            mtab = '{}/etc/mtab'.format(config.FILESYSTEM_DIR)
            if not os.path.isfile(mtab) and not os.path.islink(mtab):
                os.symlink('../../proc/mounts', mtab)
            if not os.path.isfile(inhibit):
                write_file(inhibit, "exit 101")
                os.chmod(inhibit, 0o755)

        if not config.LOCALES == 'C':
            system_command(('locale-gen', config.LOCALES))

        if CHROOT_DEBUG: message.sub_debug('Enumerating environment variables')
        # all operations on reference to os.environ change the environment!
        environment = {}
        for item in os.environ:
            # skip desktop environment specifiec variables because if a DE is
            # run in the chroot it may encounter some issues, e.g. with the
            # XDG menus
            if item.startswith('KDE_') or item == 'XDG_CURRENT_DESKTOP':
                continue
            environment[item] = os.environ.get(item)
        environment['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
        environment['HOME'] = '/root'
        environment['LC_ALL'] = config.LOCALES
        environment['LANGUAGE'] = config.LOCALES
        environment['LANG'] = config.LOCALES
        environment['USER'] = '******'
        environment['CASPER_GENERATE_UUID'] = '1'
        if xnest:
            environment['HOME'] = '/etc/skel'
            environment['XDG_CACHE_HOME'] = '/etc/skel/.cache'
            environment['XDG_DATA_HOME'] = '/etc/skel/.local/share'
            environment['XDG_CONFIG_HOME'] = '/etc/skel/.config'
            environment['DISPLAY'] = ':13'
        else:
            environment['DEBIAN_FRONTEND'] = 'noninteractive'
            # FIXME: is this needed?
            # environment['DEBIAN_PRIORITY'] = ''
            environment['DEBCONF_NONINTERACTIVE_SEEN'] = 'true'
            environment['DEBCONF_NOWARNINGS'] = 'true'

        if output:
            if CHROOT_DEBUG: message.sub_debug('Entering chroot')
            out = get_output(chroot_command)
            if CHROOT_DEBUG: message.sub_debug('Exiting chroot')
        else:
            if CHROOT_DEBUG: message.sub_debug('Entering chroot')
            system_command(chroot_command, shell=shell, \
                env=environment, cwd=cwd)
            if CHROOT_DEBUG: message.sub_debug('Exiting chroot')
    finally:
        if prepare:
            if os.path.isfile('{}.backup'.format(hosts)):
                copy_file('{}.backup'.format(hosts), hosts)
                os.unlink('{}.backup'.format(hosts))
            if os.path.isfile(inhibit):
                os.unlink(inhibit)
        if mount:
            for s in reversed(pseudofs):
                sdir = config.FILESYSTEM_DIR + s
                if os.path.ismount(sdir):
                    if MOUNT_DEBUG: message.sub_debug('Unmounting -f -l', sdir)
                    system_command((umount, '-f', '-l', sdir))
            time.sleep(0.1)  # Wait for lazy unmounts to unlazy...
        system_command(('sleep', '1'))  # Make sure of it. (and log it)
    if output:
        return out
コード例 #24
0
ファイル: qemu.py プロジェクト: Ch0pp3r/Customizer
def main():
    common.check_filesystem()

    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')
    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if not os.path.exists(iso_file):
        raise(message.exception('ISO Image does not exists', iso_file))

    message.sub_info('Running QEMU with ISO image', iso_file)
    host_arch = os.uname()[4]
    if host_arch == 'x86_64':
        qemu = misc.whereis('qemu-system-x86_64')
    else:
        qemu = misc.whereis('qemu-system-i386')
    if not qemu:
        raise(message.exception('QEMU is not installed'))

    qemu_kvm = False
    command = [qemu, '-m', config.VRAM, '-cdrom', iso_file]
    if misc.search_string('-enable-kvm', misc.get_output((qemu, '-h'))):
        qemu_kvm = True
    # vmx for intel, svm for amd processors. it will most likely not work in
    # XEN environment
    host_kvm = False
    if os.path.exists('/dev/kvm') and os.path.exists('/proc/cpuinfo') and \
        misc.search_file('(?:\\s|^)flags.*(?:\\s)(vme|vmx)(?:\\s|$)', \
        '/proc/cpuinfo', escape=False):
        host_kvm = True
    if qemu_kvm and host_kvm:
        command.append('-enable-kvm')
    message.sub_debug('Host architecture', host_arch)
    message.sub_debug('QEMU KVM', qemu_kvm)
    message.sub_debug('Host KVM', host_kvm)
    misc.system_command(command)
コード例 #25
0
ファイル: qemu.py プロジェクト: willprice/customizer
def main():
    common.check_filesystem()

    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')
    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    if isinstance(arch, bytes):  # For some reason this is of type 'bytes'.
        if int(sys.version_info[0]) >= 3:  # If we're running under python3
            arch = str(arch, 'utf-8')
        else:  # Otherwise just cast it to a str without the 'utf-8' option.
            arch = str(arch)
    
    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if not os.path.exists(iso_file):
        raise(message.exception('ISO image does not exist', iso_file))

    message.sub_info('Running QEMU with ISO image', iso_file)
    host_arch = os.uname()[4]
    if host_arch == 'x86_64':
        qemu = misc.whereis('qemu-system-x86_64')
    else:
        qemu = misc.whereis('qemu-system-i386')
    if not qemu:
        raise(message.exception('QEMU is not installed'))

    qemu_kvm = False
    command = [qemu, '-m', config.VRAM, '-cdrom', iso_file]
    if misc.search_string('-enable-kvm', misc.get_output((qemu, '-h'))):
        qemu_kvm = True
    # CPU flag: "vmx" for Intel processors, "svm" for AMD processors
    # These flags are hidden in Xen environment
    # https://wiki.xenproject.org/wiki/Xen_Common_Problems
    host_kvm = False
    if os.path.exists('/dev/kvm') and os.path.exists('/proc/cpuinfo') and \
        misc.search_file('(?:\\s|^)flags.*(?:\\s)(vmx|svm)(?:\\s|$)', \
        '/proc/cpuinfo', escape=False):
        host_kvm = True
    if qemu_kvm and host_kvm:
        command.append('-enable-kvm')
    message.sub_debug('Host architecture', host_arch)
    message.sub_debug('QEMU KVM', qemu_kvm)
    message.sub_debug('Host KVM', host_kvm)
    misc.system_command(command)
コード例 #26
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def read_file(sfile):
    if FILE_DEBUG: message.sub_debug('Reading entire file', sfile)
    rfile = open(sfile, 'r')
    content = rfile.read()
    rfile.close()
    return content
コード例 #27
0
ファイル: rebuild.py プロジェクト: kamilion/customizer
def main():
    common.check_filesystem()

    # Basic sanity checks of files and paths that absolutely need to exist.
    message.sub_info("Doing sanity checks")
    lsb_file = misc.join_paths(config.FILESYSTEM_DIR, "etc/lsb-release")
    if not os.path.isfile(lsb_file):
        raise (message.exception(lsb_file + " does not exist"))

    isolinux_dir = misc.join_paths(config.ISO_DIR, "isolinux")
    if not os.path.isdir(isolinux_dir):
        raise (message.exception(isolinux_dir + " does not exist"))

    if misc.search_file("999:999", misc.join_paths(config.FILESYSTEM_DIR, "etc/passwd")):
        raise (message.exception("User with UID 999 exists, this mean that automatic login will fail"))
    elif misc.search_file("999:999", misc.join_paths(config.FILESYSTEM_DIR, "etc/group")):
        raise (message.exception("Group with GID 999 exists, this mean that automatic login will fail"))

    casper_dir = misc.join_paths(config.ISO_DIR, "casper")
    if not os.path.isdir(casper_dir):
        message.sub_debug("Creating", casper_dir)
        os.makedirs(casper_dir)

    base_file = misc.join_paths(config.ISO_DIR, ".disk/base_installable")
    if os.path.isfile(misc.join_paths(config.FILESYSTEM_DIR, "usr/bin/ubiquity")):
        if not os.path.isfile(base_file):
            message.sub_debug("Creating", base_file)
            misc.write_file(base_file, "")
    elif os.path.isfile(base_file):
        message.sub_debug("Removing", base_file)
        os.unlink(base_file)

    # Acquire distribution information from the FileSystem
    message.sub_info("Gathering information")
    arch = misc.chroot_exec(("dpkg", "--print-architecture"), prepare=False, mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + "/etc/lsb-release", "DISTRIB_ID=")
    release = common.get_value(config.FILESYSTEM_DIR + "/etc/lsb-release", "DISTRIB_RELEASE=")

    # It's really annoying to override the output filename other ways.
    # If you actually try to change lsb-release, you end up breaking apt.
    livecd_file = misc.join_paths(config.FILESYSTEM_DIR, "etc/livecd-release")
    if os.path.isfile(livecd_file):
        distrib = common.get_value(config.FILESYSTEM_DIR + "/etc/livecd-release", "DISTRIB_ID=")
        release = common.get_value(config.FILESYSTEM_DIR + "/etc/livecd-release", "DISTRIB_RELEASE=")
        message.sub_debug("Distribution and Release overriden by /etc/livecd-release")
        # Just overwrite the variables if the file actually exists, it's cleaner.

    message.sub_debug("Architecture", arch)
    message.sub_debug("Distribution (DISTRIB_ID)", distrib)
    message.sub_debug("Release (DISTRIB_RELEASE)", release)

    # Remove files, by name, that we know we must repopulate if they exist.
    message.sub_info("Cleaning up")
    cleanup_files = [
        "casper/filesystem.squashfs",
        "casper/initrd.lz",
        "casper/vmlinuz",
        "casper/vmlinuz.efi",
        "casper/filesystem.manifest",
        "casper/filesystem.size",
    ]
    cleanup_files.extend(glob.glob(".disk/casper-uuid-*"))
    for sfile in cleanup_files:
        full_file = misc.join_paths(config.ISO_DIR, sfile)
        if os.path.exists(full_file):
            message.sub_debug("Removing", full_file)
            os.unlink(full_file)

    # Define the checksum files, and the ISO filename.
    md5sum_iso_file = misc.join_paths(config.WORK_DIR, "md5sum")
    sha1sum_iso_file = misc.join_paths(config.WORK_DIR, "sha1sum")
    sha256sum_iso_file = misc.join_paths(config.WORK_DIR, "sha256sum")
    iso_file = "%s/%s-%s-%s.iso" % (config.WORK_DIR, distrib, arch, release)
    if os.path.exists(iso_file):
        message.sub_debug("Removing", iso_file)
        os.unlink(iso_file)
    if os.path.exists(md5sum_iso_file):
        message.sub_debug("Removing", md5sum_iso_file)
        os.unlink(md5sum_iso_file)
    if os.path.exists(sha1sum_iso_file):
        message.sub_debug("Removing", sha1sum_iso_file)
        os.unlink(sha1sum_iso_file)
    if os.path.exists(sha256sum_iso_file):
        message.sub_debug("Removing", sha256sum_iso_file)
        os.unlink(sha256sum_iso_file)

    # Detect files needed for booting, the kernel, initramfs, xen and anything else.
    detect_boot()
    if not vmlinuz:
        message.sub_info("Re-installing kernel")
        misc.chroot_exec(("apt-get", "purge", "--yes", "linux-image*", "-q"))
        misc.chroot_exec(("apt-get", "install", "--yes", "linux-signed-generic", "-q"))
        misc.chroot_exec(("apt-get", "clean"))
    else:
        message.sub_info("Updating initramfs")
        misc.chroot_exec(("update-initramfs", "-k", "all", "-t", "-u"))
    detect_boot()

    if not initrd or not vmlinuz:
        raise (message.exception("Missing boot file (initrd or vmlinuz)"))
    else:
        message.sub_info("Copying boot files")
        message.sub_debug("Initrd", initrd)
        message.sub_debug("Vmlinuz", vmlinuz)
        misc.copy_file(initrd, misc.join_paths(config.ISO_DIR, "casper/initrd.lz"))

        # FIXME: extend to support grub
        efi_boot_entry = False
        isolinux_dir = config.ISO_DIR + "/isolinux"
        if os.path.isdir(isolinux_dir):
            for sfile in os.listdir(isolinux_dir):
                if sfile.endswith(".cfg") and misc.search_file("vmlinuz.efi", isolinux_dir + "/" + sfile):
                    message.sub_debug("Found EFI entry in isolinux conf", sfile)
                    efi_boot_entry = True
        if os.path.isdir(misc.join_paths(config.ISO_DIR, "efi/boot")) or efi_boot_entry:
            message.sub_debug("Copying EFI vmlinuz")
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, "casper/vmlinuz.efi"))
            os.link(
                misc.join_paths(config.ISO_DIR, "casper/vmlinuz.efi"), misc.join_paths(config.ISO_DIR, "casper/vmlinuz")
            )
            # EFI Kernels are still loadable by grub, modern ISOs lack a bare vmlinuz.
            # mkisofs/genisoimage -cache-inodes reuses hard linked inodes.
        else:
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, "casper/vmlinuz"))
            # We only need to copy the bare kernel if we're not using EFI at all.

    # Copy optional boot-enablement packages onto the ISO, if found.
    if mt86plus:
        message.sub_debug("Memtest86+ kernel", mt86plus)
        misc.copy_file(mt86plus, misc.join_paths(config.ISO_DIR, "install/mt86plus"))
    if xen_kernel:
        message.sub_debug("Xen kernel", xen_kernel)
        misc.copy_file(xen_kernel, misc.join_paths(config.ISO_DIR, "casper/" + os.path.basename(xen_kernel)))
    if xen_efi:
        message.sub_debug("Xen EFI kernel", xen_efi)
        misc.copy_file(xen_efi, misc.join_paths(config.ISO_DIR, "casper/" + os.path.basename(xen_efi)))
    if ipxe_kernel:
        message.sub_debug("iPXE kernel", ipxe_kernel)
        misc.copy_file(ipxe_kernel, misc.join_paths(config.ISO_DIR, "casper/" + os.path.basename(ipxe_kernel)))
    if ipxe_efi:
        message.sub_debug("iPXE EFI kernel", ipxe_efi)
        misc.copy_file(ipxe_efi, misc.join_paths(config.ISO_DIR, "casper/" + os.path.basename(ipxe_efi)))

    message.sub_info("Extracting casper UUID")
    confdir = config.FILESYSTEM_DIR + "/conf"
    if os.path.isdir(confdir):
        shutil.rmtree(confdir)
    os.makedirs(confdir)
    try:
        misc.chroot_exec(
            "zcat " + initrd.replace(config.FILESYSTEM_DIR, "") + " | cpio --quiet -id conf/uuid.conf",
            shell=True,
            cwd=config.FILESYSTEM_DIR,
        )
        kernel = re.search("initrd.img-*.*.*-*-(.*)", initrd).group(1)
        message.sub_debug("Kernel", kernel)
        misc.copy_file(confdir + "/uuid.conf", misc.join_paths(config.ISO_DIR, ".disk/casper-uuid-" + kernel))
    finally:
        shutil.rmtree(confdir)

    # Define some default compression parameters, including a 1MB blocksize for all compressors.
    compression_parameters = ("-b", "1048576", "-comp", config.COMPRESSION)
    if config.COMPRESSION == "xz":  # Append additional compression parameters for xz.
        # Using the branch-call-jump filter provides a compression boost with executable code.
        # This can save a hundred megabytes easily, on an 800MB ISO. The dictionary size must
        # match the block size, and it's advisable to use larger block sizes, like 1MB or 4MB.
        compression_parameters += ("-Xbcj", "x86", "-Xdict-size", "100%")
    message.sub_info("SquashFS Compression parameters", compression_parameters)

    # Create the compressed filesystem
    message.sub_info("Creating SquashFS Compressed Filesystem")
    make_squash_fs = (
        "mksquashfs",
        config.FILESYSTEM_DIR,
        misc.join_paths(config.ISO_DIR, "casper/filesystem.squashfs"),
        "-wildcards",
        "-no-recovery",
        "-noappend",
        "-ef",
        os.path.join(sys.prefix, "share/customizer/exclude.list"),
    )
    misc.system_command(make_squash_fs + compression_parameters)

    message.sub_info("Checking SquashFS filesystem size")
    sfs_size = os.path.getsize(misc.join_paths(config.ISO_DIR, "casper/filesystem.squashfs"))
    message.sub_debug("SquashFS filesystem size", sfs_size)
    if sfs_size > 4000000000:
        raise (message.exception("The SquashFS filesystem size is greater than 4GB"))

    message.sub_info("Creating filesystem.size")
    fs_size = 0
    for root, subdirs, files in os.walk(config.FILESYSTEM_DIR):
        for sfile in files:
            sfull = os.path.join(root, sfile)
            if os.path.islink(sfull):
                continue
            # FIXME: respect ignored files from exclude.list
            fs_size += os.path.getsize(sfull)
    message.sub_debug("Root filesystem size", fs_size)
    misc.write_file(misc.join_paths(config.ISO_DIR, "casper/filesystem.size"), str(fs_size))

    message.sub_info("Creating filesystem.manifest")
    lpackages = misc.chroot_exec(
        ("dpkg-query", "-W", "--showformat=${Package} ${Version}\\n"), prepare=False, mount=False, output=True
    )
    message.sub_debug("Packages", lpackages)
    misc.write_file(misc.join_paths(config.ISO_DIR, "casper/filesystem.manifest"), lpackages)

    # FIXME: do some kung-fu to check if packages are installed
    # and remove them from filesystem.manifest-remove if they are not

    # Creating a md5sum.txt file fixes lubuntu's integrity check.
    md5sums_file = misc.join_paths(config.ISO_DIR, "md5sum.txt")
    if os.path.isfile(md5sums_file):
        message.sub_info("Creating md5sum.txt")
        misc.write_file(md5sums_file, "")
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith("md5sum.txt"):
                continue
            if sfile.endswith("SHA256SUMS"):
                continue
            message.sub_debug("MD5 Checksumming", sfile)
            checksum = misc.generate_hash_for_file("md5", sfile)
            misc.append_file(md5sums_file, checksum + "  ." + sfile.replace(config.ISO_DIR, "") + "\n")

    # Creating a SHA256SUMS file fixes ubuntu-mini-remix's integrity check.
    shasums_file = misc.join_paths(config.ISO_DIR, "SHA256SUMS")
    if os.path.isfile(shasums_file):
        message.sub_info("Creating SHA256SUMS")
        misc.write_file(shasums_file, "")
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith("md5sum.txt"):
                continue
            if sfile.endswith("SHA256SUMS"):
                continue
            message.sub_debug("SHA256 Checksumming", sfile)
            checksum = misc.generate_hash_for_file("sha256", sfile)
            misc.append_file(shasums_file, checksum + "  ." + sfile.replace(config.ISO_DIR, "") + "\n")

    # Create the ISO filesystem
    message.sub_info("Creating ISO")
    os.chdir(config.ISO_DIR)
    misc.system_command(
        (
            "xorriso",
            "-as",
            "mkisofs",
            "-r",
            "-V",
            distrib + "-" + arch + "-" + release,
            "-b",
            "isolinux/isolinux.bin",
            "-c",
            "isolinux/boot.cat",
            "-J",
            "-l",
            "-no-emul-boot",
            "-boot-load-size",
            "4",
            "-boot-info-table",
            "-o",
            iso_file,
            "-cache-inodes",
            "-input-charset",
            "utf-8",
            ".",
        )
    )

    message.sub_info("Creating ISO checksums")
    md5checksum = misc.generate_hash_for_file("md5", iso_file)
    message.sub_info("ISO md5 checksum", md5checksum)
    misc.append_file(md5sum_iso_file, md5checksum + "  ." + iso_file.replace(config.WORK_DIR, "") + "\n")
    sha1checksum = misc.generate_hash_for_file("sha1", iso_file)
    message.sub_info("ISO sha1 checksum", sha1checksum)
    misc.append_file(sha1sum_iso_file, sha1checksum + "  ." + iso_file.replace(config.WORK_DIR, "") + "\n")
    sha256checksum = misc.generate_hash_for_file("sha256", iso_file)
    message.sub_info("ISO sha256 checksum", sha256checksum)
    misc.append_file(sha256sum_iso_file, sha256checksum + "  ." + iso_file.replace(config.WORK_DIR, "") + "\n")

    message.sub_info("Successfuly created ISO image", iso_file)
コード例 #28
0
ファイル: rebuild.py プロジェクト: kamilion/customizer
def detect_boot():
    global initrd, vmlinuz, mt86plus, xen_kernel, xen_efi, ipxe_kernel, ipxe_efi
    initrd = None
    vmlinuz = None
    mt86plus = None
    xen_kernel = None
    xen_efi = None
    ipxe_kernel = None
    ipxe_efi = None

    for sfile in sorted(misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, "boot"))):
        if "initrd.img" in sfile:
            initrd = sfile
            message.sub_debug("Initrd detected", sfile)
        elif "vmlinuz" in sfile:
            vmlinuz = sfile
            message.sub_debug("Vmlinuz detected", sfile)
        elif "memtest86" in sfile:
            if "+.bin" in sfile:
                # In theory, We want memtest86+.bin, not memtest86+_multiboot.bin
                # But in actual practice, they're often the same file. Let's be picky.
                mt86plus = sfile
                message.sub_debug("Memtest86+ kernel detected", sfile)
        elif "xen" in sfile:
            if "gz" in sfile:
                xen_kernel = sfile
                message.sub_debug("Xen Hypervisor kernel detected", sfile)
            if "efi" in sfile:
                xen_efi = sfile
                message.sub_debug("Xen Hypervisor EFI kernel detected", sfile)
        elif "ipxe" in sfile:
            if "lkrn" in sfile:
                ipxe_kernel = sfile
                message.sub_debug("iPXE kernel detected", sfile)
            if "efi" in sfile:
                ipxe_efi = sfile
                message.sub_debug("iPXE EFI kernel detected", sfile)
コード例 #29
0
def read_file(sfile):
    if FILE_DEBUG: message.sub_debug('Reading entire file', sfile)
    rfile = open(sfile, 'r')
    content = rfile.read()
    rfile.close()
    return content
コード例 #30
0
def detect_boot():
    global initrd, vmlinuz, mt86plus, xen_kernel, xen_efi, ipxe_kernel, ipxe_efi
    initrd = None
    vmlinuz = None
    mt86plus = None
    xen_kernel = None
    xen_efi = None
    ipxe_kernel = None
    ipxe_efi = None

    for sfile in sorted(misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, 'boot'))):
        if 'initrd.img' in sfile:
            initrd = sfile
            message.sub_debug('Initrd detected', sfile)
        elif 'vmlinuz' in sfile:
            vmlinuz = sfile
            message.sub_debug('Vmlinuz detected', sfile)
        elif 'memtest86' in sfile:
            if '+.bin' in sfile:
                # In theory, We want memtest86+.bin, not memtest86+_multiboot.bin
                # But in actual practice, they're often the same file. Let's be picky.
                mt86plus = sfile
                message.sub_debug('Memtest86+ kernel detected', sfile)
        elif 'xen' in sfile:
            if 'gz' in sfile:
                xen_kernel = sfile
                message.sub_debug('Xen Hypervisor kernel detected', sfile)
            if 'efi' in sfile:
                xen_efi = sfile
                message.sub_debug('Xen Hypervisor EFI kernel detected', sfile)
        elif 'ipxe' in sfile:
            if 'lkrn' in sfile:
                ipxe_kernel = sfile
                message.sub_debug('iPXE kernel detected', sfile)
            if 'efi' in sfile:
                ipxe_efi = sfile
                message.sub_debug('iPXE EFI kernel detected', sfile)
コード例 #31
0
def detect_boot():
    global initrd, vmlinuz, mt86plus, xen_kernel, xen_efi, ipxe_kernel, ipxe_efi
    initrd = None
    vmlinuz = None
    mt86plus = None
    xen_kernel = None
    xen_efi = None
    ipxe_kernel = None
    ipxe_efi = None

    for sfile in sorted(misc.list_files(misc.join_paths(config.FILESYSTEM_DIR, 'boot'))):
        if 'initrd.img' in sfile:
            initrd = sfile
            message.sub_debug('Initrd detected', sfile)
        elif 'vmlinuz' in sfile:
            vmlinuz = sfile
            message.sub_debug('Vmlinuz detected', sfile)
        elif 'memtest86' in sfile:
            if '+.bin' in sfile:
                # In theory, We want memtest86+.bin, not memtest86+_multiboot.bin
                # But in actual practice, they're often the same file. Let's be picky.
                mt86plus = sfile
                message.sub_debug('Memtest86+ kernel detected', sfile)
        elif 'xen' in sfile:
            if 'gz' in sfile:
                xen_kernel = sfile
                message.sub_debug('Xen Hypervisor kernel detected', sfile)
            if 'efi' in sfile:
                xen_efi = sfile
                message.sub_debug('Xen Hypervisor EFI kernel detected', sfile)
        elif 'ipxe' in sfile:
            if 'lkrn' in sfile:
                ipxe_kernel = sfile
                message.sub_debug('iPXE kernel detected', sfile)
            if 'efi' in sfile:
                ipxe_efi = sfile
                message.sub_debug('iPXE EFI kernel detected', sfile)
コード例 #32
0
ファイル: extract.py プロジェクト: seabirdzh/Customizer
def main():
    global mount_dir
    if not os.path.isfile(config.ISO):
        raise (message.exception('ISO does not exists', config.ISO))
    elif not config.ISO.endswith('.iso'):
        raise (message.exception('File is not ISO', config.ISO))

    common.clean_work_dirs()
    common.create_work_dirs()

    message.sub_info('Creating mount directory')
    mount_dir = tempfile.mkdtemp(prefix=config.MOUNT_DIR + '/')
    message.sub_debug('Mount directory is', mount_dir)

    message.sub_info('Mounting ISO', config.ISO)
    try:
        # load the required kernel modules in cases the are not, if they are
        # builtin the command fails so ignoring that. the "-b" argument is to
        # ensure blacklisted modules are respected
        try:
            misc.system_command(
                (misc.whereis('modprobe'), '-ba', 'loop', 'iso9660'))
        except:
            pass
        misc.system_command((misc.whereis('mount'), '-t', 'iso9660', '-o', \
            'ro,loop', config.ISO, mount_dir))
    except:
        message.sub_info('Removing', mount_dir)
        os.rmdir(mount_dir)
        common.clean_work_dirs()
        raise

    message.sub_info('Checking ISO')
    for spath in (mount_dir + '/casper/filesystem.squashfs', \
        mount_dir + '/casper/filesystem.manifest', \
        mount_dir + '/casper/filesystem.manifest-remove', \
        mount_dir + '/.disk', mount_dir + '/isolinux', ):
        if not os.path.exists(spath):
            message.sub_debug('Non-existing path', spath)
            common.clean_work_dirs()
            unmount_iso()
            raise (message.exception('Invalid ISO', config.ISO))

    message.sub_info('Unsquashing filesystem')
    try:
        misc.system_command((misc.whereis('unsquashfs'), '-f', '-d', \
            config.FILESYSTEM_DIR, mount_dir + '/casper/filesystem.squashfs'))
    except:
        unmount_iso()
        raise

    message.sub_info('Checking architecture')
    fs_arch = misc.chroot_exec(('dpkg', '--print-architecture'), \
        prepare=False, mount=False, output=True)
    host_arch = os.uname()[4]
    message.sub_debug('Filesystem architecture', fs_arch)
    message.sub_debug('Host architecture', host_arch)
    if fs_arch == 'amd64' and not host_arch == 'x86_64':
        message.sub_debug('The ISO architecture is amd64 and yours is not')
        common.clean_work_dirs()
        unmount_iso()
        raise (message.exception(
            'The ISO architecture is amd64 and yours is not'))

    message.sub_info('Copying ISO files')
    for sfile in misc.list_files(mount_dir):
        if sfile.endswith('casper/filesystem.squashfs'):
            continue
        else:
            message.sub_debug('Copying', sfile)
            misc.copy_file(sfile, sfile.replace(mount_dir, config.ISO_DIR))

    unmount_iso()
コード例 #33
0
def chroot_exec(command, prepare=True, mount=True, output=False, xnest=False, shell=False, cwd=None):
    if CHROOT_DEBUG: message.sub_debug('Trying to set up chroot command', command)
    out = None
    resolv = '{}/etc/resolv.conf'.format(config.FILESYSTEM_DIR)
    hosts = '{}/etc/hosts'.format(config.FILESYSTEM_DIR)
    inhibit = '{}/usr/sbin/policy-rc.d'.format(config.FILESYSTEM_DIR)
    mount = whereis('mount')
    umount = whereis('umount')
    chroot = whereis('chroot')
    if isinstance(command, str):
        chroot_command = '{} {} {}'.format(chroot, config.FILESYSTEM_DIR, command)
    else:
        chroot_command = [chroot, config.FILESYSTEM_DIR]
        chroot_command.extend(command)
    try:
        if prepare:
            if CHROOT_DEBUG: message.sub_debug('Preparing chroot environment for networking')
            if os.path.isfile('/etc/resolv.conf') and not os.path.islink(resolv):
                 copy_file('/etc/resolv.conf', resolv)
            elif os.path.islink(resolv):
                # usually /run/resolvconf/resolv.conf
                resolv = os.path.realpath(resolv)
                rdir = os.path.dirname(resolv)
                if not os.path.isdir(rdir):
                    os.makedirs(rdir)
                copy_file('/etc/resolv.conf', resolv)
            if os.path.isfile('/etc/hosts'):
                if os.path.isfile(hosts):
                    copy_file(hosts, '{}.backup'.format(hosts))
                copy_file('/etc/hosts', hosts)

        if mount:
            if CHROOT_DEBUG: message.sub_debug('Mounting paths inside chroot')
            pseudofs = ['/proc', '/dev', '/dev/pts', '/dev/shm', '/sys', '/tmp', '/var/lib/dbus']
            if os.path.islink(config.FILESYSTEM_DIR + '/var/run'):
                pseudofs.append('/run/dbus')
            else:
                pseudofs.append('/var/run/dbus')
            for s in pseudofs:
                if not os.path.exists(s):
                    continue
                sdir = config.FILESYSTEM_DIR + s
                if not os.path.ismount(sdir):
                    if not os.path.isdir(sdir):
                        os.makedirs(sdir)
                    if MOUNT_DEBUG: message.sub_debug('Mounting --bind {}'.format(s), sdir)
                    system_command((mount, '--bind', s, sdir))


        if prepare:
            if MOUNT_DEBUG: message.sub_debug('Creating mtab inside chroot')
            mtab = '{}/etc/mtab'.format(config.FILESYSTEM_DIR)
            if not os.path.isfile(mtab) and not os.path.islink(mtab):
                os.symlink('../../proc/mounts', mtab)
            if not os.path.isfile(inhibit):
                write_file(inhibit, "exit 101")
                os.chmod(inhibit, 0o755)
        
        if not config.LOCALES == 'C':
            system_command(('locale-gen', config.LOCALES))

        if CHROOT_DEBUG: message.sub_debug('Enumerating environment variables')
        # all operations on reference to os.environ change the environment!
        environment = {}
        for item in os.environ:
            # skip desktop environment specifiec variables because if a DE is
            # run in the chroot it may encounter some issues, e.g. with the
            # XDG menus
            if item.startswith('KDE_') or item == 'XDG_CURRENT_DESKTOP':
                continue
            environment[item] = os.environ.get(item)
        environment['PATH'] = '/usr/sbin:/usr/bin:/sbin:/bin'
        environment['HOME'] = '/root'
        environment['LC_ALL'] = config.LOCALES
        environment['LANGUAGE'] = config.LOCALES
        environment['LANG'] = config.LOCALES
        environment['USER'] = '******'
        environment['CASPER_GENERATE_UUID'] = '1'
        if xnest:
            environment['HOME'] = '/etc/skel'
            environment['XDG_CACHE_HOME'] = '/etc/skel/.cache'
            environment['XDG_DATA_HOME'] = '/etc/skel/.local/share'
            environment['XDG_CONFIG_HOME'] = '/etc/skel/.config'
            environment['DISPLAY'] = ':13'
        else:
            environment['DEBIAN_FRONTEND'] = 'noninteractive'
            # FIXME: is this needed?
            # environment['DEBIAN_PRIORITY'] = ''
            environment['DEBCONF_NONINTERACTIVE_SEEN'] = 'true'
            environment['DEBCONF_NOWARNINGS'] = 'true'

        if output:
            if CHROOT_DEBUG: message.sub_debug('Entering chroot')
            out = get_output(chroot_command)
            if CHROOT_DEBUG: message.sub_debug('Exiting chroot')
        else:
            if CHROOT_DEBUG: message.sub_debug('Entering chroot')
            system_command(chroot_command, shell=shell, \
                env=environment, cwd=cwd)
            if CHROOT_DEBUG: message.sub_debug('Exiting chroot')
    finally:
        if prepare:
            if os.path.isfile('{}.backup'.format(hosts)):
                copy_file('{}.backup'.format(hosts), hosts)
                os.unlink('{}.backup'.format(hosts))
            if os.path.isfile(inhibit):
                os.unlink(inhibit)
        if mount:
            for s in reversed(pseudofs):
                sdir = config.FILESYSTEM_DIR + s
                if os.path.ismount(sdir):
                    if MOUNT_DEBUG: message.sub_debug('Unmounting -f -l', sdir)
                    system_command((umount, '-f', '-l', sdir))
            time.sleep(0.1)  # Wait for lazy unmounts to unlazy...
        system_command(('sleep', '1')) # Make sure of it. (and log it)
    if output:
        return out
コード例 #34
0
def copy_file(source, destination):
    if FILE_DEBUG: message.sub_debug('File {} copied to'.format(source), destination)
    base = os.path.dirname(destination)
    if not os.path.isdir(base):
        os.makedirs(base)
    shutil.copyfile(source, destination)
コード例 #35
0
def main():
    global mount_dir
    if not os.path.isfile(config.ISO):
        raise(message.exception('ISO does not exist', config.ISO))
    elif not config.ISO.endswith('.iso'):
        raise(message.exception('File is not ISO', config.ISO))

    common.clean_work_dirs()
    common.create_work_dirs()

    message.sub_info('Creating mount directory')
    mount_dir = tempfile.mkdtemp(prefix=config.MOUNT_DIR + '/')
    message.sub_debug('Mount directory is', mount_dir)

    message.sub_info('Mounting ISO', config.ISO)
    try:
        # load the required kernel modules in cases the are not, if they are
        # builtin the command fails so ignoring that. the "-b" argument is to
        # ensure blacklisted modules are respected
        try:
            misc.system_command((misc.whereis('modprobe'), '-ba', 'loop', 'iso9660'))
        except:
            pass
        misc.system_command((misc.whereis('mount'), '-t', 'iso9660', '-o', \
            'ro,loop', config.ISO, mount_dir))
    except:
        message.sub_info('Removing', mount_dir)
        os.rmdir(mount_dir)
        common.clean_work_dirs()
        raise

    message.sub_info('Checking ISO')
    for spath in (mount_dir + '/casper/filesystem.squashfs', \
        mount_dir + '/casper/filesystem.manifest', \
        mount_dir + '/casper/filesystem.manifest-remove', \
        mount_dir + '/.disk', mount_dir + '/isolinux', ):
        if not os.path.exists(spath):
            message.sub_debug('Non-existing path', spath)
            common.clean_work_dirs()
            unmount_iso()
            raise(message.exception('Invalid ISO', config.ISO))

    message.sub_info('Unsquashing filesystem')
    try:
        misc.system_command((misc.whereis('unsquashfs'), '-f', '-d', \
            config.FILESYSTEM_DIR, mount_dir + '/casper/filesystem.squashfs'))
    except:
        unmount_iso()
        raise

    message.sub_info('Checking architecture')
    fs_arch = misc.chroot_exec(('dpkg', '--print-architecture'), \
        prepare=False, mount=False, output=True)
    host_arch = os.uname()[4]
    message.sub_debug('Filesystem architecture', fs_arch)
    message.sub_debug('Host architecture', host_arch)
    if fs_arch == 'amd64' and not host_arch == 'x86_64':
        message.sub_debug('The ISO architecture is amd64 and yours is not')
        common.clean_work_dirs()
        unmount_iso()
        raise(message.exception('The ISO architecture is amd64 and yours is not'))

    message.sub_info('Copying ISO files')
    for sfile in misc.list_files(mount_dir):
        if sfile.endswith('casper/filesystem.squashfs'):
            continue
        else:
            message.sub_debug('Copying', sfile)
            misc.copy_file(sfile, sfile.replace(mount_dir, config.ISO_DIR))

    unmount_iso()
コード例 #36
0
def search_file(string, sfile, exact=False, escape=True):
    if FILE_DEBUG: message.sub_debug('Searching {} for'.format(sfile), string)
    return search_string(string, read_file(sfile), exact=exact, escape=escape)
コード例 #37
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def readlines_file(sfile):
    if FILE_DEBUG: message.sub_debug('Reading lines from', sfile)
    rfile = open(sfile, 'r')
    content = rfile.readlines()
    rfile.close()
    return content
コード例 #38
0
def main():
    common.check_filesystem()

    message.sub_info('Doing sanity checks')
    lsb_file = misc.join_paths(config.FILESYSTEM_DIR, 'etc/lsb-release')
    if not os.path.isfile(lsb_file):
        raise(message.exception(lsb_file + ' does not exists'))

    isolinux_dir = misc.join_paths(config.ISO_DIR, 'isolinux')
    if not os.path.isdir(isolinux_dir):
        raise(message.exception(isolinux_dir + ' does not exist'))

    if misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/passwd')):
        raise(message.exception('User with UID 999 exists, this mean that automatic login will fail'))
    elif misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/group')):
        raise(message.exception('Group with GID 999 exists, this mean that automatic login will fail'))

    casper_dir = misc.join_paths(config.ISO_DIR, 'casper')
    if not os.path.isdir(casper_dir):
        message.sub_debug('Creating', casper_dir)
        os.makedirs(casper_dir)

    base_file = misc.join_paths(config.ISO_DIR, '.disk/base_installable')
    if os.path.isfile(misc.join_paths(config.FILESYSTEM_DIR, 'usr/bin/ubiquity')):
        if not os.path.isfile(base_file):
            message.sub_debug('Creating', base_file)
            misc.write_file(base_file, '')
    elif os.path.isfile(base_file):
        message.sub_debug('Removing', base_file)
        os.unlink(base_file)

    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')
    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    message.sub_info('Cleaning up')
    cleanup_files = ['casper/filesystem.squashfs', 'casper/initrd.lz', \
        'casper/vmlinuz', 'casper/vmlinuz.efi', 'casper/filesystem.manifest', \
        'casper/filesystem.size']
    cleanup_files.extend(glob.glob('.disk/casper-uuid-*'))
    for sfile in cleanup_files:
        full_file = misc.join_paths(config.ISO_DIR, sfile)
        if os.path.exists(full_file):
            message.sub_debug('Removing', full_file)
            os.unlink(full_file)

    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if os.path.exists(iso_file):
        message.sub_debug('Removing', iso_file)
        os.unlink(iso_file)

    detect_boot()
    if not vmlinuz:
        message.sub_info('Re-installing kernel')
        misc.chroot_exec(('apt-get', 'purge', '--yes', 'linux-image*', '-q'))
        misc.chroot_exec(('apt-get', 'install', '--yes', \
            'linux-image-generic', '-q'))
        misc.chroot_exec(('apt-get', 'clean'))
    else:
        message.sub_info('Updating initramfs')
        misc.chroot_exec(('update-initramfs', '-k', 'all', '-t', '-u'))
    detect_boot()

    if not initrd or not vmlinuz:
        raise(message.exception('Missing boot file (initrd or vmlinuz)'))
    else:
        message.sub_info('Copying boot files')
        message.sub_debug('Initrd', initrd)
        message.sub_debug('Vmlinuz', vmlinuz)
        misc.copy_file(initrd, misc.join_paths(config.ISO_DIR, 'casper/initrd.lz'))
        misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, 'casper/vmlinuz'))
        # FIXME: extend to support grub
        efi_boot_entry = False
        isolinux_dir = config.ISO_DIR + '/isolinux'
        if os.path.isdir(isolinux_dir):
            for sfile in os.listdir(isolinux_dir):
                if sfile.endswith('.cfg') and misc.search_file('vmlinuz.efi', isolinux_dir + '/' + sfile):
                    message.sub_debug('Found EFI entry in isolinux conf', sfile)
                    efi_boot_entry = True
        if os.path.isdir(misc.join_paths(config.ISO_DIR, 'efi/boot')) or \
            efi_boot_entry:
            message.sub_debug('Copying EFI vmlinuz')
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz.efi'))

    message.sub_info('Extracting casper UUID')
    confdir = config.FILESYSTEM_DIR + '/conf'
    if os.path.isdir(confdir):
        shutil.rmtree(confdir)
    os.makedirs(confdir)
    try:
        misc.chroot_exec('zcat ' + initrd.lstrip(config.FILESYSTEM_DIR) + ' | ' + ' cpio --quiet -id conf/uuid.conf', shell=True)
        kernel = re.search('initrd.img-*.*.*-*-(.*)', initrd).group(1)
        message.sub_debug('Kernel', kernel)
        misc.copy_file(confdir + '/uuid.conf', misc.join_paths(config.ISO_DIR, \
            '.disk/casper-uuid-' + kernel))
    finally:
        shutil.rmtree(confdir)

    message.sub_info('Creating squashed FileSystem')
    misc.system_command(('mksquashfs', config.FILESYSTEM_DIR, \
        misc.join_paths(config.ISO_DIR, 'casper/filesystem.squashfs'), \
        '-wildcards', '-ef', os.path.join(sys.prefix, 'share/customizer/exclude.list'), \
        '-comp', config.COMPRESSION))

    message.sub_info('Checking SquashFS filesystem size')
    sfs_size = os.path.getsize(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.squashfs'))
    message.sub_debug('SquashFS filesystem size', sfs_size)
    if sfs_size > 4000000000:
        raise(message.exception('The SquashFS filesystem size is greater than 4GB'))

    message.sub_info('Creating filesystem.size')
    fs_size = 0
    for root, subdirs, files in os.walk(config.FILESYSTEM_DIR):
        for sfile in files:
            sfull = os.path.join(root, sfile)
            if os.path.islink(sfull):
                continue
            # FIXME: respect ignored files from exclude.list
            fs_size += os.path.getsize(sfull)
    message.sub_debug('Root filesystem size', fs_size)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.size'), str(fs_size))

    message.sub_info('Creating filesystem.manifest')
    lpackages = misc.chroot_exec(('dpkg-query', '-W', \
        '--showformat=${Package} ${Version}\\n'), prepare=False, mount=False, \
        output=True)
    message.sub_debug('Packages', lpackages)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.manifest'), lpackages)

    # FIXME: do some kung-fu to check if packages are installed
    # and remove them from filesystem.manifest-remove if they are not

    md5sums_file = misc.join_paths(config.ISO_DIR, 'md5sum.txt')
    if os.path.isfile(md5sums_file):
        message.sub_info('Creating md5sum.txt')
        misc.write_file(md5sums_file, '')
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith('md5sum.txt'):
                continue

            # FIXME: read in chunks
            message.sub_debug('Checksuming', sfile)
            checksum = hashlib.md5(misc.read_file(sfile)).hexdigest()
            misc.append_file(md5sums_file, checksum + '  .' + \
                sfile.replace(config.ISO_DIR, '') +'\n')

    message.sub_info('Creating ISO')
    os.chdir(config.ISO_DIR)
    misc.system_command(('xorriso', '-as', 'mkisofs', '-r', '-V', \
        distrib + '-' + arch + '-' + release, '-b', 'isolinux/isolinux.bin', \
        '-c', 'isolinux/boot.cat', '-J', '-l', '-no-emul-boot', \
        '-boot-load-size', '4', '-boot-info-table', '-o', iso_file, \
        '-input-charset', 'utf-8', '.'))

    message.sub_info('Successfuly created ISO image', iso_file)
コード例 #39
0
ファイル: qemu.py プロジェクト: bravesoftdz/Customizer
def main():
    common.check_filesystem()

    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')
    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if not os.path.exists(iso_file):
        raise (message.exception('ISO image does not exist', iso_file))

    message.sub_info('Running QEMU with ISO image', iso_file)
    host_arch = os.uname()[4]
    if host_arch == 'x86_64':
        qemu = misc.whereis('qemu-system-x86_64')
    else:
        qemu = misc.whereis('qemu-system-i386')
    if not qemu:
        raise (message.exception('QEMU is not installed'))

    qemu_kvm = False
    command = [qemu, '-m', config.VRAM, '-cdrom', iso_file]
    if misc.search_string('-enable-kvm', misc.get_output((qemu, '-h'))):
        qemu_kvm = True
    # vmx for intel, svm for amd processors. it will most likely not work in
    # XEN environment
    host_kvm = False
    if os.path.exists('/dev/kvm') and os.path.exists('/proc/cpuinfo') and \
        misc.search_file('(?:\\s|^)flags.*(?:\\s)(vme|vmx)(?:\\s|$)', \
        '/proc/cpuinfo', escape=False):
        host_kvm = True
    if qemu_kvm and host_kvm:
        command.append('-enable-kvm')
    message.sub_debug('Host architecture', host_arch)
    message.sub_debug('QEMU KVM', qemu_kvm)
    message.sub_debug('Host KVM', host_kvm)
    misc.system_command(command)
コード例 #40
0
ファイル: misc.py プロジェクト: mnjstwins/Customizer
def search_file(string, sfile, exact=False, escape=True):
    if FILE_DEBUG: message.sub_debug('Searching {} for'.format(sfile), string)
    return search_string(string, read_file(sfile), exact=exact, escape=escape)
コード例 #41
0
def main():
    common.check_filesystem()

    # Basic sanity checks of files and paths that absolutely need to exist.
    message.sub_info('Doing sanity checks')
    lsb_file = misc.join_paths(config.FILESYSTEM_DIR, 'etc/lsb-release')
    if not os.path.isfile(lsb_file):
        raise(message.exception(lsb_file + ' does not exist'))

    isolinux_dir = misc.join_paths(config.ISO_DIR, 'isolinux')
    if not os.path.isdir(isolinux_dir):
        raise(message.exception(isolinux_dir + ' does not exist'))

    if misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/passwd')):
        raise(message.exception('User with UID 999 exists, this means automatic login will fail'))
    elif misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/group')):
        raise(message.exception('Group with GID 999 exists, this means automatic login will fail'))

    casper_dir = misc.join_paths(config.ISO_DIR, 'casper')
    if not os.path.isdir(casper_dir):
        message.sub_debug('Creating', casper_dir)
        os.makedirs(casper_dir)

    base_file = misc.join_paths(config.ISO_DIR, '.disk/base_installable')
    if os.path.isfile(misc.join_paths(config.FILESYSTEM_DIR, 'usr/bin/ubiquity')):
        if not os.path.isfile(base_file):
            message.sub_debug('Creating', base_file)
            misc.write_file(base_file, '')
    elif os.path.isfile(base_file):
        message.sub_debug('Removing', base_file)
        os.unlink(base_file)

    # Acquire distribution information from the FileSystem
    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')
    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    # Remove files, by name, that we know we must repopulate if they exist.
    message.sub_info('Cleaning up')
    cleanup_files = ['casper/filesystem.squashfs', 'casper/initrd.lz', \
        'casper/vmlinuz', 'casper/vmlinuz.efi', 'casper/filesystem.manifest', \
        'casper/filesystem.size']
    cleanup_files.extend(glob.glob('.disk/casper-uuid-*'))
    for sfile in cleanup_files:
        full_file = misc.join_paths(config.ISO_DIR, sfile)
        if os.path.exists(full_file):
            message.sub_debug('Removing', full_file)
            os.unlink(full_file)

    # Define the checksum files, and the ISO filename.
    md5sum_iso_file = misc.join_paths(config.WORK_DIR, 'md5sum')
    sha1sum_iso_file = misc.join_paths(config.WORK_DIR, 'sha1sum')
    sha256sum_iso_file = misc.join_paths(config.WORK_DIR, 'sha256sum')
    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if os.path.exists(iso_file):
        message.sub_debug('Removing', iso_file)
        os.unlink(iso_file)
    if os.path.exists(md5sum_iso_file):
        message.sub_debug('Removing', md5sum_iso_file)
        os.unlink(md5sum_iso_file)
    if os.path.exists(sha1sum_iso_file):
        message.sub_debug('Removing', sha1sum_iso_file)
        os.unlink(sha1sum_iso_file)
    if os.path.exists(sha256sum_iso_file):
        message.sub_debug('Removing', sha256sum_iso_file)
        os.unlink(sha256sum_iso_file)

    # Detect files needed for booting, the kernel, initramfs, xen and anything else.
    detect_boot()
    if not vmlinuz:
        message.sub_info('Re-installing kernel')
        misc.chroot_exec(('apt-get', 'purge', '--yes', 'linux-image*', '-q'))
        misc.chroot_exec(('apt-get', 'install', '--yes', \
            'linux-image-generic', '-q'))
        misc.chroot_exec(('apt-get', 'clean'))
    else:
        message.sub_info('Updating initramfs')
        misc.chroot_exec(('update-initramfs', '-k', 'all', '-t', '-u'))
    detect_boot()

    if not initrd or not vmlinuz:
        raise(message.exception('Missing boot file (initrd or vmlinuz)'))
    else:
        message.sub_info('Copying boot files')
        message.sub_debug('Initrd', initrd)
        message.sub_debug('Vmlinuz', vmlinuz)
        misc.copy_file(initrd, misc.join_paths(config.ISO_DIR, 'casper/initrd.lz'))
        
        # FIXME: extend to support grub
        efi_boot_entry = False
        isolinux_dir = config.ISO_DIR + '/isolinux'
        if os.path.isdir(isolinux_dir):
            for sfile in os.listdir(isolinux_dir):
                if sfile.endswith('.cfg') and misc.search_file('vmlinuz.efi', isolinux_dir + '/' + sfile):
                    message.sub_debug('Found EFI entry in isolinux conf', sfile)
                    efi_boot_entry = True
        if os.path.isdir(misc.join_paths(config.ISO_DIR, 'efi/boot')) or \
            efi_boot_entry:
            message.sub_debug('Copying EFI vmlinuz')
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz.efi'))
            os.link(misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz.efi'), misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz'))
            # EFI Kernels are still loadable by grub, modern ISOs lack a bare vmlinuz.
            # mkisofs/genisoimage -cache-inodes reuses hard linked inodes.
        else:
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, 'casper/vmlinuz'))
            # We only need to copy the bare kernel if we're not using EFI at all.

    # Copy optional boot-enablement packages onto the ISO, if found.
    if mt86plus:
        message.sub_debug('Memtest86+ kernel', mt86plus)
        misc.copy_file(mt86plus, misc.join_paths(config.ISO_DIR, 'install/mt86plus'))
    if xen_kernel:
        message.sub_debug('Xen kernel', xen_kernel)
        misc.copy_file(xen_kernel, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(xen_kernel)))
    if xen_efi:
        message.sub_debug('Xen EFI kernel', xen_efi)
        misc.copy_file(xen_efi, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(xen_efi)))
    if ipxe_kernel:
        message.sub_debug('iPXE kernel', ipxe_kernel)
        misc.copy_file(ipxe_kernel, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(ipxe_kernel)))
    if ipxe_efi:
        message.sub_debug('iPXE EFI kernel', ipxe_efi)
        misc.copy_file(ipxe_efi, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(ipxe_efi)))

    message.sub_info('Extracting casper UUID')
    confdir = config.FILESYSTEM_DIR + '/conf'
    if os.path.isdir(confdir):
        shutil.rmtree(confdir)
    os.makedirs(confdir)
    try:
        misc.chroot_exec('zcat ' + initrd.replace(config.FILESYSTEM_DIR, '') + ' | cpio --quiet -id conf/uuid.conf', \
            shell=True, cwd=config.FILESYSTEM_DIR)
        kernel = re.search('initrd.img-*.*.*-*-(.*)', initrd).group(1)
        message.sub_debug('Kernel', kernel)
        misc.copy_file(confdir + '/uuid.conf', misc.join_paths(config.ISO_DIR, \
            '.disk/casper-uuid-' + kernel))
    finally:
        shutil.rmtree(confdir)

    # Define some default compression parameters, including a 1MB blocksize for all compressors.
    compression_parameters = ('-b', '1048576', '-comp', config.COMPRESSION)
    if config.COMPRESSION == 'xz':  # Append additional compression parameters for xz.
        # Using the branch-call-jump filter provides a compression boost with executable code.
        # This can save a hundred megabytes easily, on an 800MB ISO. The dictionary size must
        # match the block size, and it's advisable to use larger block sizes, like 1MB or 4MB.
        compression_parameters += ('-Xbcj', 'x86', '-Xdict-size', '100%')
    message.sub_info('SquashFS Compression parameters', compression_parameters)

    # Create the compressed filesystem
    message.sub_info('Creating SquashFS compressed filesystem')
    make_squash_fs = ('mksquashfs', config.FILESYSTEM_DIR, \
        misc.join_paths(config.ISO_DIR, 'casper/filesystem.squashfs'), \
        '-wildcards', '-no-recovery', '-noappend', \
        '-ef', os.path.join(sys.prefix, 'share/customizer/exclude.list'))
    misc.system_command(make_squash_fs + compression_parameters)

    message.sub_info('Checking SquashFS filesystem size')
    sfs_size = os.path.getsize(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.squashfs'))
    message.sub_debug('SquashFS filesystem size', sfs_size)
    if sfs_size > 4000000000:
        raise(message.exception('The SquashFS filesystem size is greater than 4GB'))

    message.sub_info('Creating filesystem.size')
    fs_size = 0
    for root, subdirs, files in os.walk(config.FILESYSTEM_DIR):
        for sfile in files:
            sfull = os.path.join(root, sfile)
            if os.path.islink(sfull):
                continue
            # FIXME: respect ignored files from exclude.list
            fs_size += os.path.getsize(sfull)
    message.sub_debug('Root filesystem size', fs_size)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.size'), str(fs_size))

    message.sub_info('Creating filesystem.manifest')
    lpackages = misc.chroot_exec(('dpkg-query', '-W', \
        '--showformat=${Package} ${Version}\\n'), prepare=False, mount=False, \
        output=True)
    message.sub_debug('Packages', lpackages)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.manifest'), lpackages)

    # FIXME: do some kung-fu to check if packages are installed
    # and remove them from filesystem.manifest-remove if they are not

    # Creating a md5sum.txt file fixes lubuntu's integrity check.
    md5sums_file = misc.join_paths(config.ISO_DIR, 'md5sum.txt')
    if os.path.isfile(md5sums_file):
        message.sub_info('Creating md5sum.txt')
        misc.write_file(md5sums_file, '')
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith('md5sum.txt'):
                continue
            if sfile.endswith('SHA256SUMS'):
                continue
            message.sub_debug('MD5 Checksumming', sfile)
            checksum = misc.generate_hash_for_file('md5', sfile)
            misc.append_file(md5sums_file, checksum + '  .' + \
                sfile.replace(config.ISO_DIR, '') +'\n')

    # Creating a SHA256SUMS file fixes ubuntu-mini-remix's integrity check.
    shasums_file = misc.join_paths(config.ISO_DIR, 'SHA256SUMS')
    if os.path.isfile(shasums_file):
        message.sub_info('Creating SHA256SUMS')
        misc.write_file(shasums_file, '')
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith('md5sum.txt'):
                continue
            if sfile.endswith('SHA256SUMS'):
                continue
            message.sub_debug('SHA256 Checksumming', sfile)
            checksum = misc.generate_hash_for_file('sha256', sfile)
            misc.append_file(shasums_file, checksum + '  .' + \
                sfile.replace(config.ISO_DIR, '') +'\n')

    # Create the ISO filesystem
    message.sub_info('Creating ISO')
    os.chdir(config.ISO_DIR)
    misc.system_command(('xorriso', '-as', 'mkisofs', '-r', '-V', \
        distrib + '-' + arch + '-' + release, '-b', 'isolinux/isolinux.bin', \
        '-c', 'isolinux/boot.cat', '-J', '-l', '-no-emul-boot', \
        '-boot-load-size', '4', '-boot-info-table', '-o', iso_file, \
        '-cache-inodes', '-input-charset', 'utf-8', '.'))

    message.sub_info('Creating ISO checksums')
    md5checksum = misc.generate_hash_for_file('md5', iso_file)
    message.sub_info('ISO md5 checksum', md5checksum)
    misc.append_file(md5sum_iso_file, md5checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')
    sha1checksum = misc.generate_hash_for_file('sha1', iso_file)
    message.sub_info('ISO sha1 checksum', sha1checksum)
    misc.append_file(sha1sum_iso_file, sha1checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')
    sha256checksum = misc.generate_hash_for_file('sha256', iso_file)
    message.sub_info('ISO sha256 checksum', sha256checksum)
    misc.append_file(sha256sum_iso_file, sha256checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')

    message.sub_info('Successfuly created ISO image', iso_file)
コード例 #42
0
def readlines_file(sfile):
    if FILE_DEBUG: message.sub_debug('Reading lines from', sfile)
    rfile = open(sfile, 'r')
    content = rfile.readlines()
    rfile.close()
    return content
コード例 #43
0
def main():
    common.check_filesystem()

    # Basic sanity checks of files and paths that absolutely need to exist.
    message.sub_info('Doing sanity checks')
    lsb_file = misc.join_paths(config.FILESYSTEM_DIR, 'etc/lsb-release')
    if not os.path.isfile(lsb_file):
        raise(message.exception(lsb_file + ' does not exist'))

    isolinux_dir = misc.join_paths(config.ISO_DIR, 'isolinux')
    if not os.path.isdir(isolinux_dir):
        raise(message.exception(isolinux_dir + ' does not exist'))

    if misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/passwd')):
        raise(message.exception('User with UID 999 exists, this means automatic login will fail'))
    elif misc.search_file('999:999', misc.join_paths(config.FILESYSTEM_DIR, 'etc/group')):
        raise(message.exception('Group with GID 999 exists, this means automatic login will fail'))

    casper_dir = misc.join_paths(config.ISO_DIR, 'casper')
    if not os.path.isdir(casper_dir):
        message.sub_debug('Creating', casper_dir)
        os.makedirs(casper_dir)

    base_file = misc.join_paths(config.ISO_DIR, '.disk/base_installable')
    if os.path.isfile(misc.join_paths(config.FILESYSTEM_DIR, 'usr/bin/ubiquity')):
        if not os.path.isfile(base_file):
            message.sub_debug('Creating', base_file)
            misc.write_file(base_file, '')
    elif os.path.isfile(base_file):
        message.sub_debug('Removing', base_file)
        os.unlink(base_file)

    # Acquire distribution information from the FileSystem
    message.sub_info('Gathering information')
    arch = misc.chroot_exec(('dpkg', '--print-architecture'), prepare=False, \
        mount=False, output=True)
    distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_ID=')
    release = common.get_value(config.FILESYSTEM_DIR + '/etc/lsb-release', \
        'DISTRIB_RELEASE=')

    if isinstance(arch, bytes):  # For some reason this is of type 'bytes'.
        if int(sys.version_info[0]) >= 3:  # If we're running under python3
            arch = str(arch, 'utf-8')
        else:  # Otherwise just cast it to a str without the 'utf-8' option.
            arch = str(arch)

    # It's really annoying to override the output filename other ways.
    # If you actually try to change lsb-release, you end up breaking apt.
    livecd_file = misc.join_paths(config.FILESYSTEM_DIR, 'etc/livecd-release')
    if os.path.isfile(livecd_file):
        distrib = common.get_value(config.FILESYSTEM_DIR + '/etc/livecd-release', \
            'DISTRIB_ID=')
        release = common.get_value(config.FILESYSTEM_DIR + '/etc/livecd-release', \
            'DISTRIB_RELEASE=')
        message.sub_debug('Distribution and Release overriden by /etc/livecd-release')
        # Just overwrite the variables if the file actually exists, it's cleaner.

    message.sub_debug('Architecture', arch)
    message.sub_debug('Distribution (DISTRIB_ID)', distrib)
    message.sub_debug('Release (DISTRIB_RELEASE)', release)

    # Remove files, by name, that we know we must repopulate if they exist.
    message.sub_info('Cleaning up')
    cleanup_files = ['casper/filesystem.squashfs', 'casper/initrd.lz', \
        'casper/vmlinuz', 'casper/vmlinuz.efi', 'casper/filesystem.manifest', \
        'casper/filesystem.size']
    cleanup_files.extend(glob.glob('.disk/casper-uuid-*'))
    for sfile in cleanup_files:
        full_file = misc.join_paths(config.ISO_DIR, sfile)
        if os.path.exists(full_file):
            message.sub_debug('Removing', full_file)
            os.unlink(full_file)

    # Define the checksum files, and the ISO filename.
    md5sum_iso_file = misc.join_paths(config.WORK_DIR, 'md5sum')
    sha1sum_iso_file = misc.join_paths(config.WORK_DIR, 'sha1sum')
    sha256sum_iso_file = misc.join_paths(config.WORK_DIR, 'sha256sum')
    iso_file = '%s/%s-%s-%s.iso' % (config.WORK_DIR, distrib, arch, release)
    if os.path.exists(iso_file):
        message.sub_debug('Removing', iso_file)
        os.unlink(iso_file)
    if os.path.exists(md5sum_iso_file):
        message.sub_debug('Removing', md5sum_iso_file)
        os.unlink(md5sum_iso_file)
    if os.path.exists(sha1sum_iso_file):
        message.sub_debug('Removing', sha1sum_iso_file)
        os.unlink(sha1sum_iso_file)
    if os.path.exists(sha256sum_iso_file):
        message.sub_debug('Removing', sha256sum_iso_file)
        os.unlink(sha256sum_iso_file)

    # Detect files needed for booting, the kernel, initramfs, xen and anything else.
    detect_boot()
    if not vmlinuz:
        if config.PURGE_KERNEL:
            message.sub_info('Re-installing kernel')
            misc.chroot_exec(('apt-get', 'purge', '--yes', 'linux-image*', '-q'))
        message.sub_debug("Kernel Selection Debug: {0}, {1}".format(type(config.KERNEL), config.KERNEL))
        if config.KERNEL is not "default" or None:
            misc.chroot_exec(('apt-get', 'install', '--yes', \
                config.KERNEL, '-q'))
        else:  # use the kernel the user specified in the config.
            if arch is not "amd64":  # then use the 32bit 'linux-image-generic'
                misc.chroot_exec(('apt-get', 'install', '--yes', \
                    'linux-image-generic', '-q'))
            else:  # use the amd64 'linux-signed-generic' for uEFI
                misc.chroot_exec(('apt-get', 'install', '--yes', \
                    'linux-signed-generic', '-q'))

        misc.chroot_exec(('apt-get', 'clean'))
    else:
        message.sub_info('Updating initramfs')
        misc.chroot_exec(('update-initramfs', '-k', 'all', '-t', '-u'))
    detect_boot()

    if not initrd or not vmlinuz:
        raise(message.exception('Missing boot file (initrd or vmlinuz)'))
    else:
        message.sub_info('Copying boot files')
        message.sub_debug('Initrd', initrd)
        message.sub_debug('Vmlinuz', vmlinuz)
        misc.copy_file(initrd, misc.join_paths(config.ISO_DIR, 'casper/initrd.lz'))
        
        # FIXME: extend to support grub
        efi_boot_entry = False
        isolinux_dir = config.ISO_DIR + '/isolinux'
        if os.path.isdir(isolinux_dir):
            for sfile in os.listdir(isolinux_dir):
                if sfile.endswith('.cfg') and misc.search_file('vmlinuz.efi', isolinux_dir + '/' + sfile):
                    message.sub_debug('Found EFI entry in isolinux conf', sfile)
                    efi_boot_entry = True
        if os.path.isdir(misc.join_paths(config.ISO_DIR, 'efi/boot')) or \
            efi_boot_entry:
            message.sub_debug('Copying EFI vmlinuz')
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz.efi'))
            os.link(misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz.efi'), misc.join_paths(config.ISO_DIR, \
                'casper/vmlinuz'))
            # EFI Kernels are still loadable by grub, modern ISOs lack a bare vmlinuz.
            # mkisofs/genisoimage -cache-inodes reuses hard linked inodes.
        else:
            misc.copy_file(vmlinuz, misc.join_paths(config.ISO_DIR, 'casper/vmlinuz'))
            # We only need to copy the bare kernel if we're not using EFI at all.

    # Copy optional boot-enablement packages onto the ISO, if found.
    if mt86plus:
        message.sub_debug('Memtest86+ kernel', mt86plus)
        misc.copy_file(mt86plus, misc.join_paths(config.ISO_DIR, 'install/mt86plus'))
    if xen_kernel:
        message.sub_debug('Xen kernel', xen_kernel)
        misc.copy_file(xen_kernel, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(xen_kernel)))
    if xen_efi:
        message.sub_debug('Xen EFI kernel', xen_efi)
        misc.copy_file(xen_efi, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(xen_efi)))
    if ipxe_kernel:
        message.sub_debug('iPXE kernel', ipxe_kernel)
        misc.copy_file(ipxe_kernel, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(ipxe_kernel)))
    if ipxe_efi:
        message.sub_debug('iPXE EFI kernel', ipxe_efi)
        misc.copy_file(ipxe_efi, \
            misc.join_paths(config.ISO_DIR, 'casper/' + os.path.basename(ipxe_efi)))

    kernel_type = re.search('initrd.img-*.*.*-*-(.*)', initrd).group(1)
    message.sub_debug('Kernel Variant Type', kernel_type)

    message.sub_info('Extracting casper UUID')
    confdir = config.FILESYSTEM_DIR + '/conf'
    if os.path.isdir(confdir):
        shutil.rmtree(confdir)
    os.makedirs(confdir)

    if common.is_gz_file(initrd):
        message.sub_debug('Kernel Compression', "gzip without early microcode")
        try:
            misc.chroot_exec('zcat ' + initrd.replace(config.FILESYSTEM_DIR, '') + ' | cpio --quiet -id conf/uuid.conf', \
                shell=True, cwd=config.FILESYSTEM_DIR)
            misc.copy_file(confdir + '/uuid.conf', misc.join_paths(config.ISO_DIR, \
                '.disk/casper-uuid-' + kernel_type))
        finally:
            shutil.rmtree(confdir)

    else:
        message.sub_debug('Kernel Compression', "gzip with early microcode")
        try:
            misc.chroot_exec('unmkinitramfs ' + initrd.replace(config.FILESYSTEM_DIR, '') + ' conf/', \
                shell=True, cwd=config.FILESYSTEM_DIR)
            misc.copy_file(confdir + '/main/conf/uuid.conf', misc.join_paths(config.ISO_DIR, \
                '.disk/casper-uuid-' + kernel_type))
        finally:
            shutil.rmtree(confdir)

    # Define some default compression parameters, including a 1MB blocksize for all compressors.
    compression_parameters = ('-b', '1048576', '-comp', config.COMPRESSION)
    if config.COMPRESSION == 'xz':  # Append additional compression parameters for xz.
        # Using the branch-call-jump filter provides a compression boost with executable code.
        # This can save a hundred megabytes easily, on an 800MB ISO. The dictionary size must
        # match the block size, and it's advisable to use larger block sizes, like 1MB or 4MB.
        compression_parameters += ('-Xbcj', 'x86', '-Xdict-size', '100%')
    message.sub_info('SquashFS Compression parameters', compression_parameters)

    # Create the compressed filesystem
    message.sub_info('Creating SquashFS compressed filesystem')
    make_squash_fs = ('mksquashfs', config.FILESYSTEM_DIR, \
        misc.join_paths(config.ISO_DIR, 'casper/filesystem.squashfs'), \
        '-wildcards', '-no-recovery', '-noappend', \
        '-ef', os.path.join(sys.prefix, 'share/customizer/exclude.list'))
    misc.system_command(make_squash_fs + compression_parameters)

    message.sub_info('Checking SquashFS filesystem size')
    sfs_size = os.path.getsize(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.squashfs'))
    message.sub_debug('SquashFS filesystem size', sfs_size)
    if sfs_size > 4000000000:
        raise(message.exception('The SquashFS filesystem size is greater than 4GB'))

    message.sub_info('Creating filesystem.size')
    fs_size = 0
    for root, subdirs, files in os.walk(config.FILESYSTEM_DIR):
        for sfile in files:
            sfull = os.path.join(root, sfile)
            if os.path.islink(sfull):
                continue
            # FIXME: respect ignored files from exclude.list
            fs_size += os.path.getsize(sfull)
    message.sub_debug('Root filesystem size', fs_size)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.size'), str(fs_size))

    message.sub_info('Creating filesystem.manifest')
    lpackages = misc.chroot_exec(('dpkg-query', '-W', \
        '--showformat=${Package} ${Version}\\n'), prepare=False, mount=False, \
        output=True)
    if isinstance(lpackages, bytes):  # For some reason this is of type 'bytes'.
        if int(sys.version_info[0]) >= 3:  # If we're running under python3
            lpackages = str(lpackages, 'utf-8')
        else:  # Otherwise just cast it to a str without the 'utf-8' option.
            lpackages = str(lpackages)
    message.sub_debug('Packages', lpackages)
    misc.write_file(misc.join_paths(config.ISO_DIR, \
        'casper/filesystem.manifest'), lpackages)

    # FIXME: do some kung-fu to check if packages are installed
    # and remove them from filesystem.manifest-remove if they are not

    # Creating a md5sum.txt file fixes lubuntu's integrity check.
    md5sums_file = misc.join_paths(config.ISO_DIR, 'md5sum.txt')
    if os.path.isfile(md5sums_file):
        message.sub_info('Creating md5sum.txt')
        misc.write_file(md5sums_file, '')
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith('md5sum.txt'):
                continue
            if sfile.endswith('SHA256SUMS'):
                continue
            message.sub_debug('MD5 Checksumming', sfile)
            checksum = misc.generate_hash_for_file('md5', sfile)
            misc.append_file(md5sums_file, checksum + '  .' + \
                sfile.replace(config.ISO_DIR, '') +'\n')

    # Creating a SHA256SUMS file fixes ubuntu-mini-remix's integrity check.
    shasums_file = misc.join_paths(config.ISO_DIR, 'SHA256SUMS')
    if os.path.isfile(shasums_file):
        message.sub_info('Creating SHA256SUMS')
        misc.write_file(shasums_file, '')
        for sfile in misc.list_files(config.ISO_DIR):
            if sfile.endswith('md5sum.txt'):
                continue
            if sfile.endswith('SHA256SUMS'):
                continue
            message.sub_debug('SHA256 Checksumming', sfile)
            checksum = misc.generate_hash_for_file('sha256', sfile)
            misc.append_file(shasums_file, checksum + '  .' + \
                sfile.replace(config.ISO_DIR, '') +'\n')

    # Create the ISO filesystem
    message.sub_info('Creating ISO')
    os.chdir(config.ISO_DIR)
    misc.system_command(('xorriso', '-as', 'mkisofs', '-r', '-V', \
        distrib + '-' + arch + '-' + release, '-isohybrid-mbr',\
        '/usr/lib/ISOLINUX/isohdpfx.bin', '-b', 'isolinux/isolinux.bin', \
        '-c', 'isolinux/boot.cat', '-J', '-l', '-no-emul-boot', \
        '-boot-load-size', '4', '-boot-info-table', '-o', iso_file, \
        '-cache-inodes', '-input-charset', 'utf-8', '.'))

    message.sub_info('Creating ISO checksums')
    md5checksum = misc.generate_hash_for_file('md5', iso_file)
    message.sub_info('ISO md5 checksum', md5checksum)
    misc.append_file(md5sum_iso_file, md5checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')
    sha1checksum = misc.generate_hash_for_file('sha1', iso_file)
    message.sub_info('ISO sha1 checksum', sha1checksum)
    misc.append_file(sha1sum_iso_file, sha1checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')
    sha256checksum = misc.generate_hash_for_file('sha256', iso_file)
    message.sub_info('ISO sha256 checksum', sha256checksum)
    misc.append_file(sha256sum_iso_file, sha256checksum + '  .' + \
        iso_file.replace(config.WORK_DIR, '') +'\n')

    message.sub_info('Successfuly created ISO image', iso_file)