Allow binary data for configdrive

There is no reason to force standalone users to base64 encode
and gzip their config drives.

Change-Id: Ic221c4bbc165cd717b36fff8bdd66edebb08be9a
This commit is contained in:
Dmitry Tantsur 2021-01-22 17:23:54 +01:00
parent 0704bcdd9b
commit bb935f1b26
2 changed files with 36 additions and 11 deletions

View File

@ -546,20 +546,34 @@ def _get_configdrive(configdrive, node_uuid, tempdir=None):
else:
data = configdrive
try:
data = io.BytesIO(base64.decode_as_bytes(data))
except Exception as exc:
error_msg = (_('Config drive for node %(node)s is not base64 encoded '
'or the content is malformed. %(cls)s: %(err)s.')
% {'node': node_uuid, 'err': exc,
'cls': type(exc).__name__})
if is_url:
error_msg += _(' Downloaded from "%s".') % configdrive
raise exception.InstanceDeployFailure(error_msg)
configdrive_file = tempfile.NamedTemporaryFile(delete=False,
prefix='configdrive',
dir=tempdir)
try:
data = io.BytesIO(base64.decode_as_bytes(data))
except Exception as exc:
if isinstance(data, bytes):
LOG.debug('Config drive for node %(node)s is not base64 encoded '
'(%(error)s), assuming binary',
{'node': node_uuid, 'error': exc})
configdrive_mb = int(math.ceil(len(data) / units.Mi))
configdrive_file.write(data)
configdrive_file.close()
return (configdrive_mb, configdrive_file.name)
else:
configdrive_file.close()
utils.unlink_without_raise(configdrive_file.name)
error_msg = (_('Config drive for node %(node)s is not base64 '
'encoded or the content is malformed. '
'%(cls)s: %(err)s.')
% {'node': node_uuid, 'err': exc,
'cls': type(exc).__name__})
if is_url:
error_msg += _(' Downloaded from "%s".') % configdrive
raise exception.InstanceDeployFailure(error_msg)
configdrive_mb = 0
with gzip.GzipFile('configdrive', 'rb', fileobj=data) as gunzipped:
try:

View File

@ -944,6 +944,17 @@ class GetConfigdriveTestCase(base.IronicLibTestCase):
fileobj=mock.ANY)
mock_copy.assert_called_once_with(mock.ANY, mock.ANY)
def test_get_configdrive_binary(self, mock_requests, mock_copy):
mock_requests.return_value = mock.MagicMock(content=b'content')
tempdir = tempfile.mkdtemp()
(size, path) = disk_utils._get_configdrive('http://1.2.3.4/cd',
'fake-node-uuid',
tempdir=tempdir)
self.assertTrue(path.startswith(tempdir))
self.assertEqual(b'content', open(path, 'rb').read())
mock_requests.assert_called_once_with('http://1.2.3.4/cd')
self.assertFalse(mock_copy.called)
@mock.patch.object(gzip, 'GzipFile', autospec=True)
def test_get_configdrive_base64_string(self, mock_gzip, mock_requests,
mock_copy):