diff options
author | Zuul <zuul@review.opendev.org> | 2022-07-14 01:28:00 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2022-07-14 01:28:00 +0000 |
commit | 5d2283137c6d083668eec1c7bed7696a06dbafe6 (patch) | |
tree | 1f4562d2bf4bc53e056c684af8f931e6e8d02740 /ironic/common/images.py | |
parent | 442aeca6520aebd69b0fc1fb13a1d1aea4843058 (diff) | |
parent | e78f123ff8e3a4fcd5e3e596b526eb5eb39a34a9 (diff) | |
download | ironic-5d2283137c6d083668eec1c7bed7696a06dbafe6.tar.gz |
Merge "Make anaconda non-image deploys sane"
Diffstat (limited to 'ironic/common/images.py')
-rw-r--r-- | ironic/common/images.py | 75 |
1 files changed, 74 insertions, 1 deletions
diff --git a/ironic/common/images.py b/ironic/common/images.py index bffff8807..2b52b789b 100644 --- a/ironic/common/images.py +++ b/ironic/common/images.py @@ -580,7 +580,8 @@ def is_whole_disk_image(ctx, instance_info): :param instance_info: a node's instance info dict :returns: True for whole disk images and False for partition images - and None on no image_source or Error. + and None on no image_source, the source being a path, or upon an + Error. """ image_source = instance_info.get('image_source') if not image_source: @@ -606,6 +607,11 @@ def is_whole_disk_image(ctx, instance_info): and not iproperties.get('ramdisk_id')) else: # Non glance image ref + if is_source_a_path(ctx, instance_info.get('image_source')): + # Nothing is returned if not valid or there was an error. + # A third possibility is it is not a disk image, which would + # still be None. + return if (not instance_info.get('kernel') and not instance_info.get('ramdisk')): is_whole_disk_image = True @@ -613,6 +619,73 @@ def is_whole_disk_image(ctx, instance_info): return is_whole_disk_image +def is_source_a_path(ctx, image_source): + """Determine if the image source is a path. + + This method determines if a supplied URL is a path. + + :param ctx: an admin/process context. + :param image_source: The supplied image source, expected to be a + URL, which can be used to attempt to determine + if the source is a path. + :returns: True if the image_source appears to be a path as opposed + to an image to be downloaded. If the image source is not + a path, False is returned. If any error is detected, + None is returned. + """ + if not image_source: + return + image_service = service.get_image_service(image_source, + context=ctx) + try: + res = image_service.validate_href(image_source) + if 'headers' in dir(res): + # response/result is from the HTTP check path. + headers = res.headers + else: + # We have no headers. + headers = {} + except exception.ImageRefIsARedirect as e: + # Our exception handling formats this for us in this + # case. \o/ + LOG.debug(str(e)) + # Servers redirect to a proper folder ending in a slash if + # not supplied originally. + if e.redirect_url and e.redirect_url.endswith('/'): + return True + except Exception: + # NOTE(TheJulia): I don't really like this pattern, *but* + # the wholedisk image support is similar. + return + # 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: + 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.', + {'url': 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. + return True + # We were unable to determine if this was a folder or a file. + return False + + def _extract_iso(extract_iso, extract_dir): # NOTE(rpittau): we could probably just extract the files we need # if we find them. Also we probably need to detect the correct iso |