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:
parent
c882901f99
commit
197a05edbc
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue