virt: handle cdrom remote images

Libvirt allows to use network images for cdroms. Use them if the image
is a remote URL for a cdrom device.
This commit is contained in:
Cédric Bosdonnat 2020-04-28 17:13:49 +02:00 committed by Daniel Wozniak
parent 734ae1a3a4
commit 73438d43d8
3 changed files with 34 additions and 4 deletions

View file

@ -87,6 +87,7 @@ import subprocess
import sys
import time
from xml.etree import ElementTree
from xml.sax import saxutils
# Import third party libs
import jinja2
@ -107,6 +108,7 @@ from salt._compat import ipaddress
from salt.exceptions import CommandExecutionError, SaltInvocationError
from salt.ext import six
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin
from salt.ext.six.moves.urllib.parse import urlparse
from salt.utils.virt import check_remote, download_remote
try:
@ -691,8 +693,17 @@ def _gen_xml(
"index": six.text_type(i),
}
if disk.get("source_file"):
disk_context["source_file"] = disk["source_file"]
disk_context["type"] = "file"
url = urlparse(disk["source_file"])
if not url.scheme or not url.hostname:
disk_context["source_file"] = disk["source_file"]
disk_context["type"] = "file"
elif url.scheme in ["http", "https", "ftp", "ftps", "tftp"]:
disk_context["type"] = "network"
disk_context["protocol"] = url.scheme
disk_context["volume"] = url.path
disk_context["query"] = saxutils.escape(url.query)
disk_context["hosts"] = [{"name": url.hostname, "port": url.port}]
elif disk.get("pool"):
disk_context["volume"] = disk["filename"]
# If we had no source_file, then we want a volume

View file

@ -36,7 +36,7 @@
<source pool='{{ disk.pool }}' volume='{{ disk.volume }}' />
{% endif %}
{%- if disk.type == 'network' %}
<source protocol='{{ disk.protocol }}' name='{{ disk.volume }}'>
<source protocol='{{ disk.protocol }}' name='{{ disk.volume }}'{% if disk.get('query') %} query='{{ disk.query }}'{% endif %}>
{%- for host in disk.get('hosts') %}
<host name='{{ host.name }}'{% if host.get("port") %} port='{{ host.port }}'{% endif %}/>
{%- endfor %}

View file

@ -1125,7 +1125,13 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
"device": "cdrom",
"source_file": None,
"model": "ide",
}
},
{
"name": "remote",
"device": "cdrom",
"source_file": "http://myhost:8080/url/to/image?query=foo&filter=bar",
"model": "ide",
},
],
"hello",
)
@ -1139,6 +1145,19 @@ class VirtTestCase(TestCase, LoaderModuleMockMixin):
self.assertEqual(disk.attrib["device"], "cdrom")
self.assertIsNone(disk.find("source"))
disk = root.findall(".//disk")[1]
self.assertEqual(disk.get("type"), "network")
self.assertEqual(disk.attrib["device"], "cdrom")
self.assertEqual(
{
"protocol": "http",
"name": "/url/to/image",
"query": "query=foo&filter=bar",
"host": {"name": "myhost", "port": "8080"},
},
salt.utils.xmlutil.to_dict(disk.find("source"), True),
)
def test_controller_for_esxi(self):
"""
Test virt._gen_xml() generated device controller for ESXi/vmware