def modify(name, root, cfg): rpms = expand_rpms(cfg.get('rpms')) if not rpms: return util.print_iterable(rpms, header=("Installing the following rpms" " in module %s" % (util.quote(name)))) util.ensure_dir(util.abs_join(root, 'tmp')) cleanup_fns = [] for fn in rpms: cp_to = util.abs_join(root, 'tmp', os.path.basename(fn)) util.copy(fn, cp_to) cleanup_fns.append(cp_to) real_fns = [] for fn in rpms: real_fns.append(os.path.join('/tmp', os.path.basename(fn))) cmd = ['chroot', root, 'yum', '--nogpgcheck', '-y', 'localinstall'] cmd.extend(real_fns) try: util.subp(cmd, capture=False) finally: # Ensure cleaned up for fn in cleanup_fns: util.del_file(fn)
def cmd_undo(undo_how): try: yield None finally: try: util.subp(undo_how) except: pass
def dd_off(loop_dev, tmp_dir, block_size='32768k'): tmp_fn = tempfile.mktemp(dir=tmp_dir, suffix='.raw') cmd = [ 'dd', 'if=%s' % (loop_dev), 'bs=%s' % (block_size), 'of=%s' % (tmp_fn), ] util.subp(cmd, capture=False) return tmp_fn
def activate_modules(tmp_file_name, config): with util.tempdir() as tdir: devname = create_loopback(tmp_file_name, PART_OFFSET) with cmd_undo(['losetup', '-d', devname]): # Mount it root_dir = os.path.join(tdir, 'mnt') os.makedirs(root_dir) util.subp(['mount', devname, root_dir]) # Run your modules! with cmd_undo(['umount', root_dir]): return run_modules(root_dir, config)
def modify(name, root, cfg): user_names = cfg.get("add_users") if not user_names: return util.print_iterable(user_names, header="Adding the following sudo users in module %s" % (util.quote(name))) for uname in user_names: cmd = ["chroot", root, "useradd", "-m", str(uname)] util.subp(cmd, capture=False) if os.path.isfile(os.path.join(root, "etc", "sudoers")): with open(os.path.join(root, "etc", "sudoers"), "a") as fh: new_entry = "%s ALL=(ALL) ALL" % (uname) fh.write("%s\n" % (new_entry))
def _adjust_real_root(self, arch_path): if self.root_file: print("Oh you really meant %s, finding that file..." % (util.quote(self.root_file))) # Extract and then copy over the right file... with util.tempdir() as tdir: arch_dir = os.path.join(tdir, 'archive') os.makedirs(arch_dir) util.subp(['tar', '-xzf', arch_path, '-C', arch_dir]) root_gz = util.find_file(self.root_file, arch_dir) if not root_gz: raise RuntimeError(("Needed file %r not found in" " extracted contents of %s") % (self.root_file, arch_path)) else: util.copy(root_gz, arch_path) return arch_path
def create_loopback(filename, offset=None): cmd = ['losetup'] if offset: cmd.extend(['-o', str(offset)]) cmd.extend(['--show', '-f', filename]) (stdout, _stderr) = util.subp(cmd) devname = stdout.strip() return devname
def extract_into(tmp_file_name, fs_type, config): with util.tempdir() as tdir: # Download the image # TODO (make this a true module that can be changed...) tb_down = tar_ball.TarBallDownloader(dict(config['download'])) arch_fn = tb_down.download() # Extract it devname = create_loopback(tmp_file_name, PART_OFFSET) with cmd_undo(['losetup', '-d', devname]): # Mount it root_dir = os.path.join(tdir, 'mnt') os.makedirs(root_dir) util.subp(['mount', devname, root_dir]) # Extract it with cmd_undo(['umount', root_dir]): print("Extracting 'root' tarball %s to %s." % (util.quote(arch_fn), util.quote(root_dir))) util.subp(['tar', '-xzf', arch_fn, '-C', root_dir]) # Fixup the fstab fix_fstab(root_dir, fs_type)
def format_blank(tmp_file_name, size, fs_type): print("Creating the image output file %s (scratch-version)." % (util.quote(tmp_file_name))) with open(tmp_file_name, 'w+') as o_fh: o_fh.truncate(0) cmd = ['qemu-img', 'create', '-f', 'raw', tmp_file_name, size] util.subp(cmd) # Run fdisk on it print("Creating a partition table in %s." % (util.quote(tmp_file_name))) devname = create_loopback(tmp_file_name) with cmd_undo(['losetup', '-d', devname]): # These are commands to fdisk that will get activated (in order) fdisk_in = [ 'n', 'p', '1', '1', '', 'w' ] cmd = ['fdisk', devname] util.subp(cmd, data="\n".join(fdisk_in), rcs=[0, 1]) print("Creating a filesystem of type %s in %s." % (util.quote(fs_type), util.quote(tmp_file_name))) devname = create_loopback(tmp_file_name, PART_OFFSET) # Get a filesystem on it with cmd_undo(['losetup', '-d', devname]): cmd = ['mkfs.%s' % (fs_type), devname] util.subp(cmd)
def straight_convert(raw_fn, out_fn, out_fmt): cmd = ['qemu-img', 'convert', '-f', 'raw', '-O', out_fmt, raw_fn, out_fn] util.subp(cmd, capture=False)
def ec2_convert(raw_fn, out_fn, out_fmt, strip_partition, compress): # Extract the ramdisk/kernel devname = create_loopback(raw_fn, PART_OFFSET) with util.tempdir() as tdir: img_dir = os.path.join(tdir, 'img') root_dir = os.path.join(tdir, 'mnt') util.ensure_dirs([img_dir, root_dir]) with cmd_undo(['losetup', '-d', devname]): print("Copying off the ramdisk and kernel files.") # Mount it util.subp(['mount', devname, root_dir]) with cmd_undo(['umount', root_dir]): # Find the right files fns = {} for fn in os.listdir(util.abs_join(root_dir, 'boot')): if fn.endswith('.img') and fn.startswith('initramfs-'): fns['ramdisk'] = fn if fn.startswith('vmlinuz-'): fns['kernel'] = fn if fn.startswith('initrd-') and fn.endswith('.img'): fns['base'] = fn rd_fn = fns.get('ramdisk') k_fn = fns.get('kernel') if (not rd_fn and not k_fn) and 'base' in fns: kid = fns['base'] kid = kid[0:-len('.img')] kid = kid[len('initrd-'):] cmd = ['chroot', root_dir, '/sbin/mkinitrd', '-f', os.path.join('/boot', fns['base']), kid] util.subp(cmd, capture=False) if os.path.isfile(util.abs_join(root_dir, "boot", "initramfs-%s.img" % (kid))): rd_fn = "initramfs-%s.img" % (kid) if os.path.isfile(util.abs_join(root_dir, "boot", "vmlinuz-%s" % (kid))): k_fn = "vmlinuz-%s" % (kid) if not rd_fn: raise RuntimeError("No initramfs-*.img file found") if not k_fn: raise RuntimeError("No vmlinuz-* file found") shutil.move(util.abs_join(root_dir, 'boot', rd_fn), util.abs_join(img_dir, rd_fn)) shutil.move(util.abs_join(root_dir, 'boot', k_fn), util.abs_join(img_dir, k_fn)) # Copy off the data (minus the partition info) if strip_partition: print("Stripping off the partition table.") print("Please wait...") part_stripped_fn = dd_off(devname, tdir) # Replace the orginal 'raw' file if strip_partition: shutil.move(part_stripped_fn, raw_fn) # Apply some tune ups cmd = [ 'tune2fs', # Set the volume label of the filesystem '-L', 'root', raw_fn ] util.subp(cmd, capture=False) # Convert it to the final format and compress it out_base_fn = os.path.basename(out_fn) img_fn = out_base_fn if img_fn.endswith('.tar.gz'): img_fn = img_fn[0:-len('.tar.gz')] img_fn += "." + out_fmt img_fn = util.abs_join(img_dir, img_fn) straight_convert(raw_fn, img_fn, out_fmt) # Make a nice helper libvirt.xml file util.write_file(util.abs_join(img_dir, 'libvirt.xml'), make_virt_xml(util.abs_join(img_dir, k_fn), util.abs_join(img_dir, rd_fn), util.abs_join(img_dir, img_fn))) # Give every file written a hash/checksum file for fn in os.listdir(img_dir): src_fn = util.abs_join(img_dir, fn) hash_fn = src_fn + "." + HASH_ROUTINE hash_file(src_fn, hash_fn, HASH_ROUTINE) # Compress it or just move the folder around if compress: with closing(tarfile.open(out_fn, 'w:gz')) as tar_fh: for fn in os.listdir(img_dir): src_fn = util.abs_join(img_dir, fn) transfer_into_tarball(src_fn, fn, tar_fh) else: shutil.move(img_dir, out_fn)