def taring(dstfile, target): basen, ext = os.path.splitext(dstfile) comp = {".tar": None, ".gz": "gz", # for .tar.gz ".bz2": "bz2", # for .tar.bz2 ".tgz": "gz", ".tbz": "bz2"}[ext] # specify tarball file path if not comp: tarpath = dstfile elif basen.endswith(".tar"): tarpath = basen else: tarpath = basen + ".tar" tar = find_binary_path('tar') if os.path.isdir(target): for item in os.listdir(target): runner.show([tar, "-rSf", tarpath, "-C", target, "--add-file=%s" % item]) else: runner.show([tar, "-rSf", tarpath, "-C", os.path.dirname(target), "--add-file=%s" % os.path.basename(target)]) if comp: compressing(tarpath, comp) # when dstfile ext is ".tgz" and ".tbz", should rename if not basen.endswith(".tar"): shutil.move("%s.%s" % (tarpath, comp), dstfile)
def resize2fs(fs, size): resize2fs = find_binary_path("resize2fs") if size == 0: # it means to minimalize it return runner.show([resize2fs, '-M', fs]) else: return runner.show([resize2fs, fs, "%sK" % (size / 1024,)])
def unmount(self): if self.has_chroot_instance(): return if self.ismounted(): runner.show([self.umountcmd, "-l", self.dest]) self.mounted = False
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) cmdlist = [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize)] if self.extopts: cmdlist.extend(self.extopts.split()) cmdlist.extend([self.disk.device]) rc, errout = runner.runtool(cmdlist, catch=2) if rc != 0: raise MountError("Error creating %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) if not self.extopts: msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device]) rc, errout = runner.runtool([self.dumpe2fs, '-h', self.disk.device], catch=2) if rc != 0: raise MountError("Error dumpe2fs %s filesystem on disk %s:\n%s" % (self.fstype, self.disk.device, errout)) # FIXME: specify uuid in mkfs parameter try: self.uuid = self.__parse_field(out, "Filesystem UUID") except: self.uuid = None
def resize2fs(fs, size): resize2fs = find_binary_path("resize2fs") if size == 0: # it means to minimalize it return runner.show([resize2fs, '-M', fs]) else: return runner.show([resize2fs, fs, "%sK" % (size / 1024, )])
def mount(self): if self.mounted or self.ismounted(): return makedirs(self.dest) rc = runner.show([self.mountcmd, "--bind", self.src, self.dest]) if rc != 0: raise MountError("Bind-mounting '%s' to '%s' failed" % (self.src, self.dest)) if self.option: rc = runner.show([self.mountcmd, "--bind", "-o", "remount,%s" % self.option, self.dest]) if rc != 0: raise MountError("Bind-remounting '%s' failed" % self.dest) self.mounted = True
def __check_btrfs(self): found = False """ Need to load btrfs module to mount it """ load_module("btrfs") for line in open("/proc/filesystems").xreadlines(): if line.find("btrfs") > -1: found = True break if not found: raise MountError("Your system can't mount btrfs filesystem, please make sure your kernel has btrfs support and the module btrfs.ko has been loaded.") # disable selinux, selinux will block write if os.path.exists("/usr/sbin/setenforce"): runner.show(["/usr/sbin/setenforce", "0"])
def uncompress_squashfs(squashfsimg, outdir): """Uncompress file system from squshfs image""" unsquashfs = find_binary_path("unsquashfs") args = [ unsquashfs, "-d", outdir, squashfsimg ] rc = runner.show(args) if (rc != 0): raise SquashfsError("Failed to uncompress %s." % squashfsimg)
def uncompress_squashfs(squashfsimg, outdir): """Uncompress file system from squshfs image""" unsquashfs = find_binary_path("unsquashfs") args = [unsquashfs, "-d", outdir, squashfsimg] rc = runner.show(args) if (rc != 0): raise SquashfsError("Failed to uncompress %s." % squashfsimg)
def mount(self, options=None): if self.mounted: return if not os.path.isdir(self.mountdir): msger.debug("Creating mount point %s" % self.mountdir) os.makedirs(self.mountdir) self.rmdir = self.rmmountdir self.__create() msger.debug("Mounting %s at %s" % (self.disk.device, self.mountdir)) if options: args = [ self.mountcmd, "-o", options, self.disk.device, self.mountdir ] else: args = [self.mountcmd, self.disk.device, self.mountdir] if self.fstype: args.extend(["-t", self.fstype]) rc = runner.show(args) if rc != 0: raise MountError( "Failed to mount '%s' to '%s' with command '%s'. Retval: %s" % (self.disk.device, self.mountdir, " ".join(args), rc)) self.mounted = True
def get_loop_device(losetupcmd, lofile): import fcntl fp = open("/var/lock/__mic_loopdev.lock", 'w') fcntl.flock(fp, fcntl.LOCK_EX) try: devinst = LoopDevice() devinst.create() except: rc, out = runner.runtool([losetupcmd, "-f"]) if rc != 0: raise MountError("1-Failed to allocate loop device for '%s'" % lofile) loopdev = out.split()[0] else: loopdev = devinst.device finally: try: fcntl.flock(fp, fcntl.LOCK_UN) fp.close() os.unlink('/var/lock/__mic_loopdev.lock') except: pass rc = runner.show([losetupcmd, loopdev, lofile]) if rc != 0: raise MountError("2-Failed to allocate loop device for '%s'" % lofile) return loopdev
def mount(self, options = None): if self.mounted: return if not os.path.isdir(self.mountdir): msger.debug("Creating mount point %s" % self.mountdir) os.makedirs(self.mountdir) self.rmdir = self.rmmountdir self.__create() msger.debug("Mounting %s at %s" % (self.disk.device, self.mountdir)) if options: args = [ self.mountcmd, "-o", options, self.disk.device, self.mountdir ] else: args = [ self.mountcmd, self.disk.device, self.mountdir ] if self.fstype: args.extend(["-t", self.fstype]) rc = runner.show(args) if rc != 0: raise MountError("Failed to mount '%s' to '%s' with command '%s'. Retval: %s" % (self.disk.device, self.mountdir, " ".join(args), rc)) self.mounted = True
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show( [self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), self.disk.device] ) # str(self.disk.size / self.blocksize)]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device)) out = runner.outs([self.dumpe2fs, "-h", self.disk.device]) self.uuid = self.__parse_field(out, "Filesystem UUID") msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([self.mkfscmd, "-F", "-L", self.fslabel, "-m", "1", "-b", str(self.blocksize), self.disk.device]) # str(self.disk.size / self.blocksize)]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype, self.disk.device)) out = runner.outs([self.dumpe2fs, '-h', self.disk.device]) self.uuid = self.__parse_field(out, "Filesystem UUID") msger.debug("Tuning filesystem on %s" % self.disk.device) runner.show([self.tune2fs, "-c0", "-i0", "-Odir_index", "-ouser_xattr,acl", self.disk.device])
def compressing(fpath, method): comp_map = {"gz": "gzip", "bz2": "bzip2"} if method not in comp_map: raise CreatorError("Unsupport compress format: %s, valid values: %s" % (method, ','.join(comp_map.keys()))) cmd = find_binary_path(comp_map[method]) rc = runner.show([cmd, "-f", fpath]) if rc: raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
def myurlgrab(url, filename, proxies, progress_obj = None): g = grabber.URLGrabber() if progress_obj is None: progress_obj = TextProgress() if url.startswith("file:/"): file = url.replace("file:", "") if not os.path.exists(file): raise CreatorError("URLGrabber error: can't find file %s" % file) runner.show(['cp', "-f", file, filename]) else: try: filename = g.urlgrab(url = url, filename = filename, ssl_verify_host = False, ssl_verify_peer = False, proxies = proxies, http_headers = (('Pragma', 'no-cache'),), quote = 0, progress_obj = progress_obj) except grabber.URLGrabError, e: raise CreatorError("URLGrabber error: %s" % url)
def mksquashfs(in_img, out_img): fullpathmksquashfs = find_binary_path("mksquashfs") args = [fullpathmksquashfs, in_img, out_img] if not sys.stdout.isatty(): args.append("-no-progress") ret = runner.show(args) if ret != 0: raise SquashfsError("'%s' exited with error (%d)" % (' '.join(args), ret))
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([self.mkfscmd, "-L", self.fslabel, self.disk.device]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device)) self.uuid = self.__parse_field(runner.outs([self.blkidcmd, self.disk.device]), "UUID")
def __format_filesystem(self): if self.skipformat: msger.debug("Skip filesystem format.") return msger.verbose("Formating %s filesystem on %s" % (self.fstype, self.disk.device)) rc = runner.show([self.mkfscmd, "-n", self.fslabel, "-i", self.uuid, self.disk.device]) if rc != 0: raise MountError("Error creating %s filesystem on disk %s" % (self.fstype,self.disk.device)) msger.verbose("Tuning filesystem on %s" % self.disk.device)
def compressing(fpath, method): comp_map = { "gz": "gzip", "bz2": "bzip2" } if method not in comp_map: raise CreatorError("Unsupport compress format: %s, valid values: %s" % (method, ','.join(comp_map.keys()))) cmd = find_binary_path(comp_map[method]) rc = runner.show([cmd, "-f", fpath]) if rc: raise CreatorError("Failed to %s file: %s" % (comp_map[method], fpath))
def myurlgrab(url, filename, proxies, progress_obj=None): g = grabber.URLGrabber() if progress_obj is None: progress_obj = TextProgress() if url.startswith("file:/"): file = url.replace("file:", "") if not os.path.exists(file): raise CreatorError("URLGrabber error: can't find file %s" % file) runner.show(['cp', "-f", file, filename]) else: try: filename = g.urlgrab(url=url, filename=filename, ssl_verify_host=False, ssl_verify_peer=False, proxies=proxies, http_headers=(('Pragma', 'no-cache'), ), quote=0, progress_obj=progress_obj) except grabber.URLGrabError, e: raise CreatorError("URLGrabber error: %s" % url)
def get_loop_device(losetupcmd, lofile): """ Get a lock to synchronize getting a loopback device """ # internal class for simple lock class FileLock(object): def __init__(self, filename): self.filename = filename self.fd = None import atexit atexit.register(self.release) def acquire(self): try: self.fd = os.open(self.filename, os.O_CREAT | os.O_EXCL) return True except OSError: self.fd = None return False def release(self): try: if self.fd is not None: os.close(self.fd) os.remove(self.filename) except: pass lock = FileLock("/var/lock/._mic_loopdev.lock") timeout = 30 while not lock.acquire(): if timeout == 0: raise MountError("Timeout! Failed to find a free loop device") time.sleep(2) timeout -= 2 rc, losetupOutput = runner.runtool([losetupcmd, "-f"]) if rc != 0: lock.release() raise MountError("Failed to allocate loop device for '%s'" % lofile) loopdev = losetupOutput.split()[0] rc = runner.show([losetupcmd, loopdev, lofile]) lock.release() if rc != 0: raise MountError("Failed to allocate loop device for '%s'" % lofile) return loopdev
def remove(self, ignore_errors=False): if not self.__created: return time.sleep(2) rc = runner.show([self.dmsetupcmd, "remove", self.__name]) if not ignore_errors and rc != 0: raise SnapshotError("Could not remove snapshot device") self.__name = None self.__created = False self.cowloop.cleanup() self.imgloop.cleanup()
def remove(self, ignore_errors = False): if not self.__created: return time.sleep(2) rc = runner.show([self.dmsetupcmd, "remove", self.__name]) if not ignore_errors and rc != 0: raise SnapshotError("Could not remove snapshot device") self.__name = None self.__created = False self.cowloop.cleanup() self.imgloop.cleanup()
def setup_qemu_emulator(rootdir, arch): # mount binfmt_misc if it doesn't exist if not os.path.exists("/proc/sys/fs/binfmt_misc"): modprobecmd = find_binary_path("modprobe") runner.show([modprobecmd, "binfmt_misc"]) if not os.path.exists("/proc/sys/fs/binfmt_misc/register"): mountcmd = find_binary_path("mount") runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"]) # qemu_emulator is a special case, we can't use find_binary_path # qemu emulator should be a statically-linked executable file qemu_emulator = "/usr/bin/qemu-arm" if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator): qemu_emulator = "/usr/bin/qemu-arm-static" if not os.path.exists(qemu_emulator): raise CreatorError("Please install a statically-linked qemu-arm") # qemu emulator version check armv7_list = [arch for arch in rpmmisc.archPolicies.keys() if arch.startswith('armv7')] if arch in armv7_list: # need qemu (>=0.13.0) qemuout = runner.outs([qemu_emulator, "-h"]) m = re.search("version\s*([.\d]+)", qemuout) if m: qemu_version = m.group(1) if qemu_version < "0.13": raise CreatorError("Requires %s version >=0.13 for %s" % (qemu_emulator, arch)) else: msger.warning("Can't get version info of %s, please make sure it's higher than 0.13.0" % qemu_emulator) if not os.path.exists(rootdir + "/usr/bin"): makedirs(rootdir + "/usr/bin") shutil.copy(qemu_emulator, rootdir + qemu_emulator) # disable selinux, selinux will block qemu emulator to run if os.path.exists("/usr/sbin/setenforce"): msger.info('Try to disable selinux') runner.show(["/usr/sbin/setenforce", "0"]) node = "/proc/sys/fs/binfmt_misc/arm" if is_statically_linked(qemu_emulator) and os.path.exists(node): return qemu_emulator # unregister it if it has been registered and is a dynamically-linked executable if not is_statically_linked(qemu_emulator) and os.path.exists(node): qemu_unregister_string = "-1\n" fd = open("/proc/sys/fs/binfmt_misc/arm", "w") fd.write(qemu_unregister_string) fd.close() # register qemu emulator for interpreting other arch executable file if not os.path.exists(node): qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator fd = open("/proc/sys/fs/binfmt_misc/register", "w") fd.write(qemu_arm_string) fd.close() return qemu_emulator
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 create(self): if not self.created: if not self.loopid: self.loopid = self._genloopid() self.device = "/dev/loop%d" % self.loopid if os.path.exists(self.device): if self._loseek(self.device): raise MountError("Device busy: %s" % self.device) else: self.created = True return mknod = find_binary_path('mknod') rc = runner.show([mknod, '-m664', self.device, 'b', '7', str(self.loopid)]) if rc != 0: raise MountError("Failed to create device %s" % self.device) else: self.created = True
def convert_image(srcimg, srcfmt, dstimg, dstfmt): #convert disk format if dstfmt != "raw": raise CreatorError("Invalid destination image format: %s" % dstfmt) msger.debug("converting %s image to %s" % (srcimg, dstimg)) if srcfmt == "vmdk": path = find_binary_path("qemu-img") argv = [path, "convert", "-f", "vmdk", srcimg, "-O", dstfmt, dstimg] elif srcfmt == "vdi": path = find_binary_path("VBoxManage") argv = [path, "internalcommands", "converttoraw", srcimg, dstimg] else: raise CreatorError("Invalid soure image format: %s" % srcfmt) rc = runner.show(argv) if rc == 0: msger.debug("convert successful") if rc != 0: raise CreatorError("Unable to convert disk to %s" % dstfmt)
def create(self): if self.__created: return self.imgloop.create() self.cowloop.create() self.__name = "imgcreate-%d-%d" % (os.getpid(), random.randint(0, 2 ** 16)) size = os.stat(self.imgloop.lofile)[stat.ST_SIZE] table = "0 %d snapshot %s %s p 8" % (size / 512, self.imgloop.device, self.cowloop.device) args = [self.dmsetupcmd, "create", self.__name, "--table", table] if runner.show(args) != 0: self.cowloop.cleanup() self.imgloop.cleanup() raise SnapshotError("Could not create snapshot device using: " + " ".join(args)) self.__created = True
def create(self): if self.__created: return self.imgloop.create() self.cowloop.create() self.__name = "imgcreate-%d-%d" % (os.getpid(), random.randint( 0, 2**16)) size = os.stat(self.imgloop.lofile)[stat.ST_SIZE] table = "0 %d snapshot %s %s p 8" % (size / 512, self.imgloop.device, self.cowloop.device) args = [self.dmsetupcmd, "create", self.__name, "--table", table] if runner.show(args) != 0: self.cowloop.cleanup() self.imgloop.cleanup() raise SnapshotError("Could not create snapshot device using: " + ' '.join(args)) self.__created = True
def get_loop_device(losetupcmd, lofile): import fcntl fp = open("/var/lock/__mic_loopdev.lock", 'w') fcntl.flock(fp, fcntl.LOCK_EX) try: loopdev = None devinst = LoopDevice() # clean up left loop device first clean_loop_devices() # provide an avaible loop device rc, out = runner.runtool([losetupcmd, "--find"]) if rc == 0: loopdev = out.split()[0] devinst.register(loopdev) if not loopdev or not os.path.exists(loopdev): devinst.create() loopdev = devinst.device # setup a loop device for image file rc = runner.show([losetupcmd, loopdev, lofile]) if rc != 0: raise MountError("Failed to setup loop device for '%s'" % lofile) devinst.reg_atexit() # try to save device and pid makedirs(DEVICE_PIDFILE_DIR) pidfile = os.path.join(DEVICE_PIDFILE_DIR, os.path.basename(loopdev)) if os.path.exists(pidfile): os.unlink(pidfile) with open(pidfile, 'w') as wf: wf.write(str(os.getpid())) except MountError, err: raise CreatorError("%s" % str(err))
def cleanup(self): if self.device is None: return msger.debug("Losetup remove %s" % self.device) rc = runner.show([self.losetupcmd, "-d", self.device]) self.device = None
def setup_qemu_emulator(rootdir, arch): # mount binfmt_misc if it doesn't exist if not os.path.exists("/proc/sys/fs/binfmt_misc"): modprobecmd = find_binary_path("modprobe") runner.show([modprobecmd, "binfmt_misc"]) if not os.path.exists("/proc/sys/fs/binfmt_misc/register"): mountcmd = find_binary_path("mount") runner.show([mountcmd, "-t", "binfmt_misc", "none", "/proc/sys/fs/binfmt_misc"]) if arch.startswith("arm"): qemu_emulator = "/usr/bin/qemu-arm" qemu_arch = "arm" elif arch == "mipsel": qemu_emulator = "/usr/bin/qemu-mipsel" qemu_arch = "mipsel" else: raise CreatorError("No qemu for arch %s" % arch) # qemu_emulator is a special case, we can't use find_binary_path # qemu emulator should be a statically-linked executable file if not os.path.exists(qemu_emulator) or not is_statically_linked(qemu_emulator): qemu_emulator = "%s-static" % qemu_emulator if not os.path.exists(qemu_emulator): raise CreatorError("Please install a statically-linked qemu-%s" % qemu_arch) # qemu emulator version check if qemu_arch == "arm": check_armv7_qemu_version(arch, qemu_emulator) if not os.path.exists(rootdir + "/usr/bin"): makedirs(rootdir + "/usr/bin") shutil.copy(qemu_emulator, rootdir + qemu_emulator) # disable selinux, selinux will block qemu emulator to run if os.path.exists("/usr/sbin/setenforce"): msger.info('Try to disable selinux') runner.show(["/usr/sbin/setenforce", "0"]) node = "/proc/sys/fs/binfmt_misc/%s" % qemu_arch if is_statically_linked(qemu_emulator) and os.path.exists(node): return qemu_emulator # unregister it if it has been registered and is a dynamically-linked executable if not is_statically_linked(qemu_emulator) and os.path.exists(node): qemu_unregister_string = "-1\n" fd = open(node, "w") fd.write(qemu_unregister_string) fd.close() # register qemu emulator for interpreting other arch executable file if not os.path.exists(node): qemu_arm_string = ":arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfa\\xff\\xff\\xff:%s:\n" % qemu_emulator qemu_mipsel_string = ":mipsel:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x08\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:%s:\n" % qemu_emulator binfmt_register = "/proc/sys/fs/binfmt_misc/register" if qemu_arch == "arm": qemu_register_string = qemu_arm_string elif qemu_arch == "mipsel": qemu_register_string = qemu_mipsel_string fd = open(binfmt_register, "w") fd.write(qemu_register_string) fd.close() return qemu_emulator
def __fsck(self): msger.debug("Checking filesystem %s" % self.disk.lofile) runner.show([self.fsckcmd, "-y", self.disk.lofile])
def lounsetup(self): if self.losetup: runner.show([self.losetupcmd, "-d", self.loopdev]) self.losetup = False self.loopdev = None