Merge ~blake-rouse/maas:fix-1754493 into maas:master

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: 5b917d8b9d56202b56194b325668abef07d20abb
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~blake-rouse/maas:fix-1754493
Merge into: maas:master
Diff against target: 59 lines (+22/-7)
2 files modified
src/provisioningserver/rpc/boot_images.py (+7/-1)
src/provisioningserver/rpc/tests/test_boot_images.py (+15/-6)
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
MAAS Lander Approve
Review via email: mp+341678@code.launchpad.net

Commit message

Fixes LP: #1754493 - Call import boot images again if trigger for import when an import is already running.

This fixes an issue where the rack could still be performing an update with old data when the region triggers the rack to import again. This allows up to 1 import to run after the current import is finished. This will ensure that the rack controller will get always match the regiond images.

To post a comment you must log in.
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b fix-1754493 lp:~blake-rouse/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 5b917d8b9d56202b56194b325668abef07d20abb

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote :
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Interesting and subtle problem. Fix looks good!

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Revision history for this message
MAAS Lander (maas-lander) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/provisioningserver/rpc/boot_images.py b/src/provisioningserver/rpc/boot_images.py
2index 317d01f..e1ebdf4 100644
3--- a/src/provisioningserver/rpc/boot_images.py
4+++ b/src/provisioningserver/rpc/boot_images.py
5@@ -129,7 +129,13 @@ def _run_import(sources, http_proxy=None, https_proxy=None):
6 def import_boot_images(sources, http_proxy=None, https_proxy=None):
7 """Imports the boot images from the given sources."""
8 lock = concurrency.boot_images
9- if not lock.locked:
10+ # This checks if any other defer is already waiting. If nothing is waiting
11+ # then add the _import again. If its already waiting nothing is added.
12+ #
13+ # This is important to how this functions. If the rackd is already
14+ # importing images and the regiond triggers another import then after the
15+ # original import another will be fired.
16+ if not lock.waiting:
17 return lock.run(
18 _import_boot_images, sources, http_proxy=http_proxy,
19 https_proxy=https_proxy)
20diff --git a/src/provisioningserver/rpc/tests/test_boot_images.py b/src/provisioningserver/rpc/tests/test_boot_images.py
21index 5cbc734..0d45b79 100644
22--- a/src/provisioningserver/rpc/tests/test_boot_images.py
23+++ b/src/provisioningserver/rpc/tests/test_boot_images.py
24@@ -272,20 +272,29 @@ class TestImportBootImages(MAASTestCase):
25 run_tests_with = MAASTwistedRunTest.make_factory(timeout=5)
26
27 @defer.inlineCallbacks
28- def test__does_not_run_if_lock_taken(self):
29+ def test__add_to_waiting_if_lock_already_held(self):
30 yield concurrency.boot_images.acquire()
31- self.addCleanup(concurrency.boot_images.release)
32 deferToThread = self.patch(boot_images, 'deferToThread')
33 deferToThread.return_value = defer.succeed(None)
34- yield import_boot_images(sentinel.sources)
35+ d = import_boot_images(sentinel.sources)
36+ self.assertEqual(1, len(concurrency.boot_images.waiting))
37+ concurrency.boot_images.release()
38+ yield d
39 self.assertThat(
40- deferToThread, MockNotCalled())
41+ deferToThread, MockCalledOnceWith(
42+ _run_import, sentinel.sources,
43+ http_proxy=None, https_proxy=None))
44
45 @defer.inlineCallbacks
46- def test__calls__run_import_using_deferToThread(self):
47+ def test__never_more_than_one_waiting(self):
48+ yield concurrency.boot_images.acquire()
49 deferToThread = self.patch(boot_images, 'deferToThread')
50 deferToThread.return_value = defer.succeed(None)
51- yield import_boot_images(sentinel.sources)
52+ d = import_boot_images(sentinel.sources)
53+ self.assertIsNone(import_boot_images(sentinel.sources))
54+ self.assertEqual(1, len(concurrency.boot_images.waiting))
55+ concurrency.boot_images.release()
56+ yield d
57 self.assertThat(
58 deferToThread, MockCalledOnceWith(
59 _run_import, sentinel.sources,

Subscribers

People subscribed via source and target branches