Fix distribution compatability for configdrive build
Previously, the configuration drive generation code made use of ``genisoimage``, however ``genisoimage`` is not shipped universally on all linux distributions, and largely has been replaced in distributions with other forks, as the tooling has evolved, forked, and changed over the past quarter century. We now attempt to utilize multiple different commands, including the original ``mkisofs`` command and the newer ``xorrisofs`` command when attempting to generate the ISO image, falling back until one works. Credit goes to I720f25921f8e52f20a631f238a528dedf65a91c6 for the base pattern in OpenstackSDK. Story: 2009230 Task: 43328 Change-Id: Ic732c2e6c77474e0d5b701c47758959c3511743b
This commit is contained in:
parent
bc642ccabc
commit
0555b6ba72
|
@ -267,20 +267,30 @@ def make_configdrive(path):
|
|||
with tempfile.NamedTemporaryFile() as tmpfile:
|
||||
with tempfile.NamedTemporaryFile() as tmpzipfile:
|
||||
publisher = 'ironicclient-configdrive 0.1'
|
||||
try:
|
||||
p = subprocess.Popen(['genisoimage', '-o', tmpfile.name,
|
||||
'-ldots', '-allow-lowercase',
|
||||
'-allow-multidot', '-l',
|
||||
'-publisher', publisher,
|
||||
'-quiet', '-J',
|
||||
'-r', '-V', 'config-2',
|
||||
path],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
except OSError as e:
|
||||
# NOTE(toabctl): Luckily, genisoimage, mkisofs and xorrisofs
|
||||
# understand the same parameters which are currently used.
|
||||
cmds = ['genisoimage', 'mkisofs', 'xorrisofs']
|
||||
for c in cmds:
|
||||
try:
|
||||
p = subprocess.Popen([c, '-o', tmpfile.name,
|
||||
'-ldots', '-allow-lowercase',
|
||||
'-allow-multidot', '-l',
|
||||
'-publisher', publisher,
|
||||
'-quiet', '-J',
|
||||
'-r', '-V', 'config-2',
|
||||
path],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
except OSError as e:
|
||||
error = e
|
||||
else:
|
||||
error = None
|
||||
break
|
||||
if error:
|
||||
raise exc.CommandError(
|
||||
_('Error generating the config drive. Make sure the '
|
||||
'"genisoimage" tool is installed. Error: %s') % e)
|
||||
'"genisoimage", "mkisofs", or "xorriso" tool is '
|
||||
'installed. Error: %s') % error)
|
||||
|
||||
stdout, stderr = p.communicate()
|
||||
if p.returncode != 0:
|
||||
|
|
|
@ -265,6 +265,20 @@ class MakeConfigDriveTest(test_utils.BaseTestCase):
|
|||
'-quiet', '-J', '-r', '-V',
|
||||
'config-2', mock.ANY]
|
||||
|
||||
self.mkisofs_cmd = ['mkisofs', '-o', mock.ANY,
|
||||
'-ldots', '-allow-lowercase',
|
||||
'-allow-multidot', '-l',
|
||||
'-publisher', 'ironicclient-configdrive 0.1',
|
||||
'-quiet', '-J', '-r', '-V',
|
||||
'config-2', mock.ANY]
|
||||
|
||||
self.xorrisofs_cmd = ['xorrisofs', '-o', mock.ANY,
|
||||
'-ldots', '-allow-lowercase',
|
||||
'-allow-multidot', '-l',
|
||||
'-publisher', 'ironicclient-configdrive 0.1',
|
||||
'-quiet', '-J', '-r', '-V',
|
||||
'config-2', mock.ANY]
|
||||
|
||||
def test_make_configdrive(self, mock_popen):
|
||||
fake_process = mock.Mock(returncode=0)
|
||||
fake_process.communicate.return_value = ('', '')
|
||||
|
@ -278,6 +292,24 @@ class MakeConfigDriveTest(test_utils.BaseTestCase):
|
|||
stdout=subprocess.PIPE)
|
||||
fake_process.communicate.assert_called_once_with()
|
||||
|
||||
def test_make_configdrive_fallsback(self, mock_popen):
|
||||
fake_process = mock.Mock(returncode=0)
|
||||
fake_process.communicate.return_value = ('', '')
|
||||
mock_popen.side_effect = iter([OSError('boom'),
|
||||
OSError('boom'),
|
||||
fake_process])
|
||||
with utils.tempdir() as dirname:
|
||||
utils.make_configdrive(dirname)
|
||||
mock_popen.assert_has_calls([
|
||||
mock.call(self.genisoimage_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE),
|
||||
mock.call(self.mkisofs_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE),
|
||||
mock.call(self.xorrisofs_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
])
|
||||
fake_process.communicate.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(os, 'access', autospec=True)
|
||||
def test_make_configdrive_non_readable_dir(self, mock_access, mock_popen):
|
||||
mock_access.return_value = False
|
||||
|
@ -292,9 +324,14 @@ class MakeConfigDriveTest(test_utils.BaseTestCase):
|
|||
|
||||
self.assertRaises(exc.CommandError, utils.make_configdrive, 'fake-dir')
|
||||
mock_access.assert_called_once_with('fake-dir', os.R_OK)
|
||||
mock_popen.assert_called_once_with(self.genisoimage_cmd,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
mock_popen.assert_has_calls([
|
||||
mock.call(self.genisoimage_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE),
|
||||
mock.call(self.mkisofs_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE),
|
||||
mock.call(self.xorrisofs_cmd, stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE)
|
||||
])
|
||||
|
||||
@mock.patch.object(os, 'access', autospec=True)
|
||||
def test_make_configdrive_non_zero_returncode(self, mock_access,
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
fixes:
|
||||
- |
|
||||
Embedded configuration drive generation support has been updated to
|
||||
support ``mkisofs`` and ``xorrisofs`` in adition to the previously
|
||||
supported ``genisoimage`` utility. This is as distributions such as
|
||||
Debian and OpenSUSE do not ship ``genisoimage``.
|
Loading…
Reference in New Issue