Merge ~newell-jensen/maas:lp1788910 into maas:master

Proposed by Newell Jensen
Status: Merged
Approved by: Newell Jensen
Approved revision: 71ad7c8995b6424af7ac581772b645ad5cc7f965
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~newell-jensen/maas:lp1788910
Merge into: maas:master
Diff against target: 148 lines (+64/-0)
2 files modified
src/provisioningserver/drivers/pod/tests/test_virsh.py (+43/-0)
src/provisioningserver/drivers/pod/virsh.py (+21/-0)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Mike Pontillo (community) Approve
Review via email: mp+353899@code.launchpad.net

Commit message

LP: #1788910 -- check that a newly composed vm can startup properly. If it can't, it is deleted, otherwise, it is turned off and composition can proceed.

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Thanks for the fix. This is a nice improvement that could save people a lot of time when composing machines. If an error occurs while Juju is attempting to allocate, this will also fail much faster, which is great.

I've got one comment below about the docstring, but I won't block you on it.

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

UNIT TESTS
-b lp1788910 lp:~newell-jensen/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 70a3974108db2c16df51404964b6246190c839b4

review: Approve
~newell-jensen/maas:lp1788910 updated
71ad7c8... by Newell Jensen

Fix docstring.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/src/provisioningserver/drivers/pod/tests/test_virsh.py b/src/provisioningserver/drivers/pod/tests/test_virsh.py
index f6137c8..6651598 100644
--- a/src/provisioningserver/drivers/pod/tests/test_virsh.py
+++ b/src/provisioningserver/drivers/pod/tests/test_virsh.py
@@ -982,6 +982,29 @@ class TestVirshSSH(MAASTestCase):
982 discovered_machine = conn.get_discovered_machine(hostname)982 discovered_machine = conn.get_discovered_machine(hostname)
983 self.assertIsNone(discovered_machine)983 self.assertIsNone(discovered_machine)
984984
985 def test_check_machine_can_startup(self):
986 machine = factory.make_name('machine')
987 conn = self.configure_virshssh('')
988 mock_run = self.patch(virsh.VirshSSH, "run")
989 mock_run.side_effect = ("", "")
990 conn.check_machine_can_startup(machine)
991 self.assertThat(
992 mock_run, MockCallsMatch(
993 call(['start', '--paused', machine]),
994 call(['destroy', machine])))
995
996 def test_check_machine_can_startup_raises_exception(self):
997 machine = factory.make_name('machine')
998 conn = self.configure_virshssh('')
999 mock_run = self.patch(virsh.VirshSSH, "run")
1000 mock_run.side_effect = ("error: some error", "")
1001 mock_delete_domain = self.patch(virsh.VirshSSH, "delete_domain")
1002 self.assertRaises(
1003 virsh.VirshError, conn.check_machine_can_startup, machine)
1004 self.assertThat(mock_delete_domain, MockCalledOnceWith(machine))
1005 self.assertThat(
1006 mock_run, MockCalledOnceWith(['start', '--paused', machine]))
1007
985 def test_poweron(self):1008 def test_poweron(self):
986 conn = self.configure_virshssh('')1009 conn = self.configure_virshssh('')
987 expected = conn.poweron(factory.make_name('machine'))1010 expected = conn.poweron(factory.make_name('machine'))
@@ -1494,6 +1517,8 @@ class TestVirshSSH(MAASTestCase):
1494 mock_run = self.patch(virsh.VirshSSH, "run")1517 mock_run = self.patch(virsh.VirshSSH, "run")
1495 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")1518 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")
1496 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")1519 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")
1520 mock_check_machine_can_startup = self.patch(
1521 virsh.VirshSSH, "check_machine_can_startup")
1497 mock_set_machine_autostart = self.patch(1522 mock_set_machine_autostart = self.patch(
1498 virsh.VirshSSH, "set_machine_autostart")1523 virsh.VirshSSH, "set_machine_autostart")
1499 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")1524 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")
@@ -1516,6 +1541,9 @@ class TestVirshSSH(MAASTestCase):
1516 self.assertThat(1541 self.assertThat(
1517 mock_attach_nic, MockCalledOnceWith(ANY, ANY))1542 mock_attach_nic, MockCalledOnceWith(ANY, ANY))
1518 self.assertThat(1543 self.assertThat(
1544 mock_check_machine_can_startup,
1545 MockCalledOnceWith(request.hostname))
1546 self.assertThat(
1519 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))1547 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))
1520 self.assertThat(1548 self.assertThat(
1521 mock_configure_pxe, MockCalledOnceWith(request.hostname))1549 mock_configure_pxe, MockCalledOnceWith(request.hostname))
@@ -1552,6 +1580,8 @@ class TestVirshSSH(MAASTestCase):
1552 mock_run = self.patch(virsh.VirshSSH, "run")1580 mock_run = self.patch(virsh.VirshSSH, "run")
1553 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")1581 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")
1554 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")1582 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")
1583 mock_check_machine_can_startup = self.patch(
1584 virsh.VirshSSH, "check_machine_can_startup")
1555 mock_set_machine_autostart = self.patch(1585 mock_set_machine_autostart = self.patch(
1556 virsh.VirshSSH, "set_machine_autostart")1586 virsh.VirshSSH, "set_machine_autostart")
1557 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")1587 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")
@@ -1574,6 +1604,9 @@ class TestVirshSSH(MAASTestCase):
1574 self.assertThat(1604 self.assertThat(
1575 mock_attach_nic, MockCalledOnceWith(ANY, ANY))1605 mock_attach_nic, MockCalledOnceWith(ANY, ANY))
1576 self.assertThat(1606 self.assertThat(
1607 mock_check_machine_can_startup,
1608 MockCalledOnceWith(request.hostname))
1609 self.assertThat(
1577 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))1610 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))
1578 self.assertThat(1611 self.assertThat(
1579 mock_configure_pxe, MockCalledOnceWith(request.hostname))1612 mock_configure_pxe, MockCalledOnceWith(request.hostname))
@@ -1610,6 +1643,8 @@ class TestVirshSSH(MAASTestCase):
1610 mock_run = self.patch(virsh.VirshSSH, "run")1643 mock_run = self.patch(virsh.VirshSSH, "run")
1611 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")1644 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")
1612 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")1645 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")
1646 mock_check_machine_can_startup = self.patch(
1647 virsh.VirshSSH, "check_machine_can_startup")
1613 mock_set_machine_autostart = self.patch(1648 mock_set_machine_autostart = self.patch(
1614 virsh.VirshSSH, "set_machine_autostart")1649 virsh.VirshSSH, "set_machine_autostart")
1615 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")1650 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")
@@ -1632,6 +1667,9 @@ class TestVirshSSH(MAASTestCase):
1632 self.assertThat(1667 self.assertThat(
1633 mock_attach_nic, MockCalledOnceWith(ANY, ANY))1668 mock_attach_nic, MockCalledOnceWith(ANY, ANY))
1634 self.assertThat(1669 self.assertThat(
1670 mock_check_machine_can_startup,
1671 MockCalledOnceWith(request.hostname))
1672 self.assertThat(
1635 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))1673 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))
1636 self.assertThat(1674 self.assertThat(
1637 mock_configure_pxe, MockCalledOnceWith(request.hostname))1675 mock_configure_pxe, MockCalledOnceWith(request.hostname))
@@ -1668,6 +1706,8 @@ class TestVirshSSH(MAASTestCase):
1668 mock_run = self.patch(virsh.VirshSSH, "run")1706 mock_run = self.patch(virsh.VirshSSH, "run")
1669 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")1707 mock_attach_disk = self.patch(virsh.VirshSSH, "attach_local_volume")
1670 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")1708 mock_attach_nic = self.patch(virsh.VirshSSH, "attach_interface")
1709 mock_check_machine_can_startup = self.patch(
1710 virsh.VirshSSH, "check_machine_can_startup")
1671 mock_set_machine_autostart = self.patch(1711 mock_set_machine_autostart = self.patch(
1672 virsh.VirshSSH, "set_machine_autostart")1712 virsh.VirshSSH, "set_machine_autostart")
1673 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")1713 mock_configure_pxe = self.patch(virsh.VirshSSH, "configure_pxe_boot")
@@ -1690,6 +1730,9 @@ class TestVirshSSH(MAASTestCase):
1690 self.assertThat(1730 self.assertThat(
1691 mock_attach_nic, MockCalledOnceWith(ANY, ANY))1731 mock_attach_nic, MockCalledOnceWith(ANY, ANY))
1692 self.assertThat(1732 self.assertThat(
1733 mock_check_machine_can_startup,
1734 MockCalledOnceWith(request.hostname))
1735 self.assertThat(
1693 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))1736 mock_set_machine_autostart, MockCalledOnceWith(request.hostname))
1694 self.assertThat(1737 self.assertThat(
1695 mock_configure_pxe, MockCalledOnceWith(request.hostname))1738 mock_configure_pxe, MockCalledOnceWith(request.hostname))
diff --git a/src/provisioningserver/drivers/pod/virsh.py b/src/provisioningserver/drivers/pod/virsh.py
index 629c2d8..451b38a 100644
--- a/src/provisioningserver/drivers/pod/virsh.py
+++ b/src/provisioningserver/drivers/pod/virsh.py
@@ -717,6 +717,24 @@ class VirshSSH(pexpect.spawn):
717 discovered_machine.interfaces = interfaces717 discovered_machine.interfaces = interfaces
718 return discovered_machine718 return discovered_machine
719719
720 def check_machine_can_startup(self, machine):
721 """Check the machine for any startup errors
722 after the domain is created in virsh.
723
724 If an error is reported, delete the domain and raise an exception.
725 If no error is reported, destroy the domain to put it back into a
726 'shut off' state.
727 """
728 output = self.run(['start', '--paused', machine]).strip()
729 if output.startswith("error:"):
730 # Delete the domain.
731 self.delete_domain(machine)
732 # Raise the error.
733 raise VirshError("Unable to compose %s: %s" % (machine, output))
734 else:
735 # No errors, so set machine back to 'shut off' state.
736 self.run(['destroy', machine])
737
720 def set_machine_autostart(self, machine):738 def set_machine_autostart(self, machine):
721 """Set machine to autostart."""739 """Set machine to autostart."""
722 output = self.run(['autostart', machine]).strip()740 output = self.run(['autostart', machine]).strip()
@@ -1044,6 +1062,9 @@ class VirshSSH(pexpect.spawn):
1044 self.attach_local_volume(1062 self.attach_local_volume(
1045 request.hostname, pool, volume, block_name)1063 request.hostname, pool, volume, block_name)
10461064
1065 # Check machine for any startup errors.
1066 self.check_machine_can_startup(request.hostname)
1067
1047 # Set machine to autostart.1068 # Set machine to autostart.
1048 self.set_machine_autostart(request.hostname)1069 self.set_machine_autostart(request.hostname)
10491070

Subscribers

People subscribed via source and target branches