Merge lp:~blake-rouse/maas/fix-images-cache-and-import into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 5055
Proposed branch: lp:~blake-rouse/maas/fix-images-cache-and-import
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 1448 lines (+291/-323)
26 files modified
src/maasserver/api/tests/test_boot_source_selections.py (+7/-3)
src/maasserver/api/tests/test_boot_sources.py (+7/-3)
src/maasserver/bootresources.py (+25/-41)
src/maasserver/bootsources.py (+1/-1)
src/maasserver/clusterrpc/tests/test_boot_images.py (+9/-0)
src/maasserver/migrations/builtin/maasserver/0061_maas_nodegroup_worker_to_maas.py (+1/-1)
src/maasserver/migrations/builtin/maasserver/0062_fix_bootsource_daily_label.py (+27/-0)
src/maasserver/models/signals/bootsources.py (+8/-2)
src/maasserver/models/signals/tests/test_bootsources.py (+55/-0)
src/maasserver/models/testing.py (+0/-15)
src/maasserver/models/tests/test_bootresource.py (+4/-2)
src/maasserver/models/tests/test_bootsource.py (+4/-30)
src/maasserver/models/tests/test_bootsourcecache.py (+4/-2)
src/maasserver/models/tests/test_bootsourceselection.py (+4/-2)
src/maasserver/rpc/tests/test_configuration.py (+13/-0)
src/maasserver/rpc/tests/test_regionservice_calls.py (+9/-0)
src/maasserver/start_up.py (+1/-74)
src/maasserver/tests/test_bootresources.py (+31/-53)
src/maasserver/tests/test_bootsources.py (+16/-6)
src/maasserver/tests/test_compose_preseed.py (+9/-0)
src/maasserver/tests/test_forms_bootsource.py (+4/-2)
src/maasserver/tests/test_forms_bootsourceselection.py (+4/-2)
src/maasserver/tests/test_service_monitor.py (+17/-0)
src/maasserver/tests/test_start_up.py (+11/-77)
src/maasserver/views/tests/test_images.py (+7/-3)
src/maasserver/views/tests/test_settings.py (+13/-4)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-images-cache-and-import
Reviewer Review Type Date Requested Status
Andres Rodriguez (community) Approve
Review via email: mp+295762@code.launchpad.net

Commit message

Remove all the no code longer needed start_up code. Start the boot resource import always without the need for force. Fix the boot source cache to be updated on BootSource delete, enable_http_proxy and http_proxy value changes. Fix issue where daily image stream can reference the label release which is incorrect for the daily stream.

Description of the change

Running in CI now, but passing locally for me:

http://162.213.35.104:8080/job/maas-xenial-trunk-manual/227/console

To post a comment you must log in.
Revision history for this message
Blake Rouse (blake-rouse) wrote :

This did pass in the CI, even though it is showing an error which is do to JUnit not with the tests themselves.

Revision history for this message
Andres Rodriguez (andreserl) wrote :

lgtm!

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.3 MiB)

The attempt to merge lp:~blake-rouse/maas/fix-images-cache-and-import into lp:maas failed. Below is the output from the failed tests.

Hit:1 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [94.5 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]
Hit:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Get:5 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [111 kB]
Get:6 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [50.3 kB]
Fetched 350 kB in 0s (904 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
bash is already the newest version (4.3-14ubuntu1).
build-essential is already the newest version (12.1ubuntu2).
bzr is already the newest version (2.7.0-2ubuntu1).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest vers...

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.3 MiB)

The attempt to merge lp:~blake-rouse/maas/fix-images-cache-and-import into lp:maas failed. Below is the output from the failed tests.

Hit:1 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [94.5 kB]
Get:3 http://security.ubuntu.com/ubuntu xenial-security InRelease [94.5 kB]
Hit:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Fetched 189 kB in 0s (491 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
bash is already the newest version (4.3-14ubuntu1).
build-essential is already the newest version (12.1ubuntu2).
bzr is already the newest version (2.7.0-2ubuntu1).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160115ubuntu3).
distro-info is already the newest version (0.14build1).
freeipmi-tools is already the newest version (1.4.11-1ubuntu1).
git is already the newest version (1:2.7.4-0ubuntu1).
isc-dhcp-common is already the newest version (4.3.3-5ubuntu12).
libjs-angularjs is already the newest version (1.2.28-1ubuntu2).
libjs-jquery is already the newest version (1.11.3+dfsg-4).
libjs-yui3-full is already the newest version (3.5.1-1ubuntu3).
libjs-yui3-min is already the newest version (3.5.1-1ubuntu3).
make is already the newest version (4.1-6).
postgresql is already the newest version (9.5+173).
pxelinux is already the newest version...

Revision history for this message
Andres Rodriguez (andreserl) wrote :

There's another migration with the same number:

roaksoax@unleashed:~/Desktop/project/maas⟫ find ./ -name 0061*
./src/maasserver/migrations/builtin/maasserver/0061_maas_nodegroup_worker_to_maas.py

Revision history for this message
MAAS Lander (maas-lander) wrote :
Download full text (1.3 MiB)

The attempt to merge lp:~blake-rouse/maas/fix-images-cache-and-import into lp:maas failed. Below is the output from the failed tests.

Hit:1 http://security.ubuntu.com/ubuntu xenial-security InRelease
Hit:2 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial InRelease
Get:3 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates InRelease [94.5 kB]
Hit:4 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-backports InRelease
Get:5 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/main Sources [50.0 kB]
Get:6 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/universe Sources [19.7 kB]
Get:7 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [146 kB]
Get:8 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/main Translation-en [56.2 kB]
Get:9 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [71.9 kB]
Get:10 http://prodstack-zone-2.clouds.archive.ubuntu.com/ubuntu xenial-updates/universe Translation-en [33.5 kB]
Fetched 472 kB in 0s (1,106 kB/s)
Reading package lists...
sudo DEBIAN_FRONTEND=noninteractive apt-get -y \
    --no-install-recommends install apache2 archdetect-deb authbind bash bind9 bind9utils build-essential bzr bzr-builddeb chromium-browser chromium-chromedriver curl daemontools debhelper dh-apport dh-systemd distro-info dnsutils firefox freeipmi-tools git gjs ipython isc-dhcp-common libjs-angularjs libjs-jquery libjs-jquery-hotkeys libjs-yui3-full libjs-yui3-min libpq-dev make nodejs-legacy npm postgresql pxelinux python3-all python3-apt python3-bson python3-convoy python3-crochet python3-cssselect python3-curtin python3-dev python3-distro-info python3-django python3-django-nose python3-django-piston3 python3-dnspython python3-docutils python3-formencode python3-hivex python3-httplib2 python3-jinja2 python3-jsonschema python3-lxml python3-netaddr python3-netifaces python3-novaclient python3-oauth python3-oauthlib python3-openssl python3-paramiko python3-petname python3-pexpect python3-psycopg2 python3-pyinotify python3-pyparsing python3-pyvmomi python3-requests python3-seamicroclient python3-setuptools python3-simplestreams python3-sphinx python3-tempita python3-twisted python3-txtftp python3-tz python3-yaml python3-zope.interface python-bson python-crochet python-django python-django-piston python-djorm-ext-pgarray python-formencode python-lxml python-netaddr python-netifaces python-pocket-lint python-psycopg2 python-simplejson python-tempita python-twisted python-yaml socat syslinux-common tgt ubuntu-cloudimage-keyring wget xvfb
Reading package lists...
Building dependency tree...
Reading state information...
apache2 is already the newest version (2.4.18-2ubuntu3).
archdetect-deb is already the newest version (1.117ubuntu2).
authbind is already the newest version (2.1.1+nmu1).
bash is already the newest version (4.3-14ubuntu1).
build-essential is already the newest version (12.1ubuntu2).
bzr is already the newest version (2.7.0-2ubuntu1).
curl is already the newest version (7.47.0-1ubuntu2).
debhelper is already the newest version (9.20160...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/api/tests/test_boot_source_selections.py'
2--- src/maasserver/api/tests/test_boot_source_selections.py 2016-05-24 21:29:53 +0000
3+++ src/maasserver/api/tests/test_boot_source_selections.py 2016-05-31 17:22:09 +0000
4@@ -12,7 +12,7 @@
5 DISPLAYED_BOOTSOURCESELECTION_FIELDS,
6 )
7 from maasserver.models import BootSourceSelection
8-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
9+from maasserver.models.signals import bootsources
10 from maasserver.testing.api import APITestCase
11 from maasserver.testing.factory import factory
12 from maasserver.utils.converters import json_load_bytes
13@@ -36,7 +36,9 @@
14
15 def setUp(self):
16 super(TestBootSourceSelectionAPI, self).setUp()
17- self.useFixture(UpdateBootSourceCacheDisconnected())
18+ # Disable boot source cache signals.
19+ self.addCleanup(bootsources.signals.enable)
20+ bootsources.signals.disable()
21
22 def test_handler_path(self):
23 self.assertEqual(
24@@ -130,7 +132,9 @@
25
26 def setUp(self):
27 super(TestBootSourceSelectionsAPI, self).setUp()
28- self.useFixture(UpdateBootSourceCacheDisconnected())
29+ # Disable boot source cache signals.
30+ self.addCleanup(bootsources.signals.enable)
31+ bootsources.signals.disable()
32
33 def test_handler_path(self):
34 self.assertEqual(
35
36=== modified file 'src/maasserver/api/tests/test_boot_sources.py'
37--- src/maasserver/api/tests/test_boot_sources.py 2016-05-24 21:29:53 +0000
38+++ src/maasserver/api/tests/test_boot_sources.py 2016-05-31 17:22:09 +0000
39@@ -10,7 +10,7 @@
40 from django.core.urlresolvers import reverse
41 from maasserver.api.boot_sources import DISPLAYED_BOOTSOURCE_FIELDS
42 from maasserver.models import BootSource
43-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
44+from maasserver.models.signals import bootsources
45 from maasserver.testing.api import APITestCase
46 from maasserver.testing.factory import factory
47 from maasserver.utils.converters import json_load_bytes
48@@ -30,7 +30,9 @@
49
50 def setUp(self):
51 super(TestBootSourceAPI, self).setUp()
52- self.useFixture(UpdateBootSourceCacheDisconnected())
53+ # Disable boot source cache signals.
54+ self.addCleanup(bootsources.signals.enable)
55+ bootsources.signals.disable()
56
57 def test_handler_path(self):
58 self.assertEqual(
59@@ -108,7 +110,9 @@
60
61 def setUp(self):
62 super(TestBootSourcesAPI, self).setUp()
63- self.useFixture(UpdateBootSourceCacheDisconnected())
64+ # Disable boot source cache signals.
65+ self.addCleanup(bootsources.signals.enable)
66+ bootsources.signals.disable()
67
68 def test_handler_path(self):
69 self.assertEqual(
70
71=== modified file 'src/maasserver/bootresources.py'
72--- src/maasserver/bootresources.py 2016-04-12 17:36:35 +0000
73+++ src/maasserver/bootresources.py 2016-05-31 17:22:09 +0000
74@@ -183,7 +183,7 @@
75
76
77 class SimpleStreamsHandler:
78- """Simplestreams endpoint, that the clusters talk to.
79+ """Simplestreams endpoint, that the racks talk to.
80
81 This is not called from piston3, as piston uses emitters which
82 breaks the ability to return streaming content.
83@@ -924,31 +924,20 @@
84 Config.objects.set_config("default_distro_series", release)
85
86
87-@transactional
88-def has_synced_resources():
89- """Return true if SYNCED `BootResource` exist."""
90- return BootResource.objects.filter(
91- rtype=BOOT_RESOURCE_TYPE.SYNCED).exists()
92-
93-
94 @asynchronous(timeout=FOREVER)
95-def _import_resources(force=False):
96+def _import_resources():
97 """Import boot resources.
98
99 Pulls the sources from `BootSource`. This only starts the process if
100 some SYNCED `BootResource` already exist.
101
102 This MUST be called from outside of a database transaction.
103-
104- :param force: True will force the import, even if no SYNCED `BootResource`
105- exist. This is used because we want the user to start the first import
106- action, not let it run automatically.
107 """
108 # Avoid circular import.
109 from maasserver.clusterrpc.boot_images import RackControllersImporter
110
111 # Sync boot resources into the region.
112- d = deferToDatabase(_import_resources_with_lock, force=force)
113+ d = deferToDatabase(_import_resources_with_lock)
114
115 def cb_import(_):
116 d = deferToDatabase(RackControllersImporter.new)
117@@ -965,7 +954,7 @@
118 @synchronous
119 @with_connection
120 @synchronised(locks.import_images.TRY) # TRY is important; read docstring.
121-def _import_resources_with_lock(force=False):
122+def _import_resources_with_lock():
123 """Import boot resources once the `import_images` lock is held.
124
125 This should *not* be called in a transaction; it will manage transactions
126@@ -984,11 +973,6 @@
127 # Keep the descriptions cache up-to-date.
128 cache_boot_sources()
129
130- # If we're not being forced, don't sync unless we've already done it once
131- # before, i.e. we've been asked to explicitly sync by a user.
132- if not force and not has_synced_resources():
133- return
134-
135 # FIXME: This modifies the environment of the entire process, which is Not
136 # Cool. We should integrate with simplestreams in a more Pythonic manner.
137 set_simplestreams_env()
138@@ -1015,13 +999,13 @@
139 len(sources))
140
141
142-def _import_resources_in_thread(force=False):
143+def _import_resources_in_thread():
144 """Import boot resources in a thread managed by Twisted.
145
146 Errors are logged. The returned `Deferred` will never errback so it's safe
147 to use in a `TimerService`, for example.
148 """
149- d = deferToDatabase(_import_resources, force=force)
150+ d = deferToDatabase(_import_resources)
151 d.addErrback(_handle_import_failures)
152 return d
153
154@@ -1044,7 +1028,7 @@
155 doesn't wait for it to be finished, as it can take several minutes to
156 complete.
157 """
158- reactor.callFromThread(_import_resources_in_thread, force=True)
159+ reactor.callFromThread(_import_resources_in_thread)
160
161
162 def is_import_resources_running():
163@@ -1099,30 +1083,30 @@
164 def check_boot_images(self):
165 if (yield deferToDatabase(
166 self.are_boot_images_available_in_the_region)):
167- # The region has boot resources. The clusters will too soon if
168+ # The region has boot resources. The racks will too soon if
169 # they haven't already. Nothing to see here, please move along.
170 yield deferToDatabase(self.clear_import_warning)
171 else:
172- # We can ask clusters if they somehow have some imported images
173+ # We can ask racks if they somehow have some imported images
174 # already, from another source perhaps. We can provide a better
175 # message to the user in this case.
176- if (yield self.are_boot_images_available_in_any_cluster()):
177- warning = self.warning_cluster_has_boot_images
178+ if (yield self.are_boot_images_available_in_any_rack()):
179+ warning = self.warning_rack_has_boot_images
180 else:
181- warning = self.warning_cluster_has_no_boot_images
182+ warning = self.warning_rack_has_no_boot_images
183 yield deferToDatabase(self.set_import_warning, warning)
184
185- warning_cluster_has_boot_images = dedent("""\
186- One or more of your clusters currently has boot images, but your region
187- does not. Nodes will not be able to provision until you import boot images
188- into the region. Visit the <a href="%(images_link)s">boot images</a> page
189- to start the import.
190+ warning_rack_has_boot_images = dedent("""\
191+ One or more of your rack controller(s) currently has boot images, but your
192+ region controller does not. Machines will not be able to provision until
193+ you import boot images into the region. Visit the
194+ <a href="%(images_link)s">boot images</a> page to start the import.
195 """)
196
197- warning_cluster_has_no_boot_images = dedent("""\
198- Boot image import process not started. Nodes will not be able to provision
199- without boot images. Visit the <a href="%(images_link)s">boot images</a>
200- page to start the import.
201+ warning_rack_has_no_boot_images = dedent("""\
202+ Boot image import process not started. Machines will not be able to
203+ provision without boot images. Visit the
204+ <a href="%(images_link)s">boot images</a> page to start the import.
205 """)
206
207 @transactional
208@@ -1140,11 +1124,11 @@
209 return BootResource.objects.all().exists()
210
211 @asynchronous(timeout=90)
212- def are_boot_images_available_in_any_cluster(self):
213- """Return true if there are boot images available in any cluster.
214+ def are_boot_images_available_in_any_rack(self):
215+ """Return true if there are boot images available in any rack.
216
217- Only considers clusters that are currently connected, and ignores
218- errors resulting from communicating with the clusters.
219+ Only considers racks that are currently connected, and ignores
220+ errors resulting from communicating with the racks.
221 """
222 clients = getAllClients()
223
224
225=== modified file 'src/maasserver/bootsources.py'
226--- src/maasserver/bootsources.py 2016-05-17 19:30:14 +0000
227+++ src/maasserver/bootsources.py 2016-05-31 17:22:09 +0000
228@@ -59,7 +59,7 @@
229 BootSourceSelection.objects.create(
230 boot_source=source, os=ubuntu.name,
231 release=ubuntu.get_default_commissioning_release(),
232- arches=['amd64'], subarches=['*'], labels=['release'])
233+ arches=['amd64'], subarches=['*'], labels=['*'])
234
235
236 @transactional
237
238=== modified file 'src/maasserver/clusterrpc/tests/test_boot_images.py'
239--- src/maasserver/clusterrpc/tests/test_boot_images.py 2016-05-13 15:14:05 +0000
240+++ src/maasserver/clusterrpc/tests/test_boot_images.py 2016-05-31 17:22:09 +0000
241@@ -25,6 +25,7 @@
242 from maasserver.clusterrpc.testing.boot_images import make_rpc_boot_image
243 from maasserver.enum import BOOT_RESOURCE_TYPE
244 from maasserver.models.config import Config
245+from maasserver.models.signals import bootsources
246 from maasserver.rpc import getAllClients
247 from maasserver.rpc.testing.fixtures import (
248 MockLiveRegionToClusterRPCFixture,
249@@ -500,6 +501,10 @@
250 sources=Equals([get_simplestream_endpoint()])))
251
252 def test__new_obtains_proxy_if_not_given(self):
253+ # Disable boot source cache signals.
254+ self.addCleanup(bootsources.signals.enable)
255+ bootsources.signals.disable()
256+
257 proxy = factory.make_simple_http_url()
258 Config.objects.set_config("http_proxy", proxy)
259 importer = RackControllersImporter.new(system_ids=[], sources=[])
260@@ -507,6 +512,10 @@
261 proxy=Equals(urlparse(proxy))))
262
263 def test__new_obtains_None_proxy_if_disabled(self):
264+ # Disable boot source cache signals.
265+ self.addCleanup(bootsources.signals.enable)
266+ bootsources.signals.disable()
267+
268 proxy = factory.make_simple_http_url()
269 Config.objects.set_config("http_proxy", proxy)
270 Config.objects.set_config("enable_http_proxy", False)
271
272=== modified file 'src/maasserver/migrations/builtin/maasserver/0061_maas_nodegroup_worker_to_maas.py'
273--- src/maasserver/migrations/builtin/maasserver/0061_maas_nodegroup_worker_to_maas.py 2016-05-25 08:03:57 +0000
274+++ src/maasserver/migrations/builtin/maasserver/0061_maas_nodegroup_worker_to_maas.py 2016-05-31 17:22:09 +0000
275@@ -15,7 +15,7 @@
276 user.first_name = 'MAAS'
277 user.email = 'maas@localhost'
278 user.save()
279-
280+
281 class Migration(migrations.Migration):
282
283 dependencies = [
284
285=== added file 'src/maasserver/migrations/builtin/maasserver/0062_fix_bootsource_daily_label.py'
286--- src/maasserver/migrations/builtin/maasserver/0062_fix_bootsource_daily_label.py 1970-01-01 00:00:00 +0000
287+++ src/maasserver/migrations/builtin/maasserver/0062_fix_bootsource_daily_label.py 2016-05-31 17:22:09 +0000
288@@ -0,0 +1,27 @@
289+# -*- coding: utf-8 -*-
290+
291+from django.db import (
292+ migrations,
293+ models,
294+)
295+
296+
297+def fix_bootsource_daily_label(apps, schema_editor):
298+ BootSource = apps.get_model("maasserver", "BootSource")
299+ for source in BootSource.objects.filter(
300+ url="http://images.maas.io/ephemeral-v2/daily/"):
301+ for selection in source.bootsourceselection_set.filter(
302+ labels__contains=["release"]):
303+ selection.labels = ["*"]
304+ selection.save()
305+
306+
307+class Migration(migrations.Migration):
308+
309+ dependencies = [
310+ ('maasserver', '0061_maas_nodegroup_worker_to_maas'),
311+ ]
312+
313+ operations = [
314+ migrations.RunPython(fix_bootsource_daily_label),
315+ ]
316
317=== modified file 'src/maasserver/models/signals/bootsources.py'
318--- src/maasserver/models/signals/bootsources.py 2016-05-05 14:10:00 +0000
319+++ src/maasserver/models/signals/bootsources.py 2016-05-31 17:22:09 +0000
320@@ -7,7 +7,10 @@
321 "signals",
322 ]
323
324-from django.db.models.signals import post_save
325+from django.db.models.signals import (
326+ post_delete,
327+ post_save,
328+)
329 from maasserver.bootsources import cache_boot_sources
330 from maasserver.models.bootsource import BootSource
331 from maasserver.utils.orm import post_commit_do
332@@ -18,7 +21,7 @@
333 signals = SignalsManager()
334
335
336-def update_boot_source_cache(sender, instance, **kwargs):
337+def update_boot_source_cache(sender, instance, *args, **kwargs):
338 """Update the `BootSourceCache` using the updated source.
339
340 This only begins after a successful commit to the database, and is then
341@@ -28,6 +31,9 @@
342
343
344 signals.watch(post_save, update_boot_source_cache, BootSource)
345+signals.watch(post_delete, update_boot_source_cache, BootSource)
346+signals.watch_config(update_boot_source_cache, "enable_http_proxy")
347+signals.watch_config(update_boot_source_cache, "http_proxy")
348
349
350 # Enable all signals by default.
351
352=== added file 'src/maasserver/models/signals/tests/test_bootsources.py'
353--- src/maasserver/models/signals/tests/test_bootsources.py 1970-01-01 00:00:00 +0000
354+++ src/maasserver/models/signals/tests/test_bootsources.py 2016-05-31 17:22:09 +0000
355@@ -0,0 +1,55 @@
356+# Copyright 2016 Canonical Ltd. This software is licensed under the
357+# GNU Affero General Public License version 3 (see the file LICENSE).
358+
359+"""Test the behaviour of bootsource signals."""
360+
361+__all__ = []
362+
363+from maasserver.bootsources import cache_boot_sources
364+from maasserver.models import signals
365+from maasserver.models.config import Config
366+from maasserver.testing.factory import factory
367+from maasserver.testing.testcase import MAASServerTestCase
368+from maastesting.matchers import MockCalledOnceWith
369+from twisted.internet import reactor
370+
371+
372+class TestBootSourceSignals(MAASServerTestCase):
373+ """Tests for the `BootSource` model's signals."""
374+
375+ def test_arranges_for_update_on_BootSource_create(self):
376+ post_commit_do = self.patch(signals.bootsources, "post_commit_do")
377+ factory.make_BootSource(keyring_data=factory.make_bytes())
378+ self.assertThat(post_commit_do, MockCalledOnceWith(
379+ reactor.callLater, 0, cache_boot_sources))
380+
381+ def test_arranges_for_update_on_BootSource_update(self):
382+ self.patch(signals.bootsources, "post_commit_do")
383+ boot_source = factory.make_BootSource(
384+ keyring_data=factory.make_bytes())
385+ post_commit_do = self.patch(signals.bootsources, "post_commit_do")
386+ boot_source.keyring_data = factory.make_bytes()
387+ boot_source.save()
388+ self.assertThat(post_commit_do, MockCalledOnceWith(
389+ reactor.callLater, 0, cache_boot_sources))
390+
391+ def test_arranges_for_update_on_BootSource_delete(self):
392+ self.patch(signals.bootsources, "post_commit_do")
393+ boot_source = factory.make_BootSource(
394+ keyring_data=factory.make_bytes())
395+ post_commit_do = self.patch(signals.bootsources, "post_commit_do")
396+ boot_source.delete()
397+ self.assertThat(post_commit_do, MockCalledOnceWith(
398+ reactor.callLater, 0, cache_boot_sources))
399+
400+ def test_arranges_for_update_on_Config_http_proxy(self):
401+ post_commit_do = self.patch(signals.bootsources, "post_commit_do")
402+ Config.objects.set_config("http_proxy", factory.make_url())
403+ self.assertThat(post_commit_do, MockCalledOnceWith(
404+ reactor.callLater, 0, cache_boot_sources))
405+
406+ def test_arranges_for_update_on_Config_http_proxy_enable(self):
407+ post_commit_do = self.patch(signals.bootsources, "post_commit_do")
408+ Config.objects.set_config("enable_http_proxy", False)
409+ self.assertThat(post_commit_do, MockCalledOnceWith(
410+ reactor.callLater, 0, cache_boot_sources))
411
412=== modified file 'src/maasserver/models/testing.py'
413--- src/maasserver/models/testing.py 2016-05-12 19:07:37 +0000
414+++ src/maasserver/models/testing.py 2016-05-31 17:22:09 +0000
415@@ -4,13 +4,9 @@
416 """Testing helpers for ORM models and their supporting code."""
417
418 __all__ = [
419- "UpdateBootSourceCacheDisconnected",
420 ]
421
422-from django.db.models.signals import post_save
423 import fixtures
424-from maasserver.models.bootsource import BootSource
425-from maasserver.models.signals.bootsources import update_boot_source_cache
426
427
428 class SignalDisconnected(fixtures.Fixture): # DEPRECATED
429@@ -62,14 +58,3 @@
430 with signal.lock:
431 self.addCleanup(restore, signal, signal.receivers)
432 signal.receivers = []
433-
434-
435-class UpdateBootSourceCacheDisconnected(SignalDisconnected): # DEPRECATED
436- """Disconnects `update_boot_source_cache`.
437-
438- :deprecated: Use the manager in `m.models.signals.bootsources` instead.
439- """
440-
441- def __init__(self, *signals):
442- super(UpdateBootSourceCacheDisconnected, self).__init__(
443- post_save, update_boot_source_cache, BootSource)
444
445=== modified file 'src/maasserver/models/tests/test_bootresource.py'
446--- src/maasserver/models/tests/test_bootresource.py 2016-04-12 17:36:35 +0000
447+++ src/maasserver/models/tests/test_bootresource.py 2016-05-31 17:22:09 +0000
448@@ -21,7 +21,7 @@
449 BootResource,
450 RTYPE_REQUIRING_OS_SERIES_NAME,
451 )
452-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
453+from maasserver.models.signals import bootsources
454 from maasserver.testing.factory import factory
455 from maasserver.testing.testcase import MAASServerTestCase
456
457@@ -289,7 +289,9 @@
458
459 def setUp(self):
460 super(TestGetAvailableCommissioningResources, self).setUp()
461- self.useFixture(UpdateBootSourceCacheDisconnected())
462+ # Disable boot source cache signals.
463+ self.addCleanup(bootsources.signals.enable)
464+ bootsources.signals.disable()
465
466 def test__returns_empty_if_no_cache(self):
467 release = factory.make_name("release")
468
469=== modified file 'src/maasserver/models/tests/test_bootsource.py'
470--- src/maasserver/models/tests/test_bootsource.py 2016-05-12 19:07:37 +0000
471+++ src/maasserver/models/tests/test_bootsource.py 2016-05-31 17:22:09 +0000
472@@ -6,18 +6,12 @@
473 __all__ = []
474
475 import os
476-from unittest import skip
477
478 from django.core.exceptions import ValidationError
479-from maasserver.bootsources import cache_boot_sources
480-from maasserver.models import signals
481 from maasserver.models.bootsource import BootSource
482-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
483+from maasserver.models.signals import bootsources
484 from maasserver.testing.factory import factory
485 from maasserver.testing.testcase import MAASServerTestCase
486-from maasserver.utils.threads import deferToDatabase
487-from maastesting.matchers import MockCalledOnceWith
488-from twisted.internet import reactor
489
490
491 def make_BootSource():
492@@ -30,7 +24,9 @@
493
494 def setUp(self):
495 super(TestBootSource, self).setUp()
496- self.useFixture(UpdateBootSourceCacheDisconnected())
497+ # Disable boot source cache signals.
498+ self.addCleanup(bootsources.signals.enable)
499+ bootsources.signals.disable()
500
501 def test_valid_boot_source_is_valid(self):
502 boot_source = BootSource(
503@@ -126,25 +122,3 @@
504 boot_source_dict[factory.make_name("key")] = factory.make_name("value")
505 self.assertTrue(
506 boot_source.compare_dict_without_selections(boot_source_dict))
507-
508- # XXX: GavinPanella 2015-03-03 bug=1376317: This test is fragile, possibly
509- # due to isolation issues. Note: this test may not be superfluous.
510- @skip("Possible isolation issues")
511- def test_calls_cache_boot_sources_on_create(self):
512- mock_callLater = self.patch(reactor, 'callLater')
513- BootSource.objects.create(
514- url="http://test.test/", keyring_data=b"1234")
515- self.assertThat(
516- mock_callLater,
517- MockCalledOnceWith(
518- 1, deferToDatabase, cache_boot_sources))
519-
520-
521-class TestBootSourceSignals(MAASServerTestCase):
522- """Tests for the `BootSource` model's signals."""
523-
524- def test_arranges_for_later_update_to_boot_sources_post_commit(self):
525- post_commit_do = self.patch(signals.bootsources, "post_commit_do")
526- make_BootSource()
527- self.assertThat(post_commit_do, MockCalledOnceWith(
528- reactor.callLater, 0, cache_boot_sources))
529
530=== modified file 'src/maasserver/models/tests/test_bootsourcecache.py'
531--- src/maasserver/models/tests/test_bootsourcecache.py 2016-04-08 14:42:52 +0000
532+++ src/maasserver/models/tests/test_bootsourcecache.py 2016-05-31 17:22:09 +0000
533@@ -6,7 +6,7 @@
534 __all__ = []
535
536 from maasserver.models.bootsourcecache import BootSourceCache
537-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
538+from maasserver.models.signals import bootsources
539 from maasserver.testing.factory import factory
540 from maasserver.testing.testcase import MAASServerTestCase
541
542@@ -15,7 +15,9 @@
543
544 def setUp(self):
545 super(TestBootSourceCache, self).setUp()
546- self.useFixture(UpdateBootSourceCacheDisconnected())
547+ # Disable boot source cache signals.
548+ self.addCleanup(bootsources.signals.enable)
549+ bootsources.signals.disable()
550
551 def test_get_release_title_returns_None_for_unknown(self):
552 self.assertIsNone(
553
554=== modified file 'src/maasserver/models/tests/test_bootsourceselection.py'
555--- src/maasserver/models/tests/test_bootsourceselection.py 2015-12-01 18:12:59 +0000
556+++ src/maasserver/models/tests/test_bootsourceselection.py 2016-05-31 17:22:09 +0000
557@@ -9,7 +9,7 @@
558 BootSource,
559 BootSourceSelection,
560 )
561-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
562+from maasserver.models.signals import bootsources
563 from maasserver.testing.factory import factory
564 from maasserver.testing.testcase import MAASServerTestCase
565
566@@ -19,7 +19,9 @@
567
568 def setUp(self):
569 super(TestBootSourceSelection, self).setUp()
570- self.useFixture(UpdateBootSourceCacheDisconnected())
571+ # Disable boot source cache signals.
572+ self.addCleanup(bootsources.signals.enable)
573+ bootsources.signals.disable()
574
575 def test_can_create_selection(self):
576 boot_source = BootSource(
577
578=== modified file 'src/maasserver/rpc/tests/test_configuration.py'
579--- src/maasserver/rpc/tests/test_configuration.py 2015-12-01 18:12:59 +0000
580+++ src/maasserver/rpc/tests/test_configuration.py 2016-05-31 17:22:09 +0000
581@@ -8,6 +8,7 @@
582 from urllib.parse import urlparse
583
584 from maasserver.models.config import Config
585+from maasserver.models.signals import bootsources
586 from maasserver.rpc.configuration import (
587 get_archive_mirrors,
588 get_proxies,
589@@ -18,6 +19,12 @@
590
591 class TestGetArchiveMirrors(MAASServerTestCase):
592
593+ def setUp(self):
594+ super(TestGetArchiveMirrors, self).setUp()
595+ # Disable boot source cache signals.
596+ self.addCleanup(bootsources.signals.enable)
597+ bootsources.signals.disable()
598+
599 def test_returns_populated_dict_when_main_and_port_is_set(self):
600 url = factory.make_parsed_url().geturl()
601 Config.objects.set_config("main_archive", url)
602@@ -29,6 +36,12 @@
603
604 class TestGetProxies(MAASServerTestCase):
605
606+ def setUp(self):
607+ super(TestGetProxies, self).setUp()
608+ # Disable boot source cache signals.
609+ self.addCleanup(bootsources.signals.enable)
610+ bootsources.signals.disable()
611+
612 def test_returns_populated_dict_when_http_proxy_is_not_set(self):
613 Config.objects.set_config("enable_http_proxy", True)
614 Config.objects.set_config("http_proxy", None)
615
616=== modified file 'src/maasserver/rpc/tests/test_regionservice_calls.py'
617--- src/maasserver/rpc/tests/test_regionservice_calls.py 2016-05-17 15:24:59 +0000
618+++ src/maasserver/rpc/tests/test_regionservice_calls.py 2016-05-31 17:22:09 +0000
619@@ -35,6 +35,7 @@
620 Node,
621 )
622 from maasserver.models.interface import PhysicalInterface
623+from maasserver.models.signals import bootsources
624 from maasserver.models.signals.testing import SignalsDisabled
625 from maasserver.rpc import (
626 events as events_module,
627@@ -442,6 +443,10 @@
628 @wait_for_reactor
629 @inlineCallbacks
630 def test_get_proxies_with_http_proxy_not_set(self):
631+ # Disable boot source cache signals.
632+ self.addCleanup(bootsources.signals.enable)
633+ bootsources.signals.disable()
634+
635 yield deferToDatabase(self.set_http_proxy, None)
636
637 response = yield call_responder(Region(), GetProxies, {})
638@@ -453,6 +458,10 @@
639 @wait_for_reactor
640 @inlineCallbacks
641 def test_get_proxies_with_http_proxy_set(self):
642+ # Disable boot source cache signals.
643+ self.addCleanup(bootsources.signals.enable)
644+ bootsources.signals.disable()
645+
646 url = factory.make_parsed_url()
647 yield deferToDatabase(self.set_http_proxy, url.geturl())
648
649
650=== modified file 'src/maasserver/start_up.py'
651--- src/maasserver/start_up.py 2016-03-31 23:43:06 +0000
652+++ src/maasserver/start_up.py 2016-05-31 17:22:09 +0000
653@@ -8,7 +8,6 @@
654 ]
655
656 import logging
657-from random import randrange
658
659 from django.db import connection
660 from django.db.utils import DatabaseError
661@@ -17,22 +16,12 @@
662 locks,
663 security,
664 )
665-from maasserver.bootresources import (
666- ensure_boot_source_definition,
667- import_resources,
668-)
669-from maasserver.clusterrpc.boot_images import get_all_available_boot_images
670+from maasserver.bootresources import ensure_boot_source_definition
671 from maasserver.fields import register_mac_type
672-from maasserver.models import (
673- BootResource,
674- BootSource,
675- BootSourceSelection,
676-)
677 from maasserver.models.domain import dns_kms_setting_changed
678 from maasserver.utils import synchronised
679 from maasserver.utils.orm import (
680 get_psycopg2_exception,
681- post_commit_do,
682 transactional,
683 with_connection,
684 )
685@@ -44,7 +33,6 @@
686 FOREVER,
687 pause,
688 )
689-from twisted.internet import reactor
690 from twisted.internet.defer import inlineCallbacks
691
692
693@@ -107,61 +95,6 @@
694 @with_connection # Needed by the following lock.
695 @synchronised(locks.startup)
696 @transactional
697-def start_import_on_upgrade():
698- """Starts importing `BootResource`s on upgrade from MAAS where the boot
699- images where only stored on the clusters."""
700- # Do nothing, because `BootResource`s already exist.
701- if BootResource.objects.exists():
702- return
703-
704- # Do nothing if none of the clusters have boot images present.
705- boot_images = get_all_available_boot_images()
706- if len(boot_images) == 0:
707- return
708-
709- # Build the selections that need to be set based on the images
710- # that live on the cluster.
711- osystems = dict()
712- for image in boot_images:
713- osystem = image["osystem"]
714- if osystem not in osystems:
715- osystems[osystem] = {
716- "arches": set(),
717- "releases": set(),
718- "labels": set(),
719- }
720- osystems[osystem]["arches"].add(
721- image["architecture"])
722- osystems[osystem]["releases"].add(
723- image["release"])
724- osystems[osystem]["labels"].add(
725- image["label"])
726-
727- # We have no way to truly know which boot source this came
728- # from, but since this should only occur on upgrade we
729- # take the first source, which will be the default source and
730- # apply the selection to that source.
731- boot_source = BootSource.objects.first()
732-
733- # Clear all current selections and create the new selections
734- # based on the information retrieved from clusters.
735- boot_source.bootsourceselection_set.all().delete()
736- for osystem, options in osystems.items():
737- for release in options["releases"]:
738- BootSourceSelection.objects.create(
739- boot_source=boot_source, os=osystem,
740- release=release, arches=list(options["arches"]),
741- subarches=["*"], labels=list(options["labels"]))
742-
743- # Start the import process for the user, since the cluster
744- # already has images. Even though the cluster is usable the
745- # region will not be usable until it has boot images as well.
746- import_resources()
747-
748-
749-@with_connection # Needed by the following lock.
750-@synchronised(locks.startup)
751-@transactional
752 def inner_start_up():
753 """Startup jobs that must run serialized w.r.t. other starting servers."""
754 # Register our MAC data type with psycopg.
755@@ -178,11 +111,5 @@
756 # If there are no boot-source definitions yet, create defaults.
757 ensure_boot_source_definition()
758
759- # Start import on upgrade if needed, but not until there's a good
760- # chance than one or more clusters are connected.
761- post_commit_do(
762- reactor.callLater, randrange(45, 90), reactor.callInDatabase,
763- start_import_on_upgrade)
764-
765 # Freshen the kms SRV records.
766 dns_kms_setting_changed()
767
768=== modified file 'src/maasserver/tests/test_bootresources.py'
769--- src/maasserver/tests/test_bootresources.py 2016-05-16 09:21:53 +0000
770+++ src/maasserver/tests/test_bootresources.py 2016-05-31 17:22:09 +0000
771@@ -58,6 +58,7 @@
772 BootResourceSet,
773 Config,
774 LargeFile,
775+ signals,
776 )
777 from maasserver.models.signals.testing import SignalsDisabled
778 from maasserver.rpc.testing.fixtures import MockLiveRegionToClusterRPCFixture
779@@ -1220,38 +1221,14 @@
780 fake_finalize,
781 MockCalledOnceWith())
782
783- def test_has_synced_resources_returns_true(self):
784- factory.make_BootResource(rtype=BOOT_RESOURCE_TYPE.SYNCED)
785- self.assertTrue(bootresources.has_synced_resources())
786-
787- def test_has_synced_resources_returns_false(self):
788- factory.make_BootResource(rtype=BOOT_RESOURCE_TYPE.UPLOADED)
789- self.assertFalse(bootresources.has_synced_resources())
790-
791 def test__import_resources_exits_early_if_lock_held(self):
792- has_synced_resources = self.patch_autospec(
793- bootresources, "has_synced_resources")
794+ set_simplestreams_env = self.patch_autospec(
795+ bootresources, "set_simplestreams_env")
796 with lock_held_in_other_thread(bootresources.locks.import_images):
797- bootresources._import_resources(force=True)
798- # The test for already-synced resources is not called if the
799+ bootresources._import_resources()
800+ # The test for set_simplestreams_env is not called if the
801 # lock is already held.
802- self.assertThat(has_synced_resources, MockNotCalled())
803-
804- def test__import_resources_exits_early_without_force(self):
805- has_synced_resources = self.patch(
806- bootresources, "has_synced_resources")
807- bootresources._import_resources(force=False)
808- # The test for already-synced resources is not performed if we're
809- # forcing a sync.
810- self.assertThat(has_synced_resources, MockCalledOnceWith())
811-
812- def test__import_resources_continues_with_force(self):
813- has_synced_resources = self.patch(
814- bootresources, "has_synced_resources")
815- bootresources._import_resources(force=True)
816- # The test for already-synced resources is performed if we're not
817- # forcing a sync.
818- self.assertThat(has_synced_resources, MockNotCalled())
819+ self.assertThat(set_simplestreams_env, MockNotCalled())
820
821 def test__import_resources_holds_lock(self):
822 fake_write_all_keyrings = self.patch(
823@@ -1262,7 +1239,7 @@
824 return []
825 fake_write_all_keyrings.side_effect = test_for_held_lock
826
827- bootresources._import_resources(force=True)
828+ bootresources._import_resources()
829 self.assertFalse(bootresources.locks.import_images.is_locked())
830
831 def test__import_resources_calls_functions_with_correct_parameters(self):
832@@ -1282,7 +1259,7 @@
833 set_global_default_releases = self.patch(
834 bootresources, 'set_global_default_releases')
835
836- bootresources._import_resources(force=True)
837+ bootresources._import_resources()
838
839 self.expectThat(
840 bootresources.cache_boot_sources,
841@@ -1312,12 +1289,13 @@
842 self.patch(bootresources, 'map_products')
843 capture = self.patch_and_capture_env_for_download_all_boot_resources()
844
845- bootresources._import_resources(force=True)
846+ bootresources._import_resources()
847 self.assertEqual(
848 get_maas_user_gpghome(), capture.env['GNUPGHOME'])
849
850 def test__import_resources_has_env_http_and_https_proxy_set(self):
851 proxy_address = factory.make_name('proxy')
852+ self.patch(signals.bootsources, "post_commit_do")
853 Config.objects.set_config('http_proxy', proxy_address)
854
855 fake_image_descriptions = self.patch(
856@@ -1328,7 +1306,7 @@
857 self.patch(bootresources, 'map_products')
858 capture = self.patch_and_capture_env_for_download_all_boot_resources()
859
860- bootresources._import_resources(force=True)
861+ bootresources._import_resources()
862 self.assertEqual(
863 (proxy_address, proxy_address),
864 (capture.env['http_proxy'], capture.env['http_proxy']))
865@@ -1337,7 +1315,7 @@
866 from maasserver.clusterrpc import boot_images
867 self.patch(boot_images.RackControllersImporter, "run")
868
869- bootresources._import_resources(force=True)
870+ bootresources._import_resources()
871
872 self.assertThat(
873 boot_images.RackControllersImporter.run,
874@@ -1349,24 +1327,24 @@
875
876 def test__defers__import_resources_to_thread(self):
877 deferToDatabase = self.patch(bootresources, "deferToDatabase")
878- bootresources._import_resources_in_thread(force=sentinel.force)
879+ bootresources._import_resources_in_thread()
880 self.assertThat(
881 deferToDatabase, MockCalledOnceWith(
882- bootresources._import_resources, force=sentinel.force))
883+ bootresources._import_resources))
884
885 def tests__defaults_force_to_False(self):
886 deferToDatabase = self.patch(bootresources, "deferToDatabase")
887 bootresources._import_resources_in_thread()
888 self.assertThat(
889 deferToDatabase, MockCalledOnceWith(
890- bootresources._import_resources, force=False))
891+ bootresources._import_resources))
892
893 def test__logs_errors_and_does_not_errback(self):
894 logger = self.useFixture(TwistedLoggerFixture())
895 exception_type = factory.make_exception_type()
896 deferToDatabase = self.patch(bootresources, "deferToDatabase")
897 deferToDatabase.return_value = fail(exception_type())
898- d = bootresources._import_resources_in_thread(force=sentinel.force)
899+ d = bootresources._import_resources_in_thread()
900 self.assertIsNone(extract_result(d))
901 self.assertDocTestMatches(
902 """\
903@@ -1383,7 +1361,7 @@
904 factory.make_name("output"))
905 deferToDatabase = self.patch(bootresources, "deferToDatabase")
906 deferToDatabase.return_value = fail(exception)
907- d = bootresources._import_resources_in_thread(force=sentinel.force)
908+ d = bootresources._import_resources_in_thread()
909 self.assertIsNone(extract_result(d))
910 self.assertDocTestMatches(
911 """\
912@@ -1488,7 +1466,7 @@
913 service, "are_boot_images_available_in_the_region")
914 are_region_func.return_value = region_answer
915 are_cluster_func = self.patch_autospec(
916- service, "are_boot_images_available_in_any_cluster")
917+ service, "are_boot_images_available_in_any_rack")
918 are_cluster_func.return_value = cluster_answer
919
920 def test__adds_warning_if_boot_images_exists_on_cluster_not_region(self):
921@@ -1502,10 +1480,10 @@
922
923 error_observed = get_persistent_error(COMPONENT.IMPORT_PXE_FILES)
924 error_expected = """\
925- One or more of your clusters currently has boot images, but your
926- region does not. Nodes will not be able to provision until you import
927- boot images into the region. Visit the <a href="%s">boot images</a>
928- page to start the import.
929+ One or more of your rack controller(s) currently has boot images, but
930+ your region controller does not. Machines will not be able to provision
931+ until you import boot images into the region. Visit the
932+ <a href="%s">boot images</a> page to start the import.
933 """
934 images_link = maas_url_path + '/images/'
935 self.assertEqual(
936@@ -1523,7 +1501,7 @@
937
938 error_observed = get_persistent_error(COMPONENT.IMPORT_PXE_FILES)
939 error_expected = """\
940- Boot image import process not started. Nodes will not be able to
941+ Boot image import process not started. Machines will not be able to
942 provision without boot images. Visit the <a href="%s">boot images</a>
943 page to start the import.
944 """
945@@ -1571,7 +1549,7 @@
946 factory.make_BootResource()
947 self.assertTrue(service.are_boot_images_available_in_the_region())
948
949- def test__are_boot_images_available_in_any_cluster_v2(self):
950+ def test__are_boot_images_available_in_any_rack_v2(self):
951 # Import the websocket handlers now: merely defining DeviceHandler,
952 # e.g., causes a database access, which will crash if it happens
953 # inside the reactor thread where database access is forbidden and
954@@ -1589,7 +1567,7 @@
955
956 # are_boot_images_available_in_the_region() returns False when there
957 # are no clusters connected.
958- self.assertFalse(service.are_boot_images_available_in_any_cluster())
959+ self.assertFalse(service.are_boot_images_available_in_any_rack())
960
961 # Connect a rack controller to the region via RPC.
962 cluster_rpc = region_rpc.makeCluster(rack_controller, ListBootImagesV2)
963@@ -1597,15 +1575,15 @@
964 # are_boot_images_available_in_the_region() returns False when none of
965 # the clusters have any images.
966 cluster_rpc.ListBootImagesV2.return_value = succeed({"images": []})
967- self.assertFalse(service.are_boot_images_available_in_any_cluster())
968+ self.assertFalse(service.are_boot_images_available_in_any_rack())
969
970 # are_boot_images_available_in_the_region() returns True when a
971 # cluster has an imported boot image.
972 response = {"images": [make_rpc_boot_image()]}
973 cluster_rpc.ListBootImagesV2.return_value = succeed(response)
974- self.assertTrue(service.are_boot_images_available_in_any_cluster())
975+ self.assertTrue(service.are_boot_images_available_in_any_rack())
976
977- def test__are_boot_images_available_in_any_cluster_v1(self):
978+ def test__are_boot_images_available_in_any_rack_v1(self):
979 # Import the websocket handlers now: merely defining DeviceHandler,
980 # e.g., causes a database access, which will crash if it happens
981 # inside the reactor thread where database access is forbidden and
982@@ -1623,7 +1601,7 @@
983
984 # are_boot_images_available_in_the_region() returns False when there
985 # are no clusters connected.
986- self.assertFalse(service.are_boot_images_available_in_any_cluster())
987+ self.assertFalse(service.are_boot_images_available_in_any_rack())
988
989 # Connect a rack controller to the region via RPC.
990 cluster_rpc = region_rpc.makeCluster(
991@@ -1635,10 +1613,10 @@
992 # are_boot_images_available_in_the_region() returns False when none of
993 # the clusters have any images.
994 cluster_rpc.ListBootImages.return_value = succeed({"images": []})
995- self.assertFalse(service.are_boot_images_available_in_any_cluster())
996+ self.assertFalse(service.are_boot_images_available_in_any_rack())
997
998 # are_boot_images_available_in_the_region() returns True when a
999 # cluster has an imported boot image.
1000 response = {"images": [make_rpc_boot_image()]}
1001 cluster_rpc.ListBootImages.return_value = succeed(response)
1002- self.assertTrue(service.are_boot_images_available_in_any_cluster())
1003+ self.assertTrue(service.are_boot_images_available_in_any_rack())
1004
1005=== modified file 'src/maasserver/tests/test_bootsources.py'
1006--- src/maasserver/tests/test_bootsources.py 2016-05-17 21:08:34 +0000
1007+++ src/maasserver/tests/test_bootsources.py 2016-05-31 17:22:09 +0000
1008@@ -27,7 +27,9 @@
1009 BootSourceSelection,
1010 Config,
1011 )
1012-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1013+from maasserver.models.signals.bootsources import (
1014+ signals as bootsources_signals,
1015+)
1016 from maasserver.testing.factory import factory
1017 from maasserver.testing.testcase import (
1018 MAASServerTestCase,
1019@@ -92,7 +94,9 @@
1020
1021 def setUp(self):
1022 super(TestHelpers, self).setUp()
1023- self.useFixture(UpdateBootSourceCacheDisconnected())
1024+ # Disable boot source cache signals.
1025+ self.addCleanup(bootsources_signals.enable)
1026+ bootsources_signals.disable()
1027
1028 def test_ensure_boot_source_definition_creates_default_source(self):
1029 BootSource.objects.all().delete()
1030@@ -119,7 +123,7 @@
1031 'release': 'xenial',
1032 'arches': ['amd64'],
1033 'subarches': ['*'],
1034- 'labels': ['release'],
1035+ 'labels': ['*'],
1036 })
1037
1038 def test_ensure_boot_source_definition_skips_if_already_present(self):
1039@@ -143,7 +147,9 @@
1040
1041 def setUp(self):
1042 super(TestGetOSInfoFromBootSources, self).setUp()
1043- self.useFixture(UpdateBootSourceCacheDisconnected())
1044+ # Disable boot source cache signals.
1045+ self.addCleanup(bootsources_signals.enable)
1046+ bootsources_signals.disable()
1047
1048 def test__returns_empty_sources_and_sets_when_cache_empty(self):
1049 self.assertEqual(
1050@@ -180,7 +186,9 @@
1051 def setUp(self):
1052 super(TestPrivateCacheBootSources, self).setUp()
1053 self.useFixture(SimplestreamsEnvFixture())
1054- self.useFixture(UpdateBootSourceCacheDisconnected())
1055+ # Disable boot source cache signals.
1056+ self.addCleanup(bootsources_signals.enable)
1057+ bootsources_signals.disable()
1058
1059 def test__has_env_GNUPGHOME_set(self):
1060 capture = (
1061@@ -274,7 +282,9 @@
1062 def setUp(self):
1063 super(TestBadConnectionHandling, self).setUp()
1064 self.useFixture(SimplestreamsEnvFixture())
1065- self.useFixture(UpdateBootSourceCacheDisconnected())
1066+ # Disable boot source cache signals.
1067+ self.addCleanup(bootsources_signals.enable)
1068+ bootsources_signals.disable()
1069
1070 def test__catches_connection_errors_and_sets_component_error(self):
1071 sources = [
1072
1073=== modified file 'src/maasserver/tests/test_compose_preseed.py'
1074--- src/maasserver/tests/test_compose_preseed.py 2016-03-28 13:54:47 +0000
1075+++ src/maasserver/tests/test_compose_preseed.py 2016-05-31 17:22:09 +0000
1076@@ -14,6 +14,7 @@
1077 PRESEED_TYPE,
1078 )
1079 from maasserver.models.config import Config
1080+from maasserver.models.signals import bootsources
1081 from maasserver.rpc.testing.fixtures import RunningClusterRPCFixture
1082 from maasserver.testing.factory import factory
1083 from maasserver.testing.osystems import make_usable_osystem
1084@@ -79,6 +80,10 @@
1085 }))
1086
1087 def test_compose_preseed_for_commissioning_node_skips_apt_proxy(self):
1088+ # Disable boot source cache signals.
1089+ self.addCleanup(bootsources.signals.enable)
1090+ bootsources.signals.disable()
1091+
1092 rack_controller = factory.make_RackController()
1093 node = factory.make_Node(
1094 interface=True, status=NODE_STATUS.COMMISSIONING)
1095@@ -228,6 +233,10 @@
1096 self.assertSystemInfo(preseed)
1097
1098 def test_compose_preseed_with_curtin_installer_skips_apt_proxy(self):
1099+ # Disable boot source cache signals.
1100+ self.addCleanup(bootsources.signals.enable)
1101+ bootsources.signals.disable()
1102+
1103 rack_controller = factory.make_RackController()
1104 node = factory.make_Node(
1105 interface=True, status=NODE_STATUS.READY)
1106
1107=== modified file 'src/maasserver/tests/test_forms_bootsource.py'
1108--- src/maasserver/tests/test_forms_bootsource.py 2016-03-28 13:54:47 +0000
1109+++ src/maasserver/tests/test_forms_bootsource.py 2016-05-31 17:22:09 +0000
1110@@ -9,7 +9,7 @@
1111
1112 from django.core.files.uploadedfile import InMemoryUploadedFile
1113 from maasserver.forms import BootSourceForm
1114-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1115+from maasserver.models.signals import bootsources
1116 from maasserver.testing.factory import factory
1117 from maasserver.testing.testcase import MAASServerTestCase
1118 from maasserver.utils.orm import reload_object
1119@@ -21,7 +21,9 @@
1120
1121 def setUp(self):
1122 super(TestBootSourceForm, self).setUp()
1123- self.useFixture(UpdateBootSourceCacheDisconnected())
1124+ # Disable boot source cache signals.
1125+ self.addCleanup(bootsources.signals.enable)
1126+ bootsources.signals.disable()
1127
1128 def test_edits_boot_source_object(self):
1129 boot_source = factory.make_BootSource()
1130
1131=== modified file 'src/maasserver/tests/test_forms_bootsourceselection.py'
1132--- src/maasserver/tests/test_forms_bootsourceselection.py 2016-03-28 13:54:47 +0000
1133+++ src/maasserver/tests/test_forms_bootsourceselection.py 2016-05-31 17:22:09 +0000
1134@@ -7,7 +7,7 @@
1135
1136 from django.core.exceptions import ValidationError
1137 from maasserver.forms import BootSourceSelectionForm
1138-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1139+from maasserver.models.signals import bootsources
1140 from maasserver.testing.factory import factory
1141 from maasserver.testing.testcase import MAASServerTestCase
1142 from maasserver.utils.orm import reload_object
1143@@ -18,7 +18,9 @@
1144
1145 def setUp(self):
1146 super(TestBootSourceSelectionForm, self).setUp()
1147- self.useFixture(UpdateBootSourceCacheDisconnected())
1148+ # Disable boot source cache signals.
1149+ self.addCleanup(bootsources.signals.enable)
1150+ bootsources.signals.disable()
1151
1152 def make_valid_source_selection_params(self, boot_source=None):
1153 # Helper that creates a valid BootSourceCache and parameters for
1154
1155=== modified file 'src/maasserver/tests/test_service_monitor.py'
1156--- src/maasserver/tests/test_service_monitor.py 2016-05-12 19:07:37 +0000
1157+++ src/maasserver/tests/test_service_monitor.py 2016-05-31 17:22:09 +0000
1158@@ -17,6 +17,7 @@
1159 from maasserver.enum import SERVICE_STATUS
1160 from maasserver.models.config import Config
1161 from maasserver.models.service import Service
1162+from maasserver.models.signals import bootsources
1163 from maasserver.rpc.regionservice import (
1164 RegionAdvertising,
1165 RegionAdvertisingService,
1166@@ -181,6 +182,10 @@
1167 @wait_for_reactor
1168 @inlineCallbacks
1169 def test_get_expected_state_returns_on_for_proxy_off_and_unset(self):
1170+ # Disable boot source cache signals.
1171+ self.addCleanup(bootsources.signals.enable)
1172+ bootsources.signals.disable()
1173+
1174 service = self.make_proxy_service()
1175 yield deferToDatabase(
1176 transactional(Config.objects.set_config),
1177@@ -206,6 +211,10 @@
1178 @wait_for_reactor
1179 @inlineCallbacks
1180 def test_get_expected_state_returns_on_for_proxy_off_and_set(self):
1181+ # Disable boot source cache signals.
1182+ self.addCleanup(bootsources.signals.enable)
1183+ bootsources.signals.disable()
1184+
1185 service = self.make_proxy_service()
1186 yield deferToDatabase(
1187 transactional(Config.objects.set_config),
1188@@ -220,6 +229,10 @@
1189 @wait_for_reactor
1190 @inlineCallbacks
1191 def test_get_expected_state_returns_on_for_proxy_on_but_unset(self):
1192+ # Disable boot source cache signals.
1193+ self.addCleanup(bootsources.signals.enable)
1194+ bootsources.signals.disable()
1195+
1196 service = self.make_proxy_service()
1197 yield deferToDatabase(
1198 transactional(Config.objects.set_config),
1199@@ -234,6 +247,10 @@
1200 @wait_for_reactor
1201 @inlineCallbacks
1202 def test_get_expected_state_returns_off_for_proxy_on_and_set(self):
1203+ # Disable boot source cache signals.
1204+ self.addCleanup(bootsources.signals.enable)
1205+ bootsources.signals.disable()
1206+
1207 service = self.make_proxy_service()
1208 yield deferToDatabase(
1209 transactional(Config.objects.set_config),
1210
1211=== modified file 'src/maasserver/tests/test_start_up.py'
1212--- src/maasserver/tests/test_start_up.py 2016-05-12 19:07:37 +0000
1213+++ src/maasserver/tests/test_start_up.py 2016-05-31 17:22:09 +0000
1214@@ -5,23 +5,15 @@
1215
1216 __all__ = []
1217
1218-from unittest.mock import (
1219- ANY,
1220- call,
1221-)
1222+from unittest.mock import call
1223
1224 from maasserver import (
1225 eventloop,
1226 locks,
1227 start_up,
1228 )
1229-from maasserver.bootresources import ensure_boot_source_definition
1230-from maasserver.clusterrpc.testing.boot_images import make_rpc_boot_image
1231-from maasserver.models import (
1232- BootSource,
1233- BootSourceSelection,
1234-)
1235-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1236+from maasserver.models import BootSource
1237+from maasserver.models.signals import bootsources
1238 from maasserver.testing.eventloop import RegionEventLoopFixture
1239 from maasserver.testing.factory import factory
1240 from maasserver.testing.testcase import MAASServerTestCase
1241@@ -30,11 +22,7 @@
1242 MockCallsMatch,
1243 MockNotCalled,
1244 )
1245-from testtools.matchers import (
1246- Equals,
1247- HasLength,
1248-)
1249-from twisted.internet import reactor
1250+from testtools.matchers import HasLength
1251
1252
1253 class LockChecker:
1254@@ -62,7 +50,6 @@
1255 super(TestStartUp, self).setUp()
1256 self.useFixture(RegionEventLoopFixture())
1257 self.patch(start_up, 'create_gnupg_home')
1258- self.patch(start_up, 'post_commit_do')
1259
1260 def tearDown(self):
1261 super(TestStartUp, self).tearDown()
1262@@ -70,7 +57,10 @@
1263 eventloop.reset().wait(5)
1264
1265 def test_inner_start_up_runs_in_exclusion(self):
1266- self.useFixture(UpdateBootSourceCacheDisconnected())
1267+ # Disable boot source cache signals.
1268+ self.addCleanup(bootsources.signals.enable)
1269+ bootsources.signals.disable()
1270+
1271 lock_checker = LockChecker()
1272 self.patch(start_up, 'register_mac_type', lock_checker)
1273 start_up.inner_start_up()
1274@@ -94,58 +84,17 @@
1275 self.expectThat(start_up.pause, MockCalledOnceWith(3.0))
1276
1277
1278-class TestStartImportOnUpgrade(MAASServerTestCase):
1279- """Tests for the `start_import_on_upgrade` function."""
1280-
1281- def setUp(self):
1282- super(TestStartImportOnUpgrade, self).setUp()
1283- self.useFixture(UpdateBootSourceCacheDisconnected())
1284- self.patch_autospec(start_up, "get_all_available_boot_images")
1285- self.patch_autospec(start_up, 'import_resources')
1286- ensure_boot_source_definition()
1287-
1288- def test__does_nothing_if_boot_resources_exist(self):
1289- factory.make_BootResource()
1290- start_up.start_import_on_upgrade()
1291- self.assertThat(start_up.import_resources, MockNotCalled())
1292-
1293- def test__does_nothing_if_no_cluster_has_any_images(self):
1294- start_up.get_all_available_boot_images.return_value = []
1295- start_up.start_import_on_upgrade()
1296- self.assertThat(start_up.import_resources, MockNotCalled())
1297-
1298- def test__calls_import_resources_when_any_cluster_has_an_image(self):
1299- boot_images = [make_rpc_boot_image()]
1300- start_up.get_all_available_boot_images.return_value = boot_images
1301- start_up.start_import_on_upgrade()
1302- self.assertThat(start_up.import_resources, MockCalledOnceWith())
1303-
1304- def test__sets_source_selections_based_on_boot_images(self):
1305- boot_images = [make_rpc_boot_image() for _ in range(3)]
1306- start_up.get_all_available_boot_images.return_value = boot_images
1307- start_up.start_import_on_upgrade()
1308-
1309- boot_source = BootSource.objects.first()
1310- for image in boot_images:
1311- selection = BootSourceSelection.objects.get(
1312- boot_source=boot_source, os=image["osystem"],
1313- release=image["release"])
1314- self.assertIsNotNone(selection)
1315- self.expectThat(selection.arches, Equals([image["architecture"]]))
1316- self.expectThat(selection.subarches, Equals(["*"]))
1317- self.expectThat(selection.labels, Equals([image["label"]]))
1318-
1319-
1320 class TestInnerStartUp(MAASServerTestCase):
1321
1322 """Tests for the actual work done in `inner_start_up`."""
1323
1324 def setUp(self):
1325 super(TestInnerStartUp, self).setUp()
1326- self.useFixture(UpdateBootSourceCacheDisconnected())
1327 self.patch_autospec(start_up, 'create_gnupg_home')
1328- self.patch_autospec(start_up, 'post_commit_do')
1329 self.patch_autospec(start_up, 'dns_kms_setting_changed')
1330+ # Disable boot source cache signals.
1331+ self.addCleanup(bootsources.signals.enable)
1332+ bootsources.signals.disable()
1333
1334 def test__calls_create_gnupg_home_if_master(self):
1335 self.patch(start_up, "is_master_process").return_value = True
1336@@ -169,21 +118,6 @@
1337 start_up.inner_start_up()
1338 self.assertThat(BootSource.objects.all(), HasLength(0))
1339
1340- def test__calls_start_import_on_upgrade_if_master(self):
1341- self.patch(start_up, "is_master_process").return_value = True
1342- start_up.inner_start_up()
1343- self.assertThat(
1344- start_up.post_commit_do, MockCalledOnceWith(
1345- reactor.callLater, ANY,
1346- reactor.threadpoolForDatabase.callInThread,
1347- start_up.start_import_on_upgrade))
1348-
1349- def test__doesnt_call_start_import_on_upgrade_if_bot_master(self):
1350- self.patch(start_up, "is_master_process").return_value = False
1351- start_up.inner_start_up()
1352- self.assertThat(
1353- start_up.post_commit_do, MockNotCalled())
1354-
1355 def test__calls_dns_kms_setting_changed_if_master(self):
1356 self.patch(start_up, "is_master_process").return_value = True
1357 start_up.inner_start_up()
1358
1359=== modified file 'src/maasserver/views/tests/test_images.py'
1360--- src/maasserver/views/tests/test_images.py 2016-03-28 13:54:47 +0000
1361+++ src/maasserver/views/tests/test_images.py 2016-05-31 17:22:09 +0000
1362@@ -23,7 +23,7 @@
1363 BootSourceSelection,
1364 Config,
1365 )
1366-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1367+from maasserver.models.signals import bootsources
1368 from maasserver.testing import extract_redirect
1369 from maasserver.testing.factory import factory
1370 from maasserver.testing.testcase import MAASServerTestCase
1371@@ -48,7 +48,9 @@
1372
1373 def setUp(self):
1374 super(UbuntuImagesTest, self).setUp()
1375- self.useFixture(UpdateBootSourceCacheDisconnected())
1376+ # Disable boot source cache signals.
1377+ self.addCleanup(bootsources.signals.enable)
1378+ bootsources.signals.disable()
1379
1380 def patch_get_os_info_from_boot_sources(
1381 self, sources, releases=None, arches=None):
1382@@ -225,7 +227,9 @@
1383
1384 def setUp(self):
1385 super(OtherImagesTest, self).setUp()
1386- self.useFixture(UpdateBootSourceCacheDisconnected())
1387+ # Disable boot source cache signals.
1388+ self.addCleanup(bootsources.signals.enable)
1389+ bootsources.signals.disable()
1390
1391 def make_other_resource(self, os=None, arch=None, subarch=None,
1392 release=None):
1393
1394=== modified file 'src/maasserver/views/tests/test_settings.py'
1395--- src/maasserver/views/tests/test_settings.py 2016-03-31 23:34:55 +0000
1396+++ src/maasserver/views/tests/test_settings.py 2016-05-31 17:22:09 +0000
1397@@ -19,7 +19,7 @@
1398 Config,
1399 UserProfile,
1400 )
1401-from maasserver.models.testing import UpdateBootSourceCacheDisconnected
1402+from maasserver.models.signals import bootsources
1403 from maasserver.storage_layouts import get_storage_layout_choices
1404 from maasserver.testing import (
1405 extract_redirect,
1406@@ -82,6 +82,9 @@
1407 reverse('accounts-del', args=[user.username]), links)
1408
1409 def test_settings_maas_and_network_POST(self):
1410+ # Disable boot source cache signals.
1411+ self.addCleanup(bootsources.signals.enable)
1412+ bootsources.signals.disable()
1413 self.client_log_in(as_admin=True)
1414 new_name = factory.make_string()
1415 new_proxy = "http://%s.example.com:1234/" % factory.make_string()
1416@@ -272,7 +275,9 @@
1417 1, len(boot_source), "Didn't show boot image settings section.")
1418
1419 def test_settings_boot_source_is_not_shown(self):
1420- self.useFixture(UpdateBootSourceCacheDisconnected())
1421+ # Disable boot source cache signals.
1422+ self.addCleanup(bootsources.signals.enable)
1423+ bootsources.signals.disable()
1424 self.client_log_in(as_admin=True)
1425 for _ in range(2):
1426 factory.make_BootSource()
1427@@ -283,7 +288,9 @@
1428 0, len(boot_source), "Didn't hide boot image settings section.")
1429
1430 def test_settings_boot_source_POST_creates_new_source(self):
1431- self.useFixture(UpdateBootSourceCacheDisconnected())
1432+ # Disable boot source cache signals.
1433+ self.addCleanup(bootsources.signals.enable)
1434+ bootsources.signals.disable()
1435 self.client_log_in(as_admin=True)
1436 url = "http://test.example.com/archive"
1437 keyring = "/usr/local/testing/path.gpg"
1438@@ -306,7 +313,9 @@
1439 (boot_source.url, boot_source.keyring_filename))
1440
1441 def test_settings_boot_source_POST_updates_source(self):
1442- self.useFixture(UpdateBootSourceCacheDisconnected())
1443+ # Disable boot source cache signals.
1444+ self.addCleanup(bootsources.signals.enable)
1445+ bootsources.signals.disable()
1446 self.client_log_in(as_admin=True)
1447 boot_source = factory.make_BootSource()
1448 url = "http://test.example.com/archive"