Merge "libvirt: make <encryption> a sub element of <source>"

This commit is contained in:
Zuul 2024-03-01 20:05:16 +00:00 committed by Gerrit Code Review
commit dac8bd2493
6 changed files with 76 additions and 40 deletions

View File

@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import ddt
from lxml import etree
from oslo_utils.fixture import uuidsentinel as uuids
from oslo_utils import units
@ -738,6 +739,7 @@ class LibvirtConfigGuestSysinfoTest(LibvirtConfigBaseTest):
""")
@ddt.ddt
class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
def test_config_file(self):
@ -982,7 +984,8 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
obj.parse_dom(xmldoc)
self.assertEqual(obj.mirror.ready, "yes")
def test_config_disk_encryption_format(self):
@ddt.data('volume_encryption', 'ephemeral_encryption')
def test_config_disk_encryption_format(self, encryption):
d = config.LibvirtConfigGuestDisk()
e = config.LibvirtConfigGuestDiskEncryption()
s = config.LibvirtConfigGuestDiskEncryptionSecret()
@ -1001,42 +1004,57 @@ class LibvirtConfigGuestDiskTest(LibvirtConfigBaseTest):
s.type = "passphrase"
s.uuid = uuids.secret
e.secret = s
d.encryption = e
setattr(d, encryption, e)
xml = d.to_xml()
expected_xml = """
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" cache="none" io="native"/>
<source file="/tmp/hello.qcow2"/>
<target bus="ide" dev="/dev/hda"/>
<serial>%s</serial>
<boot order="1"/>
<encryption format='luks'>
<secret type='passphrase' uuid='%s'/>
</encryption>
</disk>""" % (uuids.serial, uuids.secret)
if encryption == 'volume_encryption':
expected_xml = """
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" cache="none" io="native"/>
<source file="/tmp/hello.qcow2"/>
<target bus="ide" dev="/dev/hda"/>
<serial>%s</serial>
<boot order="1"/>
<encryption format='luks'>
<secret type='passphrase' uuid='%s'/>
</encryption>
</disk>""" % (uuids.serial, uuids.secret)
elif encryption == 'ephemeral_encryption':
expected_xml = """
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" cache="none" io="native"/>
<source file="/tmp/hello.qcow2">
<encryption format='luks'>
<secret type='passphrase' uuid='%s'/>
</encryption>
</source>
<target bus="ide" dev="/dev/hda"/>
<serial>%s</serial>
<boot order="1"/>
</disk>""" % (uuids.secret, uuids.serial)
self.assertXmlEqual(expected_xml, xml)
def test_config_disk_encryption_parse(self):
xml = """
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" cache="none" io="native"/>
<source file="/tmp/hello.qcow2"/>
<source file="/tmp/hello.qcow2">
<encryption format='luks'>
<secret type='passphrase' uuid='%s'/>
</encryption>
</source>
<target bus="ide" dev="/dev/hda"/>
<serial>%s</serial>
<boot order="1"/>
<encryption format='luks'>
<secret type='passphrase' uuid='%s'/>
</encryption>
</disk>""" % (uuids.serial, uuids.secret)
</disk>""" % (uuids.secret, uuids.serial)
xmldoc = etree.fromstring(xml)
d = config.LibvirtConfigGuestDisk()
d.parse_dom(xmldoc)
self.assertEqual(d.encryption.format, "luks")
self.assertEqual(d.encryption.secret.type, "passphrase")
self.assertEqual(d.encryption.secret.uuid, uuids.secret)
self.assertEqual(d.ephemeral_encryption.format, "luks")
self.assertEqual(d.ephemeral_encryption.secret.type, "passphrase")
self.assertEqual(d.ephemeral_encryption.secret.uuid, uuids.secret)
def test_config_boot_order_parse(self):
xml = """

View File

@ -256,13 +256,14 @@ class _ImageTestCase(object):
self.assertEqual("1", disk.boot_order)
self.assertIsInstance(
disk.encryption, vconfig.LibvirtConfigGuestDiskEncryption)
disk.ephemeral_encryption,
vconfig.LibvirtConfigGuestDiskEncryption)
self.assertIsInstance(
disk.encryption.secret,
disk.ephemeral_encryption.secret,
vconfig.LibvirtConfigGuestDiskEncryptionSecret)
self.assertEqual("passphrase", disk.encryption.secret.type)
self.assertEqual(uuids.secret, disk.encryption.secret.uuid)
self.assertEqual("luks", disk.encryption.format)
self.assertEqual("passphrase", disk.ephemeral_encryption.secret.type)
self.assertEqual(uuids.secret, disk.ephemeral_encryption.secret.uuid)
self.assertEqual("luks", disk.ephemeral_encryption.format)
class FlatTestCase(_ImageTestCase, test.NoDBTestCase):

View File

@ -1173,7 +1173,8 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
self.device_addr = None
self.boot_order = None
self.mirror = None
self.encryption = None
self.volume_encryption = None
self.ephemeral_encryption = None
self.alias = None
def _format_iotune(self, dev):
@ -1266,11 +1267,14 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
dev.append(alias)
if self.source_type == "file":
dev.append(etree.Element("source", file=self.source_path))
source = etree.Element("source", file=self.source_path)
dev.append(source)
elif self.source_type == "block":
dev.append(etree.Element("source", dev=self.source_path))
source = etree.Element("source", dev=self.source_path)
dev.append(source)
elif self.source_type == "mount":
dev.append(etree.Element("source", dir=self.source_path))
source = etree.Element("source", dir=self.source_path)
dev.append(source)
elif self.source_type == "network" and self.source_protocol:
source = etree.Element("source", protocol=self.source_protocol)
if self.source_name is not None:
@ -1283,6 +1287,14 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
source.append(host)
dev.append(source)
if self.ephemeral_encryption:
# NOTE(melwitt): <encryption> should be a sub element of <source>
# in order to ensure the image uses encryption.
# See the following for more details:
# https://libvirt.org/formatdomain.html#hard-drives-floppy-disks-cdroms
# https://bugzilla.redhat.com/show_bug.cgi?id=1371022#c13
source.append(self.ephemeral_encryption.format_dom())
if self.auth_secret_type is not None:
auth = etree.Element("auth")
auth.set("username", self.auth_username)
@ -1325,8 +1337,8 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
if self.device_addr:
dev.append(self.device_addr.format_dom())
if self.encryption:
dev.append(self.encryption.format_dom())
if self.volume_encryption:
dev.append(self.volume_encryption.format_dom())
return dev
@ -1358,6 +1370,11 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
if sub.tag == 'host':
self.source_hosts.append(sub.get('name'))
self.source_ports.append(sub.get('port'))
for sub in c:
if sub.tag == 'encryption':
e = LibvirtConfigGuestDiskEncryption()
e.parse_dom(sub)
self.ephemeral_encryption = e
elif c.tag == 'serial':
self.serial = c.text
@ -1388,7 +1405,7 @@ class LibvirtConfigGuestDisk(LibvirtConfigGuestDevice):
elif c.tag == 'encryption':
e = LibvirtConfigGuestDiskEncryption()
e.parse_dom(c)
self.encryption = e
self.volume_encryption = e
elif c.tag == 'alias':
self.alias = c.get('name')

View File

@ -196,7 +196,7 @@ class Image(metaclass=abc.ABCMeta):
secret.uuid = self.disk_info_mapping.get('encryption_secret_uuid')
encryption.secret = secret
encryption.format = self.disk_info_mapping.get('encryption_format')
info.encryption = encryption
info.ephemeral_encryption = encryption
if disk_bus == 'scsi':
self.disk_scsi(info, disk_unit)

View File

@ -250,12 +250,12 @@ def _update_volume_xml(xml_doc, migrate_data, instance, get_volume_config):
instance, bdm_info.connection_info, bdm_info.as_disk_info())
if bdm_info.obj_attr_is_set('encryption_secret_uuid'):
conf.encryption = vconfig.LibvirtConfigGuestDiskEncryption()
conf.encryption.format = 'luks'
conf.volume_encryption = vconfig.LibvirtConfigGuestDiskEncryption()
conf.volume_encryption.format = 'luks'
secret = vconfig.LibvirtConfigGuestDiskEncryptionSecret()
secret.type = 'passphrase'
secret.uuid = bdm_info.encryption_secret_uuid
conf.encryption.secret = secret
conf.volume_encryption.secret = secret
xml_doc2 = etree.XML(conf.to_xml(), parser)
serial_dest = xml_doc2.findtext('serial')

View File

@ -123,12 +123,12 @@ class LibvirtBaseVolumeDriver(object):
if volume_id:
volume_secret = self.host.find_secret('volume', volume_id)
if volume_secret:
conf.encryption = vconfig.LibvirtConfigGuestDiskEncryption()
conf.volume_encryption = vconfig.LibvirtConfigGuestDiskEncryption()
secret = vconfig.LibvirtConfigGuestDiskEncryptionSecret()
secret.type = 'passphrase'
secret.uuid = volume_secret.UUIDString()
conf.encryption.format = 'luks'
conf.encryption.secret = secret
conf.volume_encryption.format = 'luks'
conf.volume_encryption.secret = secret
return conf