zone list now comes from scheduler zonemanager

This commit is contained in:
Sandy Walsh
2011-02-17 12:12:19 -08:00
parent ba6be95c6a
commit d15db67bdc
2 changed files with 16 additions and 77 deletions

View File

@@ -22,11 +22,6 @@ Scheduler Service
""" """
import functools import functools
import novatools
import thread
from datetime import datetime
from eventlet.greenpool import GreenPool
from nova import db from nova import db
from nova import flags from nova import flags
@@ -34,83 +29,14 @@ from nova import log as logging
from nova import manager from nova import manager
from nova import rpc from nova import rpc
from nova import utils from nova import utils
from nova.scheduler.zone_manager import ZoneManager
LOG = logging.getLogger('nova.scheduler.manager') LOG = logging.getLogger('nova.scheduler.manager')
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
flags.DEFINE_string('scheduler_driver', flags.DEFINE_string('scheduler_driver',
'nova.scheduler.chance.ChanceScheduler', 'nova.scheduler.chance.ChanceScheduler',
'Driver to use for the scheduler') 'Driver to use for the scheduler')
flags.DEFINE_integer('zone_db_check_interval',
60,
'Seconds between getting fresh zone info from db.')
class ZoneState(object):
"""Holds the state of all connected child zones."""
def __init__(self):
self.is_active = True
self.name = None
self.capabilities = None
self.retry = 0
self.last_seen = datetime.min
def update(self, zone):
"""Update zone credentials from db"""
self.zone_id = zone.id
self.api_url = zone.api_url
self.username = zone.username
self.password = zone.password
def _poll_zone(zone):
"""Eventlet worker to poll a zone."""
logging.debug("_POLL_ZONE: STARTING")
os = novatools.OpenStack(zone.username, zone.password, zone.api_url)
zone_metadata = os.zones.info()
logging.debug("_POLL_ZONE: GOT %s" % zone_metadata._info)
# Stuff this in our cache.
class ZoneManager(object):
"""Keeps the zone states updated."""
def __init__(self):
self.last_zone_db_check = datetime.min
self.zone_states = {}
def _refresh_from_db(self, context):
"""Make our zone state map match the db."""
# Add/update existing zones ...
zones = db.zone_get_all(context)
existing = self.zone_states.keys()
db_keys = []
for zone in zones:
db_keys.append(zone.id)
if zone.id not in existing:
self.zone_states[zone.id] = ZoneState()
self.zone_states[zone.id].update(zone)
# Cleanup zones removed from db ...
for zone_id in self.zone_states.keys():
if zone_id not in db_keys:
del self.zone_states[zone_id]
def _poll_zones(self, context):
"""Try to connect to each child zone and get update."""
green_pool = GreenPool()
green_pool.imap(_poll_zone, self.zone_states.values())
def ping(self, context=None):
"""Ping should be called periodically to update zone status."""
logging.debug("ZoneManager PING")
diff = datetime.now() - self.last_zone_db_check
if diff.seconds >= FLAGS.zone_db_check_interval:
logging.debug("ZoneManager RECHECKING DB ")
self.last_zone_db_check = datetime.now()
self._refresh_from_db(context)
self._poll_zones(context)
class SchedulerManager(manager.Manager): class SchedulerManager(manager.Manager):
"""Chooses a host to run instances on.""" """Chooses a host to run instances on."""
@@ -129,6 +55,10 @@ class SchedulerManager(manager.Manager):
"""Poll child zones periodically to get status.""" """Poll child zones periodically to get status."""
self.zone_manager.ping(context) self.zone_manager.ping(context)
def get_zone_list(self, context=None):
"""Get a list of zones from the ZoneManager."""
return self.zone_manager.get_zone_list()
def _schedule(self, method, context, topic, *args, **kwargs): def _schedule(self, method, context, topic, *args, **kwargs):
"""Tries to call schedule_* method on the driver to retrieve host. """Tries to call schedule_* method on the driver to retrieve host.

View File

@@ -21,6 +21,7 @@ ZoneManager oversees all communications with child Zones.
import novatools import novatools
import thread import thread
import traceback
from datetime import datetime from datetime import datetime
from eventlet.greenpool import GreenPool from eventlet.greenpool import GreenPool
@@ -63,6 +64,11 @@ class ZoneState(object):
self.capabilities = zone_metadata["capabilities"] self.capabilities = zone_metadata["capabilities"]
self.is_active = True self.is_active = True
def to_dict(self):
return dict(name=self.name, capabilities=self.capabilities,
is_active=self.is_active, api_url=self.api_url,
id=self.zone_id)
def log_error(self, exception): def log_error(self, exception):
"""Something went wrong. Check to see if zone should be """Something went wrong. Check to see if zone should be
marked as offline.""" marked as offline."""
@@ -91,7 +97,7 @@ def _poll_zone(zone):
try: try:
zone.update_metadata(_call_novatools(zone)) zone.update_metadata(_call_novatools(zone))
except Exception, e: except Exception, e:
zone.log_error(e) zone.log_error(traceback.format_exc())
class ZoneManager(object): class ZoneManager(object):
@@ -100,6 +106,9 @@ class ZoneManager(object):
self.last_zone_db_check = datetime.min self.last_zone_db_check = datetime.min
self.zone_states = {} self.zone_states = {}
def get_zone_list(self):
return [ zone.to_dict() for zone in self.zone_states.values() ]
def _refresh_from_db(self, context): def _refresh_from_db(self, context):
"""Make our zone state map match the db.""" """Make our zone state map match the db."""
# Add/update existing zones ... # Add/update existing zones ...