disk/vfs: ensure guestfs capabilities

Ensures that guestfs is available and well configured. Also
when checking for capabilities this commit introduces an in-memory
flag to avoid repeating the process if succeeded.
If we are able to load guestfs but something wrong happens a fatal
error is raised.

DocImpact: We should add a not for ubuntu like systems that use
libguestfs to execute the command 'update-guestfs-appliance' for
configuring it.

Closes-Bug: #1275267
Closes-Bug: #1157922
Change-Id: I97b3a23829ea1f3aadfe08ca6448b35010d2f312
This commit is contained in:
Sahid Orentino Ferdjaoui 2014-09-10 16:05:22 +00:00
parent eb860c2f21
commit 6a0e6209ca
3 changed files with 47 additions and 16 deletions

View File

@ -54,6 +54,9 @@ class GuestFS(object):
self.drives.append((file, kwargs['format']))
def add_drive(self, file, format=None, *args, **kwargs):
self.add_drive_opts(file, format=None, *args, **kwargs)
def inspect_os(self):
return ["/dev/guestvgf/lv_root"]

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import exception
from nova.i18n import _LW
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
@ -21,31 +22,42 @@ LOG = logging.getLogger(__name__)
class VFS(object):
# Class level flag to indicate whether we can consider
# that guestfs is ready to be used.
guestfs_ready = False
@staticmethod
def instance_for_image(imgfile, imgfmt, partition):
LOG.debug("Instance for image imgfile=%(imgfile)s "
"imgfmt=%(imgfmt)s partition=%(partition)s",
{'imgfile': imgfile, 'imgfmt': imgfmt,
'partition': partition})
hasGuestfs = False
try:
LOG.debug("Trying to import guestfs")
importutils.import_module("guestfs")
hasGuestfs = True
except Exception:
pass
if hasGuestfs:
vfs = None
try:
LOG.debug("Using primary VFSGuestFS")
return importutils.import_object(
vfs = importutils.import_object(
"nova.virt.disk.vfs.guestfs.VFSGuestFS",
imgfile, imgfmt, partition)
else:
LOG.warn(_LW("Unable to import guestfs, "
"falling back to VFSLocalFS"))
return importutils.import_object(
"nova.virt.disk.vfs.localfs.VFSLocalFS",
imgfile, imgfmt, partition)
if not VFS.guestfs_ready:
# Inspect for capabilities and keep
# track of the result only if succeeded.
vfs.inspect_capabilities()
VFS.guestfs_ready = True
return vfs
except exception.NovaException:
if vfs is not None:
# We are able to load libguestfs but
# something wrong happens when trying to
# check for capabilities.
raise
else:
LOG.warn(_LW("Unable to import guestfs"
"falling back to VFSLocalFS"))
return importutils.import_object(
"nova.virt.disk.vfs.localfs.VFSLocalFS",
imgfile, imgfmt, partition)
"""
The VFS class defines an interface for manipulating files within

View File

@ -52,10 +52,26 @@ class VFSGuestFS(vfs.VFS):
global guestfs
if guestfs is None:
guestfs = importutils.import_module('guestfs')
try:
guestfs = importutils.import_module('guestfs')
except Exception as e:
raise exception.NovaException(
_("libguestfs is not installed (%s)") % e)
self.handle = None
def inspect_capabilities(self):
"""Determines whether guestfs is well configured."""
try:
g = guestfs.GuestFS()
g.add_drive("/dev/null") # sic
g.launch()
except Exception as e:
raise exception.NovaException(
_("libguestfs installed but not usable (%s)") % e)
return self
def setup_os(self):
if self.partition == -1:
self.setup_os_inspect()