60
def _qemu_sanitize_drvtype(phystype, fmt):
62
Sanitize libvirt storage volume format to a valid qemu driver type
66
if phystype == VirtualDisk.TYPE_BLOCK:
67
return VirtualDisk.DRIVER_QEMU_RAW
70
return VirtualDisk.DRIVER_QEMU_RAW
76
Return UID for string username
78
pwdinfo = pwd.getpwnam(user)
81
def _is_dir_searchable(uid, username, path):
83
Check if passed directory is searchable by uid
86
statinfo = os.stat(path)
90
if uid == statinfo.st_uid:
92
elif uid == statinfo.st_gid:
97
if bool(statinfo.st_mode & flag):
100
# Check POSIX ACL (since that is what we use to 'fix' access)
101
cmd = ["getfacl", path]
102
proc = subprocess.Popen(cmd,
103
stdout=subprocess.PIPE,
104
stderr=subprocess.PIPE)
105
out, err = proc.communicate()
107
if proc.returncode != 0:
108
logging.debug("Cmd '%s' failed: %s" % (cmd, err))
111
return bool(re.search("user:%s:..x" % username, out))
58
114
class VirtualDisk(VirtualDevice):
60
116
Builds a libvirt domain disk xml description
202
def check_path_search_for_user(conn, path, username):
204
Check if the passed user has search permissions for all the
205
directories in the disk path.
207
@return: List of the directories the user cannot search, or empty list
210
if _util.is_uri_remote(conn.getURI()):
214
uid = _name_uid(username)
216
logging.debug("Error looking up username: %s" % str(e))
221
if os.path.isdir(path):
225
dirname, base = os.path.split(path)
228
if not _is_dir_searchable(uid, username, dirname):
229
fixlist.append(dirname)
231
dirname, base = os.path.split(dirname)
236
def fix_path_search_for_user(conn, path, username):
238
Try to fix any permission problems found by check_path_search_for_user
240
@return: Return a dictionary of entries { broken path : error msg }
243
def fix_perms(dirname, useacl=True):
245
cmd = ["setfacl", "--modify", "user:%s:x" % username, dirname]
246
proc = subprocess.Popen(cmd,
247
stdout=subprocess.PIPE,
248
stderr=subprocess.PIPE)
249
out, err = proc.communicate()
251
logging.debug("Ran command '%s'" % cmd)
253
logging.debug("out=%s\nerr=%s" % (out, err))
255
if proc.returncode != 0:
256
raise ValueError(err)
258
mode = os.stat(dirname).st_mode
259
os.chmod(dirname, mode | stat.S_IXOTH)
261
fixlist = VirtualDisk.check_path_search_for_user(conn, path, username)
269
for dirname in fixlist:
272
fix_perms(dirname, useacl)
274
# If acl fails, fall back to chmod and retry
279
fix_perms(dirname, useacl)
281
errdict[dirname] = str(e)
145
286
def __init__(self, path=None, size=None, transient=False, type=None,
146
287
device=DEVICE_DISK, driverName=None, driverType=None,
147
288
readOnly=False, sparse=True, conn=None, volObject=None,
148
289
volInstall=None, volName=None, bus=None, shareable=False,
149
driverCache=None, selinuxLabel=None):
290
driverCache=None, selinuxLabel=None, format=None):
151
292
@param path: filesystem path to the disk image.
152
293
@type path: C{str}
375
520
self.__validate_wrapper("_selinux_label", val, validate)
376
521
selinux_label = property(_get_selinux_label, _set_selinux_label)
523
def _get_format(self):
525
def _set_format(self, val, validate=True):
527
self._check_str(val, "format")
528
self.__validate_wrapper("_format", val, validate)
529
format = property(_get_format, _set_format)
378
531
# Validation assistance methods
380
533
# Initializes attribute if it hasn't been done, then validates args.
392
545
setattr(self, varname, orig)
548
def __set_format(self):
552
if not self.__creating_storage():
556
if not hasattr(self.vol_install, "format"):
557
raise ValueError(_("Storage type does not support format "
559
if self.vol_install.format != self.format:
560
self.vol_install.format = self.format
562
elif self.format != "raw":
563
raise RuntimeError(_("Format cannot be specified for "
564
"unmanaged storage."))
395
566
def __set_size(self):
397
568
Fill in 'size' attribute for existing storage.
469
640
drvname = self.DRIVER_QEMU
471
642
if self.vol_object:
472
drvtype = _util.get_xml_path(self.vol_object.XMLDesc(0),
473
"/volume/target/format")
643
fmt = _util.get_xml_path(self.vol_object.XMLDesc(0),
644
"/volume/target/format/@type")
645
if drvname == self.DRIVER_QEMU:
646
drvtype = _qemu_sanitize_drvtype(self.type, fmt)
475
648
elif self.vol_install:
476
649
if drvname == self.DRIVER_QEMU:
477
if self.vol_install.file_type == libvirt.VIR_STORAGE_VOL_FILE:
478
drvtype = self.vol_install.format
480
drvtype = self.DRIVER_QEMU_RAW
650
if hasattr(self.vol_install, "format"):
651
drvtype = _qemu_sanitize_drvtype(self.type,
652
self.vol_install.format)
482
654
elif self.__creating_storage():
483
655
if drvname == self.DRIVER_QEMU:
751
921
if not os.access(os.path.dirname(self.path), os.W_OK):
752
922
raise ValueError, _("No write access to directory '%s'") % \
753
923
os.path.dirname(self.path)
755
# Set dev type from existing storage
756
self.__set_dev_type()
758
925
# Applicable for managed or local storage
759
926
ret = self.is_size_conflict()
860
1027
zeros = '\0' * 4096
1029
src_fd, dst_fd = None, None
863
src_fd = os.open(self.clone_path, os.O_RDONLY)
864
dst_fd = os.open(self.path, os.O_WRONLY | os.O_CREAT)
1032
src_fd = os.open(self.clone_path, os.O_RDONLY)
1033
dst_fd = os.open(self.path, os.O_WRONLY | os.O_CREAT)
868
l = os.read(src_fd, clone_block_size)
871
meter.end(size_bytes)
873
# check sequence of zeros
874
if sparse and zeros == l:
875
os.lseek(dst_fd, s, 1)
877
b = os.write(dst_fd, l)
1037
l = os.read(src_fd, clone_block_size)
1040
meter.end(size_bytes)
1042
# check sequence of zeros
1043
if sparse and zeros == l:
1044
os.lseek(dst_fd, s, 1)
1046
b = os.write(dst_fd, l)
1054
raise RuntimeError(_("Error cloning diskimage %s to %s: %s") %
1055
(self.clone_path, self.path, str(e)))
886
1057
if src_fd is not None:
887
1058
os.close(src_fd)