Catch exception if servers are in error state with no bm_node attached
There have been reports (rhbz#1851507) where generating the fencing parameters fails because of one or more servers in error state, like when a scale out operation doesn't go as planned. This commit wraps get_by_instance_uuid in a try/except block to prevent this from happening, skipping the node in error state and allowing users to still get a valid fencing config for the remaining servers. Change-Id: I397f8d641504ac2ceed36fa975cf97fac5bbb81a
This commit is contained in:
@@ -16,10 +16,12 @@ from unittest import mock
|
|||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from swiftclient import exceptions as swiftexceptions
|
from swiftclient import exceptions as swiftexceptions
|
||||||
|
from ironicclient import exceptions as ironicexceptions
|
||||||
|
|
||||||
from tripleo_common import constants
|
from tripleo_common import constants
|
||||||
from tripleo_common.tests import base
|
from tripleo_common.tests import base
|
||||||
from tripleo_common.utils import stack_parameters
|
from tripleo_common.utils import stack_parameters
|
||||||
|
from tripleo_common.utils import nodes
|
||||||
|
|
||||||
|
|
||||||
class StackParametersTest(base.TestCase):
|
class StackParametersTest(base.TestCase):
|
||||||
@@ -475,6 +477,64 @@ class StackParametersTest(base.TestCase):
|
|||||||
result = stack_parameters.get_flattened_parameters(swift, mock_heat)
|
result = stack_parameters.get_flattened_parameters(swift, mock_heat)
|
||||||
self.assertEqual(result, expected_value)
|
self.assertEqual(result, expected_value)
|
||||||
|
|
||||||
|
def test_generate_hostmap(self):
|
||||||
|
|
||||||
|
# two instances in 'nova list'.
|
||||||
|
# vm1 with id=123 and vm2 with id=234
|
||||||
|
server1 = mock.MagicMock()
|
||||||
|
server1.id = 123
|
||||||
|
server1.name = 'vm1'
|
||||||
|
|
||||||
|
server2 = mock.MagicMock()
|
||||||
|
server2.id = 234
|
||||||
|
server2.name = 'vm2'
|
||||||
|
|
||||||
|
servers = mock.MagicMock()
|
||||||
|
servers = [server1, server2]
|
||||||
|
|
||||||
|
compute_client = mock.MagicMock()
|
||||||
|
compute_client.servers.list.side_effect = (servers, )
|
||||||
|
|
||||||
|
# we assume instance id=123 has been provisioned using bm node 'bm1'
|
||||||
|
# while instance id=234 is in error state, so no bm node has been used
|
||||||
|
|
||||||
|
def side_effect(args):
|
||||||
|
if args == 123:
|
||||||
|
return bm1
|
||||||
|
elif args == 234:
|
||||||
|
raise ironicexceptions.NotFound
|
||||||
|
|
||||||
|
baremetal_client = mock.MagicMock()
|
||||||
|
baremetal_client.node.get_by_instance_uuid = mock.MagicMock(
|
||||||
|
side_effect=side_effect)
|
||||||
|
|
||||||
|
# bm server with name='bm1' and uuid='9876'
|
||||||
|
bm1 = mock.MagicMock()
|
||||||
|
bm1.uuid = 9876
|
||||||
|
bm1.name = 'bm1'
|
||||||
|
|
||||||
|
# 'bm1' has a single port with mac='aa:bb:cc:dd:ee:ff'
|
||||||
|
port1 = mock.MagicMock()
|
||||||
|
port1.address = 'aa:bb:cc:dd:ee:ff'
|
||||||
|
|
||||||
|
def side_effect2(node, *args):
|
||||||
|
if node == 9876:
|
||||||
|
return [port1, ]
|
||||||
|
else:
|
||||||
|
raise ironicexceptions.NotFound
|
||||||
|
|
||||||
|
baremetal_client.port.list = mock.MagicMock(side_effect=side_effect2)
|
||||||
|
|
||||||
|
expected_hostmap = {
|
||||||
|
'aa:bb:cc:dd:ee:ff': {
|
||||||
|
'compute_name': 'vm1',
|
||||||
|
'baremetal_name': 'bm1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = nodes.generate_hostmap(baremetal_client, compute_client)
|
||||||
|
self.assertEqual(result, expected_hostmap)
|
||||||
|
|
||||||
@mock.patch('tripleo_common.utils.nodes.generate_hostmap')
|
@mock.patch('tripleo_common.utils.nodes.generate_hostmap')
|
||||||
def test_generate_fencing_parameters(self, mock_generate_hostmap):
|
def test_generate_fencing_parameters(self, mock_generate_hostmap):
|
||||||
test_hostmap = {
|
test_hostmap = {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import re
|
|||||||
from oslo_utils import netutils
|
from oslo_utils import netutils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from ironicclient import exceptions as ironicexceptions
|
||||||
from oslo_concurrency import processutils
|
from oslo_concurrency import processutils
|
||||||
from tripleo_common import exception
|
from tripleo_common import exception
|
||||||
from tripleo_common.utils import glance
|
from tripleo_common.utils import glance
|
||||||
@@ -708,10 +709,16 @@ def generate_hostmap(baremetal_client, compute_client):
|
|||||||
"""Create a map between Compute nodes and Baremetal nodes"""
|
"""Create a map between Compute nodes and Baremetal nodes"""
|
||||||
hostmap = {}
|
hostmap = {}
|
||||||
for node in compute_client.servers.list():
|
for node in compute_client.servers.list():
|
||||||
|
try:
|
||||||
bm_node = baremetal_client.node.get_by_instance_uuid(node.id)
|
bm_node = baremetal_client.node.get_by_instance_uuid(node.id)
|
||||||
for port in baremetal_client.port.list(node=bm_node.uuid):
|
for port in baremetal_client.port.list(node=bm_node.uuid):
|
||||||
hostmap[port.address] = {"compute_name": node.name,
|
hostmap[port.address] = {"compute_name": node.name,
|
||||||
"baremetal_name": bm_node.name}
|
"baremetal_name": bm_node.name}
|
||||||
|
except ironicexceptions.NotFound:
|
||||||
|
LOG.warning('Baremetal node for server %s not found - skipping it',
|
||||||
|
node.id)
|
||||||
|
pass
|
||||||
|
|
||||||
if hostmap == {}:
|
if hostmap == {}:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user