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')))
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
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' ) ) )
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))
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')
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
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
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 ) )
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]))
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')
def _parted(block_device, cmd_list): execute('/sbin/parted -s {0} -- {1}'.format(block_device, '\\ \n'.join(cmd_list)))
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
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:
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))
def _parted(block_device, cmd): execute('/sbin/parted -s {0} -- {1}'.format(block_device, cmd))