From c3b7f1b2ae7af995f4815e3571c9828683dc0db7 Mon Sep 17 00:00:00 2001 From: Fei Long Wang Date: Tue, 17 Feb 2015 00:58:45 +1300 Subject: [PATCH] Fix metering agent failure when chain missing The metering agent will fail if one of the iptables chains is missing, which will cause errors extracting data from all the other chains. Add a simple try/except to let the loop continue. Closes-Bug: #1421037 Change-Id: I370ee0e2cc58ca7e1c5ef9bf4dbcce5abf7545a1 --- .../drivers/iptables/iptables_driver.py | 17 ++++++++++++----- .../metering/drivers/test_iptables_driver.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/neutron/services/metering/drivers/iptables/iptables_driver.py b/neutron/services/metering/drivers/iptables/iptables_driver.py index 8bdec808c73..0e828f096f8 100644 --- a/neutron/services/metering/drivers/iptables/iptables_driver.py +++ b/neutron/services/metering/drivers/iptables/iptables_driver.py @@ -23,7 +23,7 @@ from neutron.agent.linux import iptables_manager from neutron.common import constants as constants from neutron.common import ipv6_utils from neutron.common import log -from neutron.i18n import _LI +from neutron.i18n import _LE, _LI from neutron.services.metering.drivers import abstract_driver @@ -266,11 +266,18 @@ class IptablesMeteringDriver(abstract_driver.MeteringAbstractDriver): continue for label_id, label in rm.metering_labels.items(): - chain = iptables_manager.get_chain_name(WRAP_NAME + LABEL + - label_id, wrap=False) + try: + chain = iptables_manager.get_chain_name(WRAP_NAME + + LABEL + + label_id, + wrap=False) - chain_acc = rm.iptables_manager.get_traffic_counters( - chain, wrap=False, zero=True) + chain_acc = rm.iptables_manager.get_traffic_counters( + chain, wrap=False, zero=True) + except RuntimeError: + LOG.exception(_LE('Failed to get traffic counters, ' + 'router: %s'), router) + continue if not chain_acc: continue diff --git a/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py b/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py index 292a7983963..45dd3202721 100644 --- a/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py +++ b/neutron/tests/unit/services/metering/drivers/test_iptables_driver.py @@ -360,3 +360,19 @@ class IptablesDriverTestCase(base.BaseTestCase): wrap=False)] self.v4filter_inst.assert_has_calls(calls) + + def test_get_traffic_counters_with_missing_chain(self): + for r in TEST_ROUTERS: + rm = iptables_driver.RouterWithMetering(self.metering.conf, r) + rm.metering_labels = {r['_metering_labels'][0]['id']: 'fake'} + self.metering.routers[r['id']] = rm + + mocked_method = self.iptables_cls.return_value.get_traffic_counters + mocked_method.side_effect = [{'pkts': 1, 'bytes': 8}, + RuntimeError('Failed to find the chain')] + + counters = self.metering.get_traffic_counters(None, TEST_ROUTERS) + expected_label_id = TEST_ROUTERS[0]['_metering_labels'][0]['id'] + self.assertIn(expected_label_id, counters) + self.assertEqual(1, counters[expected_label_id]['pkts']) + self.assertEqual(8, counters[expected_label_id]['bytes'])