Add support for uploading local image

The current python image uploader only supports uploading an image from
a remote source to a repository. Since customers my have a custom image
locally and want to push it to an undercloud repository (non-docker
based), we need to expose a way to upload a local image to an undercloud
repository. This change adjusts the upload function to check if the
source image is local because it is prefixed with containers-storage:
rather than docker:// or no prefix.

Change-Id: Ie4f34f668bdb32395187662566d917e799249444
Related-Blueprint: podman-support
(cherry picked from commit ae5198b6c6)
This commit is contained in:
Alex Schultz 2019-08-27 09:59:14 -06:00 committed by Emilien Macchi
parent c882901f99
commit 197a05edbc
2 changed files with 84 additions and 0 deletions

View File

@ -1095,9 +1095,24 @@ class PythonImageUploader(BaseImageUploader):
"""Upload images using a direct implementation of the registry API"""
def upload_image(self, task):
"""Upload image from a task
This function takes an UploadTask and pushes it to the appropriate
target destinations. It should be noted that if the source container
is prefix with 'containers-storage:' instead of 'docker://' or no
prefix, this process will assume that the source container is already
local to the system. The local container upload does not currently
support any of the modification actions. In order to run the
modification actions on a container prior to upload, the source must
be a remote image. Additionally, cleanup has no affect when
uploading a local image as well.
:param: task: UploadTask with container information
"""
t = task
LOG.info('imagename: %s' % t.image_name)
source_local = t.source_image.startswith('containers-storage:')
target_image_local_url = parse.urlparse('containers-storage:%s' %
t.target_image)
if t.dry_run:
@ -1113,6 +1128,24 @@ class PythonImageUploader(BaseImageUploader):
self._detect_target_export(t.target_image_url, target_session)
if source_local:
if t.modify_role:
raise NotImplementedError('Modify role not implemented for '
'local containers')
if t.cleanup:
LOG.warning('Cleanup has no effect with a local source '
'container.')
source_local_url = parse.urlparse(t.source_image)
# Copy from local storage to target registry
self._copy_local_to_registry(
source_local_url,
t.target_image_url,
session=target_session
)
target_session.close()
return []
if t.modify_role:
if self._image_exists(
t.target_image, target_session):

View File

@ -1636,6 +1636,57 @@ class TestPythonImageUploader(base.TestCase):
session=target_session
)
@mock.patch('tripleo_common.image.image_uploader.'
'PythonImageUploader._detect_target_export')
@mock.patch('tripleo_common.image.image_uploader.'
'PythonImageUploader.credentials_for_registry')
@mock.patch('tripleo_common.image.image_uploader.'
'PythonImageUploader._copy_local_to_registry')
@mock.patch('tripleo_common.image.image_uploader.'
'PythonImageUploader.authenticate')
def test_upload_image_local(self, authenticate, mock_copy, mock_creds,
mock_detect):
mock_creds.return_value = (None, None)
target_session = mock.Mock()
authenticate.side_effect = [
target_session
]
image = 'docker.io/tripleomaster/heat-docker-agents-centos'
tag = 'latest'
push_destination = 'localhost:8787'
source_image = 'containers-storage:%s:%s' % (image, tag)
task = image_uploader.UploadTask(
image_name=source_image,
pull_source=None,
push_destination=push_destination,
append_tag=None,
modify_role=None,
modify_vars=None,
dry_run=False,
cleanup='full',
multi_arch=False
)
self.assertEqual(
[],
self.uploader.upload_image(task)
)
source_url = urlparse(source_image)
target_url = urlparse('docker://localhost:8787/tripleomaster/'
'heat-docker-agents-centos:latest')
authenticate.assert_has_calls([
mock.call(
target_url,
username=None,
password=None
)
])
mock_detect.assert_called_once_with(target_url, target_session)
mock_copy.assert_called_once_with(source_url, target_url,
session=target_session)
@mock.patch('tripleo_common.image.image_uploader.'
'BaseImageUploader.check_status')
def test_fetch_manifest(self, check_status):