class NodeConfigurator(CompositeNode): def __init__(self, *args, **kw): self.nodes = None super(NodeConfigurator, self).__init__(*args, **kw) def start(self): if self.nodes is None: dictname = "%s (%s)" % (type(self).__name__, self.name) self.nodes = PersistentDictionary(dictname) nodeurls = self.nodes.keys() nodeurls.sort(pathcompare) for nodeurl in nodeurls: nodedata = self.nodes[nodeurl] factory,configuration = nodedata self.create_node(factory, nodeurl, **configuration) super(NodeConfigurator, self).start() def get_managed_node(self, nodeurl): if not self.nodes.has_key(nodeurl): raise TypeError("cannot manipulate unmanaged node: %s" % nodeurl) return as_node(nodeurl) def node_children(self, nodeurl): node = self.get_managed_node(nodeurl) return node.children_names() def node_configuration(self, nodeurl): node = self.get_managed_node(nodeurl) return node.configuration() def start_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.start() def stop_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.stop() def node_attr(self, nodeurl, name, value=Undefined): node = self.get_managed_node(nodeurl) if value is not Undefined: setattr(node, name, value) self.updatepdo(nodeurl, node) return getattr(node, name) def configure_node(self, nodeurl, config): node = self.get_managed_node(nodeurl) node.stop() try: node.configure(config) except: msglog.log("broadway", msglog.types.WARN, "Error prevented reconfiguration of node: %s" % node) msglog.exception(prefix="handled") msglog.log("broadway", msglog.types.WARN, "Rolling back configuration.") try: node.configure(self.nodes[nodeurl]) except: msglog.log("broadway", msglog.types.WARN, "Configuration rollback failed.") msglog.exception(prefix="handled") else: msglog.log("broadway", msglog.types.INFO, "Rollback of configuration succeeded.") else: msglog.log("broadway", msglog.types.INFO, "Node reconfigured: %s" % node) self.updatepdo(nodeurl, node) finally: node.start() return node.configuration() def create_node(self, factory, nodeurl, **config): try: as_node(nodeurl) except KeyError: pass else: raise TypeError("Node exists: %s" % nodeurl) if isinstance(factory, str): module,sep,name = factory.rpartition(".") if name: exec("import %s" % module) factory = eval(factory) parent,sep,name = nodeurl.rpartition("/") configuration = {"name": name, "parent": parent} configuration.update(config) node = factory() try: node.configure(configuration) except: msglog.log("broadway", msglog.types.WARN, "Error prevented configuration of new node: %s" % node) msglog.exception(prefix="handled") try: node.prune() except: msglog.exception(prefix="handled") else: msglog.log("broadway", msglog.types.INFO, "Node successfully pruned.") else: msglog.log("broadway", msglog.types.INFO, "New node created: %s" % node) self.updatepdo(nodeurl, node) node.start() return node.configuration() def remove_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.prune() self.updatepdo(nodeurl, None) def updatepdo(self, nodeurl, node): if self.nodes.has_key(nodeurl): self.nodes.pop(nodeurl) if node: node = as_node(node) nodeurl = as_node_url(node) datatype = type(node) factory = "%s.%s" % (datatype.__module__, datatype.__name__) data = (factory, node.configuration()) self.nodes[nodeurl] = (factory, node.configuration()) return nodeurl
class PersistanceManager(object): def __init__(self): # {nodepath:{'node_config':node_config, # 'group_config':group_config, # 'entity_map':entity_map}} self._persisted_data = PersistentDictionary('GSPData') self.debug = 1 self._persist_enabled = False def message(self, message, mtype=msglog.types.INFO, level=1): if self.debug >= level: msglog.log('Global Setpoint Manager', mtype, message) def persist_enabled(self): return self._persist_enabled def enable_persist(self): self._persist_enabled = True def disable_persist(self): self._persist_enabled = False def get_gsp_groups(self): groups = self._persisted_data.keys() groups.sort(lambda a,b: cmp(a.count('/'), b.count('/'))) return groups def get_gsp_group(self, nodepath): return self._persisted_data[normalize_nodepath(nodepath)] def put_gsp_group(self, nodepath, nodedata): if not self.persist_enabled(): return nodepath = normalize_nodepath(nodepath) if not self._persisted_data.has_key(nodepath): # create default configuration. data = {'node_config':{}, 'group_config':[], 'entity_map':{}, 'node_factory':''} self._persisted_data[nodepath] = data self.put_gsp_group_data(nodepath, nodedata) def remove_gsp_group(self, nodepath): nodepath = normalize_nodepath(nodepath) if self._persisted_data.has_key(nodepath): del self._persisted_data[nodepath] def get_gsp_group_data(self, nodepath): nodepath = normalize_nodepath(nodepath) return self._persisted_data[nodepath] def put_gsp_group_data(self, nodepath, nodedata): nodepath = normalize_nodepath(nodepath) for data_key in self._persisted_data[nodepath].keys(): value = nodedata.get(data_key) if value is not None: self._put_entry(nodepath, data_key, value) def get_gsp_group_nconfig(self, nodepath): # node configuration data return self._get_entry(nodepath, 'node_config') def put_gsp_group_nconfig(self, nodepath, value): # node configuration data self._put_entry(nodepath, 'node_config', value) def get_gsp_group_gconfig(self, nodepath): # gsp group configuration data return self._get_entry(nodepath, 'group_config') def putt_gsp_group_gconfig(self, nodepath, value): # gsp group configuration data self._put_entry(nodepath, 'group_config', value) def get_gsp_group_entity_map(self, nodepath): return self._get_entry(nodepath, 'entity_map') def put_gsp_group_entity_map(self, nodepath, value): self._put_entry(nodepath, 'entity_map', value) def _get_entry(self, nodepath, data_type): return self.get_gsp_group(normalize_nodepath(nodepath))[data_type] def _put_entry(self, nodepath, data_type, value): if not self.persist_enabled(): return nodepath = normalize_nodepath(nodepath) group = self.get_gsp_group(nodepath) assert group, \ 'A group must exist before data can be stored against it.' group[data_type] = value self._persisted_data.notify_changed(nodepath) def singleton_unload_hook(self): pass
class PersistanceManager(object): def __init__(self): # {nodepath:{'cfg':cfg, # 'summary':summary, # 'meta':meta, # 'properties':properties, # 'fail_list':fail_list, # 'sync_state':sync_in_progress, # 'override':override}} self._persisted_data = PersistentDictionary('ScheduleData') self.debug = 1 def message(self, message, mtype=msglog.types.INFO, level=1): if self.debug >= level: msglog.log('Scheduler', mtype, message) def get_scheds(self): scheds = self._persisted_data.keys() scheds.sort(sched_sort) return scheds def get_sched(self, nodepath): return self._persisted_data[normalize_nodepath(nodepath)] def put_sched(self, nodepath, cfg): nodepath = normalize_nodepath(nodepath) if not self._persisted_data.has_key(nodepath): # create default configuration. pdata = {'cfg':{}, 'summary':[[], [], [], 'exceptions'], 'meta':{}, 'properties':[], 'fail_list':[], 'sync_state':False, 'override':False} self._persisted_data[nodepath] = pdata self.put_sched_cfg(nodepath, cfg) def remove_sched(self, nodepath): nodepath = normalize_nodepath(nodepath) if self._persisted_data.has_key(nodepath): for sched in self.get_scheds(): if sched.startswith(nodepath): del self._persisted_data[sched] else: msg = 'Error removing non-existent schedule %s from persistent data.' \ % nodepath self.message(msg) def move_sched(self, source, destination, cfg, is_rename=False): source = normalize_nodepath(source) destination = normalize_nodepath(destination) for sched in self.get_scheds(): if not sched.startswith(source): continue data = self._persisted_data[sched] del self._persisted_data[sched] if sched == source: # rename if is_rename: newsched = destination else: newsched = sched.replace(source, destination) + source.split('/')[-2] + '/' oldroot = sched newroot = newsched self._persisted_data[newsched] = data # prior to persisting, the schedule should have been moved # within the nodetree. We grab and persist the latest configuration. # This put call will also ensure sync to disk to takes place. self.put_sched_cfg(newsched, cfg) else: newsched = normalize_nodepath(sched.replace(oldroot, newroot)) #+ sched_name + '/' self._persisted_data[newsched] = data self.put_sched_cfg(newsched, serialize_node(as_node(newsched))) def get_sched_cfg(self, nodepath): return self._get_entry('cfg', nodepath) def put_sched_cfg(self, nodepath, cfg): self._put_entry('cfg', nodepath, cfg) def get_sched_summary(self, nodepath): return self._get_entry('summary', nodepath) def put_sched_summary(self, nodepath, summary): self._put_entry('summary', nodepath, summary) def get_sched_props(self, nodepath): return self._get_entry('properties', nodepath) def put_sched_props(self, nodepath, properties): self._put_entry('properties', nodepath, properties) def get_sched_meta(self, nodepath): return self._get_entry('meta', nodepath) def put_sched_meta(self, nodepath, meta): self._put_entry('meta', nodepath, meta) def get_fail_list(self, nodepath): return self._get_entry('fail_list', nodepath) def put_fail_list(self, nodepath, fail_list): self._put_entry('fail_list', nodepath, fail_list) def get_sync_state(self, nodepath): return self._get_entry('sync_state', nodepath) def put_sync_state(self, nodepath, sync_state): self._put_entry('sync_state', nodepath, sync_state) def get_override(self, nodepath): return self._get_entry('override', nodepath) def put_override(self, nodepath, override): self._put_entry('override', nodepath, override) def _get_entry(self, ptype, nodepath): return self.get_sched(normalize_nodepath(nodepath))[ptype] def _put_entry(self, ptype, nodepath, value): nodepath = normalize_nodepath(nodepath) sched = self.get_sched(nodepath) assert sched, \ 'A schedule must exist before data can be stored against it.' sched[ptype] = value self._persisted_data.notify_changed(nodepath) def singleton_unload_hook(self): pass
class PersistanceManager(object): def __init__(self): # {nodepath:{'cfg':cfg, # 'summary':summary, # 'meta':meta, # 'properties':properties, # 'fail_list':fail_list, # 'sync_state':sync_in_progress, # 'override':override}} self._persisted_data = PersistentDictionary('ScheduleData') self.debug = 1 def message(self, message, mtype=msglog.types.INFO, level=1): if self.debug >= level: msglog.log('Scheduler', mtype, message) def get_scheds(self): scheds = self._persisted_data.keys() scheds.sort(sched_sort) return scheds def get_sched(self, nodepath): return self._persisted_data[normalize_nodepath(nodepath)] def put_sched(self, nodepath, cfg): nodepath = normalize_nodepath(nodepath) if not self._persisted_data.has_key(nodepath): # create default configuration. pdata = { 'cfg': {}, 'summary': [[], [], [], 'exceptions'], 'meta': {}, 'properties': [], 'fail_list': [], 'sync_state': False, 'override': False } self._persisted_data[nodepath] = pdata self.put_sched_cfg(nodepath, cfg) def remove_sched(self, nodepath): nodepath = normalize_nodepath(nodepath) if self._persisted_data.has_key(nodepath): for sched in self.get_scheds(): if sched.startswith(nodepath): del self._persisted_data[sched] else: msg = 'Error removing non-existent schedule %s from persistent data.' \ % nodepath self.message(msg) def move_sched(self, source, destination, cfg, is_rename=False): source = normalize_nodepath(source) destination = normalize_nodepath(destination) for sched in self.get_scheds(): if not sched.startswith(source): continue data = self._persisted_data[sched] del self._persisted_data[sched] if sched == source: # rename if is_rename: newsched = destination else: newsched = sched.replace( source, destination) + source.split('/')[-2] + '/' oldroot = sched newroot = newsched self._persisted_data[newsched] = data # prior to persisting, the schedule should have been moved # within the nodetree. We grab and persist the latest configuration. # This put call will also ensure sync to disk to takes place. self.put_sched_cfg(newsched, cfg) else: newsched = normalize_nodepath(sched.replace( oldroot, newroot)) #+ sched_name + '/' self._persisted_data[newsched] = data self.put_sched_cfg(newsched, serialize_node(as_node(newsched))) def get_sched_cfg(self, nodepath): return self._get_entry('cfg', nodepath) def put_sched_cfg(self, nodepath, cfg): self._put_entry('cfg', nodepath, cfg) def get_sched_summary(self, nodepath): return self._get_entry('summary', nodepath) def put_sched_summary(self, nodepath, summary): self._put_entry('summary', nodepath, summary) def get_sched_props(self, nodepath): return self._get_entry('properties', nodepath) def put_sched_props(self, nodepath, properties): self._put_entry('properties', nodepath, properties) def get_sched_meta(self, nodepath): return self._get_entry('meta', nodepath) def put_sched_meta(self, nodepath, meta): self._put_entry('meta', nodepath, meta) def get_fail_list(self, nodepath): return self._get_entry('fail_list', nodepath) def put_fail_list(self, nodepath, fail_list): self._put_entry('fail_list', nodepath, fail_list) def get_sync_state(self, nodepath): return self._get_entry('sync_state', nodepath) def put_sync_state(self, nodepath, sync_state): self._put_entry('sync_state', nodepath, sync_state) def get_override(self, nodepath): return self._get_entry('override', nodepath) def put_override(self, nodepath, override): self._put_entry('override', nodepath, override) def _get_entry(self, ptype, nodepath): return self.get_sched(normalize_nodepath(nodepath))[ptype] def _put_entry(self, ptype, nodepath, value): nodepath = normalize_nodepath(nodepath) sched = self.get_sched(nodepath) assert sched, \ 'A schedule must exist before data can be stored against it.' sched[ptype] = value self._persisted_data.notify_changed(nodepath) def singleton_unload_hook(self): pass
class PersistanceManager(object): def __init__(self): # {nodepath:{'node_config':node_config, # 'group_config':group_config, # 'entity_map':entity_map}} self._persisted_data = PersistentDictionary('GSPData') self.debug = 1 self._persist_enabled = False def message(self, message, mtype=msglog.types.INFO, level=1): if self.debug >= level: msglog.log('Global Setpoint Manager', mtype, message) def persist_enabled(self): return self._persist_enabled def enable_persist(self): self._persist_enabled = True def disable_persist(self): self._persist_enabled = False def get_gsp_groups(self): groups = self._persisted_data.keys() groups.sort(lambda a, b: cmp(a.count('/'), b.count('/'))) return groups def get_gsp_group(self, nodepath): return self._persisted_data[normalize_nodepath(nodepath)] def put_gsp_group(self, nodepath, nodedata): if not self.persist_enabled(): return nodepath = normalize_nodepath(nodepath) if not self._persisted_data.has_key(nodepath): # create default configuration. data = { 'node_config': {}, 'group_config': [], 'entity_map': {}, 'node_factory': '' } self._persisted_data[nodepath] = data self.put_gsp_group_data(nodepath, nodedata) def remove_gsp_group(self, nodepath): nodepath = normalize_nodepath(nodepath) if self._persisted_data.has_key(nodepath): del self._persisted_data[nodepath] def get_gsp_group_data(self, nodepath): nodepath = normalize_nodepath(nodepath) return self._persisted_data[nodepath] def put_gsp_group_data(self, nodepath, nodedata): nodepath = normalize_nodepath(nodepath) for data_key in self._persisted_data[nodepath].keys(): value = nodedata.get(data_key) if value is not None: self._put_entry(nodepath, data_key, value) def get_gsp_group_nconfig(self, nodepath): # node configuration data return self._get_entry(nodepath, 'node_config') def put_gsp_group_nconfig(self, nodepath, value): # node configuration data self._put_entry(nodepath, 'node_config', value) def get_gsp_group_gconfig(self, nodepath): # gsp group configuration data return self._get_entry(nodepath, 'group_config') def putt_gsp_group_gconfig(self, nodepath, value): # gsp group configuration data self._put_entry(nodepath, 'group_config', value) def get_gsp_group_entity_map(self, nodepath): return self._get_entry(nodepath, 'entity_map') def put_gsp_group_entity_map(self, nodepath, value): self._put_entry(nodepath, 'entity_map', value) def _get_entry(self, nodepath, data_type): return self.get_gsp_group(normalize_nodepath(nodepath))[data_type] def _put_entry(self, nodepath, data_type, value): if not self.persist_enabled(): return nodepath = normalize_nodepath(nodepath) group = self.get_gsp_group(nodepath) assert group, \ 'A group must exist before data can be stored against it.' group[data_type] = value self._persisted_data.notify_changed(nodepath) def singleton_unload_hook(self): pass
class NodeConfigurator(CompositeNode): def __init__(self, *args, **kw): self.nodes = None super(NodeConfigurator, self).__init__(*args, **kw) def start(self): if self.nodes is None: dictname = "%s (%s)" % (type(self).__name__, self.name) self.nodes = PersistentDictionary(dictname) nodeurls = self.nodes.keys() nodeurls.sort(pathcompare) for nodeurl in nodeurls: nodedata = self.nodes[nodeurl] factory, configuration = nodedata self.create_node(factory, nodeurl, **configuration) super(NodeConfigurator, self).start() def get_managed_node(self, nodeurl): if not self.nodes.has_key(nodeurl): raise TypeError("cannot manipulate unmanaged node: %s" % nodeurl) return as_node(nodeurl) def node_children(self, nodeurl): node = self.get_managed_node(nodeurl) return node.children_names() def node_configuration(self, nodeurl): node = self.get_managed_node(nodeurl) return node.configuration() def start_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.start() def stop_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.stop() def node_attr(self, nodeurl, name, value=Undefined): node = self.get_managed_node(nodeurl) if value is not Undefined: setattr(node, name, value) self.updatepdo(nodeurl, node) return getattr(node, name) def configure_node(self, nodeurl, config): node = self.get_managed_node(nodeurl) node.stop() try: node.configure(config) except: msglog.log("broadway", msglog.types.WARN, "Error prevented reconfiguration of node: %s" % node) msglog.exception(prefix="handled") msglog.log("broadway", msglog.types.WARN, "Rolling back configuration.") try: node.configure(self.nodes[nodeurl]) except: msglog.log("broadway", msglog.types.WARN, "Configuration rollback failed.") msglog.exception(prefix="handled") else: msglog.log("broadway", msglog.types.INFO, "Rollback of configuration succeeded.") else: msglog.log("broadway", msglog.types.INFO, "Node reconfigured: %s" % node) self.updatepdo(nodeurl, node) finally: node.start() return node.configuration() def create_node(self, factory, nodeurl, **config): try: as_node(nodeurl) except KeyError: pass else: raise TypeError("Node exists: %s" % nodeurl) if isinstance(factory, str): module, sep, name = factory.rpartition(".") if name: exec("import %s" % module) factory = eval(factory) parent, sep, name = nodeurl.rpartition("/") configuration = {"name": name, "parent": parent} configuration.update(config) node = factory() try: node.configure(configuration) except: msglog.log("broadway", msglog.types.WARN, "Error prevented configuration of new node: %s" % node) msglog.exception(prefix="handled") try: node.prune() except: msglog.exception(prefix="handled") else: msglog.log("broadway", msglog.types.INFO, "Node successfully pruned.") else: msglog.log("broadway", msglog.types.INFO, "New node created: %s" % node) self.updatepdo(nodeurl, node) node.start() return node.configuration() def remove_node(self, nodeurl): node = self.get_managed_node(nodeurl) node.prune() self.updatepdo(nodeurl, None) def updatepdo(self, nodeurl, node): if self.nodes.has_key(nodeurl): self.nodes.pop(nodeurl) if node: node = as_node(node) nodeurl = as_node_url(node) datatype = type(node) factory = "%s.%s" % (datatype.__module__, datatype.__name__) data = (factory, node.configuration()) self.nodes[nodeurl] = (factory, node.configuration()) return nodeurl