When setting ownership of a file or directory, the guestfs driver
looks for the /etc/passwd and/or /etc/group files. In case they
are not found, the current driver lets the auges RuntimeError
through, which does not produce a very helpful error message.
Fixing that by handling the original exception and rasing a
Nova exception with more details in it.
Related-bug: #
1646002
Change-Id: I2d15865c8be13b938e10e67c1b1b160f2a80f0c0
class GuestFS(object):
SUPPORT_CLOSE_ON_EXIT = True
SUPPORT_RETURN_DICT = True
+ CAN_SET_OWNERSHIP = True
def __init__(self, **kwargs):
if not self.SUPPORT_CLOSE_ON_EXIT and 'close_on_exit' in kwargs:
if not self.auginit:
raise RuntimeError("Augeus not initialized")
+ if ((cfgpath.startswith("/files/etc/passwd") or
+ cfgpath.startswith("/files/etc/group")) and not
+ self.CAN_SET_OWNERSHIP):
+ raise RuntimeError("Node not found %s", cfgpath)
+
if cfgpath == "/files/etc/passwd/root/uid":
return 0
elif cfgpath == "/files/etc/passwd/fred/uid":
vfs.teardown()
+ def test_set_ownership_not_supported(self):
+ # NOTE(andreaf) Setting ownership relies on /etc/passwd and/or
+ # /etc/group being available in the image, which is not always the
+ # case - e.g. CirrOS image before boot.
+ vfs = vfsimpl.VFSGuestFS(self.qcowfile)
+ vfs.setup()
+ self.stub_out('nova.tests.unit.virt.disk.vfs.fakeguestfs.GuestFS.'
+ 'CAN_SET_OWNERSHIP', False)
+
+ self.assertRaises(exception.NovaException, vfs.set_ownership,
+ "/some/file", "fred", None)
+ self.assertRaises(exception.NovaException, vfs.set_ownership,
+ "/some/file", None, "users")
+
def test_close_on_error(self):
vfs = vfsimpl.VFSGuestFS(self.qcowfile)
vfs.setup()
uid = -1
gid = -1
+ def _get_item_id(id_path):
+ try:
+ return int(self.handle.aug_get("/files/etc/" + id_path))
+ except RuntimeError as e:
+ msg = _("Error obtaining uid/gid for %(user)s/%(group)s: "
+ " path %(id_path)s not found (%(e)s)") % {
+ 'id_path': "/files/etc/" + id_path, 'user': user,
+ 'group': group, 'e': e}
+ raise exception.NovaException(msg)
+
if user is not None:
- uid = int(self.handle.aug_get(
- "/files/etc/passwd/" + user + "/uid"))
+ uid = _get_item_id('passwd/' + user + '/uid')
if group is not None:
- gid = int(self.handle.aug_get(
- "/files/etc/group/" + group + "/gid"))
-
+ gid = _get_item_id('group/' + group + '/gid')
LOG.debug("chown uid=%(uid)d gid=%(gid)s",
{'uid': uid, 'gid': gid})
self.handle.chown(uid, gid, path)