def do_chroot(cls, target): os_image = cls.do_unpack(target) os_image_dir = os.path.dirname(os_image) # unpack image to target dir imgsize = misc.get_file_size(os_image) * 1024L * 1024L imgtype = misc.get_image_type(os_image) if imgtype == "btrfsimg": fstype = "btrfs" myDiskMount = fs_related.BtrfsDiskMount elif imgtype in ("ext3fsimg", "ext4fsimg"): fstype = imgtype[:4] myDiskMount = fs_related.ExtDiskMount else: raise errors.CreatorError("Unsupported filesystem type: %s" % fstype) extmnt = misc.mkdtemp() extloop = myDiskMount(fs_related.SparseLoopbackDisk(os_image, imgsize), extmnt, fstype, 4096, "%s label" % fstype) try: extloop.mount() except errors.MountError: extloop.cleanup() shutil.rmtree(extmnt, ignore_errors=True) raise try: chroot.chroot(extmnt, None, "/bin/env HOME=/root /bin/bash") except: raise errors.CreatorError("Failed to chroot to %s." % target) finally: chroot.cleanup_after_chroot("img", extloop, os_image_dir, extmnt)
def do_unpack(cls, srcimg): srcimgsize = (misc.get_file_size(srcimg)) * 1024L * 1024L srcmnt = misc.mkdtemp("srcmnt") disk = fs_related.SparseLoopbackDisk(srcimg, srcimgsize) srcloop = PartitionedMount({'/dev/sdb': disk}, srcmnt, skipformat=True) srcloop.add_partition(srcimgsize / 1024 / 1024, "/dev/sdb", "/", "ext3", boot=False) try: srcloop.mount() except errors.MountError: srcloop.cleanup() raise image = os.path.join(tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"), "target.img") args = [ 'dd', "if=%s" % srcloop.partitions[0]['device'], "of=%s" % image ] msger.info("`dd` image ...") rc = runner.show(args) srcloop.cleanup() shutil.rmtree(os.path.dirname(srcmnt), ignore_errors=True) if rc != 0: raise errors.CreatorError("Failed to dd") else: return image
def _mount_instroot(self, base_on=None): self.__imgdir = self._mkdtemp() parts = self._get_parts() #create disk for item in self.get_diskinfo(): msger.debug("Adding disk %s as %s/%s-%s.raw" % (item['name'], self.__imgdir, self.name, item['name'])) disk = fs_related.SparseLoopbackDisk( "%s/%s-%s.raw" % (self.__imgdir, self.name, item['name']), item['size']) self.__disks[item['name']] = disk self.__instloop = PartitionedMount(self.__disks, self._instroot) for p in parts: self.__instloop.add_partition(int(p.size), p.disk, p.mountpoint, p.fstype, fsopts=p.fsopts, boot=p.active) self.__instloop.mount() self._create_mkinitrd_config()
def _mount_instroot(self, base_on = None): parts = self._get_parts() self.__instloop = PartitionedMount(self._instroot) for p in parts: self.__instloop.add_partition(int(p.size), p.disk, p.mountpoint, p.fstype, p.label, fsopts = p.fsopts, boot = p.active, align = p.align, part_type = p.part_type) self.__instloop.layout_partitions(self._ptable_format) # Create the disks self.__imgdir = self._mkdtemp() for disk_name, disk in self.__instloop.disks.items(): full_path = self._full_path(self.__imgdir, disk_name, "raw") msger.debug("Adding disk %s as %s with size %s bytes" \ % (disk_name, full_path, disk['min_size'])) disk_obj = fs_related.SparseLoopbackDisk(full_path, disk['min_size']) self.__disks[disk_name] = disk_obj self.__instloop.add_disk(disk_name, disk_obj) self.__instloop.mount() self._create_mkinitrd_config()
def _mount_instroot(self, base_on=None): if base_on and os.path.isfile(base_on): self._imgdir = os.path.dirname(base_on) imgname = os.path.basename(base_on) self._base_on(base_on) self._set_image_size(misc.get_file_size(self._image)) # here, self._instloops must be [] self._instloops.append({ "mountpoint": "/", "label": self.name, "name": imgname, "size": self.__image_size or 4096L, "fstype": self.__fstype or "ext3", "extopts": None, "loop": None, "uuid": None, "kspart": None }) self._check_imgdir() for loop in self._instloops: fstype = loop['fstype'] mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/')) size = loop['size'] * 1024L * 1024L imgname = loop['name'] if fstype in ("ext2", "ext3", "ext4"): MyDiskMount = fs.ExtDiskMount elif fstype == "btrfs": MyDiskMount = fs.BtrfsDiskMount elif fstype in ("vfat", "msdos"): MyDiskMount = fs.VfatDiskMount else: raise MountError('Cannot support fstype: %s' % fstype) loop['loop'] = MyDiskMount(fs.SparseLoopbackDisk( os.path.join(self._imgdir, imgname), size), mp, fstype, self._blocksize, loop['label'], fsuuid=loop['uuid']) if fstype in ("ext2", "ext3", "ext4"): loop['loop'].extopts = loop['extopts'] try: msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp)) fs.makedirs(mp) loop['loop'].mount() # Make an autogenerated uuid avaialble in _get_post_scripts_env() if loop['kspart'] and loop['kspart'].uuid is None and \ loop['loop'].uuid: loop['kspart'].uuid = loop['loop'].uuid except MountError, e: raise
def _do_chroot_tar(cls, target, cmd=[]): mountfp_xml = os.path.splitext(target)[0] + '.xml' if not os.path.exists(mountfp_xml): raise errors.CreatorError("No mount point file found for this tar " "image, please check %s" % mountfp_xml) import tarfile tar = tarfile.open(target, 'r') tmpdir = misc.mkdtemp() tar.extractall(path=tmpdir) tar.close() mntdir = misc.mkdtemp() loops = [] for (mp, label, name, size, fstype) in load_mountpoints(mountfp_xml): if fstype in ("ext2", "ext3", "ext4"): myDiskMount = fs_related.ExtDiskMount elif fstype == "btrfs": myDiskMount = fs_related.BtrfsDiskMount elif fstype in ("vfat", "msdos"): myDiskMount = fs_related.VfatDiskMount else: raise errors.CreatorError("Cannot support fstype: %s" % fstype) name = os.path.join(tmpdir, name) size = size * 1024L * 1024L loop = myDiskMount(fs_related.SparseLoopbackDisk(name, size), os.path.join(mntdir, mp.lstrip('/')), fstype, size, label) try: msger.verbose("Mount %s to %s" % (mp, mntdir + mp)) fs_related.makedirs(os.path.join(mntdir, mp.lstrip('/'))) loop.mount() except: loop.cleanup() for lp in reversed(loops): chroot.cleanup_after_chroot("img", lp, None, mntdir) shutil.rmtree(tmpdir, ignore_errors=True) raise loops.append(loop) try: if len(cmd) != 0: cmdline = "/usr/bin/env HOME=/root " + ' '.join(cmd) else: cmdline = "/usr/bin/env HOME=/root /bin/bash" chroot.chroot(mntdir, None, cmdline) except: raise errors.CreatorError("Failed to chroot to %s." % target) finally: for loop in reversed(loops): chroot.cleanup_after_chroot("img", loop, None, mntdir) shutil.rmtree(tmpdir, ignore_errors=True)
def _mount_instroot(self, base_on=None): if base_on and os.path.isfile(base_on): self.__imgdir = os.path.dirname(base_on) imgname = os.path.basename(base_on) self._base_on(base_on) self._set_image_size(misc.get_file_size(self._image)) # here, self._instloops must be [] self._instloops.append({ "mountpoint": "/", "label": self.name, "name": imgname, "size": self.__image_size or 4096, "fstype": self.__fstype or "ext3", "loop": None }) self._check_imgdir() for loop in self._instloops: fstype = loop['fstype'] mp = os.path.join(self._instroot, loop['mountpoint'].lstrip('/')) size = loop['size'] * 1024 * 1024 imgname = loop['name'] fsopts = loop['fsopts'] dargs = [ fs.SparseLoopbackDisk(os.path.join(self._imgdir, imgname), size), mp, fstype, self._blocksize, loop['label'] ] dkwargs = {"fsopts": fsopts} if fstype in ("ext2", "ext3", "ext4"): MyDiskMount = fs.ExtDiskMount elif fstype == "btrfs": MyDiskMount = fs.BtrfsDiskMount dkwargs["subvolumes"] = loop["subvolumes"] dkwargs["snapshots"] = loop["snapshots"] elif fstype in ("vfat", "msdos"): MyDiskMount = fs.VfatDiskMount else: msger.error('Cannot support fstype: %s' % fstype) loop['loop'] = MyDiskMount(*dargs, **dkwargs) loop['uuid'] = loop['loop'].uuid try: msger.verbose('Mounting image "%s" on "%s"' % (imgname, mp)) fs.makedirs(mp) loop['loop'].mount() except MountError as e: raise
def do_unpack(cls, srcimg): img = srcimg imgsize = misc.get_file_size(img) * 1024L * 1024L imgmnt = misc.mkdtemp() disk = fs_related.SparseLoopbackDisk(img, imgsize) imgloop = PartitionedMount(imgmnt, skipformat=True) imgloop.add_disk('/dev/sdb', disk) imgloop.add_partition(imgsize / 1024 / 1024, "/dev/sdb", "/", "vfat", boot=False) try: imgloop.mount() except errors.MountError: imgloop.cleanup() raise # legacy LiveOS filesystem layout support, remove for F9 or F10 if os.path.exists(imgmnt + "/squashfs.img"): squashimg = imgmnt + "/squashfs.img" else: squashimg = imgmnt + "/LiveOS/squashfs.img" tmpoutdir = misc.mkdtemp() # unsquashfs requires outdir mustn't exist shutil.rmtree(tmpoutdir, ignore_errors=True) misc.uncompress_squashfs(squashimg, tmpoutdir) try: # legacy LiveOS filesystem layout support, remove for F9 or F10 if os.path.exists(tmpoutdir + "/os.img"): os_image = tmpoutdir + "/os.img" else: os_image = tmpoutdir + "/LiveOS/ext3fs.img" if not os.path.exists(os_image): raise errors.CreatorError( "'%s' is not a valid live CD ISO : neither " "LiveOS/ext3fs.img nor os.img exist" % img) imgname = os.path.basename(srcimg) imgname = os.path.splitext(imgname)[0] + ".img" rtimage = os.path.join( tempfile.mkdtemp(dir="/var/tmp", prefix="tmp"), imgname) shutil.copyfile(os_image, rtimage) finally: imgloop.cleanup() shutil.rmtree(tmpoutdir, ignore_errors=True) shutil.rmtree(imgmnt, ignore_errors=True) return rtimage
def do_chroot(cls, target, cmd=[]): if target.endswith('.tar'): import tarfile if tarfile.is_tarfile(target): LoopPlugin._do_chroot_tar(target, cmd) return else: raise errors.CreatorError("damaged tarball for loop images") img = target imgsize = misc.get_file_size(img) * 1024L * 1024L imgtype = misc.get_image_type(img) if imgtype == "btrfsimg": fstype = "btrfs" myDiskMount = fs_related.BtrfsDiskMount elif imgtype in ("ext3fsimg", "ext4fsimg"): fstype = imgtype[:4] myDiskMount = fs_related.ExtDiskMount else: raise errors.CreatorError("Unsupported filesystem type: %s" \ % imgtype) extmnt = misc.mkdtemp() extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize), extmnt, fstype, 4096, "%s label" % fstype) try: extloop.mount() except errors.MountError: extloop.cleanup() shutil.rmtree(extmnt, ignore_errors=True) raise try: if cmd is not None: cmdline = cmd else: cmdline = "/bin/bash" envcmd = fs_related.find_binary_inchroot("env", extmnt) if envcmd: cmdline = "%s HOME=/root %s" % (envcmd, cmdline) chroot.chroot(extmnt, None, cmdline) except: raise errors.CreatorError("Failed to chroot to %s." % img) finally: chroot.cleanup_after_chroot("img", extloop, None, extmnt)
def do_chroot(cls, target): import tarfile if tarfile.is_tarfile(target): LoopPlugin._do_chroot_tar(target) return img = target imgsize = misc.get_file_size(img) * 1024L * 1024L imgtype = misc.get_image_type(img) if imgtype == "btrfsimg": fstype = "btrfs" myDiskMount = fs_related.BtrfsDiskMount elif imgtype in ("ext3fsimg", "ext4fsimg"): fstype = imgtype[:4] myDiskMount = fs_related.ExtDiskMount else: raise errors.CreatorError("Unsupported filesystem type: %s" \ % imgtype) extmnt = misc.mkdtemp() extloop = myDiskMount(fs_related.SparseLoopbackDisk(img, imgsize), extmnt, fstype, 4096, "%s label" % fstype) try: extloop.mount() except errors.MountError: extloop.cleanup() shutil.rmtree(extmnt, ignore_errors=True) raise try: chroot.chroot(extmnt, None, "/bin/env HOME=/root /bin/bash") except: raise errors.CreatorError("Failed to chroot to %s." % img) finally: chroot.cleanup_after_chroot("img", extloop, None, extmnt)
def do_chroot(cls, target): img = target imgsize = misc.get_file_size(img) * 1024L * 1024L partedcmd = fs_related.find_binary_path("parted") disk = fs_related.SparseLoopbackDisk(img, imgsize) imgmnt = misc.mkdtemp() imgloop = PartitionedMount({'/dev/sdb': disk}, imgmnt, skipformat=True) img_fstype = "ext3" # Check the partitions from raw disk. root_mounted = False partition_mounts = 0 for line in runner.outs([partedcmd, "-s", img, "unit", "B", "print"]).splitlines(): line = line.strip() # Lines that start with number are the partitions, # because parted can be translated we can't refer to any text lines. if not line or not line[0].isdigit(): continue # Some vars have extra , as list seperator. line = line.replace(",", "") # Example of parted output lines that are handled: # Number Start End Size Type File system Flags # 1 512B 3400000511B 3400000000B primary # 2 3400531968B 3656384511B 255852544B primary linux-swap(v1) # 3 3656384512B 3720347647B 63963136B primary fat16 boot, lba partition_info = re.split("\s+", line) size = partition_info[3].split("B")[0] if len(partition_info) < 6 or partition_info[5] in ["boot"]: # No filesystem can be found from partition line. Assuming # btrfs, because that is the only MeeGo fs that parted does # not recognize properly. # TODO: Can we make better assumption? fstype = "btrfs" elif partition_info[5] in ["ext2", "ext3", "ext4", "btrfs"]: fstype = partition_info[5] elif partition_info[5] in ["fat16", "fat32"]: fstype = "vfat" elif "swap" in partition_info[5]: fstype = "swap" else: raise errors.CreatorError( "Could not recognize partition fs type '%s'." % partition_info[5]) if not root_mounted and fstype in [ "ext2", "ext3", "ext4", "btrfs" ]: # TODO: Check that this is actually the valid root partition from /etc/fstab mountpoint = "/" root_mounted = True elif fstype == "swap": mountpoint = "swap" else: # TODO: Assing better mount points for the rest of the partitions. partition_mounts += 1 mountpoint = "/media/partition_%d" % partition_mounts if "boot" in partition_info: boot = True else: boot = False msger.verbose( "Size: %s Bytes, fstype: %s, mountpoint: %s, boot: %s" % (size, fstype, mountpoint, boot)) # TODO: add_partition should take bytes as size parameter. imgloop.add_partition((int)(size) / 1024 / 1024, "/dev/sdb", mountpoint, fstype=fstype, boot=boot) try: imgloop.mount() except errors.MountError: imgloop.cleanup() raise try: chroot.chroot(imgmnt, None, "/bin/env HOME=/root /bin/bash") except: raise errors.CreatorError("Failed to chroot to %s." % img) finally: chroot.cleanup_after_chroot("img", imgloop, None, imgmnt)
def _create_usbimg(self, isodir): overlaysizemb = 64 #default #skipcompress = self.skip_compression? fstype = "vfat" homesizemb=0 swapsizemb=0 homefile="home.img" plussize=128 kernelargs=None if fstype == 'vfat': if overlaysizemb > 2047: raise CreatorError("Can't have an overlay of 2048MB or " "greater on VFAT") if homesizemb > 2047: raise CreatorError("Can't have an home overlay of 2048MB or " "greater on VFAT") if swapsizemb > 2047: raise CreatorError("Can't have an swap overlay of 2048MB or " "greater on VFAT") livesize = misc.get_file_size(isodir + "/LiveOS") usbimgsize = (overlaysizemb + \ homesizemb + \ swapsizemb + \ livesize + \ plussize) * 1024 * 1024 disk = fs_related.SparseLoopbackDisk("%s/%s.usbimg" \ % (self._outdir, self.name), usbimgsize) usbmnt = self._mkdtemp("usb-mnt") usbloop = PartitionedMount({'/dev/sdb':disk}, usbmnt) usbloop.add_partition(usbimgsize/1024/1024, "/dev/sdb", "/", fstype, boot=True) usbloop.mount() try: fs_related.makedirs(usbmnt + "/LiveOS") if os.path.exists(isodir + "/LiveOS/squashfs.img"): shutil.copyfile(isodir + "/LiveOS/squashfs.img", usbmnt + "/LiveOS/squashfs.img") else: fs_related.mksquashfs(os.path.dirname(self._image), usbmnt + "/LiveOS/squashfs.img") if os.path.exists(isodir + "/LiveOS/osmin.img"): shutil.copyfile(isodir + "/LiveOS/osmin.img", usbmnt + "/LiveOS/osmin.img") uuid = usbloop.partitions[0]['mount'].uuid label = usbloop.partitions[0]['mount'].fslabel usblabel = "UUID=%s" % (uuid) overlaysuffix = "-%s-%s" % (label, uuid) args = ['cp', "-Rf", isodir + "/isolinux", usbmnt + "/syslinux"] rc = runner.show(args) if rc: raise CreatorError("Can't copy isolinux directory %s" \ % (isodir + "/isolinux/*")) if os.path.isfile("/usr/share/syslinux/isolinux.bin"): syslinux_path = "/usr/share/syslinux" elif os.path.isfile("/usr/lib/syslinux/isolinux.bin"): syslinux_path = "/usr/lib/syslinux" else: raise CreatorError("syslinux not installed : " "cannot find syslinux installation path") for f in ("isolinux.bin", "vesamenu.c32"): path = os.path.join(syslinux_path, f) if os.path.isfile(path): args = ['cp', path, usbmnt + "/syslinux/"] rc = runner.show(args) if rc: raise CreatorError("Can't copy syslinux file " + path) else: raise CreatorError("syslinux not installed: " "syslinux file %s not found" % path) fd = open(isodir + "/isolinux/isolinux.cfg", "r") text = fd.read() fd.close() pattern = re.compile('CDLABEL=[^ ]*') text = pattern.sub(usblabel, text) pattern = re.compile('rootfstype=[^ ]*') text = pattern.sub("rootfstype=" + fstype, text) if kernelargs: text = text.replace("liveimg", "liveimg " + kernelargs) if overlaysizemb > 0: msger.info("Initializing persistent overlay file") overfile = "overlay" + overlaysuffix if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + usbmnt + "/LiveOS/" + overfile, "count=%d" % overlaysizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + usbmnt + "/LiveOS/" + overfile, "count=1", "bs=1M", "seek=%d" % overlaysizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create overlay file") text = text.replace("liveimg", "liveimg overlay=" + usblabel) text = text.replace(" ro ", " rw ") if swapsizemb > 0: msger.info("Initializing swap file") swapfile = usbmnt + "/LiveOS/" + "swap.img" args = ['dd', "if=/dev/zero", "of=" + swapfile, "count=%d" % swapsizemb, "bs=1M"] rc = runner.show(args) if rc: raise CreatorError("Can't create swap file") args = ["mkswap", "-f", swapfile] rc = runner.show(args) if rc: raise CreatorError("Can't mkswap on swap file") if homesizemb > 0: msger.info("Initializing persistent /home") homefile = usbmnt + "/LiveOS/" + homefile if fstype == "vfat": args = ['dd', "if=/dev/zero", "of=" + homefile, "count=%d" % homesizemb, "bs=1M"] else: args = ['dd', "if=/dev/null", "of=" + homefile, "count=1", "bs=1M", "seek=%d" % homesizemb] rc = runner.show(args) if rc: raise CreatorError("Can't create home file") mkfscmd = fs_related.find_binary_path("/sbin/mkfs." + fstype) if fstype == "ext2" or fstype == "ext3": args = [mkfscmd, "-F", "-j", homefile] else: args = [mkfscmd, homefile] rc = runner.show(args) if rc: raise CreatorError("Can't mke2fs home file") if fstype == "ext2" or fstype == "ext3": tune2fs = fs_related.find_binary_path("tune2fs") args = [tune2fs, "-c0", "-i0", "-ouser_xattr,acl", homefile] rc = runner.show(args) if rc: raise CreatorError("Can't tune2fs home file") if fstype == "vfat" or fstype == "msdos": syslinuxcmd = fs_related.find_binary_path("syslinux") syslinuxcfg = usbmnt + "/syslinux/syslinux.cfg" args = [syslinuxcmd, "-d", "syslinux", usbloop.partitions[0]["device"]] elif fstype == "ext2" or fstype == "ext3": extlinuxcmd = fs_related.find_binary_path("extlinux") syslinuxcfg = usbmnt + "/syslinux/extlinux.conf" args = [extlinuxcmd, "-i", usbmnt + "/syslinux"] else: raise CreatorError("Invalid file system type: %s" % (fstype)) os.unlink(usbmnt + "/syslinux/isolinux.cfg") fd = open(syslinuxcfg, "w") fd.write(text) fd.close() rc = runner.show(args) if rc: raise CreatorError("Can't install boot loader.") finally: usbloop.unmount() usbloop.cleanup() # Need to do this after image is unmounted and device mapper is closed msger.info("set MBR") mbrfile = "/usr/lib/syslinux/mbr.bin" if not os.path.exists(mbrfile): mbrfile = "/usr/share/syslinux/mbr.bin" if not os.path.exists(mbrfile): raise CreatorError("mbr.bin file didn't exist.") mbrsize = os.path.getsize(mbrfile) outimg = "%s/%s.usbimg" % (self._outdir, self.name) args = ['dd', "if=" + mbrfile, "of=" + outimg, "seek=0", "conv=notrunc", "bs=1", "count=%d" % (mbrsize)] rc = runner.show(args) if rc: raise CreatorError("Can't set MBR.")
def _mount_instroot(self, base_on=None): self.__imgdir = self._mkdtemp() #Set a default partition if no partition is given out if not self.ks.handler.partition.partitions: partstr = "part / --size 1900 --ondisk sda --fstype=ext3" args = partstr.split() pd = self.ks.handler.partition.parse(args[1:]) if pd not in self.ks.handler.partition.partitions: self.ks.handler.partition.partitions.append(pd) #list of partitions from kickstart file parts = kickstart.get_partitions(self.ks) #list of disks where a disk is an dict with name: and size disks = [] for i in range(len(parts)): if parts[i].disk: disk = parts[i].disk else: raise CreatorError( "Failed to create disks, no --ondisk specified in partition line of ks file" ) if not parts[i].fstype: raise CreatorError( "Failed to create disks, no --fstype specified in partition line of ks file" ) size = parts[i].size * 1024L * 1024L found = False for j in range(len(disks)): if disks[j]['name'] == disk: disks[j]['size'] = disks[j]['size'] + size found = True break else: found = False if not found: disks.append({'name': disk, 'size': size}) #create disk for item in disks: msger.debug("Adding disk %s as %s/%s-%s.raw" % (item['name'], self.__imgdir, self.name, item['name'])) disk = fs_related.SparseLoopbackDisk( "%s/%s-%s.raw" % (self.__imgdir, self.name, item['name']), item['size']) self.__disks[item['name']] = disk self.__instloop = PartitionedMount(self.__disks, self._instroot) for p in parts: self.__instloop.add_partition(int(p.size), p.disk, p.mountpoint, p.fstype, fsopts=p.fsopts, boot=p.active) self.__instloop.mount() self._create_mkinitrd_config()