def package(self, destdir = "."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._img_compression_method: if not self._img_name: raise CreatorError("Image name not set.") rc = None img_location = os.path.join(self._outdir,self._img_name) if self._img_compression_method == "bz2": bzip2 = fs.find_binary_path('bzip2') msger.info("Compressing %s with bzip2. Please wait..." \ % img_location) rc = runner.show([bzip2, "-f", img_location]) if rc: raise CreatorError("Failed to compress image %s with %s." \ % (img_location, self._img_compression_method)) for bootimg in glob.glob(os.path.dirname(img_location) + \ "/*-boot.bin"): msger.info("Compressing %s with bzip2. Please wait..." \ % bootimg) rc = runner.show([bzip2, "-f", bootimg]) if rc: raise CreatorError("Failed to compress image %s with " "%s." \ % (bootimg, self._img_compression_method)) if self._recording_pkgs: self._save_recording_pkgs(destdir) # For image formats with two or multiple image files, it will be # better to put them under a directory if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" \ % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet('sync') for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def __map_partitions(self): """Load it if dm_snapshot isn't loaded""" load_module("dm_snapshot") for dev in self.disks.keys(): d = self.disks[dev] if d['mapped']: continue msger.debug("Running kpartx on %s" % d['disk'].device ) rc, kpartxOutput = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device]) kpartxOutput = kpartxOutput.splitlines() if rc != 0: raise MountError("Failed to query partition mapping for '%s'" % d['disk'].device) # Strip trailing blank and mask verbose output i = 0 while i < len(kpartxOutput) and kpartxOutput[i][0:4] != "loop": i = i + 1 kpartxOutput = kpartxOutput[i:] # Quick sanity check that the number of partitions matches # our expectation. If it doesn't, someone broke the code # further up if len(kpartxOutput) != d['numpart']: raise MountError("Unexpected number of partitions from kpartx: %d != %d" % (len(kpartxOutput), d['numpart'])) for i in range(len(kpartxOutput)): line = kpartxOutput[i] newdev = line.split()[0] mapperdev = "/dev/mapper/" + newdev loopdev = d['disk'].device + newdev[-1] msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev)) pnum = d['partitions'][i] self.partitions[pnum]['device'] = loopdev # grub's install wants partitions to be named # to match their parent device + partition num # kpartx doesn't work like this, so we add compat # symlinks to point to /dev/mapper if os.path.lexists(loopdev): os.unlink(loopdev) os.symlink(mapperdev, loopdev) msger.debug("Adding partx mapping for %s" % d['disk'].device) rc = runner.show([self.kpartx, "-v", "-a", d['disk'].device]) if rc != 0: # Make sure that the device maps are also removed on error case. # The d['mapped'] isn't set to True if the kpartx fails so # failed mapping will not be cleaned on cleanup either. runner.quiet([self.kpartx, "-d", d['disk'].device]) raise MountError("Failed to map partitions for '%s'" % d['disk'].device) d['mapped'] = True
def savefs_before_chroot(chrootdir, saveto=None): """ backup chrootdir to another directory before chrooting in """ if configmgr.chroot['saveto']: savefs = True saveto = configmgr.chroot['saveto'] wrnmsg = "Can't save chroot fs for dir %s exists" % saveto if saveto == chrootdir: savefs = False wrnmsg = "Dir %s is being used to chroot" % saveto elif os.path.exists(saveto): if msger.ask("Dir %s already exists, cleanup and continue?" % saveto): shutil.rmtree(saveto, ignore_errors=True) savefs = True else: savefs = False if savefs: msger.info("Saving image to directory %s" % saveto) fs_related.makedirs(os.path.dirname(os.path.abspath(saveto))) runner.quiet("cp -af %s %s" % (chrootdir, saveto)) devs = [ 'dev/fd', 'dev/stdin', 'dev/stdout', 'dev/stderr', 'etc/mtab' ] ignlst = [os.path.join(saveto, x) for x in devs] map(os.unlink, filter(os.path.exists, ignlst)) else: msger.warning(wrnmsg)
def _install_syslinux(self): for name in self.__disks.keys(): loopdev = self.__disks[name].device # Set MBR mbrfile = "%s/usr/share/syslinux/" % self._instroot if self._ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: mbrfile += "mbr.bin" msger.debug("Installing syslinux bootloader '%s' to %s" % \ (mbrfile, loopdev)) mbrsize = os.stat(mbrfile)[stat.ST_SIZE] rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) # Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %s" \ % loopdev)
def _install_syslinux(self): i = 0 for name in self.__disks.keys(): loopdev = self.__disks[name].device i =i+1 msger.debug("Installing syslinux bootloader to %s" % loopdev) (bootdevnum, rootdevnum, rootdev, prefix) = self._get_syslinux_boot_config() #Set MBR mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" % self._instroot)[stat.ST_SIZE] rc = runner.show(['dd', "if=%s/usr/share/syslinux/mbr.bin" % self._instroot, "of=" + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) #Set Bootable flag parted = fs_related.find_binary_path("parted") rc = runner.quiet([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"]) #XXX disabled return code check because parted always fails to #reload part table with loop devices. Annoying because we can't #distinguish this failure from real partition failures :-( if rc != 0 and 1 == 0: raise MountError("Unable to set bootable flag to %sp%d" % (loopdev, (bootdevnum + 1))) #Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %sp%d" % (loopdev, (bootdevnum + 1)))
def _install_syslinux(self): for name in self.__disks.keys(): loopdev = self.__disks[name].device # Set MBR mbrfile = "%s/usr/share/syslinux/" % self._instroot if self._ptable_format == 'gpt': mbrfile += "gptmbr.bin" else: mbrfile += "mbr.bin" msger.debug("Installing syslinux bootloader '%s' to %s" % \ (mbrfile, loopdev)) rc = runner.show(['dd', 'if=%s' % mbrfile, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) # Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %s" \ % loopdev)
def cleanup_mounts(chrootdir): umountcmd = misc.find_binary_path("umount") for point in BIND_MOUNTS: args = [umountcmd, "-l", chrootdir + point] runner.quiet(args) point = '/parentroot' args = [umountcmd, "-l", chrootdir + point] runner.quiet(args) abs_chrootdir = os.path.abspath(chrootdir) with open('/proc/mounts') as f: for line in f: if abs_chrootdir in line: point = line.split()[1] if abs_chrootdir == point: continue args = [umountcmd, "-l", point] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) return ret return 0
def savefs_before_chroot(chrootdir, saveto = None): """ backup chrootdir to another directory before chrooting in """ if configmgr.chroot['saveto']: savefs = True saveto = configmgr.chroot['saveto'] wrnmsg = "Can't save chroot fs for dir %s exists" % saveto if saveto == chrootdir: savefs = False wrnmsg = "Dir %s is being used to chroot" % saveto elif os.path.exists(saveto): if msger.ask("Dir %s already exists, cleanup and continue?" % saveto): shutil.rmtree(saveto, ignore_errors = True) savefs = True else: savefs = False if savefs: msger.info("Saving image to directory %s" % saveto) fs_related.makedirs(os.path.dirname(os.path.abspath(saveto))) runner.quiet("cp -af %s %s" % (chrootdir, saveto)) devs = ['dev/fd', 'dev/stdin', 'dev/stdout', 'dev/stderr', 'etc/mtab'] ignlst = [os.path.join(saveto, x) for x in devs] map(os.unlink, filter(os.path.exists, ignlst)) else: msger.warning(wrnmsg)
def cleanup_mounts(chrootdir): umountcmd = misc.find_binary_path("umount") for point in BIND_MOUNTS: args = [ umountcmd, "-l", chrootdir + point ] runner.quiet(args) point = '/parentroot' args = [ umountcmd, "-l", chrootdir + point ] runner.quiet(args) abs_chrootdir = os.path.abspath(chrootdir) with open('/proc/mounts') as f: for line in f: if abs_chrootdir in line: point = line.split()[1] if abs_chrootdir == point: continue args = [ umountcmd, "-l", point ] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) return ret return 0
def package(self, destdir="."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._recording_pkgs: self._save_recording_pkgs(destdir) # For image formats with two or multiple image files, it will be # better to put them under a directory if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet("sync") misc.check_space_pre_cp(self._outdir, destdir) for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def load_module(module): found = False for line in open('/proc/modules').xreadlines(): if line.startswith("%s " % module): found = True break if not found: msger.info("Loading %s..." % module) runner.quiet(['modprobe', module])
def apply(self, ksrepo, repodata): for repo in ksrepo.repoList: if repo.save: # self.__create_repo_file(repo, "/etc/yum.repos.d") self.__create_repo_file(repo, "/etc/zypp/repos.d") """ Import repo gpg keys """ if repodata: for repo in repodata: if repo["repokey"]: runner.quiet(["rpm", "--root=%s" % self.instroot, "--import", repo["repokey"]])
def unhide_loopdev_presentation(): global _LOOP_RULE_PTH if not _LOOP_RULE_PTH: return try: os.unlink(_LOOP_RULE_PTH) runner.quiet('udevadm trigger') except: pass
def _get_uncompressed_data_from_url(url, filename, proxies): filename = myurlgrab(url, filename, proxies) suffix = None if filename.endswith(".gz"): suffix = ".gz" runner.quiet(['gunzip', "-f", filename]) elif filename.endswith(".bz2"): suffix = ".bz2" runner.quiet(['bunzip2', "-f", filename]) if suffix: filename = filename.replace(suffix, "") return filename
def apply(self, ksrepo, repodata): for repo in ksrepo.repoList: if repo.save: #self.__create_repo_file(repo, "/etc/yum.repos.d") self.__create_repo_file(repo, "/etc/zypp/repos.d") """ Import repo gpg keys """ if repodata: for repo in repodata: if repo['repokey']: runner.quiet(['rpm', "--root=%s" % self.instroot, "--import", repo['repokey']])
def cleanup(self): if self.device is None: return if self._kpseek(self.device): runner.quiet([self.kpartxcmd, "-d", self.device]) if self._loseek(self.device): runner.quiet([self.losetupcmd, "-d", self.device]) # FIXME: should sleep a while between two loseek if self._loseek(self.device): msger.warning("Can't cleanup loop device %s" % self.device) elif self.loopid: os.unlink(self.device)
def package(self, destdir = "."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._img_compression_method: if not self._img_name: raise CreatorError("Image name not set.") rc = None img_location = os.path.join(self._outdir,self._img_name) if self._img_compression_method == "bz2": bzip2 = fs.find_binary_path('bzip2') msger.info("Compressing %s with bzip2. Please wait..." % img_location) rc = runner.show([bzip2, "-f", img_location]) if rc: raise CreatorError("Failed to compress image %s with %s." % (img_location, self._img_compression_method)) for bootimg in glob.glob(os.path.dirname(img_location) + "/*-boot.bin"): msger.info("Compressing %s with bzip2. Please wait..." % bootimg) rc = runner.show([bzip2, "-f", bootimg]) if rc: raise CreatorError("Failed to compress image %s with %s." % (bootimg, self._img_compression_method)) if self._recording_pkgs: self._save_recording_pkgs(destdir) """ For image formats with two or multiple image files, it will be better to put them under a directory """ if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet('sync') for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def unmount(self): if self.mounted: msger.debug("Unmounting directory %s" % self.mountdir) runner.quiet('sync') # sync the data on this mount point rc = runner.show([self.umountcmd, "-l", self.mountdir]) if rc == 0: self.mounted = False else: raise MountError("Failed to umount %s" % self.mountdir) if self.rmdir and not self.mounted: try: os.rmdir(self.mountdir) except OSError, e: pass self.rmdir = False
def apply(self, ksrepo, repodata, repourl): for repo in ksrepo.repoList: if repo.name in repourl: repo.baseurl = repourl[repo.name] if repo.save: #self.__create_repo_file(repo, "/etc/yum.repos.d") self.__create_repo_file(repo, "/etc/zypp/repos.d") """ Import repo gpg keys """ if repodata: for repo in repodata: if repo['repokey']: runner.quiet(['rpm', "--root=%s" % self.instroot, "--import", repo['repokey']])
def _install_syslinux(self): i = 0 for name in self.__disks.keys(): loopdev = self.__disks[name].device i =i+1 msger.debug("Installing syslinux bootloader to %s" % loopdev) (bootdevnum, rootdevnum, rootdev, prefix) = \ self._get_syslinux_boot_config() #Set MBR mbrsize = os.stat("%s/usr/share/syslinux/mbr.bin" \ % self._instroot)[stat.ST_SIZE] rc = runner.show(['dd', 'if=%s/usr/share/syslinux/mbr.bin' % self._instroot, 'of=' + loopdev]) if rc != 0: raise MountError("Unable to set MBR to %s" % loopdev) #Set Bootable flag parted = fs_related.find_binary_path("parted") rc = runner.quiet([parted, "-s", loopdev, "set", "%d" % (bootdevnum + 1), "boot", "on"]) #XXX disabled return code check because parted always fails to #reload part table with loop devices. Annoying because we can't #distinguish this failure from real partition failures :-( if rc != 0 and 1 == 0: raise MountError("Unable to set bootable flag to %sp%d" \ % (loopdev, (bootdevnum + 1))) #Ensure all data is flushed to disk before doing syslinux install runner.quiet('sync') fullpathsyslinux = fs_related.find_binary_path("extlinux") rc = runner.show([fullpathsyslinux, "-i", "%s/boot/extlinux" % self._instroot]) if rc != 0: raise MountError("Unable to install syslinux bootloader to %sp%d" \ % (loopdev, (bootdevnum + 1)))
def cleanup(self): if self.device is None: return if self._kpseek(self.device): if self.created: for i in range(3, os.sysconf("SC_OPEN_MAX")): try: os.close(i) except: pass runner.quiet([self.kpartxcmd, "-d", self.device]) if self._loseek(self.device): runner.quiet([self.losetupcmd, "-d", self.device]) # FIXME: should sleep a while between two loseek if self._loseek(self.device): msger.warning("Can't cleanup loop device %s" % self.device) elif self.loopid: os.unlink(self.device)
def hide_loopdev_presentation(): udev_rules = "80-prevent-loop-present.rules" udev_rules_dir = [ '/usr/lib/udev/rules.d/', '/lib/udev/rules.d/', '/etc/udev/rules.d/' ] global _LOOP_RULE_PTH for rdir in udev_rules_dir: if os.path.exists(rdir): _LOOP_RULE_PTH = os.path.join(rdir, udev_rules) if not _LOOP_RULE_PTH: return try: with open(_LOOP_RULE_PTH, 'w') as wf: wf.write('KERNEL=="loop*", ENV{UDISKS_PRESENTATION_HIDE}="1"') runner.quiet('udevadm trigger') except: pass
def package(self, destdir="."): """Prepares the created image for final delivery. In its simplest form, this method merely copies the install root to the supplied destination directory; other subclasses may choose to package the image by e.g. creating a bootable ISO containing the image and bootloader configuration. destdir -- the directory into which the final image should be moved; this defaults to the current directory. """ self._stage_final_image() if not os.path.exists(destdir): fs.makedirs(destdir) if self._recording_pkgs: self._save_recording_pkgs(destdir) # For image formats with two or multiple image files, it will be # better to put them under a directory if self.image_format in ("raw", "vmdk", "vdi", "nand", "mrstnand"): destdir = os.path.join(destdir, "%s-%s" \ % (self.name, self.image_format)) msger.debug("creating destination dir: %s" % destdir) fs.makedirs(destdir) # Ensure all data is flushed to _outdir runner.quiet('sync') misc.check_space_pre_cp(self._outdir, destdir) for f in os.listdir(self._outdir): shutil.move(os.path.join(self._outdir, f), os.path.join(destdir, f)) self.outimage.append(os.path.join(destdir, f)) self.do_genchecksum(os.path.join(destdir, f))
def my_fuser(fp): fuser = find_binary_path("fuser") if not os.path.exists(fp): return False rc = runner.quiet([fuser, "-s", fp]) if rc == 0: for pid in runner.outs([fuser, fp]).split(): fd = open("/proc/%s/cmdline" % pid, "r") cmdline = fd.read() fd.close() if cmdline[:-1] == "/bin/bash": return True # not found return False
def cleanup_mounts(chrootdir): umountcmd = misc.find_binary_path("umount") abs_chrootdir = os.path.abspath(chrootdir) mounts = open('/proc/mounts').readlines() for line in reversed(mounts): if abs_chrootdir not in line: continue point = line.split()[1] # '/' to avoid common name prefix if abs_chrootdir == point or point.startswith(abs_chrootdir + '/'): args = [umountcmd, "-l", point] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) return 0
def cleanup_mounts(chrootdir): umountcmd = misc.find_binary_path("umount") abs_chrootdir = os.path.abspath(chrootdir) mounts = open('/proc/mounts').readlines() for line in reversed(mounts): if abs_chrootdir not in line: continue point = line.split()[1] # '/' to avoid common name prefix if abs_chrootdir == point or point.startswith(abs_chrootdir + '/'): args = [ umountcmd, "-l", point ] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) return 0
def __unmap_partitions(self): for dev in self.disks.keys(): d = self.disks[dev] if not d['mapped']: continue msger.debug("Removing compat symlinks") for pnum in d['partitions']: if self.partitions[pnum]['device'] != None: os.unlink(self.partitions[pnum]['device']) self.partitions[pnum]['device'] = None msger.debug("Unmapping %s" % d['disk'].device) rc = runner.quiet([self.kpartx, "-d", d['disk'].device]) if rc != 0: raise MountError("Failed to unmap partitions for '%s'" % d['disk'].device) d['mapped'] = False
def __unmap_partitions(self): for dev in self.disks.keys(): d = self.disks[dev] if not d['mapped']: continue msger.debug("Removing compat symlinks") for pnum in d['partitions']: if self.partitions[pnum]['device'] != None: os.unlink(self.partitions[pnum]['device']) self.partitions[pnum]['device'] = None msger.debug("Unmapping %s" % d['disk'].device) rc = runner.quiet([self.kpartx, "-sd", d['disk'].device]) if rc != 0: raise MountError("Failed to unmap partitions for '%s'" % d['disk'].device) d['mapped'] = False
def cleanup_mounts(chrootdir): """ clean up all mount entries owned by chrootdir """ umountcmd = misc.find_binary_path("umount") mounts = open('/proc/mounts').readlines() for line in reversed(mounts): if chrootdir not in line: continue point = line.split()[1] # '/' to avoid common name prefix if chrootdir == point or point.startswith(chrootdir + '/'): args = [umountcmd, "-l", point] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) if os.path.isdir(point) and len(os.listdir(point)) == 0: shutil.rmtree(point) else: msger.warning("%s is not directory or is not empty" % point)
def cleanup_mounts(chrootdir): """ clean up all mount entries owned by chrootdir """ umountcmd = misc.find_binary_path("umount") mounts = open('/proc/mounts').readlines() for line in reversed(mounts): if chrootdir not in line: continue point = line.split()[1] # '/' to avoid common name prefix if chrootdir == point or point.startswith(chrootdir + '/'): args = [ umountcmd, "-l", point ] ret = runner.quiet(args) if ret != 0: msger.warning("failed to unmount %s" % point) if os.path.isdir(point) and len(os.listdir(point)) == 0: shutil.rmtree(point) else: msger.warning("%s is not directory or is not empty" % point)
def __unmap_partitions(self): for dev in list(self.disks.keys()): d = self.disks[dev] if not d['mapped']: continue msger.debug("Removing compat symlinks") for pnum in d['partitions']: if self.partitions[pnum]['device'] != None: os.unlink(self.partitions[pnum]['device']) self.partitions[pnum]['device'] = None msger.debug("Unmapping %s" % d['disk'].device) #FIXME: find a better way to workaround delayed IO keeping the devices busy time.sleep(4) rc = runner.quiet([self.kpartx, "-d", d['disk'].device]) if rc != 0: raise MountError("Failed to unmap partitions for '%s'" % d['disk'].device) d['mapped'] = False
def __unmap_partitions(self): for dev in self.disks.keys(): d = self.disks[dev] if not d['mapped']: continue msger.debug("Removing compat symlinks") for pnum in d['partitions']: if self.partitions[pnum]['device'] != None: os.unlink(self.partitions[pnum]['device']) self.partitions[pnum]['device'] = None msger.debug("Unmapping %s" % d['disk'].device) #FIXME: find a better way to workaround delayed IO keeping the devices busy time.sleep(4) rc = runner.quiet([self.kpartx, "-d", d['disk'].device]) if rc != 0: raise MountError("Failed to unmap partitions for '%s'" % d['disk'].device) d['mapped'] = False
def __fsck(self): msger.info("Checking filesystem %s" % self.disk.lofile) runner.quiet(["/sbin/e2fsck", "-f", "-y", self.disk.lofile])
def __map_partitions(self): """Load it if dm_snapshot isn't loaded. """ load_module("dm_snapshot") for dev in self.disks.keys(): d = self.disks[dev] if d['mapped']: continue msger.debug("Running kpartx on %s" % d['disk'].device) rc, kpartx_output = runner.runtool( [self.kpartx, "-l", "-v", d['disk'].device]) kpartx_output = kpartx_output.splitlines() if rc != 0: raise MountError("Failed to query partition mapping for '%s'" % d['disk'].device) # Strip trailing blank and mask verbose output i = 0 while i < len(kpartx_output) and kpartx_output[i][0:4] != "loop": i = i + 1 kpartx_output = kpartx_output[i:] # Make sure kpartx reported the right count of partitions if len(kpartx_output) != d['numpart']: # If this disk has more than 3 partitions, then in case of MBR # paritions there is an extended parition. Different versions # of kpartx behave differently WRT the extended partition - # some map it, some ignore it. This is why we do the below hack # - if kpartx reported one more partition and the partition # table type is "msdos" and the amount of partitions is more # than 3, we just assume kpartx mapped the extended parition # and we remove it. if len(kpartx_output) == d['numpart'] + 1 \ and d['ptable_format'] == 'msdos' and len(kpartx_output) > 3: kpartx_output.pop(3) else: raise MountError("Unexpected number of partitions from " \ "kpartx: %d != %d" % \ (len(kpartx_output), d['numpart'])) for i in range(len(kpartx_output)): line = kpartx_output[i] newdev = line.split()[0] mapperdev = "/dev/mapper/" + newdev loopdev = d['disk'].device + newdev[-1] msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev)) pnum = d['partitions'][i] self.partitions[pnum]['device'] = loopdev self.partitions[pnum]['mapper_device'] = mapperdev # grub's install wants partitions to be named # to match their parent device + partition num # kpartx doesn't work like this, so we add compat # symlinks to point to /dev/mapper if os.path.lexists(loopdev): os.unlink(loopdev) os.symlink(mapperdev, loopdev) msger.debug("Adding partx mapping for %s" % d['disk'].device) rc = runner.show([self.kpartx, "-v", "-sa", d['disk'].device]) if rc != 0: # Make sure that the device maps are also removed on error case. # The d['mapped'] isn't set to True if the kpartx fails so # failed mapping will not be cleaned on cleanup either. runner.quiet([self.kpartx, "-sd", d['disk'].device]) raise MountError("Failed to map partitions for '%s'" % d['disk'].device) for p in self.partitions: if p['mapper_device'] and os.path.islink(p['mapper_device']): p['mpath_device'] = resolve_ref(p['mapper_device']) else: p['mpath_device'] = '' # FIXME: need a better way to fix the latency import time time.sleep(1) if not os.path.exists(mapperdev): # load mapper device if not updated runner.quiet([self.dmsetup, "mknodes"]) # still not updated, roll back if not os.path.exists(mapperdev): runner.quiet([self.kpartx, "-sd", d['disk'].device]) raise MountError("Failed to load mapper devices for '%s'" % d['disk'].device) d['mapped'] = True
def __fsck(self): msger.debug("Checking filesystem %s" % self.disk.lofile) runner.quiet([self.btrfsckcmd, self.disk.lofile])
def checkRpmIntegrity(bin_rpm, package): return runner.quiet([bin_rpm, "-K", "--nosignature", package])
def _stage_final_image(self): if self.pack_to or self.shrink_image: self._resparse(0) else: self._resparse() for item in self._instloops: imgfile = os.path.join(self._imgdir, item['name']) if item['aft_fstype'] in AFTER_MNT_FS.keys(): mountpoint = misc.mkdtemp() ext4img = os.path.join(self._imgdir, item['name']) runner.show('mount -t ext4 %s %s' % (ext4img, mountpoint)) runner.show('ls -al %s' % (mountpoint)) # item['loop'].mount(None, 'not_create') # point_mnt = os.path.join(self._instroot, item['mountpoint'].lstrip('/')) fs_suffix = AFTER_MNT_FS[item['aft_fstype']] if item['aft_fstype'] == "squashfs": # fs.mksquashfs(mountpoint, self._outdir+"/"+item['label']+fs_suffix) args = "mksquashfs " + mountpoint + " " + self._imgdir+"/"+item['label']+fs_suffix if item['squashfsopts']: squashfsopts=item['squashfsopts'].replace(',', ' ') runner.show("mksquashfs --help") runner.show("%s %s" % (args, squashfsopts)) else: runner.show("%s " % args) if item['aft_fstype'] == "vdfs": ##FIXME temporary code - replace this with fs.mkvdfs() if item['vdfsopts']: vdfsopts=item['vdfsopts'].replace(',', ' ') else: vdfsopts="-i -z 1024M" fullpathmkvdfs = "mkfs.vdfs" #find_binary_path("mkfs.vdfs") runner.show("%s --help" % fullpathmkvdfs) # fs.mkvdfs(mountpoint, self._outdir+"/"+item['label']+fs_suffix, vdfsopts) runner.show('%s %s -r %s %s' % (fullpathmkvdfs, vdfsopts, mountpoint, self._imgdir+"/"+item['label']+fs_suffix)) runner.show('umount %s' % mountpoint) # os.unlink(mountpoint) runner.show('mv %s %s' % (self._imgdir+"/"+item['label']+fs_suffix, self._imgdir+"/"+item['label']+".img") ) runner.show('ls -al %s' % self._imgdir) if item['fstype'] == "ext4": if not item['cpioopts']: runner.show('/sbin/tune2fs -O ^huge_file,extents,uninit_bg %s ' % imgfile) runner.quiet(["/sbin/e2fsck", "-f", "-y", imgfile]) self.image_files.setdefault('partitions', {}).update( {item['mountpoint']: item['label']}) if self.compress_image: compressing(imgfile, self.compress_image) self.image_files.setdefault('image_files', []).append( '.'.join([item['name'], self.compress_image])) else: self.image_files.setdefault('image_files', []).append(item['name']) for item in os.listdir(self._imgdir): imgfile = os.path.join(self._imgdir, item) imgsize = os.path.getsize(imgfile) msger.info("filesystem size of %s : %s bytes" % (item, imgsize)) self.run_sign_scripts() if not self.pack_to: for item in os.listdir(self._imgdir): shutil.move(os.path.join(self._imgdir, item), os.path.join(self._outdir, item)) else: msger.info("Pack all loop images together to %s" % self.pack_to) dstfile = os.path.join(self._outdir, self.pack_to) packing(dstfile, self._imgdir) self.image_files['image_files'] = [self.pack_to] if self.pack_to: mountfp_xml = os.path.splitext(self.pack_to)[0] mountfp_xml = misc.strip_end(mountfp_xml, '.tar') + ".xml" else: mountfp_xml = self.name + ".xml" # save mount points mapping file to xml save_mountpoints(os.path.join(self._outdir, mountfp_xml), self._instloops, self.target_arch)
def chroot(chrootdir, bindmounts=None, execute="/bin/bash"): def mychroot(): os.chroot(chrootdir) os.chdir("/") if configmgr.chroot['saveto']: savefs = True saveto = configmgr.chroot['saveto'] wrnmsg = "Can't save chroot fs for dir %s exists" % saveto if saveto == chrootdir: savefs = False wrnmsg = "Dir %s is being used to chroot" % saveto elif os.path.exists(saveto): if msger.ask("Dir %s already exists, cleanup and continue?" % saveto): shutil.rmtree(saveto, ignore_errors=True) savefs = True else: savefs = False if savefs: msger.info("Saving image to directory %s" % saveto) runner.quiet("cp -af %s %s" % (chrootdir, saveto)) devs = [ 'dev/fd', 'dev/stdin', 'dev/stdout', 'dev/stderr', 'etc/mtab' ] ignlst = [os.path.join(saveto, x) for x in devs] map(os.unlink, filter(os.path.exists, ignlst)) else: msger.warning(wrnmsg) dev_null = os.open("/dev/null", os.O_WRONLY) files_to_check = ["/bin/bash", "/sbin/init"] architecture_found = False """ Register statically-linked qemu-arm if it is an ARM fs """ qemu_emulator = None for ftc in files_to_check: ftc = "%s/%s" % (chrootdir, ftc) # Return code of 'file' is "almost always" 0 based on some man pages # so we need to check the file existance first. if not os.path.exists(ftc): continue for line in runner.outs(['file', ftc]).splitlines(): if 'ARM' in line: qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm") architecture_found = True break if 'Intel' in line: architecture_found = True break if architecture_found: break os.close(dev_null) if not architecture_found: raise errors.CreatorError("Failed to get architecture from any of the " "following files %s from chroot." \ % files_to_check) try: msger.info("Launching shell. Exit to continue.\n" "----------------------------------") globalmounts = setup_chrootenv(chrootdir, bindmounts) subprocess.call(execute, preexec_fn=mychroot, shell=True) except OSError, err: raise errors.CreatorError("chroot err: %s" % str(err))
def chroot(chrootdir, bindmounts = None, execute = "/bin/bash"): def mychroot(): os.chroot(chrootdir) os.chdir("/") if configmgr.chroot['saveto']: savefs = True saveto = configmgr.chroot['saveto'] wrnmsg = "Can't save chroot fs for dir %s exists" % saveto if saveto == chrootdir: savefs = False wrnmsg = "Dir %s is being used to chroot" % saveto elif os.path.exists(saveto): if msger.ask("Dir %s already exists, cleanup and continue?" % saveto): shutil.rmtree(saveto, ignore_errors = True) savefs = True else: savefs = False if savefs: msger.info("Saving image to directory %s" % saveto) fs_related.makedirs(os.path.dirname(os.path.abspath(saveto))) runner.quiet("cp -af %s %s" % (chrootdir, saveto)) devs = ['dev/fd', 'dev/stdin', 'dev/stdout', 'dev/stderr', 'etc/mtab'] ignlst = [os.path.join(saveto, x) for x in devs] map(os.unlink, filter(os.path.exists, ignlst)) else: msger.warning(wrnmsg) dev_null = os.open("/dev/null", os.O_WRONLY) files_to_check = ["/bin/bash", "/sbin/init"] architecture_found = False """ Register statically-linked qemu-arm if it is an ARM fs """ qemu_emulator = None for ftc in files_to_check: ftc = "%s/%s" % (chrootdir,ftc) # Return code of 'file' is "almost always" 0 based on some man pages # so we need to check the file existance first. if not os.path.exists(ftc): continue for line in runner.outs(['file', ftc]).splitlines(): if 'ARM' in line: qemu_emulator = misc.setup_qemu_emulator(chrootdir, "arm") architecture_found = True break if 'Intel' in line: architecture_found = True break if architecture_found: break os.close(dev_null) if not architecture_found: raise errors.CreatorError("Failed to get architecture from any of the " "following files %s from chroot." \ % files_to_check) try: msger.info("Launching shell. Exit to continue.\n" "----------------------------------") globalmounts = setup_chrootenv(chrootdir, bindmounts) subprocess.call(execute, preexec_fn = mychroot, shell=True) except OSError, err: raise errors.CreatorError("chroot err: %s" % str(err))
def __map_partitions(self): """Load it if dm_snapshot isn't loaded. """ load_module("dm_snapshot") for dev in self.disks.keys(): d = self.disks[dev] if d['mapped']: continue msger.debug("Running kpartx on %s" % d['disk'].device ) rc, kpartxOutput = runner.runtool([self.kpartx, "-l", "-v", d['disk'].device]) kpartxOutput = kpartxOutput.splitlines() if rc != 0: raise MountError("Failed to query partition mapping for '%s'" % d['disk'].device) # Strip trailing blank and mask verbose output i = 0 while i < len(kpartxOutput) and kpartxOutput[i][0:4] != "loop": i = i + 1 kpartxOutput = kpartxOutput[i:] # Make sure kpartx reported the right count of partitions if len(kpartxOutput) != d['numpart']: # If this disk has more than 3 partitions, then in case of MBR # paritions there is an extended parition. Different versions # of kpartx behave differently WRT the extended partition - # some map it, some ignore it. This is why we do the below hack # - if kpartx reported one more partition and the partition # table type is "msdos" and the amount of partitions is more # than 3, we just assume kpartx mapped the extended parition # and we remove it. if len(kpartxOutput) == d['numpart'] + 1 \ and d['ptable_format'] == 'msdos' and len(kpartxOutput) > 3: kpartxOutput.pop(3) else: raise MountError("Unexpected number of partitions from " \ "kpartx: %d != %d" % \ (len(kpartxOutput), d['numpart'])) for i in range(len(kpartxOutput)): line = kpartxOutput[i] newdev = line.split()[0] mapperdev = "/dev/mapper/" + newdev loopdev = d['disk'].device + newdev[-1] msger.debug("Dev %s: %s -> %s" % (newdev, loopdev, mapperdev)) pnum = d['partitions'][i] self.partitions[pnum]['device'] = loopdev # grub's install wants partitions to be named # to match their parent device + partition num # kpartx doesn't work like this, so we add compat # symlinks to point to /dev/mapper if os.path.lexists(loopdev): os.unlink(loopdev) os.symlink(mapperdev, loopdev) msger.debug("Adding partx mapping for %s" % d['disk'].device) rc = runner.show([self.kpartx, "-v", "-a", d['disk'].device]) if rc != 0: # Make sure that the device maps are also removed on error case. # The d['mapped'] isn't set to True if the kpartx fails so # failed mapping will not be cleaned on cleanup either. runner.quiet([self.kpartx, "-d", d['disk'].device]) raise MountError("Failed to map partitions for '%s'" % d['disk'].device) # FIXME: there is a bit delay for multipath device setup, # wait 10ms for the setup import time time.sleep(10) d['mapped'] = True