def write(self, text): # Generate a name for the temp file tmpname = os.path.join( properties.TEMP_DIR, '__TMP__XML__' ) \ + str( randrange( 0, 999999999, 1) ) # Validate the XML by copying it to a temporary file and checking it # with parse_xml.. tmpfile = open(tmpname, 'w+') invalid_xml = 1 try: tmpfile.write(text) tmpfile.flush() parse_xml(tmpname) invalid_xml = 0 finally: # Try really hard to discard the temporary file. try: tmpfile.close() except: msglog.exception() try: os.unlink(tmpname) except: msglog.exception() if invalid_xml: raise EInvalidXML # If we get here, at 'looks' like a valid configuration. # OK, here comes the scary bit. # Try to save old configuration. old_config_name = None config_file_full = properties.CONFIGURATION_FILE paths = config_file_full.split('/') config_file = paths[-1] config_path = config_file_full[0:-len(config_file)] if os.path.exists(config_path): if os.path.exists(config_file_full): old_config_name = os.path.join(config_path, 'broadway_old.xml') os.rename(config_file_full, old_config_name) else: # The config path does not exist, try to create it. os.makedirs(config_path) all_ok = 0 try: newfile = open(config_file_full, 'w+') newfile.write(text) newfile.close() all_ok = 1 finally: # I use a finally block so a meaningful exception is raised. if not all_ok and old_config_name: os.rename(old_config_name, config_file_full)
def write(self, text): # Generate a name for the temp file tmpname = os.path.join( properties.TEMP_DIR, '__TMP__XML__' ) \ + str( randrange( 0, 999999999, 1) ) # Validate the XML by copying it to a temporary file and checking it # with parse_xml.. tmpfile = open(tmpname,'w+') invalid_xml = 1 try: tmpfile.write(text) tmpfile.flush() parse_xml(tmpname) invalid_xml = 0 finally: # Try really hard to discard the temporary file. try: tmpfile.close() except: msglog.exception() try: os.unlink(tmpname) except: msglog.exception() if invalid_xml: raise EInvalidXML # If we get here, at 'looks' like a valid configuration. # OK, here comes the scary bit. # Try to save old configuration. old_config_name = None config_file_full = properties.CONFIGURATION_FILE paths = config_file_full.split('/') config_file = paths[-1] config_path = config_file_full[0:-len(config_file)] if os.path.exists(config_path): if os.path.exists(config_file_full): old_config_name = os.path.join(config_path, 'broadway_old.xml') os.rename(config_file_full, old_config_name) else: # The config path does not exist, try to create it. os.makedirs(config_path) all_ok = 0 try: newfile = open(config_file_full, 'w+') newfile.write(text) newfile.close() all_ok = 1 finally: # I use a finally block so a meaningful exception is raised. if not all_ok and old_config_name: os.rename(old_config_name, config_file_full)
def load_xml(parent, path): legal_controlling_authority = parent.as_node_url() msglog.log(legal_controlling_authority, msglog.types.INFO, 'Stage 1: Parsing configuration file: %s' % (path, )) root = parse_xml( path ) #this would be a replacement rznet_peer node but we will throw it away return load_root(root, parent)
def loads(self, data): datastream = StringIO.StringIO(data) xmlroot = parse_xml(datastream) xmlroot.parent = self.node.url crawler = Iterator(xmlroot) nodecount = 0 while crawler.has_more(): xmlnode = crawler.get_next_node() config = xmlnode.get_config() print 'Loading node %d: %s' % (nodecount, config) node = load_node(config) node.configure(config) nodecount += 1 return nodecount
def _configure_file(filename, faillist): msglog.log('broadway',msglog.types.INFO, 'Stage 1: Parsing configuration file.') root = parse_xml(filename) # configure the root node. msglog.log('broadway',msglog.types.INFO, 'Stage 2: Configuring the root node.') node = mpx.lib.node.from_path(root.get_url()) node.configure(root.get_config()) anchors = [] # Sort the namespace anchors according to their priority. for a in root.children: anchors.append(a) anchors.sort(_priority_sort) msglog.log('broadway',msglog.types.INFO, 'Stage 3: Configuring anchors.') n = 0 for a in anchors: n += 1 msglog.log('broadway',msglog.types.INFO, "Stage 3.%d: Configuring %r." % (n, a.get_url())) ai = Iterator(a) # The while, try, while construct minimizes constructing try/except # blocks which is an expensive operation. while ai is not None and ai.has_more(): config = a state = 'none' try: while ai.has_more(): previous_config = config state = 'lookup' config = ai.get_next_node() state = 'decode' cd = config.get_config() cd['name'] = cd['name'].strip() state = 'load' node = _load(cd) state = 'configure' node.configure(cd) state = 'next' except Exception, e: # @fixme Add children, partial configure (name and parent). msg = '' if state == 'lookup': msg = '%s%r%s' % ( 'Internal failure fetching the node after ', previous_config.get_url(), ' in the configuration. Aborting configuration.') # We're toast, give up. ai = None elif state == 'decode': msg = ( 'Internal failure decoding %r\'s configuration data.' % config.get_url() ) elif state == 'load': msg = 'Failed to create node described by %r' % cd faillist.append({'name':cd['name'],'parent':cd['parent'], 'type':'load'}) elif state == 'configure': msg = 'Failed to configure node %r with %r' % ( (config.get_url(), cd)) faillist.append({'name':cd['name'],'parent':cd['parent'], 'type':'config'}) else: msg = 'Internal failure in %r state' % state msglog.log('broadway', msglog.types.ERR, msg) msglog.exception(msglog.types.ERR) if ai is not None: ai.remove_children() msglog.log('broadway', msglog.types.WARN, 'Unable to create/configure node %s, %s' % (config.get_url(), 'skipping children'))
def load_xml(parent, path): legal_controlling_authority = parent.as_node_url() msglog.log(legal_controlling_authority,msglog.types.INFO, 'Stage 1: Parsing configuration file: %s' % (path,)) root = parse_xml(path) #this would be a replacement rznet_peer node but we will throw it away return load_root(root, parent)
def check_and_load_application_files(self, starting=0): app_reloaded = starting #return value to signal that the children need to be started save_pdo = 0 #flag to control saving config data to pdo files = os.listdir( config_path) #/var/mpx/config/services/control (usually) xml_filenames = [] for f in files: if f.find('.xml') > 0 and len(f) == ( f.find('.xml') + 4 ): #any xml file in this folder is assumed to be a control app xml_filenames.append(f) modify_time = os.stat(config_path + f)[8] stale_pdo = True no_stats_pdo = True if f in self._pdo.stats_dict: #check for change since last time no_stats_pdo = False if self._pdo.stats_dict[f][0] == modify_time: stale_pdo = False #old news, no change detected #self.stats_dict[f]=modify_time if starting or no_stats_pdo or ( stale_pdo and ALLOW_APP_RELOAD): #need to (re)load application if app_reloaded == 0: #only stop all application nodes for the first detected change try: self._status = 'Stopping %s' % (f, ) msglog.log( self.as_node_url(), msglog.types.INFO, 'Stage 0: Stop Application templates.') for c in self.children_nodes(): if hasattr(c, '_stop_running_app'): c._stop_running_app() except: msglog.exception() app_reloaded = 1 #no need to "stop" for any other app changes self._status = 'Loading %s' % (f, ) try: root = None if not stale_pdo: #so no change was detected, we are starting up the framework try: #to get the pickled config data rather than load the xml again msglog.log( self.as_node_url(), msglog.types.INFO, 'Stage 1: XML unchanged. Loading configuration data from PDO: %s' % (f, )) root = cPickle.loads( self._pdo.stats_dict[f][1]) except: msglog.exception() msglog.log( self.as_node_url(), msglog.types.WARN, 'Stage 1: Unable to reload config data. Next, try XML file.' ) if root is None: msglog.log( self.as_node_url(), msglog.types.INFO, 'Stage 1: Parsing configuration xml file: %s' % (f, )) root = parse_xml(config_path + f) self._pdo.stats_dict[f] = (modify_time, cPickle.dumps(root)) save_pdo = 1 if f in self._stale_apps: self._stale_apps.remove(f) #now we have the root configuration. Turn it into configured nodes module = root.get_config().get('module', None) if module == 'mpx.ion.rz.rzhost_node.RzhostNode': load_rz_root(root, self) elif module == 'mpx.service.control.graphical.ApplicationNode': load_tim_root(root, self) else: raise EInvalidValue() except Exception, e: msglog.exception() pass elif stale_pdo: if not f in self._stale_apps: msglog.log( self.as_node_url(), msglog.types.INFO, 'Application %s has been modified, please restart the framework.' % (f, )) self._stale_apps.append(f) try: self.get_child(f.split('.')[0]).set_stale_flag() except: msglog.exception()
def check_and_load_application_files(self, starting=0): app_reloaded = starting #return value to signal that the children need to be started save_pdo = 0 #flag to control saving config data to pdo files = os.listdir(config_path) #/var/mpx/config/services/control (usually) xml_filenames = [] for f in files: if f.find('.xml') > 0 and len(f) == (f.find('.xml') + 4): #any xml file in this folder is assumed to be a control app xml_filenames.append(f) modify_time = os.stat(config_path + f)[8] stale_pdo = True no_stats_pdo = True if f in self._pdo.stats_dict: #check for change since last time no_stats_pdo = False if self._pdo.stats_dict[f][0] == modify_time: stale_pdo = False #old news, no change detected #self.stats_dict[f]=modify_time if starting or no_stats_pdo or (stale_pdo and ALLOW_APP_RELOAD): #need to (re)load application if app_reloaded == 0: #only stop all application nodes for the first detected change try: self._status = 'Stopping %s' % (f,) msglog.log(self.as_node_url(),msglog.types.INFO, 'Stage 0: Stop Application templates.') for c in self.children_nodes(): if hasattr(c, '_stop_running_app'): c._stop_running_app() except: msglog.exception() app_reloaded = 1 #no need to "stop" for any other app changes self._status = 'Loading %s' % (f,) try: root = None if not stale_pdo: #so no change was detected, we are starting up the framework try: #to get the pickled config data rather than load the xml again msglog.log(self.as_node_url(),msglog.types.INFO, 'Stage 1: XML unchanged. Loading configuration data from PDO: %s' % (f,)) root = cPickle.loads(self._pdo.stats_dict[f][1]) except: msglog.exception() msglog.log(self.as_node_url(),msglog.types.WARN, 'Stage 1: Unable to reload config data. Next, try XML file.') if root is None: msglog.log(self.as_node_url(),msglog.types.INFO, 'Stage 1: Parsing configuration xml file: %s' % (f,)) root = parse_xml(config_path + f) self._pdo.stats_dict[f] = (modify_time, cPickle.dumps(root)) save_pdo = 1 if f in self._stale_apps: self._stale_apps.remove(f) #now we have the root configuration. Turn it into configured nodes module = root.get_config().get('module', None) if module == 'mpx.ion.rz.rzhost_node.RzhostNode': load_rz_root(root, self) elif module == 'mpx.service.control.graphical.ApplicationNode': load_tim_root(root, self) else: raise EInvalidValue() except Exception, e: msglog.exception() pass elif stale_pdo: if not f in self._stale_apps: msglog.log(self.as_node_url(), msglog.types.INFO, 'Application %s has been modified, please restart the framework.' % (f,)) self._stale_apps.append(f) try: self.get_child(f.split('.')[0]).set_stale_flag() except: msglog.exception()