Greetings, Spoke with Dan Berrangé on irc about using virtinst/ImageFetcher.py for use in the snake project. I've basically copied the contents with a few tweaks. Dan suggested sending the patch to et-mgmt-tools@xxxxxxxxxx for comments/thoughts. The patch consists of 3 main hunks: 1 Split acquireFile() into 2 new methods > saveFile() - does what acquireFile() does now, downloads file, writes contents to disk, returns its path > loadFile() - downloads file and returns file contents 2 MountedImageFetcher().prepareLocation() will check if the requested server:/path is already mounted > Supporting mtab code can be found at http://git.fedorahosted.org/git/snake?p=snake;a=blob;f=snake/util.py;h=5815e28ce98e3a5c9dd0b0ec7b380cc05fd39d6c;hb=HEAD 3 LocalImageFetcher()._acquireFile() will use grabber.urlopen so that it can make use of of the progress callback when copying files via saveTemp() calls. Hope this is helpful. Thanks, James -- ========================================== James Laska -- jlaska@xxxxxxxxxx Quality Engineering -- Red Hat, Inc. ==========================================
--- virtinst--devel/virtinst/ImageFetcher.py 2008-03-26 14:38:48.000000000 -0400 +++ snake.git/snake/uri.py 2008-04-08 12:05:59.000000000 -0400 @@ -58,7 +110,13 @@ def cleanupLocation(self): pass - def acquireFile(self, src, progresscb): + def loadFile(self, filename, progresscb): + return self._acquireFile(filename, progresscb, save=False) + + def saveFile(self, filename, progresscb): + return self._acquireFile(filename, progresscb, save=True) + + def _acquireFile(self, src, progresscb): raise "Must be implemented in subclass" def hasFile(self, src): @@ -79,7 +137,7 @@ (self.location, e)) return False - def acquireFile(self, filename, progresscb): + def _acquireFile(self, filename, progresscb, save=False): file = None try: base = os.path.basename(filename) @@ -91,11 +149,14 @@ except IOError, e: raise ValueError, _("Couldn't acquire file %s: %s") %\ ((self.location + "/" + filename), str(e)) - tmpname = self.saveTemp(file, prefix=base + ".") - logging.debug("Saved file to " + tmpname) - return tmpname + if save: + tmpname = self.saveTemp(file, prefix=base + ".") + return tmpname + else: + return file finally: - if file: + if save and file: + '''only close the file if we were asked to save it to a file''' file.close() class HTTPImageFetcher(URIImageFetcher): @@ -132,8 +193,9 @@ def __init__(self, location, scratchdir, srcdir=None): ImageFetcher.__init__(self, location, scratchdir) + self.srcdir = srcdir - def acquireFile(self, filename, progresscb): + def _acquireFile(self, filename, progresscb, save=False): file = None try: logging.debug("Acquiring file from " + self.srcdir + "/" + filename) @@ -144,16 +206,22 @@ logging.debug("Found a directory") return None else: - file = open(src, "r") + # file = open(src, "r") + file = grabber.urlopen(self.srcdir + "/" + filename, \ + progress_obj = progresscb, \ + text = _("Retrieving file %s...") % base) except IOError, e: raise ValueError, _("Invalid file location given: ") + str(e) except OSError, (errno, msg): raise ValueError, _("Invalid file location given: ") + msg - tmpname = self.saveTemp(file, prefix=base + ".") - logging.debug("Saved file to " + tmpname) - return tmpname + if save: + tmpname = self.saveTemp(file, prefix=base + ".") + return tmpname + else: + return file finally: - if file: + if save and file: + '''only close the file if we were asked to save it to a file''' file.close() def hasFile(self, filename): @@ -169,28 +237,52 @@ class MountedImageFetcher(LocalImageFetcher): def prepareLocation(self, progresscb): - cmd = None - self.srcdir = tempfile.mkdtemp(prefix="virtinstmnt.", dir=self.scratchdir) - logging.debug("Preparing mount at " + self.srcdir) - if self.location.startswith("nfs:"): - cmd = ["mount", "-o", "ro", self.location[4:], self.srcdir] + + self.need_umount = True + self.srcdir = None + + # First, see if the nfs server:path is already mounted? + (scheme,netloc,path) = self.location.split(':',2) + for mount in snake.util.get_mtab(vfstype="nfs"): + (mnt_hostname,mnt_path) = mount.mnt_fsname.split(":") + if mnt_hostname == netloc and \ + path.startswith(mnt_path): + self.srcdir = "/%s" % path.replace(mnt_path.rstrip('/'), mount.mnt_dir.rstrip('/')) + + # is the directory already mounted? + if self.srcdir: + if not os.path.exists(self.srcdir): + raise ValueError(_("Location %s could not be found") % (self.location)) + # instruct the obj not to attempt a umount + self.need_umount = False + return os.path.exists(self.srcdir) + + # Otherwise, attempt to mount the nfs uri else: - if stat.S_ISBLK(os.stat(self.location)[stat.ST_MODE]): - cmd = ["mount", "-o", "ro", self.location, self.srcdir] + cmd = None + self.srcdir = tempfile.mkdtemp(prefix="snakemnt.", dir=self.scratchdir) + logging.debug("Preparing mount at " + self.srcdir) + if self.location.startswith("nfs:"): + cmd = ["mount", "-o", "ro", self.location[4:], self.srcdir] else: - cmd = ["mount", "-o", "ro,loop", self.location, self.srcdir] - ret = subprocess.call(cmd) - if ret != 0: - self.cleanupLocation() - logging.debug("Mounting location %s failed" % (self.location,)) - raise ValueError(_("Mounting location %s failed") % (self.location)) - return False - return True + if stat.S_ISBLK(os.stat(self.location)[stat.ST_MODE]): + cmd = ["mount", "-o", "ro", self.location, self.srcdir] + else: + cmd = ["mount", "-o", "ro,loop", self.location, self.srcdir] + ret = snake.util.pcall(cmd, stderr=open('/dev/null', 'w')) + if ret != 0: + self.cleanupLocation() + logging.debug("Mounting location %s failed" % (self.location,)) + raise ValueError(_("Mounting location %s failed") % (self.location)) + return False + return True def cleanupLocation(self): + if not self.need_umount: + return logging.debug("Cleaning up mount at " + self.srcdir) cmd = ["umount", self.srcdir] - ret = subprocess.call(cmd) + ret = snake.util.pcall(cmd, stderr=open('/dev/null', 'w')) try: os.rmdir(self.srcdir) except:
_______________________________________________ et-mgmt-tools mailing list et-mgmt-tools@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/et-mgmt-tools