diff --git a/ironic/common/images.py b/ironic/common/images.py index 2b52b789b2..aa883ada3b 100644 --- a/ironic/common/images.py +++ b/ironic/common/images.py @@ -657,10 +657,24 @@ def is_source_a_path(ctx, image_source): # NOTE(TheJulia): I don't really like this pattern, *but* # the wholedisk image support is similar. return + # NOTE(TheJulia): Files should have been caught almost exclusively + # before with the Content-Length check. + # When the ISO is mounted and the webserver mount point url is + # checked here, it has both 'Content-Length' and 'Content-Type' + # due to which it always returns False. Hence switched the conditions. + if ('Content-Type' in headers + and str(headers['Content-Type']).startswith('text/html')): + LOG.debug('Evaluated %(url)s to determine if it is a URL to a path ' + 'or a file. A Content-Type header was returned with a text ' + 'content, which suggests a file list was returned.', + {'url': image_source}) + return True # When issuing a head request, folders have no length # A list can be generated by the server.. This is a solid # hint. - if 'Content-Length' in headers: + if ('Content-Type' in headers + and (str(headers['Content-Type']) != 'text/html') + and 'Content-Length' in headers): LOG.debug('Evaluated %(url)s to determine if it is a URL to a path ' 'or a file. A Content-Length header was returned ' 'suggesting file.', @@ -668,16 +682,6 @@ def is_source_a_path(ctx, image_source): # NOTE(TheJulia): Files on a webserver have a length which is returned # when headres are queried. return False - if ('Content-Type' in headers - and str(headers['Content-Type']).startswith('text') - and 'Content-Length' not in headers): - LOG.debug('Evaluated %(url)s to determine if it is a URL to a path ' - 'or a file. A Content-Type header was returned with a text ' - 'content, which suggests a file list was returned.', - {'url': image_source}) - return True - # NOTE(TheJulia): Files should have been caught almost exclusively - # before with the Content-Length check. if image_source.endswith('/'): # If all else fails, looks like a URL, and the server didn't give # us any hints. diff --git a/ironic/tests/unit/common/test_images.py b/ironic/tests/unit/common/test_images.py index dd782c687a..5530feb38c 100644 --- a/ironic/tests/unit/common/test_images.py +++ b/ironic/tests/unit/common/test_images.py @@ -318,7 +318,8 @@ class IronicImagesTestCase(base.TestCase): autospec=True) def test_is_source_a_path_content_length(self, validate_mock): mock_response = mock.Mock() - mock_response.headers = {'Content-Length': 1} + mock_response.headers = {'Content-Length': 1, + 'Content-Type': 'text/plain'} validate_mock.return_value = mock_response self.assertFalse(images.is_source_a_path('context', 'http://foo/bar/')) validate_mock.assert_called_once_with(mock.ANY, 'http://foo/bar/') diff --git a/releasenotes/notes/fix_anaconda-70f4268edc255ff4.yaml b/releasenotes/notes/fix_anaconda-70f4268edc255ff4.yaml new file mode 100644 index 0000000000..3882a28207 --- /dev/null +++ b/releasenotes/notes/fix_anaconda-70f4268edc255ff4.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes the URL based anaconda deployment for parsing the given ``image_source`` + url.