Add locks to container image commands
Ie5ef4045b7e22c06551e886f9f9b6f22c8d4bd21 added some additional
processing when uploading images. This unfortunately broke the
'openstack tripleo container image push' command because it assumes a
lock is always available. This change adds a process lock to the
ImageManagers used by the cli to ensure we are locking correctly when
doing any multiprocessing
Change-Id: I2d661682b3ee4d82d9f445a04e930c2fb328ef80
Closes-Bug: #1855184
(cherry picked from commit 94f8ef1df8
)
This commit is contained in:
parent
d24b159f9b
commit
1a49259357
|
@ -51,20 +51,28 @@ class TestContainerImageUpload(TestPluginV1):
|
|||
# Get the command object to test
|
||||
self.cmd = container_image.UploadImage(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.utils.locks.processlock.'
|
||||
'ProcessLock')
|
||||
@mock.patch('sys.exit')
|
||||
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager')
|
||||
def test_container_image_upload_noargs(self, mock_manager, exit_mock):
|
||||
def test_container_image_upload_noargs(self, mock_manager, exit_mock,
|
||||
mock_lock):
|
||||
arglist = []
|
||||
verifylist = []
|
||||
|
||||
mock_lockobj = mock.MagicMock()
|
||||
mock_lock.return_value = mock_lockobj
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
# argparse will complain that --config-file is missing and exit with 2
|
||||
exit_mock.assert_called_with(2)
|
||||
|
||||
@mock.patch('tripleo_common.utils.locks.processlock.'
|
||||
'ProcessLock')
|
||||
@mock.patch('tripleo_common.image.image_uploader.ImageUploadManager')
|
||||
def test_container_image_upload_conf_files(self, mock_manager):
|
||||
def test_container_image_upload_conf_files(self, mock_manager, mock_lock):
|
||||
arglist = [
|
||||
'--config-file',
|
||||
'/tmp/foo.yaml',
|
||||
|
@ -73,18 +81,27 @@ class TestContainerImageUpload(TestPluginV1):
|
|||
]
|
||||
verifylist = []
|
||||
|
||||
mock_lockobj = mock.MagicMock()
|
||||
mock_lock.return_value = mock_lockobj
|
||||
|
||||
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
|
||||
|
||||
self.cmd.take_action(parsed_args)
|
||||
|
||||
mock_manager.assert_called_once_with(
|
||||
['/tmp/foo.yaml', '/tmp/bar.yaml'], cleanup='full')
|
||||
['/tmp/foo.yaml', '/tmp/bar.yaml'], cleanup='full',
|
||||
lock=mock_lockobj)
|
||||
mock_manager.return_value.upload.assert_called_once_with()
|
||||
|
||||
|
||||
class TestContainerImagePush(TestPluginV1):
|
||||
def setUp(self):
|
||||
super(TestContainerImagePush, self).setUp()
|
||||
|
||||
lock = mock.patch('tripleo_common.utils.locks.processlock.ProcessLock')
|
||||
self.mock_lock = lock.start()
|
||||
self.addCleanup(lock.stop)
|
||||
|
||||
self.cmd = container_image.TripleOContainerImagePush(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.image.image_uploader.get_undercloud_registry',
|
||||
|
@ -360,6 +377,11 @@ class TestContainerImageDelete(TestPluginV1):
|
|||
|
||||
def setUp(self):
|
||||
super(TestContainerImageDelete, self).setUp()
|
||||
|
||||
lock = mock.patch('tripleo_common.utils.locks.processlock.ProcessLock')
|
||||
self.mock_lock = lock.start()
|
||||
self.addCleanup(lock.stop)
|
||||
|
||||
self.cmd = container_image.TripleOContainerImageDelete(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.image.image_uploader.get_undercloud_registry',
|
||||
|
@ -402,6 +424,11 @@ class TestContainerImageList(TestPluginV1):
|
|||
|
||||
def setUp(self):
|
||||
super(TestContainerImageList, self).setUp()
|
||||
|
||||
lock = mock.patch('tripleo_common.utils.locks.processlock.ProcessLock')
|
||||
self.mock_lock = lock.start()
|
||||
self.addCleanup(lock.stop)
|
||||
|
||||
self.cmd = container_image.TripleOContainerImageList(self.app, None)
|
||||
|
||||
@mock.patch('tripleo_common.image.image_uploader.get_undercloud_registry',
|
||||
|
@ -471,6 +498,11 @@ class TestContainerImageShow(TestPluginV1):
|
|||
|
||||
def setUp(self):
|
||||
super(TestContainerImageShow, self).setUp()
|
||||
|
||||
lock = mock.patch('tripleo_common.utils.locks.processlock.ProcessLock')
|
||||
self.mock_lock = lock.start()
|
||||
self.addCleanup(lock.stop)
|
||||
|
||||
self.cmd = container_image.TripleOContainerImageShow(self.app, None)
|
||||
|
||||
@mock.patch('tripleoclient.v1.container_image.TripleOContainerImageShow.'
|
||||
|
|
|
@ -91,8 +91,9 @@ class UploadImage(command.Command):
|
|||
if parsed_args.cleanup not in image_uploader.CLEANUP:
|
||||
raise oscexc.CommandError('--cleanup must be one of: %s' %
|
||||
', '.join(image_uploader.CLEANUP))
|
||||
lock = processlock.ProcessLock()
|
||||
uploader = image_uploader.ImageUploadManager(
|
||||
parsed_args.config_files, cleanup=parsed_args.cleanup)
|
||||
parsed_args.config_files, cleanup=parsed_args.cleanup, lock=lock)
|
||||
try:
|
||||
uploader.upload()
|
||||
except KeyboardInterrupt: # ctrl-c
|
||||
|
@ -511,7 +512,8 @@ class DiscoverImageTag(command.Command):
|
|||
"replaced by the 'openstack tripleo container image "
|
||||
"prepare' command.")
|
||||
|
||||
uploader = image_uploader.ImageUploadManager([])
|
||||
lock = processlock.ProcessLock()
|
||||
uploader = image_uploader.ImageUploadManager([], lock=lock)
|
||||
print(uploader.discover_image_tag(
|
||||
image=parsed_args.image,
|
||||
tag_from_label=parsed_args.tag_from_label
|
||||
|
@ -594,7 +596,8 @@ class TripleOContainerImagePush(command.Command):
|
|||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
manager = image_uploader.ImageUploadManager()
|
||||
lock = processlock.ProcessLock()
|
||||
manager = image_uploader.ImageUploadManager(lock=lock)
|
||||
uploader = manager.uploader('python')
|
||||
|
||||
source_image = parsed_args.image_to_push
|
||||
|
@ -703,7 +706,8 @@ class TripleOContainerImageDelete(command.Command):
|
|||
if not confirm:
|
||||
raise oscexc.CommandError("Action not confirmed, exiting.")
|
||||
|
||||
manager = image_uploader.ImageUploadManager()
|
||||
lock = processlock.ProcessLock()
|
||||
manager = image_uploader.ImageUploadManager(lock=lock)
|
||||
uploader = manager.uploader('python')
|
||||
url = uploader._image_to_url(parsed_args.registry_url)
|
||||
session = uploader.authenticate(url, parsed_args.username,
|
||||
|
@ -750,7 +754,8 @@ class TripleOContainerImageList(command.Lister):
|
|||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
manager = image_uploader.ImageUploadManager()
|
||||
lock = processlock.ProcessLock()
|
||||
manager = image_uploader.ImageUploadManager(lock=lock)
|
||||
uploader = manager.uploader('python')
|
||||
url = uploader._image_to_url(parsed_args.registry_url)
|
||||
session = uploader.authenticate(url, parsed_args.username,
|
||||
|
@ -799,7 +804,8 @@ class TripleOContainerImageShow(command.ShowOne):
|
|||
def take_action(self, parsed_args):
|
||||
self.log.debug("take_action(%s)" % parsed_args)
|
||||
|
||||
manager = image_uploader.ImageUploadManager()
|
||||
lock = processlock.ProcessLock()
|
||||
manager = image_uploader.ImageUploadManager(lock=lock)
|
||||
uploader = manager.uploader('python')
|
||||
url = uploader._image_to_url(parsed_args.image_to_inspect)
|
||||
session = uploader.authenticate(url, parsed_args.username,
|
||||
|
|
Loading…
Reference in New Issue