201 lines
8.0 KiB
Diff
201 lines
8.0 KiB
Diff
|
From 2bda38a197a780a85e9ce448ea81a81fe866c981 Mon Sep 17 00:00:00 2001
|
||
|
From: Cole Robinson <crobinso@redhat.com>
|
||
|
Date: Wed, 7 Apr 2021 11:45:00 -0400
|
||
|
Subject: [PATCH] urlfetcher: Add xorriso ISOReader implementation
|
||
|
|
||
|
xorisso is the still maintained isoinfo alternative, and may be
|
||
|
the only iso reading tool in RHEL9, so we need to support it.
|
||
|
Make it the default for our spec file and test suite too
|
||
|
|
||
|
Signed-off-by: Cole Robinson <crobinso@redhat.com>
|
||
|
(cherry picked from commit f793986378f84bb409d2451bdb62ca08fd4cb5b4)
|
||
|
|
||
|
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1973236
|
||
|
|
||
|
Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
|
||
|
---
|
||
|
man/virt-install.rst | 2 +-
|
||
|
tests/test_cli.py | 12 ++++-----
|
||
|
virt-manager.spec | 4 +--
|
||
|
virtinst/install/urldetect.py | 4 +--
|
||
|
virtinst/install/urlfetcher.py | 48 +++++++++++++++++++++++++---------
|
||
|
5 files changed, 47 insertions(+), 23 deletions(-)
|
||
|
|
||
|
diff --git a/man/virt-install.rst b/man/virt-install.rst
|
||
|
index 963f9564..f75af635 100644
|
||
|
--- a/man/virt-install.rst
|
||
|
+++ b/man/virt-install.rst
|
||
|
@@ -617,7 +617,7 @@ ftp://host/path
|
||
|
An FTP server location containing an installable distribution image.
|
||
|
|
||
|
ISO
|
||
|
- Probe the ISO and extract files using 'isoinfo'
|
||
|
+ Extract files directly from the ISO path
|
||
|
|
||
|
DIRECTORY
|
||
|
Path to a local directory containing an installable distribution image.
|
||
|
diff --git a/tests/test_cli.py b/tests/test_cli.py
|
||
|
index 5e69a135..3534e0e2 100644
|
||
|
--- a/tests/test_cli.py
|
||
|
+++ b/tests/test_cli.py
|
||
|
@@ -39,7 +39,7 @@ MEDIA_DIR = os.path.relpath(utils.DATADIR + "/fakemedia", utils.TOPDIR)
|
||
|
UNATTENDED_DIR = XMLDIR + "/unattended"
|
||
|
OLD_OSINFO = utils.has_old_osinfo()
|
||
|
NO_OSINFO_UNATTEND = not unattended.OSInstallScript.have_new_libosinfo()
|
||
|
-HAS_ISOINFO = shutil.which("isoinfo")
|
||
|
+HAS_xorriso = shutil.which("xorriso")
|
||
|
|
||
|
# We use this check as a surrogate for a released libosinfo with a bug
|
||
|
# fix we need to get full test coverage
|
||
|
@@ -100,9 +100,9 @@ def has_old_osinfo():
|
||
|
return "osinfo is too old"
|
||
|
|
||
|
|
||
|
-def missing_isoinfo():
|
||
|
- if not HAS_ISOINFO:
|
||
|
- return "isoinfo not installed"
|
||
|
+def missing_xorriso():
|
||
|
+ if not HAS_xorriso:
|
||
|
+ return "xorriso not installed"
|
||
|
|
||
|
|
||
|
def no_osinfo_unattend_cb():
|
||
|
@@ -995,8 +995,8 @@ c.add_compare("--connect " + utils.URIs.kvm_session + " --disk size=8 --os-varia
|
||
|
c.add_valid("--connect " + utils.URIs.kvm_session + " --install fedora21", prerun_check=has_old_osinfo) # hits some get_search_paths and media_upload code paths
|
||
|
|
||
|
# misc KVM config tests
|
||
|
-c.add_compare("--disk none --location %(ISO-NO-OS)s,kernel=frib.img,initrd=/frob.img", "location-manual-kernel", prerun_check=missing_isoinfo) # --location with an unknown ISO but manually specified kernel paths
|
||
|
-c.add_compare("--disk %(EXISTIMG1)s --location %(ISOTREE)s --nonetworks", "location-iso", prerun_check=missing_isoinfo) # Using --location iso mounting
|
||
|
+c.add_compare("--disk none --location %(ISO-NO-OS)s,kernel=frib.img,initrd=/frob.img", "location-manual-kernel", prerun_check=missing_xorriso) # --location with an unknown ISO but manually specified kernel paths
|
||
|
+c.add_compare("--disk %(EXISTIMG1)s --location %(ISOTREE)s --nonetworks", "location-iso", prerun_check=missing_xorriso) # Using --location iso mounting
|
||
|
c.add_compare("--disk %(EXISTIMG1)s --cdrom %(ISOLABEL)s", "cdrom-centos-label") # Using --cdrom with centos CD label, should use virtio etc.
|
||
|
c.add_compare("--disk %(EXISTIMG1)s --install bootdev=network --os-variant rhel5.4 --cloud-init none", "kvm-rhel5") # RHEL5 defaults
|
||
|
c.add_compare("--disk %(EXISTIMG1)s --install kernel=%(ISO-WIN7)s,initrd=%(ISOLABEL)s,kernel_args='foo bar' --os-variant rhel6.4 --unattended none", "kvm-rhel6") # RHEL6 defaults. ISO paths are just to point at existing files
|
||
|
diff --git a/virt-manager.spec b/virt-manager.spec
|
||
|
index f523551b..3946c300 100644
|
||
|
--- a/virt-manager.spec
|
||
|
+++ b/virt-manager.spec
|
||
|
@@ -71,8 +71,8 @@ Requires: python3-requests
|
||
|
Requires: libosinfo >= 0.2.10
|
||
|
# Required for gobject-introspection infrastructure
|
||
|
Requires: python3-gobject-base
|
||
|
-# Required for pulling files from iso media with isoinfo
|
||
|
-Requires: genisoimage
|
||
|
+# Required for pulling files from iso media
|
||
|
+Requires: xorriso
|
||
|
|
||
|
%description common
|
||
|
Common files used by the different virt-manager interfaces, as well as
|
||
|
diff --git a/virtinst/install/urldetect.py b/virtinst/install/urldetect.py
|
||
|
index a73b0bf1..f5ed0270 100644
|
||
|
--- a/virtinst/install/urldetect.py
|
||
|
+++ b/virtinst/install/urldetect.py
|
||
|
@@ -40,9 +40,9 @@ class _DistroCache(object):
|
||
|
if path not in self._filecache:
|
||
|
try:
|
||
|
content = self._fetcher.acquireFileContent(path)
|
||
|
- except ValueError:
|
||
|
+ except ValueError as e:
|
||
|
content = None
|
||
|
- log.debug("Failed to acquire file=%s", path)
|
||
|
+ log.debug("Failed to acquire file=%s: %s", path, e)
|
||
|
self._filecache[path] = content
|
||
|
return self._filecache[path]
|
||
|
|
||
|
diff --git a/virtinst/install/urlfetcher.py b/virtinst/install/urlfetcher.py
|
||
|
index 3cacab1a..835c9e40 100644
|
||
|
--- a/virtinst/install/urlfetcher.py
|
||
|
+++ b/virtinst/install/urlfetcher.py
|
||
|
@@ -26,7 +26,7 @@ class _ISOReader:
|
||
|
def __init__(self, location):
|
||
|
self._location = location
|
||
|
|
||
|
- def grabFile(self, url):
|
||
|
+ def grabFile(self, url, scratchdir):
|
||
|
raise NotImplementedError()
|
||
|
def hasFile(self, url):
|
||
|
raise NotImplementedError()
|
||
|
@@ -43,20 +43,50 @@ class _ISOinfoReader(_ISOReader):
|
||
|
def _make_file_list(self):
|
||
|
cmd = ["isoinfo", "-J", "-i", self._location, "-f"]
|
||
|
|
||
|
- log.debug("Running isoinfo: %s", cmd)
|
||
|
+ log.debug("Generating iso filelist: %s", cmd)
|
||
|
output = subprocess.check_output(cmd, stderr=subprocess.DEVNULL)
|
||
|
return output.splitlines(False)
|
||
|
|
||
|
- def grabFile(self, url):
|
||
|
+ def grabFile(self, url, scratchdir):
|
||
|
+ ignore = scratchdir
|
||
|
cmd = ["isoinfo", "-J", "-i", self._location, "-x", url]
|
||
|
|
||
|
- log.debug("Running isoinfo: %s", cmd)
|
||
|
+ log.debug("Extracting iso file: %s", cmd)
|
||
|
return subprocess.check_output(cmd)
|
||
|
|
||
|
def hasFile(self, url):
|
||
|
return url.encode("ascii") in self._cache_file_list
|
||
|
|
||
|
|
||
|
+class _XorrisoReader(_ISOReader):
|
||
|
+ def __init__(self, location):
|
||
|
+ super().__init__(location)
|
||
|
+ self._cache_file_list = self._make_file_list()
|
||
|
+
|
||
|
+ def _make_file_list(self):
|
||
|
+ delim = "VIRTINST_BEGINLIST"
|
||
|
+ cmd = ["xorriso", "-indev", self._location, "-print", delim, "-find"]
|
||
|
+
|
||
|
+ log.debug("Generating iso filelist: %s", cmd)
|
||
|
+ output = subprocess.check_output(cmd,
|
||
|
+ stderr=subprocess.DEVNULL, text=True)
|
||
|
+ return output.split(delim, 1)[1].strip().splitlines()
|
||
|
+
|
||
|
+ def grabFile(self, url, scratchdir):
|
||
|
+ tmp = tempfile.NamedTemporaryFile(
|
||
|
+ prefix="virtinst-iso", suffix="-" + os.path.basename(url),
|
||
|
+ dir=scratchdir)
|
||
|
+
|
||
|
+ cmd = ["xorriso", "-osirrox", "on", "-indev", self._location,
|
||
|
+ "-extract", url, tmp.name]
|
||
|
+ log.debug("Extracting iso file: %s", cmd)
|
||
|
+ subprocess.check_output(cmd)
|
||
|
+ return open(tmp.name, "rb").read()
|
||
|
+
|
||
|
+ def hasFile(self, url):
|
||
|
+ return ("'.%s'" % url) in self._cache_file_list
|
||
|
+
|
||
|
+
|
||
|
###########################
|
||
|
# Fetcher implementations #
|
||
|
###########################
|
||
|
@@ -349,23 +379,17 @@ class _ISOURLFetcher(_URLFetcher):
|
||
|
|
||
|
def _get_isoreader(self):
|
||
|
if not self._isoreader:
|
||
|
- self._isoreader = _ISOinfoReader(self.location)
|
||
|
+ self._isoreader = _XorrisoReader(self.location)
|
||
|
return self._isoreader
|
||
|
|
||
|
def _grabber(self, url):
|
||
|
- """
|
||
|
- Use isoinfo to grab the file
|
||
|
- """
|
||
|
if not self._hasFile(url):
|
||
|
raise RuntimeError("iso doesn't have file=%s" % url)
|
||
|
|
||
|
- output = self._get_isoreader().grabFile(url)
|
||
|
+ output = self._get_isoreader().grabFile(url, self.scratchdir)
|
||
|
return io.BytesIO(output), len(output)
|
||
|
|
||
|
def _hasFile(self, url):
|
||
|
- """
|
||
|
- Use isoinfo to list and search for the file
|
||
|
- """
|
||
|
return self._get_isoreader().hasFile(url)
|
||
|
|
||
|
|
||
|
--
|
||
|
2.31.1
|
||
|
|