Exemple #1
0
def mount(mount_point, profile):
    mount_points = {}

    for item in profile.items('filesystem'):
        if item[0].startswith('extra_mount_'):
            parts = [i.strip() for i in item[1].split(':')]
            if len(parts) == 3:
                mount_points[parts[2]] = tuple(parts[:2])
            else:
                mount_points[parts[2]] = tuple(parts[:2] +
                                               [parts[3].split(',')])

    for fs in filesystem_list:
        if 'mount_point' in fs and fs['mount_point'] is not None:
            mount_points[fs['mount_point']] = (fs['type'], fs['block_device'],
                                               fs['options'])

    mount_order = list(mount_points.keys())
    mount_order.sort(
        key=lambda x: len(x)
    )  # no need to do any fancy trees, we know that the string length of a dependant mount point is allways longer than it's parent

    for point in mount_order:
        _mount('{0}{1}'.format(mount_point, point), *mount_points[point])

    if not os.path.isdir(os.path.join(mount_point, 'etc')):
        os.makedirs(os.path.join(mount_point, 'etc'))

    execute('ln -s /proc/self/mounts {0}'.format(
        os.path.join(mount_point, 'etc', 'mtab')))
Exemple #2
0
def mkfs():
    for fs in filesystem_list:
        if 'type' in fs:
            print('Making Filesystem "{0}" on "{1}"...'.format(
                fs['type'], fs['block_device']))
            execute(mkfs_map[fs['type']].format(**fs))
            for line in execute_lines('/sbin/blkid -o export {0}'.format(
                    fs['block_device'])):
                (key, value) = line.split('=')
                if key.endswith('UUID'):
                    fs['uuid'] = value
                    break
Exemple #3
0
def installBase( install_root, profile ):
  if manager_type == 'apt':
    chroot_execute( '/usr/bin/apt-get install -q -y {0}'.format( profile.get( 'packaging', 'base' ) ) )

  elif manager_type == 'yum':
    chroot_execute( '/usr/bin/yum -y groupinstall {0}'.format( profile.get( 'packaging', 'base' ) ) )
    chroot_execute( '/usr/bin/yum -y reinstall yum centos-release' )  # find a better way to figure out what needs to be re-installed
    execute( 'ash -c "rm {0}/etc/yum.repos.d/*"'.format( install_root ) )  # clean up extra repos that some package might have left behind... this is the last time we will do this.... any package after this we will allow to keep their repos, we are really just after the base ones
    renderTemplates( profile.get( 'packaging', 'source_templates' ).split( ',' ) )

  elif manager_type == 'zypper':
    chroot_execute( '/usr/bin/zypper --non-interactive install {0}'.format( profile.get( 'packaging', 'base' ) ) )
Exemple #4
0
def _do_mount(mount_point, fstype, fs, options=[]):
    print('Mounting "{0}"({1}) to "{2}", options "{3}"...'.format(
        fs, fstype, mount_point, options))

    if options:
        options = '-o {0}'.format(','.join(options))
    else:
        options = ''

    if fstype:
        execute('mount {0} -t {1} {2} {3}'.format(options, fstype, fs,
                                                  mount_point))
    else:
        execute('mount {0} {1} {2}'.format(options, fs, mount_point))
Exemple #5
0
def configSources(install_root, profile, value_map):
    global manager_type
    manager_type = profile.get('packaging', 'manager_type')

    if manager_type not in ('apt', 'yum', 'zypper'):
        raise Exception(
            'Unknwon Packaging manager type "{0}"'.format(manager_type))

    if manager_type == 'yum':
        execute('ash -c "rm {0}/etc/yum.repos.d/*"'.format(install_root))

    key_uris = []
    for repo in value_map['repo_list']:
        if 'key_uri' in repo:
            if repo['type'] != manager_type:
                continue

            uri = repo['key_uri']
            if uri not in key_uris:
                try:
                    proxy = repo['proxy']
                except Exception:
                    proxy = None

                tmp = http_getfile(uri, proxy=proxy)

                if 'key_file' in repo:
                    key_file_path = '{0}/{1}'.format(install_root,
                                                     repo['key_file'])
                    if not os.path.isdir(os.path.dirname(key_file_path)):
                        os.makedirs(os.path.dirname(key_file_path))

                    open(key_file_path, 'wb').write(tmp)

                elif manager_type == 'apt':  # for binary keys, write it to a file ^
                    chroot_execute('/usr/bin/apt-key add -', tmp.decode())

                key_uris.append(uri)

    renderTemplates(profile.get('packaging', 'source_templates').split(','))

    print('Updating Repo Data...')
    if manager_type == 'apt':
        chroot_execute('/usr/bin/apt-get update')
Exemple #6
0
def _addBCache(
    id, backing_dev, cache_dev, mode
):  # until we find a way to get the device name from make-bcache, we hope that the ids start at 0 and incrament by one
    dev_name = '/dev/bcache{0}'.format(id)

    if not os.path.exists('/sys/fs/bcache'):
        execute('/sbin/modprobe bcache')

    print('Creating bcache "{0}" with backing "{1}" and cache "{2}"...'.format(
        dev_name, backing_dev, cache_dev))

    execute('/sbin/make-bcache --wipe-bcache {0} -B {1} -C {2}'.format(
        ('--writeback' if mode == 'writeback' else ''), backing_dev,
        cache_dev))

    open('/sys/fs/bcache/register', 'w').write(backing_dev)
    open('/sys/fs/bcache/register', 'w').write(cache_dev)

    return dev_name
Exemple #7
0
def _addRAID(id, member_list, md_type, meta_version):
    dev_name = '/dev/md{0}'.format(id)

    print('Creating RAID "{0}" of type "{1}" members {2}...'.format(
        dev_name, md_type, member_list))

    if md_type in (1, 10) and len(member_list) % 2:
        raise Exception(
            'RAID {0} requires even number of members'.format(md_type))

    if md_type in (5, 6) and len(member_list) < 3:
        raise Exception(
            'RAID {0} requires a minimum of 3 members'.format(md_type))

    execute(
        '/sbin/mdadm {0} --create --run --force --metadata={1} --level={2} --raid-devices={3} {4}'
        .format(dev_name, meta_version, md_type, len(member_list),
                ' '.join(member_list)))

    return dev_name
Exemple #8
0
def cleanPackaging( install_root ):
  if manager_type == 'apt':
    chroot_execute( '/usr/bin/apt-get clean' )

  elif manager_type == 'yum':
    chroot_execute( '/usr/bin/yum clean all' )
    execute( '/bin/find {0} \( -path {0}/proc -o -path {0}/sys \) -prune -o -name *.rpmnew -exec rm {{}} \;'.format( install_root ) )
    execute( '/bin/find {0} \( -path {0}/proc -o -path {0}/sys \) -prune -o -name *.rpmsave -exec rm {{}} \;'.format( install_root ) )

  elif manager_type == 'zypper':
    chroot_execute( '/usr/bin/zypper --non-interactive clean' )
    execute( '/bin/find {0} \( -path {0}/proc -o -path {0}/sys \) -prune -o -name *.rpmnew -exec rm {{}} \;'.format( install_root ) )
    execute( '/bin/find {0} \( -path {0}/proc -o -path {0}/sys \) -prune -o -name *.rpmsave -exec rm {{}} \;'.format( install_root ) )
Exemple #9
0
def unmount(
    mount_point, profile
):  # don't umount -a, other things after the installer still need /proc and such
    execute('rm {0}'.format(os.path.join(mount_point, 'etc', 'mtab')))
    mtab = profile.get('filesystem', 'mtab')
    if mtab == 'file':
        execute('touch {0}'.format(os.path.join(mount_point, 'etc', 'mtab')))
    else:
        execute('ln -s {0} {1}'.format(
            mtab, os.path.join(mount_point, 'etc', 'mtab')))

    count = 0
    pid_list = [
        int(i)
        for i in execute_lines('sh -c "lsof | grep target | cut -f 1 | uniq"')
    ]
    while pid_list:
        if count < 3:
            print('Sending SIGTERM to pids: {0} ...'.format(pid_list))
            tmp = signal.SIGTERM

        else:
            print('Sending SIGKILL to pids: {0} ...'.format(pid_list))
            tmp = signal.SIGKILL

        for pid in pid_list:
            try:
                os.kill(pid, tmp)
            except OSError as e:
                if e.errno != 3:
                    raise e

        time.sleep(2)
        pid_list = [
            int(i) for i in execute_lines(
                'sh -c "lsof | grep target | cut -f 1 | uniq"')
        ]
        count += 1

    mount_list.sort(key=lambda x: len(x[0]))
    mount_list.reverse()
    for mount in mount_list:
        print('Unmounting "{0}"...'.format(mount[0]))
        execute('/bin/umount {0}'.format(mount[0]))
Exemple #10
0
def partition(profile, value_map):
    global filesystem_list, boot_drives, partition_map, parted_task_map

    partition_type = profile.get('filesystem', 'partition_type')
    if partition_type not in ('gpt', 'msdos'):
        raise FileSystemException(
            'Invalid partition_type "{0}"'.format(partition_type))

    fs_type = profile.get('filesystem', 'fs_type')
    if fs_type not in mkfs_map.keys():
        raise FileSystemException('Invalid fs_type "{0}"'.format(fs_type))

    boot_fs_type = profile.get('filesystem', 'boot_fs_type')
    if boot_fs_type not in mkfs_map.keys():
        raise FileSystemException(
            'Invalid boot_fs_type "{0}"'.format(boot_fs_type))

    md_meta_version = profile.get(
        'filesystem', 'md_meta_version'
    )  # TODO:  remove md_meta_version from the profiles, then detect if the disks are 4K, if so use version 1.2 else 1.1, then update _mdSyncPercentange
    try:
        if value_map['md_meta_version']:
            md_meta_version = value_map['md_meta_version']
    except KeyError:
        pass

    try:
        tmp_target_drives = value_map['target_drives']
    except KeyError:
        tmp_target_drives = None

    target_drives = None

    if tmp_target_drives:
        print('Target Drives: "{0}"'.format('", "'.join(tmp_target_drives)))

    count = 0
    while True:
        try:
            (target_drives, drive_map) = _getTargetDrives(tmp_target_drives)
            break
        except MissingDrives as e:
            count += 1
            if count >= 10:
                raise e
            print('Waiting for target drive ({0}) to appear...'.format(e))
            time.sleep(6)

    print('Target Block Devices: "{0}"'.format('", "'.join(target_drives)))

    if partition_type == 'gpt':
        boot_rsvd_size = 5
    else:
        boot_rsvd_size = 1

    swap_size = 512
    try:
        if value_map['swap_size']:
            swap_size = int(value_map['swap_size'])
    except KeyError:
        pass

    boot_size = 512
    try:
        if value_map['boot_size']:
            boot_size = int(value_map['boot_size'])
    except KeyError:
        pass

    mounting_options = []
    try:
        if value_map['mounting_options'] and value_map[
                'mounting_options'] != 'defaults':
            mounting_options = value_map['mounting_options'].split(',')
    except KeyError:
        pass

    scheme = 'single'
    try:
        if value_map['partition_scheme']:
            scheme = value_map['partition_scheme']
    except KeyError:
        pass

    recipe = None
    if scheme == 'custom':
        try:
            recipe = value_map['partition_recipe']
        except KeyError:
            raise Exception(
                'custom paritition_scheme specified, but recipe not found.')

    elif scheme in partition_recipes:
        recipe = partition_recipes[scheme]

    if not recipe:
        raise Exception('Unknown partitioning scheme "{0}"'.format(scheme))

    targets = set([int(i['target']) for i in recipe if 'target' in i])
    if len(target_drives) <= max(targets):
        raise Exception(
            'Not Enough Target Drives, need "{0}" found "{1}"'.format(
                max(targets) + 1, len(target_drives)))

    md_list = {}
    pv_list = {}
    bcache_cache_list = {}
    bcache_backing_list = {}

    try:
        swap_size = swap_size / sum(
            [1 for i in recipe if 'type' in i and i['type'] == 'swap'])
    except ZeroDivisionError:  # swap unused
        swap_size = 0

    # check drive sizes

    boot_drives = _targetsWithMount(recipe, '/boot')
    if not boot_drives:
        boot_drives = _targetsWithMount(recipe, '/')
    if not boot_drives:
        raise Exception('Unable to determine the boot_drives')

    boot_drives = [target_drives[i] for i in boot_drives]

    for target in targets:
        parted_task_map[target_drives[target]] = [
            'mklabel {0}'.format(partition_type)
        ]

    if partition_type == 'gpt':
        for drive in boot_drives:
            grub_partition = _addPartition(drive, 'bios_grub', boot_rsvd_size)
            if os.path.exists('/sys/firmware/efi'):
                filesystem_list.append({
                    'mount_point': '/boot/efi',
                    'options': mounting_options,
                    'type': 'vfat',
                    'block_device': grub_partition
                })
            else:
                filesystem_list.append({
                    'type': 'vfat',
                    'block_device': grub_partition
                })

    else:  # give room for MBR Boot sector
        for drive in boot_drives:
            _addPartition(drive, 'blank', boot_rsvd_size)

    # { 'ref_size': [ swap | boot ], 'lambda': < lambda takes a dict returns a number, sizes in the dict update as it goes > }
    for item in [i for i in recipe if 'ref_size' in i]:
        sizes = {
            'swap': swap_size,
            'boot': boot_size,
            'boot_rsvd': boot_rsvd_size
        }
        if 'lambda' in item:
            tmp = item['lambda'](sizes)

        if item['ref_size'] == 'boot':
            boot_size = tmp

        elif item['ref_size'] == 'swap':
            swap_size = tmp

    # { 'target': < drive # >, [ 'type': '<swap|fs type|md|pv|blank>' if not specified, fs will be used], [ 'group': <md group> (if type == 'md') ][ 'group': <bcache group> (if type == 'bcache') ][ 'group': <volume group group> (if type == 'pv') ][ 'options': '<mounting options other than the default>' (for type == 'fs') | 'priority': <swap memer priority other then 0> (for type == 'swap') ] [ 'mount_point': '< mount point >' if type is a fs type, set to None to not mount], 'size': '<see if statement>' }
    for item in [i for i in recipe if 'target' in i]:
        target = int(item['target'])
        target_drive = target_drives[target]
        size = item['size']

        if size == 'end':
            size = 0

        elif size == 'boot':
            size = boot_size

        elif size == '- boot':
            size = -1 * boot_size

        elif size == 'swap':
            size = swap_size

        elif size == '- swap':
            size = -1 * swap_size

        elif isinstance(size, str) and size[-1] == '%':
            size = float(size[0:-1]) / 100.0
            if size == 1.0:
                size = 0  # avoid any potential math problems

            elif size <= 0.0 or size >= 1.0:  # yes inclusive, can't do a 0% nor a 100% sized disks
                raise Exception('Invalid size percentage "{0}"'.format(
                    item['size']))

            else:
                size = int((drive_map[target_drive].drive.capacity * 1024) *
                           size)  # drive.capacity is in Gb

        else:
            size = int(size)  # in Mb

        try:
            part_type = item['type']
        except KeyError:
            if item['mount_point'] == '/boot':
                part_type = boot_fs_type
            else:
                part_type = fs_type

        try:
            if item['options'] != 'defaults':
                options = item['options'].split(',')
        except KeyError:
            options = list(mounting_options)

        try:
            priority = int(item['priority'])
        except KeyError:
            priority = 0

        if part_type == 'swap':
            block_device = _addPartition(target_drive, 'swap', size)

        elif part_type in ('blank', 'empty'):
            _addPartition(target_drive, part_type, size)

        else:
            block_device = _addPartition(target_drive, 'fs', size)

        if part_type == 'md':
            try:
                md_list[int(item['group'])].append(
                    (block_device, drive_map[target_drive]))
            except KeyError:
                md_list[int(item['group'])] = [(block_device,
                                                drive_map[target_drive])]

        elif part_type == 'bcache':
            if item['as'] == 'cache':
                bcache_cache_list[int(item['group'])] = (block_device)
            elif item['as'] == 'backing':
                bcache_backing_list[int(item['group'])] = (block_device)

        elif part_type == 'pv':
            try:
                pv_list[int(item['group'])].append(
                    (block_device, drive_map[target_drive]))
            except KeyError:
                pv_list[int(item['group'])] = [(block_device,
                                                drive_map[target_drive])]

        elif part_type == 'swap':
            filesystem_list.append({
                'type': 'swap',
                'priority': priority,
                'block_device': block_device
            })

        elif part_type in ('blank', 'empty'):
            pass

        else:
            if drive_map[
                    target_drive].supportsTrim and part_type in FS_WITH_TRIM:
                options.append('discard')

            filesystem_list.append({
                'mount_point': item['mount_point'],
                'type': part_type,
                'options': options,
                'block_device': block_device
            })

    for target in parted_task_map:
        print('Setting up partitions on "{0}"...'.format(target))
        _parted(target, parted_task_map[target])

    # { 'md': <group #>, [ 'type': '<fs type>' if not specified, default fs will be used], 'level': <raid level> [ 'options': '<mounting options other than the default>' ], [ 'meta_version': <md meta version if not default ], 'mount_point': '<mount point>' }
    for item in [i for i in recipe if 'md' in i]:
        try:
            part_type = item['type']
        except KeyError:
            part_type = fs_type

        try:
            meta_version = item['meta_version']
        except KeyError:
            meta_version = md_meta_version

        try:
            if item['options'] != 'defaults':
                options = item['options'].split(',')
        except KeyError:
            options = list(mounting_options)

        block_list = []
        supportsTrim = True
        for (block_device, drive) in md_list[int(item['md'])]:
            block_list.append(block_device)
            supportsTrim &= drive.supportsTrim

        block_device = _addRAID(int(item['md']), block_list,
                                int(item['level']), meta_version)

        if part_type == 'swap':
            filesystem_list.append({
                'type': 'swap',
                'priority': priority,
                'block_device': block_device
            })

        elif part_type == 'bcache':
            if item['as'] == 'cache':
                bcache_cache_list[int(item['group'])] = (block_device)
            elif item['as'] == 'backing':
                bcache_backing_list[int(item['group'])] = (block_device)

        elif 'mount_point' in item:
            if supportsTrim and part_type in FS_WITH_TRIM:
                options.append('discard')

            filesystem_list.append({
                'mount_point': item['mount_point'],
                'type': part_type,
                'options': options,
                'block_device': block_device,
                'members': block_list
            })

    # { 'bcache': <group #>, 'backing': <list of block device>, [ 'type': '<fs type>' if not specified, default fs will be used], [ 'options': '<mounting options other than the default>' ], 'mount_point': '<mount point>' }
    for item in [i for i in recipe if 'bcache' in i]:
        try:
            part_type = item['type']
        except KeyError:
            part_type = fs_type

        try:
            if item['options'] != 'defaults':
                options = item['options'].split(',')
        except KeyError:
            options = list(mounting_options)

        block_device = _addBCache(int(item['bcache']),
                                  bcache_backing_list[int(item['bcache'])],
                                  bcache_cache_list[int(item['bcache'])],
                                  item.get('mode', None))

        if part_type == 'swap':
            filesystem_list.append({
                'type': 'swap',
                'priority': priority,
                'block_device': block_device
            })
        elif 'mount_point' in item:
            filesystem_list.append(
                {
                    'mount_point': item['mount_point'],
                    'type': part_type,
                    'options': options,
                    'block_device': block_device
                }
            )  # 'members' could recursivly include the members of the backing, for now this will prevent support from booting from a bcache

    if pv_list:
        vg_names = {}
        vg_extents = {}
        vg_disks = {}

        for vg in pv_list:
            for (block_device, drive) in pv_list[vg]:
                print('Creating PV on "{0}"...'.format(block_device))
                execute('/sbin/lvm pvcreate -ff -y {0}'.format(block_device))

        # { 'vg': < volumne group #>, 'name': <volume group name > },
        for item in [i for i in recipe if 'vg' in i]:
            vg = int(item['vg'])
            vg_names[vg] = item['name']
            vg_disks[vg] = []
            block_list = []
            for (block_device, drive) in pv_list[vg]:
                block_list.append(block_device)
                vg_disks[vg].append(drive)

            print('Creating LV "{0}" members {1}...'.format(
                vg_names[vg], block_list))
            execute('/sbin/lvm vgcreate {0} {1}'.format(
                vg_names[vg], ' '.join(block_list)))
            for line in execute_lines('/sbin/lvm vgdisplay {0}'.format(
                    vg_names[vg])):
                result = re.match('[ ]*Total PE[ ]*([0-9\.]*)', line)
                if result:
                    vg_extents[vg] = int(result.group(1))
                    break
            if vg not in vg_extents or not vg_extents[vg]:
                raise Exception(
                    'Unable to get Size/Extents of VG "{0}"'.format(
                        vg_names[vg]))

        # { 'lv': < volume group #>, 'name': <lv name>, 'mount_point': <mount point>, 'size': < integer size>, [ 'type': '<fs type>' if not specified, default fs will be used][ 'options': '<mounting options other than the default>' ] }
        for item in [i for i in recipe if 'lv' in i]:
            vg = int(item['lv'])
            size = item['size']

            if size == 'boot':
                size = boot_size

            elif size == 'swap':
                size = swap_size

            if isinstance(size, str) and size[-1] == '%':
                size = float(size[0:-1]) / 100.0
                if size == 1.0:
                    size = '--extents {0}'.format(
                        vg_extents[vg])  # avoid any potential math problems
                elif size <= 0.0 or size >= 1.0:
                    raise Exception('Invalid size percentage "{0}"'.format(
                        item['size']))
                else:
                    size = '--extents {0}'.format(int(vg_extents[vg] * size))
            else:
                size = '--size {0}M'.format(int(size))

            try:
                part_type = item['type']
            except KeyError:
                part_type = fs_type

            try:
                if item['options'] != 'defaults':
                    options = item['options'].split(',')
            except KeyError:
                options = list(mounting_options)

            block_device = '/dev/mapper/{0}-{1}'.format(
                vg_names[vg], item['name'])

            print('Creating LV "{0}" size "{1}" in VG "{2}"...'.format(
                item['name'], size, vg_names[vg]))
            execute('/sbin/lvm lvcreate --name "{0}" {1} {2}'.format(
                item['name'], size, vg_names[vg]))

            supportsTrim = True
            for drive in vg_disks[vg]:
                supportsTrim &= drive.supportsTrim

            if part_type == 'swap':
                filesystem_list.append({
                    'type': 'swap',
                    'priority': priority,
                    'block_device': block_device
                })

            else:
                if supportsTrim and part_type in FS_WITH_TRIM:
                    options.append('discard')

                filesystem_list.append({
                    'mount_point': item['mount_point'],
                    'type': fs_type,
                    'options': options,
                    'block_device': block_device
                })

    for fs in filesystem_list:
        try:
            if fs['mount_point'] is not None:
                partition_map[fs['mount_point']] = fs['block_device']
        except KeyError:
            pass

    if md_list:  # wait till the drives have synced to at least 2% or 10 min.
        print('Letting the MD RAID(s) Sync...')
        start_at = time.time()
        open('/proc/sys/dev/raid/speed_limit_min', 'w').write('500000000')
        open('/proc/sys/dev/raid/speed_limit_max', 'w').write('500000000')
        perc_list = _mdSyncPercentange(
        )  # this is empty if all the RAIDs are synced
        while perc_list and min(perc_list) < 0.5:
            if time.time() - 300 > start_at:
                break

            print('Curent Sync Percentage: {0}'.format(', '.join(
                [str(i) for i in perc_list])))
            time.sleep(30)
            perc_list = _mdSyncPercentange()

        open('/proc/sys/dev/raid/speed_limit_min', 'w').write('2000')
Exemple #11
0
def _parted(block_device, cmd_list):
    execute('/sbin/parted -s {0} -- {1}'.format(block_device,
                                                '\\ \n'.join(cmd_list)))
Exemple #12
0
    install_root = '/target'

set_chroot(install_root)

contractor.postMessage('Setting Up Configurator...')
initConfig(install_root, template_path, profile_file)
updateConfig('filesystem', fsConfigValues())

value_map = getValues()

profile = getProfile()

contractor.postMessage('Loading Kernel Modules...')
for item in profile.items('kernel'):
    if item[0].startswith('load_module_'):
        execute('/sbin/modprobe {0}'.format(item[1]))

if target == 'drive':
    contractor.postMessage('Partitioning....')
    try:
        partition(profile, value_map)
    except MissingDrives as e:
        print('Timeout while waiting for drive "{0}"'.format(e))
        sys.exit(1)

    contractor.postMessage('Making Filesystems....')
    mkfs()

updateConfig('filesystem', fsConfigValues())

profile = getProfile()  # reload now with the file system values
Exemple #13
0
distro_version = config.get('distro_version', None)
bootstrap_source = config.get('bootstrap_source', None)

target = config.get('install_target', 'drive')

open_output(STDOUT_OUTPUT)

if image_package and distro:
    print(
        '"image_package" and "distro" can not be specified at the same time.')
    sys.exit(1)

if image_package:
    if image_package_location:
        contractor.postMessage('Downloading Install Package...')
        execute('/bin/wget -O /tmp/package {0}{1}'.format(
            image_package_location, image_package))
        image_package = '/tmp/package'

    if not os.access(image_package, os.R_OK):
        raise Exception(
            'Unable to find image package "{0}"'.format(image_package))

    contractor.postMessage('Extracting Install Package...')
    os.makedirs('/package')
    execute(
        '/bin/tar -C /package --exclude=image* -xzf {0}'.format(image_package))

    profile_file = '/package/profile'
    template_path = '/package/templates'

else:
Exemple #14
0
def bootstrap(mount_point, source,
              profile):  # TODO: bootstrap http proxy, also see misc
    bootstrap_type = profile.get('bootstrap', 'type')

    # debians copy over /etc/hostname and /etc/resolv.conf, but cent dosen't (SELS Unknown), and pre_base_cmd is chrooted, so for now we will do these here
    shutil.copyfile('/etc/hostname', os.path.join(mount_point, 'etc/hostname'))
    shutil.copyfile('/etc/resolv.conf',
                    os.path.join(mount_point, 'etc/resolv.conf'))

    try:
        packages = profile.get('bootstrap', 'packages')
    except NoOptionError:
        packages = ''

    if bootstrap_type == 'debbootstrap':
        if packages:
            execute(
                '/usr/sbin/debootstrap --arch amd64 --include {0} {1} {2} {3}'.
                format(packages, profile.get('bootstrap', 'distro'),
                       mount_point, source))
        else:
            execute('/usr/sbin/debootstrap --arch amd64 {0} {1} {2}'.format(
                profile.get('bootstrap', 'distro'), mount_point, source))

    elif bootstrap_type == 'squashimg':  # we should change this to using the squash fs as a intermediat step to do a boot strap from scratch https://wiki.centos.org/HowTos/ManualInstall
        version = profile.get('bootstrap', 'version')
        repo_root = '{0}{1}/os/x86_64/'.format(source, version)

        print('Getting Treeinfo...')
        execute('/bin/wget -O /tmp/treeinfo {0}.treeinfo'.format(repo_root))
        treeinfo = ConfigParser()
        treeinfo.read('/tmp/treeinfo')
        image = treeinfo.get('stage2', 'mainimage')
        print('   Stage 2 image "{0}"'.format(image))

        print('Downloading image...')
        execute('/bin/wget -O {0}/bootstrap.img {1}{2}'.format(
            mount_point, repo_root, image))

        print('Extractig image...')
        file_list = execute_lines(
            '/bin/unsquashfs -d . -ls {0}/bootstrap.img'.format(mount_point))
        execute(
            '/bin/unsquashfs -f -d {0} {0}/bootstrap.img'.format(mount_point))
        os.unlink('{0}/bootstrap.img'.format(mount_point))

        if file_list[-1] == './LiveOS/rootfs.img':  # Centos 7
            os.rename('{0}/LiveOS/rootfs.img'.format(mount_point),
                      '{0}/rootfs.img'.format(mount_point))
            os.rmdir('{0}/LiveOS'.format(mount_point))
            os.mkdir('/tmp/mnt')
            execute('/bin/mount -oloop,ro {0}/rootfs.img /tmp/mnt'.format(
                mount_point))
            execute('/bin/cp -ar /tmp/mnt/. {0}'.format(mount_point))
            execute('/bin/umount /tmp/mnt')
            os.unlink('{0}/rootfs.img'.format(mount_point))
            os.rmdir('/tmp/mnt')
            shutil.copyfile(
                '/etc/resolv.conf', os.path.join(
                    mount_point,
                    'etc/resolv.conf'))  # get's overwritten by the rootfs

        print('Retreiving Package List...')
        execute('/bin/wget -q -O /tmp/pkglist {0}Packages/'.format(repo_root))
        yum_match = re.compile('"(yum-[^"]*\.rpm)"')
        release_match = re.compile('"(centos-release-[^"]*\.rpm)"')
        yum_filename = None
        release_filename = None
        for line in open('/tmp/pkglist', 'r').readlines():
            tmp = yum_match.search(line)
            if tmp:
                yum_filename = tmp.group(1)

            tmp = release_match.search(line)
            if tmp:
                release_filename = tmp.group(1)

            if release_filename and yum_filename:
                break

        execute(
            'rm /tmp/pkglist'
        )  # if there are more packages installed here, make sure to update the list in packaging.py - installBase
        print('   YUM rpm filename "{0}"'.format(yum_filename))
        print('   release rpm filename "{0}"'.format(release_filename))

        print('Retreiving YUM...')
        execute('/bin/wget -q -O {0} {1}Packages/{2}'.format(
            os.path.join(mount_point, 'tmp.rpm'), repo_root, yum_filename))
        print('Instaing YUM...')
        chroot_execute('/usr/bin/rpm -i --nodeps /tmp.rpm')
        chroot_execute('rm /tmp.rpm')

        print('Retreiving Release...')
        execute('/bin/wget -q -O {0} {1}Packages/{2}'.format(
            os.path.join(mount_point, 'tmp.rpm'), repo_root, release_filename))
        print('Instaiing Release...')
        chroot_execute('/usr/bin/rpm -i --nodeps /tmp.rpm')
        chroot_execute('rm /tmp.rpm')

    else:
        raise Exception('Unknown "{0}" type'.format(bootstrap_type))
Exemple #15
0
def _parted(block_device, cmd):
    execute('/sbin/parted -s {0} -- {1}'.format(block_device, cmd))