Merge ~bjornt/maas:bug-1845459-kvm-pod-creation-failure into maas:master

Proposed by Björn Tillenius
Status: Merged
Approved by: Björn Tillenius
Approved revision: 4ae70450d9905810b527d9c0b13b16456f45c9ef
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~bjornt/maas:bug-1845459-kvm-pod-creation-failure
Merge into: maas:master
Diff against target: 60 lines (+27/-0)
2 files modified
src/metadataserver/api_twisted.py (+10/-0)
src/metadataserver/tests/test_api_twisted.py (+17/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Needs Fixing
Alberto Donato (community) Approve
Review via email: mp+373402@code.launchpad.net

Commit message

LP #1845459: Failure creating KVM pod in CI

Re-raise DatabaseErrors if form_pod.save() raises an exception.
The old code tried to mark the node as failed deployment, which failed
since the transaction was broken. Further more, the transaction wouldn't
be retried, which would have make the deploy succeed.

This is a stop-gap fix that improves the situation slightly. It's made
small so tha it can be backported to 2.6. The real fix is to refactor
the processing of the messages, so that marking the node as failed or
succeeded happens in a separate transaction.

To post a comment you must log in.
Revision history for this message
Björn Tillenius (bjornt) wrote :

The test isn't create, but it's how the existing tests look like. I'd like to write better tests when we refactor the message processing instead.

I've confirmed that this works in CI. I can see a conflict happen, but the transaction now gets retried so the deployment succeeds.

Revision history for this message
Alberto Donato (ack) wrote :

+1!

Looks good, just a typo fix needed

review: Approve
Revision history for this message
Björn Tillenius (bjornt) :
Revision history for this message
MAAS Lander (maas-lander) wrote :
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b bug-1845459-kvm-pod-creation-failure lp:~bjornt/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci-jenkins.internal:8080/job/maas/job/branch-tester/6538/console
COMMIT: 42b5a7637ba74be7aa58590fff446e60e6bfd84f

review: Needs Fixing
4ae7045... by Björn Tillenius

make format.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/metadataserver/api_twisted.py b/src/metadataserver/api_twisted.py
2index 7549fd0..b727cc7 100644
3--- a/src/metadataserver/api_twisted.py
4+++ b/src/metadataserver/api_twisted.py
5@@ -9,6 +9,7 @@ from collections import defaultdict
6 from datetime import datetime
7 import json
8
9+from django.db.utils import DatabaseError
10 from maasserver.api.utils import extract_oauth_key_from_auth_header
11 from maasserver.enum import (
12 NODE_STATUS,
13@@ -211,6 +212,15 @@ def _create_pod_for_deployment(node):
14 if pod_form.is_valid():
15 try:
16 pod_form.save()
17+ except DatabaseError:
18+ # Re-raise database errors, since we want it to be
19+ # retried if possible. If it's not retriable, we
20+ # couldn't mark the node as failed anyway, since the
21+ # transaction will be broken.
22+ # XXX: We should refactor the processing of messages so
23+ # that the node is marked failed/deployed in a seperate
24+ # transaction than the one doing the processing.
25+ raise
26 except Exception:
27 node.mark_failed(comment=POD_CREATION_ERROR, commit=False)
28 log.err(None, "Exception while saving pod form.")
29diff --git a/src/metadataserver/tests/test_api_twisted.py b/src/metadataserver/tests/test_api_twisted.py
30index 4c2add2..dce81a3 100644
31--- a/src/metadataserver/tests/test_api_twisted.py
32+++ b/src/metadataserver/tests/test_api_twisted.py
33@@ -21,6 +21,7 @@ from unittest.mock import (
34 )
35
36 from crochet import wait_for
37+from django.db.utils import DatabaseError
38 from maasserver.enum import NODE_STATUS
39 from maasserver.models import (
40 Event,
41@@ -1125,3 +1126,19 @@ class TestCreatePodForDeployment(MAASServerTestCase):
42 self.assertThat(node.status, Equals(NODE_STATUS.FAILED_DEPLOYMENT))
43 self.assertThat(node.error_description, DocTestMatches(
44 POD_CREATION_ERROR))
45+
46+ def test__raises_if_save_raises_database_error(self):
47+ mock_pod_form = Mock()
48+ self.mock_PodForm.return_value = mock_pod_form
49+ mock_pod_form.errors = {}
50+ mock_pod_form.is_valid = Mock()
51+ mock_pod_form.is_valid.return_value = True
52+ mock_pod_form.save = Mock()
53+ mock_pod_form.save.side_effect = DatabaseError('broken transaction')
54+ node = factory.make_Node_with_Interface_on_Subnet(
55+ status=NODE_STATUS.DEPLOYING, agent_name="maas-kvm-pod",
56+ install_kvm=True)
57+ factory.make_StaticIPAddress(interface=node.boot_interface)
58+ NodeMetadata.objects.create(
59+ node=node, key="virsh_password", value="xyz123")
60+ self.assertRaises(DatabaseError, _create_pod_for_deployment, node)

Subscribers

People subscribed via source and target branches