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 [email protected] 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 -- [EMAIL PROTECTED]
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
[email protected]
https://www.redhat.com/mailman/listinfo/et-mgmt-tools