summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Waldon <brian.waldon@rackspace.com>2011-07-11 14:41:29 -0400
committerBrian Waldon <brian.waldon@rackspace.com>2011-07-11 14:41:29 -0400
commit2aacfcbef233113ce25c52f1504bde9dd49f758e (patch)
tree96349a78a121d228f1a94e6dcc7fe957c90b6da5
parent02b0ca3e44626623c70d04ccaa50af8c75d640af (diff)
parent11be49aa59efc2d0d991d70546899b3625270af6 (diff)
downloadnova-2aacfcbef233113ce25c52f1504bde9dd49f758e.tar.gz
nova-2aacfcbef233113ce25c52f1504bde9dd49f758e.tar.xz
nova-2aacfcbef233113ce25c52f1504bde9dd49f758e.zip
merging trunk
-rw-r--r--Authors2
-rwxr-xr-xcontrib/nova.sh20
-rw-r--r--nova/api/openstack/contrib/multinic.py125
-rw-r--r--nova/scheduler/zone_manager.py32
-rw-r--r--nova/tests/api/openstack/contrib/test_multinic_xs.py117
-rw-r--r--nova/tests/test_zones.py175
-rwxr-xr-xtools/clean-vlans6
-rwxr-xr-xtools/nova-debug21
8 files changed, 480 insertions, 18 deletions
diff --git a/Authors b/Authors
index 1b3c90764..d2b1b627c 100644
--- a/Authors
+++ b/Authors
@@ -20,6 +20,7 @@ Dan Prince <dan.prince@rackspace.com>
Dave Walker <DaveWalker@ubuntu.com>
David Pravec <David.Pravec@danix.org>
Dean Troyer <dtroyer@gmail.com>
+Devendra Modium <dmodium@isi.edu>
Devin Carlen <devin.carlen@gmail.com>
Ed Leafe <ed@leafe.com>
Eldar Nugaev <reldan@oscloud.ru>
@@ -43,6 +44,7 @@ John Dewey <john@dewey.ws>
John Tran <jtran@attinteractive.com>
Jonathan Bryce <jbryce@jbryce.com>
Jordan Rinke <jordan@openstack.org>
+Joseph Suh <jsuh@isi.edu>
Josh Durgin <joshd@hq.newdream.net>
Josh Kearney <josh@jk0.org>
Josh Kleinpeter <josh@kleinpeter.org>
diff --git a/contrib/nova.sh b/contrib/nova.sh
index d7d34dcbd..eab680580 100755
--- a/contrib/nova.sh
+++ b/contrib/nova.sh
@@ -17,7 +17,7 @@ if [ ! -n "$HOST_IP" ]; then
HOST_IP=`LC_ALL=C ifconfig | grep -m 1 'inet addr:'| cut -d: -f2 | awk '{print $1}'`
fi
-USE_MYSQL=${USE_MYSQL:-0}
+USE_MYSQL=${USE_MYSQL:-1}
INTERFACE=${INTERFACE:-eth0}
FLOATING_RANGE=${FLOATING_RANGE:-10.6.0.0/27}
FIXED_RANGE=${FIXED_RANGE:-10.0.0.0/24}
@@ -159,10 +159,6 @@ NOVA_CONF_EOF
mkdir -p $NOVA_DIR/instances
rm -rf $NOVA_DIR/networks
mkdir -p $NOVA_DIR/networks
- if [ ! -d "$NOVA_DIR/images" ]; then
- ln -s $DIR/images $NOVA_DIR/images
- fi
-
if [ "$TEST" == 1 ]; then
cd $NOVA_DIR
python $NOVA_DIR/run_tests.py
@@ -181,8 +177,18 @@ NOVA_CONF_EOF
# create some floating ips
$NOVA_DIR/bin/nova-manage floating create `hostname` $FLOATING_RANGE
- # convert old images
- $NOVA_DIR/bin/nova-manage image convert $DIR/images
+ if [ ! -d "$NOVA_DIR/images" ]; then
+ if [ ! -d "$DIR/converted-images" ]; then
+ # convert old images
+ mkdir $DIR/converted-images
+ ln -s $DIR/converted-images $NOVA_DIR/images
+ $NOVA_DIR/bin/nova-manage image convert $DIR/images
+ else
+ ln -s $DIR/converted-images $NOVA_DIR/images
+ fi
+
+ fi
+
# nova api crashes if we start it with a regular screen command,
# so send the start command by forcing text into the window.
diff --git a/nova/api/openstack/contrib/multinic.py b/nova/api/openstack/contrib/multinic.py
new file mode 100644
index 000000000..841061721
--- /dev/null
+++ b/nova/api/openstack/contrib/multinic.py
@@ -0,0 +1,125 @@
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""The multinic extension."""
+
+from webob import exc
+
+from nova import compute
+from nova import log as logging
+from nova.api.openstack import extensions
+from nova.api.openstack import faults
+
+
+LOG = logging.getLogger("nova.api.multinic")
+
+
+# Note: The class name is as it has to be for this to be loaded as an
+# extension--only first character capitalized.
+class Multinic(extensions.ExtensionDescriptor):
+ """The multinic extension.
+
+ Exposes addFixedIp and removeFixedIp actions on servers.
+
+ """
+
+ def __init__(self, *args, **kwargs):
+ """Initialize the extension.
+
+ Gets a compute.API object so we can call the back-end
+ add_fixed_ip() and remove_fixed_ip() methods.
+ """
+
+ super(Multinic, self).__init__(*args, **kwargs)
+ self.compute_api = compute.API()
+
+ def get_name(self):
+ """Return the extension name, as required by contract."""
+
+ return "Multinic"
+
+ def get_alias(self):
+ """Return the extension alias, as required by contract."""
+
+ return "NMN"
+
+ def get_description(self):
+ """Return the extension description, as required by contract."""
+
+ return "Multiple network support"
+
+ def get_namespace(self):
+ """Return the namespace, as required by contract."""
+
+ return "http://docs.openstack.org/ext/multinic/api/v1.1"
+
+ def get_updated(self):
+ """Return the last updated timestamp, as required by contract."""
+
+ return "2011-06-09T00:00:00+00:00"
+
+ def get_actions(self):
+ """Return the actions the extension adds, as required by contract."""
+
+ actions = []
+
+ # Add the add_fixed_ip action
+ act = extensions.ActionExtension("servers", "addFixedIp",
+ self._add_fixed_ip)
+ actions.append(act)
+
+ # Add the remove_fixed_ip action
+ act = extensions.ActionExtension("servers", "removeFixedIp",
+ self._remove_fixed_ip)
+ actions.append(act)
+
+ return actions
+
+ def _add_fixed_ip(self, input_dict, req, id):
+ """Adds an IP on a given network to an instance."""
+
+ try:
+ # Validate the input entity
+ if 'networkId' not in input_dict['addFixedIp']:
+ LOG.exception(_("Missing 'networkId' argument for addFixedIp"))
+ return faults.Fault(exc.HTTPUnprocessableEntity())
+
+ # Add the fixed IP
+ network_id = input_dict['addFixedIp']['networkId']
+ self.compute_api.add_fixed_ip(req.environ['nova.context'], id,
+ network_id)
+ except Exception, e:
+ LOG.exception(_("Error in addFixedIp %s"), e)
+ return faults.Fault(exc.HTTPBadRequest())
+ return exc.HTTPAccepted()
+
+ def _remove_fixed_ip(self, input_dict, req, id):
+ """Removes an IP from an instance."""
+
+ try:
+ # Validate the input entity
+ if 'address' not in input_dict['removeFixedIp']:
+ LOG.exception(_("Missing 'address' argument for "
+ "removeFixedIp"))
+ return faults.Fault(exc.HTTPUnprocessableEntity())
+
+ # Remove the fixed IP
+ address = input_dict['removeFixedIp']['address']
+ self.compute_api.remove_fixed_ip(req.environ['nova.context'], id,
+ address)
+ except Exception, e:
+ LOG.exception(_("Error in removeFixedIp %s"), e)
+ return faults.Fault(exc.HTTPBadRequest())
+ return exc.HTTPAccepted()
diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py
index 6093443a9..efdac06e1 100644
--- a/nova/scheduler/zone_manager.py
+++ b/nova/scheduler/zone_manager.py
@@ -137,17 +137,30 @@ class ZoneManager(object):
# But it's likely to change once we understand what the Best-Match
# code will need better.
combined = {} # { <service>_<cap> : (min, max), ... }
+ stale_host_services = {} # { host1 : [svc1, svc2], host2 :[svc1]}
for host, host_dict in hosts_dict.iteritems():
for service_name, service_dict in host_dict.iteritems():
if not service_dict.get("enabled", True):
# Service is disabled; do no include it
continue
+
+ #Check if the service capabilities became stale
+ if self.host_service_caps_stale(host, service_name):
+ if host not in stale_host_services:
+ stale_host_services[host] = [] # Adding host key once
+ stale_host_services[host].append(service_name)
+ continue
for cap, value in service_dict.iteritems():
+ if cap == "timestamp": # Timestamp is not needed
+ continue
key = "%s_%s" % (service_name, cap)
min_value, max_value = combined.get(key, (value, value))
min_value = min(min_value, value)
max_value = max(max_value, value)
combined[key] = (min_value, max_value)
+
+ # Delete the expired host services
+ self.delete_expired_host_services(stale_host_services)
return combined
def _refresh_from_db(self, context):
@@ -186,5 +199,24 @@ class ZoneManager(object):
logging.debug(_("Received %(service_name)s service update from "
"%(host)s: %(capabilities)s") % locals())
service_caps = self.service_states.get(host, {})
+ capabilities["timestamp"] = utils.utcnow() # Reported time
service_caps[service_name] = capabilities
self.service_states[host] = service_caps
+
+ def host_service_caps_stale(self, host, service):
+ """Check if host service capabilites are not recent enough."""
+ allowed_time_diff = FLAGS.periodic_interval * 3
+ caps = self.service_states[host][service]
+ if (utils.utcnow() - caps["timestamp"]) <= \
+ datetime.timedelta(seconds=allowed_time_diff):
+ return False
+ return True
+
+ def delete_expired_host_services(self, host_services_dict):
+ """Delete all the inactive host services information."""
+ for host, services in host_services_dict.iteritems():
+ service_caps = self.service_states[host]
+ for service in services:
+ del service_caps[service]
+ if len(service_caps) == 0: # Delete host if no services
+ del self.service_states[host]
diff --git a/nova/tests/api/openstack/contrib/test_multinic_xs.py b/nova/tests/api/openstack/contrib/test_multinic_xs.py
new file mode 100644
index 000000000..484cd1c17
--- /dev/null
+++ b/nova/tests/api/openstack/contrib/test_multinic_xs.py
@@ -0,0 +1,117 @@
+# Copyright 2011 OpenStack LLC.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+import stubout
+import webob
+
+from nova import compute
+from nova import context
+from nova import test
+from nova.tests.api.openstack import fakes
+
+
+last_add_fixed_ip = (None, None)
+last_remove_fixed_ip = (None, None)
+
+
+def compute_api_add_fixed_ip(self, context, instance_id, network_id):
+ global last_add_fixed_ip
+
+ last_add_fixed_ip = (instance_id, network_id)
+
+
+def compute_api_remove_fixed_ip(self, context, instance_id, address):
+ global last_remove_fixed_ip
+
+ last_remove_fixed_ip = (instance_id, address)
+
+
+class FixedIpTest(test.TestCase):
+ def setUp(self):
+ super(FixedIpTest, self).setUp()
+ self.stubs = stubout.StubOutForTesting()
+ fakes.FakeAuthManager.reset_fake_data()
+ fakes.FakeAuthDatabase.data = {}
+ fakes.stub_out_networking(self.stubs)
+ fakes.stub_out_rate_limiting(self.stubs)
+ fakes.stub_out_auth(self.stubs)
+ self.stubs.Set(compute.api.API, "add_fixed_ip",
+ compute_api_add_fixed_ip)
+ # TODO(Vek): Fails until remove_fixed_ip() added
+ # self.stubs.Set(compute.api.API, "remove_fixed_ip",
+ # compute_api_remove_fixed_ip)
+ self.context = context.get_admin_context()
+
+ def tearDown(self):
+ self.stubs.UnsetAll()
+ super(FixedIpTest, self).tearDown()
+
+ def test_add_fixed_ip(self):
+ global last_add_fixed_ip
+ last_add_fixed_ip = (None, None)
+
+ body = dict(addFixedIp=dict(networkId='test_net'))
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers['content-type'] = 'application/json'
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 202)
+ self.assertEqual(last_add_fixed_ip, ('test_inst', 'test_net'))
+
+ def test_add_fixed_ip_no_network(self):
+ global last_add_fixed_ip
+ last_add_fixed_ip = (None, None)
+
+ body = dict(addFixedIp=dict())
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers['content-type'] = 'application/json'
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 422)
+ self.assertEqual(last_add_fixed_ip, (None, None))
+
+ def test_remove_fixed_ip(self):
+ global last_remove_fixed_ip
+ last_remove_fixed_ip = (None, None)
+
+ body = dict(removeFixedIp=dict(address='10.10.10.1'))
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers['content-type'] = 'application/json'
+
+ resp = req.get_response(fakes.wsgi_app())
+ # TODO(Vek): Fails until remove_fixed_ip() added
+ # self.assertEqual(resp.status_int, 202)
+ # self.assertEqual(last_remove_fixed_ip, ('test_inst', '10.10.10.1'))
+
+ def test_remove_fixed_ip_no_address(self):
+ global last_remove_fixed_ip
+ last_remove_fixed_ip = (None, None)
+
+ body = dict(removeFixedIp=dict())
+ req = webob.Request.blank('/v1.1/servers/test_inst/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers['content-type'] = 'application/json'
+
+ resp = req.get_response(fakes.wsgi_app())
+ self.assertEqual(resp.status_int, 422)
+ self.assertEqual(last_remove_fixed_ip, (None, None))
diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py
index e132809dc..a943fee27 100644
--- a/nova/tests/test_zones.py
+++ b/nova/tests/test_zones.py
@@ -198,3 +198,178 @@ class ZoneManagerTestCase(test.TestCase):
self.assertEquals(zone_state.attempt, 3)
self.assertFalse(zone_state.is_active)
self.assertEquals(zone_state.name, None)
+
+ def test_host_service_caps_stale_no_stale_service(self):
+ zm = zone_manager.ZoneManager()
+
+ # services just updated capabilities
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4))
+ self.assertFalse(zm.host_service_caps_stale("host1", "svc1"))
+ self.assertFalse(zm.host_service_caps_stale("host1", "svc2"))
+
+ def test_host_service_caps_stale_all_stale_services(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # Both services became stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4))
+ time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time)
+ utils.set_time_override(time_future)
+ self.assertTrue(zm.host_service_caps_stale("host1", "svc1"))
+ self.assertTrue(zm.host_service_caps_stale("host1", "svc2"))
+ utils.clear_time_override()
+
+ def test_host_service_caps_stale_one_stale_service(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # One service became stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4))
+ caps = zm.service_states["host1"]["svc1"]
+ caps["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ self.assertTrue(zm.host_service_caps_stale("host1", "svc1"))
+ self.assertFalse(zm.host_service_caps_stale("host1", "svc2"))
+
+ def test_delete_expired_host_services_del_one_service(self):
+ zm = zone_manager.ZoneManager()
+
+ # Delete one service in a host
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4))
+ stale_host_services = {"host1": ["svc1"]}
+ zm.delete_expired_host_services(stale_host_services)
+ self.assertFalse("svc1" in zm.service_states["host1"])
+ self.assertTrue("svc2" in zm.service_states["host1"])
+
+ def test_delete_expired_host_services_del_all_hosts(self):
+ zm = zone_manager.ZoneManager()
+
+ # Delete all services in a host
+ zm.update_service_capabilities("svc2", "host1", dict(a=3, b=4))
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ stale_host_services = {"host1": ["svc1", "svc2"]}
+ zm.delete_expired_host_services(stale_host_services)
+ self.assertFalse("host1" in zm.service_states)
+
+ def test_delete_expired_host_services_del_one_service_per_host(self):
+ zm = zone_manager.ZoneManager()
+
+ # Delete one service per host
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ stale_host_services = {"host1": ["svc1"], "host2": ["svc1"]}
+ zm.delete_expired_host_services(stale_host_services)
+ self.assertFalse("host1" in zm.service_states)
+ self.assertFalse("host2" in zm.service_states)
+
+ def test_get_zone_capabilities_one_host(self):
+ zm = zone_manager.ZoneManager()
+
+ # Service capabilities recent
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2)))
+
+ def test_get_zone_capabilities_expired_host(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # Service capabilities stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time)
+ utils.set_time_override(time_future)
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, {})
+ utils.clear_time_override()
+
+ def test_get_zone_capabilities_multiple_hosts(self):
+ zm = zone_manager.ZoneManager()
+
+ # Both host service capabilities recent
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4)))
+
+ def test_get_zone_capabilities_one_stale_host(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # One host service capabilities become stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ serv_caps = zm.service_states["host1"]["svc1"]
+ serv_caps["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(3, 3), svc1_b=(4, 4)))
+
+ def test_get_zone_capabilities_multiple_service_per_host(self):
+ zm = zone_manager.ZoneManager()
+
+ # Multiple services per host
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6))
+ zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8))
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(1, 3), svc1_b=(2, 4),
+ svc2_a=(5, 7), svc2_b=(6, 8)))
+
+ def test_get_zone_capabilities_one_stale_service_per_host(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # Two host services among four become stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6))
+ zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8))
+ serv_caps_1 = zm.service_states["host1"]["svc2"]
+ serv_caps_1["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ serv_caps_2 = zm.service_states["host2"]["svc1"]
+ serv_caps_2["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2),
+ svc2_a=(7, 7), svc2_b=(8, 8)))
+
+ def test_get_zone_capabilities_three_stale_host_services(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # Three host services among four become stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6))
+ zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8))
+ serv_caps_1 = zm.service_states["host1"]["svc2"]
+ serv_caps_1["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ serv_caps_2 = zm.service_states["host2"]["svc1"]
+ serv_caps_2["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ serv_caps_3 = zm.service_states["host2"]["svc2"]
+ serv_caps_3["timestamp"] = utils.utcnow() - \
+ datetime.timedelta(seconds=expiry_time)
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, dict(svc1_a=(1, 1), svc1_b=(2, 2)))
+
+ def test_get_zone_capabilities_all_stale_host_services(self):
+ zm = zone_manager.ZoneManager()
+ expiry_time = (FLAGS.periodic_interval * 3) + 1
+
+ # All the host services become stale
+ zm.update_service_capabilities("svc1", "host1", dict(a=1, b=2))
+ zm.update_service_capabilities("svc1", "host2", dict(a=3, b=4))
+ zm.update_service_capabilities("svc2", "host1", dict(a=5, b=6))
+ zm.update_service_capabilities("svc2", "host2", dict(a=7, b=8))
+ time_future = utils.utcnow() + datetime.timedelta(seconds=expiry_time)
+ utils.set_time_override(time_future)
+ caps = zm.get_zone_capabilities(None)
+ self.assertEquals(caps, {})
diff --git a/tools/clean-vlans b/tools/clean-vlans
index 820a9dbe5..a26ad86ad 100755
--- a/tools/clean-vlans
+++ b/tools/clean-vlans
@@ -17,9 +17,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-export LC_ALL=C
+export LC_ALL=C
sudo ifconfig -a | grep br | grep -v bridge | cut -f1 -d" " | xargs -n1 -ifoo ifconfig foo down
sudo ifconfig -a | grep br | grep -v bridge | cut -f1 -d" " | xargs -n1 -ifoo brctl delbr foo
-sudo ifconfig -a | grep vlan | grep -v vlan124 | grep -v vlan5 | cut -f1 -d" " | xargs -n1 -ifoo ifconfig foo down
-sudo ifconfig -a | grep vlan | grep -v vlan124 | grep -v vlan5 | cut -f1 -d" " | xargs -n1 -ifoo vconfig rem foo
+sudo ifconfig -a | grep vlan | cut -f1 -d" " | xargs -n1 -ifoo ifconfig foo down
+sudo ifconfig -a | grep vlan | cut -f1 -d" " | xargs -n1 -ifoo vconfig rem foo
diff --git a/tools/nova-debug b/tools/nova-debug
index 3ff68ca35..0a78af16a 100755
--- a/tools/nova-debug
+++ b/tools/nova-debug
@@ -30,13 +30,15 @@ cd $INSTANCES_PATH/$1
if [ $CMD != "umount" ] && [ $CMD != "launch" ]; then
# destroy the instance
virsh destroy $1
+virsh undefine $1
# mount the filesystem
mkdir t
-DEVICE=`losetup --show -f disk`
+DEVICE=/dev/nbd0
echo $DEVICE
-kpartx -a $DEVICE
-mount /dev/mapper/${DEVICE:4}p1 t
+qemu-nbd -c $DEVICE disk
+sleep 3
+mount $DEVICE t
fi
if [ $CMD != "mount" ] && [ $CMD != "umount" ]; then
@@ -66,11 +68,13 @@ sed -i "s/<serial type=\"file\">.*<\/serial>/<serial type=\"pty\"><source path=\
umount t
-virsh create debug.xml
+virsh define debug.xml
+virsh start $1
virsh console $1
virsh destroy $1
+virsh undefine $1
-mount /dev/mapper/${DEVICE:4}p1 t
+mount $DEVICE t
# clear debug root password
chroot t passwd -l root
@@ -83,10 +87,11 @@ if [ $CMD != "mount" ] && [ $CMD != "launch" ]; then
# unmount the filesystem
umount t
-kpartx -d $DEVICE
-losetup -d $DEVICE
+qemu-nbd -d $DEVICE
rmdir t
# recreate the instance
-virsh create libvirt.xml
+virsh define libvirt.xml
+virsh start $1
fi
+