View | Details | Raw Unified | Return to bug 18765
Collapse All | Expand All

(-)uvmm/univention-virtual-machine-manager-daemon/debian/changelog (+6 lines)
Lines 1-3 Link Here
1
univention-virtual-machine-manager-daemon (0.10.4-6) unstable; urgency=low
2
3
  * Support qcow2 image files (Bug #18765)
4
5
 -- Philipp Hahn <hahn@univention.de>  Wed, 20 Oct 2010 16:08:36 +0200
6
1
univention-virtual-machine-manager-daemon (0.10.4-5) unstable; urgency=low
7
univention-virtual-machine-manager-daemon (0.10.4-5) unstable; urgency=low
2
8
3
  * Sort list of servers (Bug #20345)
9
  * Sort list of servers (Bug #20345)
(-)uvmm/univention-virtual-machine-manager-daemon/src/univention-virtual-machine-manager (-1 / +23 lines)
Lines 289-294 Link Here
289
				except KeyError: pass
289
				except KeyError: pass
290
			else:
290
			else:
291
				raise "Unknown os/typ='%s'" % (domain.os_type,)
291
				raise "Unknown os/typ='%s'" % (domain.os_type,)
292
			try: domain.bootloader = root.findtext('bootloader')
293
			except AttributeError: pass
294
			try: domain.bootloader_args = root.findtext('bootloader_args')
295
			except AttributeError: pass
292
			domain.maxMem = int(root.findtext('memory')) << 10
296
			domain.maxMem = int(root.findtext('memory')) << 10
293
			from univention.uvmm.node import Disk, Interface, Graphic
297
			from univention.uvmm.node import Disk, Interface, Graphic
294
			for disk in root.find('devices').findall('disk'):
298
			for disk in root.find('devices').findall('disk'):
Lines 299-311 Link Here
299
				try: d.driver = disk.find('driver').attrib['name']
303
				try: d.driver = disk.find('driver').attrib['name']
300
				except AttributeError: pass
304
				except AttributeError: pass
301
				except KeyError: pass
305
				except KeyError: pass
302
				d.source = disk.find('source').attrib['file']
306
				try: d.driver_type = disk.find('driver').attrib['type']
307
				except AttributeError: pass
308
				except KeyError: pass
309
				try: d.driver_cache = d.map_cache(name=disk.find('driver').attrib['cache'])
310
				except AttributeError: pass
311
				except KeyError: pass
312
				if d.type == Disk.TYPE_FILE:
313
					d.source = disk.find('source').attrib['file']
314
				elif d.type == Disk.TYPE_BLOCK:
315
					d.source = disk.find('source').attrib['dev']
316
				else:
317
					d.source = None # FIXME
303
				try: d.target_dev = disk.find('target').attrib['dev']
318
				try: d.target_dev = disk.find('target').attrib['dev']
304
				except AttributeError: pass
319
				except AttributeError: pass
305
				except KeyError: pass
320
				except KeyError: pass
306
				try: d.target_bus = disk.find('target').attrib['bus']
321
				try: d.target_bus = disk.find('target').attrib['bus']
307
				except AttributeError: pass
322
				except AttributeError: pass
308
				except KeyError: pass
323
				except KeyError: pass
324
				try: d.readonly = bool(disk.find('readonly'))
325
				except KeyError: pass
309
				domain.disks.append(d)
326
				domain.disks.append(d)
310
			for interface in root.find('devices').findall('interface'):
327
			for interface in root.find('devices').findall('interface'):
311
				i = Interface()
328
				i = Interface()
Lines 322-327 Link Here
322
				try: i.target = interface.find('target').attrib['dev']
339
				try: i.target = interface.find('target').attrib['dev']
323
				except AttributeError: pass
340
				except AttributeError: pass
324
				except KeyError: pass
341
				except KeyError: pass
342
				try: i.model = interface.find('model').attrib['type']
343
				except AttributeError: pass
344
				except KeyError: pass
325
				domain.interfaces.append(i)
345
				domain.interfaces.append(i)
326
			for graphics in root.find('devices').findall('graphics'):
346
			for graphics in root.find('devices').findall('graphics'):
327
				g = Graphic()
347
				g = Graphic()
Lines 334-339 Link Here
334
				except KeyError: pass
354
				except KeyError: pass
335
				try: g.listen = graphics.attrib['listen']
355
				try: g.listen = graphics.attrib['listen']
336
				except KeyError: pass
356
				except KeyError: pass
357
				try: g.passwd = graphics.attrib['passwd']
358
				except KeyError: pass
337
				domain.graphics.append(g)
359
				domain.graphics.append(g)
338
			try:
360
			try:
339
				for annotation in root.find('annotations').findall('annotation'):
361
				for annotation in root.find('annotations').findall('annotation'):
(-)uvmm/univention-virtual-machine-manager-daemon/src/univention/uvmm/node.py (-12 / +30 lines)
Lines 93-106 Link Here
93
	DEVICE_MAP = { DEVICE_DISK : 'disk', DEVICE_CDROM : 'cdrom', DEVICE_FLOPPY : 'floppy' }
93
	DEVICE_MAP = { DEVICE_DISK : 'disk', DEVICE_CDROM : 'cdrom', DEVICE_FLOPPY : 'floppy' }
94
	(TYPE_FILE, TYPE_BLOCK) = range(2)
94
	(TYPE_FILE, TYPE_BLOCK) = range(2)
95
	TYPE_MAP = {TYPE_FILE: 'file', TYPE_BLOCK: 'block'}
95
	TYPE_MAP = {TYPE_FILE: 'file', TYPE_BLOCK: 'block'}
96
	(CACHE_DEFAULT, CACHE_NONE, CACHE_WT, CACHE_WB) = range(4)
97
	CACHE_MAP = {CACHE_DEFAULT: 'default', CACHE_NONE: 'none', CACHE_WT: 'writethrough', CACHE_WB: 'writeback'}
96
	def __init__( self ):
98
	def __init__( self ):
97
		self.type = Disk.TYPE_FILE
99
		self.type = Disk.TYPE_FILE	# disk/@type
98
		self.device = Disk.DEVICE_DISK
100
		self.device = Disk.DEVICE_DISK	# disk/@device
99
		self.driver = 'file'
101
		self.driver = None	# disk/driver/@name
100
		self.source = ''
102
		self.driver_type = None	# disk/driver/@type
101
		self.readonly = False
103
		self.driver_cache = Disk.CACHE_DEFAULT	# disk/driver/@cache
102
		self.target_dev = ''
104
		self.source = ''	# disk/source/@file | disk/source/@dev
103
		self.target_bus = 'ide'
105
		self.readonly = False	# disk/readonly
106
		self.target_dev = ''	# disk/target/@dev
107
		self.target_bus = None	# disk/target/@bus
104
		self.size = None # not defined
108
		self.size = None # not defined
105
109
106
	@staticmethod
110
	@staticmethod
Lines 111-116 Link Here
111
	def map_type( id = None, name = None ):
115
	def map_type( id = None, name = None ):
112
		return _map( Disk.TYPE_MAP, id, name )
116
		return _map( Disk.TYPE_MAP, id, name )
113
117
118
	@staticmethod
119
	def map_cache(id=None, name=None):
120
		return _map(Disk.CACHE_MAP, id, name)
121
114
	def __str__( self ):
122
	def __str__( self ):
115
		return 'Disk(%s,%s): %s, %s' % ( Disk.map_device( id = self.device ), Disk.map_type( id = self.type ), self.source, self.target_dev )
123
		return 'Disk(%s,%s): %s, %s' % ( Disk.map_device( id = self.device ), Disk.map_type( id = self.type ), self.source, self.target_dev )
116
124
Lines 366-371 Link Here
366
			dev = Disk()
374
			dev = Disk()
367
			dev.type = Disk.map_type( name = disk.getAttribute( 'type' ) )
375
			dev.type = Disk.map_type( name = disk.getAttribute( 'type' ) )
368
			dev.device = Disk.map_device( name = disk.getAttribute( 'device' ) )
376
			dev.device = Disk.map_device( name = disk.getAttribute( 'device' ) )
377
			driver = disk.getElementsByTagName('driver')
378
			if driver:
379
				dev.driver = driver[0].getAttribute('name')
380
				dev.driver_type = driver[0].getAttribute('type')
381
				dev.driver_cache = driver[0].getAttribute('cache')
369
			source = disk.getElementsByTagName( 'source' )
382
			source = disk.getElementsByTagName( 'source' )
370
			if source:
383
			if source:
371
				if dev.type == Disk.TYPE_FILE:
384
				if dev.type == Disk.TYPE_FILE:
Lines 843-852 Link Here
843
		elem.setAttribute( 'device', disk.map_device( id = disk.device ) )
856
		elem.setAttribute( 'device', disk.map_device( id = disk.device ) )
844
		devices.appendChild( elem )
857
		devices.appendChild( elem )
845
858
846
		# FIXME: KVM doesn't like it -> Xen/libvirt adds this automatically
859
		if disk.driver:
847
		# driver = doc.createElement( 'driver' )
860
			driver = doc.createElement('driver')
848
		# driver.setAttribute( 'name', disk.driver )
861
			driver.setAttribute('name', disk.driver)
849
		# elem.appendChild( driver )
862
			if disk.driver_type:
863
				driver.setAttribute('type', disk.driver_type)
864
			if disk.driver_cache:
865
				driver.setAttribute('cache', disk.map_cache(id=disk.driver_cache))
866
			elem.appendChild(driver)
850
867
851
		source = doc.createElement( 'source' )
868
		source = doc.createElement( 'source' )
852
		if disk.type == Disk.TYPE_FILE:
869
		if disk.type == Disk.TYPE_FILE:
Lines 861-867 Link Here
861
		target = doc.createElement( 'target' )
878
		target = doc.createElement( 'target' )
862
		target.setAttribute( 'dev', disk.target_dev )
879
		target.setAttribute( 'dev', disk.target_dev )
863
		# TODO: Xen an KVM have their default based on the device names
880
		# TODO: Xen an KVM have their default based on the device names
864
		# target.setAttribute( 'bus', disk.target_bus )
881
		if disk.target_bus:
882
			target.setAttribute('bus', disk.target_bus)
865
		elem.appendChild( target )
883
		elem.appendChild( target )
866
884
867
		if disk.readonly:
885
		if disk.readonly:
(-)dvs/univention-dvs-node/univention-dvs-create-desktop (-1 / +34 lines)
Lines 127-133 Link Here
127
				continue
127
				continue
128
128
129
			origPath = disk.source
129
			origPath = disk.source
130
			diskPath = "%s_%d" % (userTemplate, i)
130
			diskPath = "%s_%d.img" % (userTemplate, i)
131
			if os.path.exists(diskPath):
131
			if os.path.exists(diskPath):
132
				if options.testing:
132
				if options.testing:
133
					debug(1, 'Existing image: %s' % diskPath)
133
					debug(1, 'Existing image: %s' % diskPath)
Lines 144-149 Link Here
144
			debug(1, 'Using image: %s' % disk.source)
144
			debug(1, 'Using image: %s' % disk.source)
145
			i += 1
145
			i += 1
146
146
147
	elif cow == "qcow2":
148
		i = 0
149
		for disk in desktopDescription.disks:
150
			if disk.readonly or disk.type == disk.DEVICE_CDROM:
151
				debug(1, 'Re-using image: %s' % disk.source)
152
				continue
153
154
			origPath = disk.source
155
			diskPath = "%s_%d.qcow2" % (userTemplate, i)
156
			if os.path.exists(diskPath):
157
				if options.testing:
158
					debug(1, 'Existing image: %s' % diskPath)
159
					continue
160
				raise StorageException('Image already exists: %s' % diskPath)
161
162
			size = os.stat(origPath).st_size # TODO: add space for metadata overhead?
163
			if desktopDescription.domain_type == 'xen':
164
				img_bin = 'qemu-img-xen'
165
			elif desktopDescription.domain_type == 'kvm':
166
				img_bin = 'kvm-img'
167
			else:
168
				img_bin = 'qemu-img'
169
			debug(1, "Creating '%s' based on '%s' using %s, size %d" % (diskPath, origPath, img_bin, size))
170
			p = subprocess.Popen([img_bin, "create", "-b", origPath, "-f", "qcow2", diskPath, str(size)])
171
			p.wait()
172
			if p.returncode != 0:
173
				raise StorageException("Failed to create image '%s' based on '%s'" % (diskPath, origPath))
174
			disk.source = diskPath
175
			disk.driver = 'tap'
176
			disk.driver_type = 'qcow2'
177
			debug(1, 'Using image: %s' % disk.source)
178
			i += 1
179
147
	elif cow == "dm":
180
	elif cow == "dm":
148
		# FIXME: sub-directories are not supported by libvirt fs storage backend
181
		# FIXME: sub-directories are not supported by libvirt fs storage backend
149
		if os.path.exists(userTemplate):
182
		if os.path.exists(userTemplate):
(-)dvs/univention-dvs-node/debian/changelog (+6 lines)
Lines 1-3 Link Here
1
univention-dvs-node (1.0.30-10) unstable; urgency=low
2
3
  * Implement qcow2 support (Bug #18765)
4
5
 -- Philipp Hahn <hahn@univention.de>  Wed, 20 Oct 2010 16:58:51 +0200
6
1
univention-dvs-node (1.0.30-9) unstable; urgency=low
7
univention-dvs-node (1.0.30-9) unstable; urgency=low
2
8
3
  * u-d-d-t: Import missing univention.debug (Bug #18192)
9
  * u-d-d-t: Import missing univention.debug (Bug #18192)
(-)dvs/univention-dvs-node/debian/univention-dvs-node.univention-config-registry-variables (-2 / +2 lines)
Lines 35-42 Link Here
35
Categories=dvs
35
Categories=dvs
36
36
37
[dvs/desktop/cow]
37
[dvs/desktop/cow]
38
Description[de]=Typ des Copy-on-Write-Image (no=kein Copy-on-Write, dm=dm-snapshots)
38
Description[de]=Typ des Copy-on-Write-Image (no=kein Copy-on-Write, dm=dm-snapshots, qcow2)
39
Description[en]=Type of the Copy-on-Write-Image (no=no copy-on-write, dm=dm-snapshots)
39
Description[en]=Type of the Copy-on-Write-Image (no=no copy-on-write, dm=dm-snapshots, qcow2)
40
Type=str
40
Type=str
41
Categories=dvs
41
Categories=dvs
42
42
(-)dvs/univention-dvs-node/update-pickle (+6 lines)
Lines 31-36 Link Here
31
for dsk in domain.disks:
31
for dsk in domain.disks:
32
	if not hasattr(dsk, 'size'):
32
	if not hasattr(dsk, 'size'):
33
		dsk.size = None
33
		dsk.size = None
34
	if not hasattr(dsk, 'driver_type'):
35
		dsk.driver_type = None
36
	if not hasattr(dsk, 'driver_cache'):
37
		dsk.driver_cache = None
38
	if dsk.target_bus == 'ide':
39
		dsk.target_bus = None
34
# Update /volume/source  s/opendvdi/dvs/
40
# Update /volume/source  s/opendvdi/dvs/
35
for dsk in domain.disks:
41
for dsk in domain.disks:
36
	dsk.source = dsk.source.replace('univention-opendvdi', 'univention-dvs')
42
	dsk.source = dsk.source.replace('univention-opendvdi', 'univention-dvs')
(-)dvs/univention-dvs-node/README.txt (+10 lines)
Lines 32-37 Link Here
32
32
33
= Copy-on-Write =
33
= Copy-on-Write =
34
34
35
== device-mapper ==
36
37
	ucr set dvs/desktop/cow=qcow2
38
35
* since the fix for CVE-2008-2004 raw is no longer the default for unknown disk formats.
39
* since the fix for CVE-2008-2004 raw is no longer the default for unknown disk formats.
36
* known disk formats are hard-coded in qemu-dm using C-code.
40
* known disk formats are hard-coded in qemu-dm using C-code.
37
* only "phy" and "file" are using "raw" as the format.
41
* only "phy" and "file" are using "raw" as the format.
Lines 48-50 Link Here
48
If you want to use pools in libvirt, you MUST set the instance directory to something outside any pool!
52
If you want to use pools in libvirt, you MUST set the instance directory to something outside any pool!
49
	mkdir /var/lib/univention-dvs-instances
53
	mkdir /var/lib/univention-dvs-instances
50
	ucr set dvs/desktop/directory=/var/lib/univention-dvs-instances
54
	ucr set dvs/desktop/directory=/var/lib/univention-dvs-instances
55
56
== qcow2 ==
57
58
	ucr set dvs/desktop/cow=qcow2
59
60
* Neewd univention-virtual-machine-manager-daemon (0.10.4-6)

Return to bug 18765