urlfetcher: Make fetcher cleanup idempotent

This commit is contained in:
Cole Robinson 2014-09-07 14:22:56 -04:00
parent faa0ef5e55
commit 050d0fb16e

View File

@ -84,7 +84,7 @@ class _ImageFetcher(object):
return fn return fn
def prepareLocation(self): def prepareLocation(self):
return True pass
def cleanupLocation(self): def cleanupLocation(self):
pass pass
@ -145,12 +145,12 @@ class _HTTPImageFetcher(_URIImageFetcher):
class _FTPImageFetcher(_URIImageFetcher): class _FTPImageFetcher(_URIImageFetcher):
def __init__(self, *args, **kwargs): ftp = None
_URIImageFetcher.__init__(self, *args, **kwargs)
self.ftp = None
def prepareLocation(self): def prepareLocation(self):
if self.ftp:
return
try: try:
url = urlparse.urlparse(self._make_path("")) url = urlparse.urlparse(self._make_path(""))
if not url[1]: if not url[1]:
@ -161,6 +161,15 @@ class _FTPImageFetcher(_URIImageFetcher):
raise ValueError(_("Opening URL %s failed: %s.") % raise ValueError(_("Opening URL %s failed: %s.") %
(self.location, str(e))) (self.location, str(e)))
def cleanupLocation(self):
if not self.ftp:
return
try:
self.ftp.quit()
except:
logging.debug("Error quitting ftp connection", exc_info=True)
def hasFile(self, filename): def hasFile(self, filename):
path = self._make_path(filename) path = self._make_path(filename)
@ -197,9 +206,11 @@ class _MountedImageFetcher(_LocalImageFetcher):
or loopback mounted file, or local CDROM device or loopback mounted file, or local CDROM device
""" """
_in_test_suite = bool("VIRTINST_TEST_SUITE" in os.environ) _in_test_suite = bool("VIRTINST_TEST_SUITE" in os.environ)
_mounted = False
def prepareLocation(self): def prepareLocation(self):
cmd = None if self._mounted:
return
if self._in_test_suite: if self._in_test_suite:
self.srcdir = os.environ["VIRTINST_TEST_URL_DIR"] self.srcdir = os.environ["VIRTINST_TEST_URL_DIR"]
@ -219,25 +230,30 @@ class _MountedImageFetcher(_LocalImageFetcher):
cmd = [mountcmd, "-o", mountopt, self.location, self.srcdir] cmd = [mountcmd, "-o", mountopt, self.location, self.srcdir]
logging.debug("mount cmd: %s", cmd) logging.debug("mount cmd: %s", cmd)
if not self._in_test_suite: if not self._in_test_suite:
ret = subprocess.call(cmd) ret = subprocess.call(cmd)
if ret != 0: if ret != 0:
self.cleanupLocation() self.cleanupLocation()
raise ValueError(_("Mounting location '%s' failed") % raise ValueError(_("Mounting location '%s' failed") %
(self.location)) (self.location))
return True
self._mounted = True
def cleanupLocation(self): def cleanupLocation(self):
logging.debug("Cleaning up mount at " + self.srcdir) if not self._mounted:
return
if not self._in_test_suite: logging.debug("Cleaning up mount at " + self.srcdir)
cmd = ["/bin/umount", self.srcdir] try:
subprocess.call(cmd) if not self._in_test_suite:
try: cmd = ["/bin/umount", self.srcdir]
os.rmdir(self.srcdir) subprocess.call(cmd)
except: try:
pass os.rmdir(self.srcdir)
except:
pass
finally:
self._mounted = False
class _DirectImageFetcher(_LocalImageFetcher): class _DirectImageFetcher(_LocalImageFetcher):