def commit_changes(self): if self.boundaries is not None: module_source = inspect.getsourcelines(self._module)[0] new_source = module_source[:self.boundaries[0] - 1] new_source.extend(self.generate_code()) new_source.extend(module_source[self.boundaries[1]:]) imports_line = self._remove_imports(new_source) self._cleanup_imports(new_source) new_imports = self._generate_imports() for no, imprt in enumerate(new_imports): new_source.insert(imports_line + no, imprt) modulefilename = self._module.__file__ if modulefilename[-1] in ['c', 'o']: modulefilename = modulefilename[:-1] modfile = open(modulefilename, 'w') modfile.writelines(new_source) modfile.close() # we must reload the class module misc.reload_module(self._module) # reload module in multi-processing enviroments services.notify(('RELOAD_MODULE', self._module.__name__))
def commit_changes(self): if self.boundaries is not None: module_source = inspect.getsourcelines(self._module)[0] new_source = module_source[: self.boundaries[0] - 1] new_source.extend(self.generate_code()) new_source.extend(module_source[self.boundaries[1] :]) imports_line = self._remove_imports(new_source) self._cleanup_imports(new_source) new_imports = self._generate_imports() for no, imprt in enumerate(new_imports): new_source.insert(imports_line + no, imprt) modulefilename = self._module.__file__ if modulefilename[-1] in ["c", "o"]: modulefilename = modulefilename[:-1] modfile = open(modulefilename, "w") modfile.writelines(new_source) modfile.close() # we must reload the class module misc.reload_module(self._module) # reload module in multi-processing enviroments services.notify(("RELOAD_MODULE", self._module.__name__))
def event_notify(a, b, c): if b == db.DB_EVENT_REP_MASTER: self.master = self.local_site # notify sub-processes services.notify(('NEW_MASTER', self.local_site)) self.broadcast(MgtMessage('REP_NEW_MASTER', self.local_site)) logger.info('REP: Node elected as new MASTER') elif b == db.DB_EVENT_REP_STARTUPDONE: self.client_startup_done = True logger.info('REP: Replication client startup is finished')
def execute_command(self, cmd, request): try: # DB maintenance commands if cmd == 'DB_BACKUP': output_file = request.data if not os.path.isdir(os.path.dirname(output_file)): raise IOError services.lock_db() try: _db.backup(output_file) finally: services.unlock_db() return (0, 'Database backup completed successfully.') elif cmd == 'DB_RESTORE': backup_set = request.data if not os.path.exists(backup_set): raise IOError services.lock_db() services.close_db() try: _db.restore(backup_set) finally: services.open_db() services.unlock_db() return (0, 'Database restore completed successfully.') elif cmd == 'DB_SHRINK': iLogs = _db.shrink() if iLogs: return (0, 'Successfully removed %d log files.' % iLogs) else: return (0, 'No log files removed.') # package management commands elif cmd == 'PACKAGE': ini_file = request.data my_pkg = None try: my_pkg = Package(ini_file=ini_file) my_pkg.create() finally: if my_pkg is not None: my_pkg.close() return (0, 'The package "%s-%s.ppf" was created succefully.' % (my_pkg.name, my_pkg.version)) elif cmd == 'INSTALL': # some scripts might require a security context from porcupine import context ppf_file = request.data my_pkg = None try: my_pkg = Package(package_file=ppf_file) # install as system context.user = _db.get_item('system') my_pkg.install() finally: if my_pkg is not None: my_pkg.close() context.user = None return (0, 'The package "%s" was installed succefully.' % ppf_file) elif cmd == 'UNINSTALL': # some scripts might require a security context from porcupine import context ppf_file = request.data my_pkg = None try: my_pkg = Package(package_file=ppf_file) # uninstall as system context.user = _db.get_item('system') my_pkg.uninstall() finally: if my_pkg is not None: my_pkg.close() context.user = None return (0, 'The package "%s" was uninstalled succefully.' % ppf_file) # replication commands elif cmd == 'SITE_INFO': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site_list = list(rep_mgr.get_site_list().values()) site_list.append( rep_mgr.local_site.address + (1,)) #print site_list info = [str.format('{0:25}{1:10}{2:6}', 'SITE', 'STATUS', 'MASTER'), '-' * 41] for site in site_list: site_address = site[:2] if site[2] == 1: s = 'ONLINE' else: s = 'OFFLINE' if rep_mgr.master and \ rep_mgr.master.address == site_address: m = 'X' else: m = '' info.append(str.format('{0:25}{1:10}{2:6}', site_address, s, m)) info.append('') info.append('Total sites: %d' % len(site_list)) return (0, '\n'.join(info)) else: raise NotImplementedError elif cmd == 'REP_JOIN_SITE': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site = request.data #print('adding remote site %s' % (site.address, )) site_list = rep_mgr.sites.values() + [rep_mgr.local_site] rep_mgr.broadcast(MgtMessage('REP_ADD_REMOTE_SITE', site)) rep_mgr.add_remote_site(site) return (0, [rep_mgr.master, site_list]) else: raise NotImplementedError elif cmd == 'REP_ADD_REMOTE_SITE': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: site = request.data #print('adding remote site %s' % (site.address, )) rep_mgr.add_remote_site(site) return (0, None) else: raise NotImplementedError elif cmd == 'REP_NEW_MASTER': rep_mgr = _db.get_replication_manager() if rep_mgr is not None: master = request.data #print('new master is %s' % (master.address, )) rep_mgr.master = master services.notify(('NEW_MASTER', master)) return (0, None) else: raise NotImplementedError # other elif cmd == 'RELOAD': mod = misc.get_rto_by_name(request.data) misc.reload_module_tree(mod) services.notify(('RELOAD_PACKAGE', request.data)) return (0, 'Reloaded module tree "%s"' % request.data) # unknown command else: logger.warning( 'Management service received unknown command: %s' % cmd) return (-1, 'Unknown command.') except IOError: return (-1, 'Invalid file path.') except NotImplementedError: return (-1, 'Unsupported command.')
def uninstall(self): logger.info('Uninstalling [%s-%s] package...' % (self.name, self.version)) # database items items = self.config_file.options('items') itemids = [self.config_file.get('items', x) for x in items] if itemids: @db.transactional(auto_commit=True) def _remove_items(): for itemid in itemids: item = db._db.get_item(itemid) if item is not None: logger.info('Removing object %s' % itemid) item._delete() _remove_items() # uninstall script contents = self.package_file.getnames() if '_uninstall.py' in contents: logger.info('Running uninstallation script...') self.package_file.extract('_uninstall.py', self.tmp_folder) self._execute_script(self.tmp_folder + '/_uninstall.py', 'Uninstall script') os.remove(self.tmp_folder + '/_uninstall.py') # files files = self.config_file.options('files') for fl in files: fname = self.config_file.get('files', fl) logger.info('Removing file ' + fname) if os.path.exists(fname): os.remove(fname) # check if it is a python file if fname[-3:] == '.py': [os.remove(fname + x) for x in ('c', 'o') if os.path.exists(fname + x)] # directories dirs = self.config_file.options('dirs') for dir in dirs: dir_path = self.config_file.get('dirs', dir) if os.path.exists(dir_path): logger.info('Removing directory ' + dir_path) shutil.rmtree(dir_path, True) # published dirs if '_pubdir.xml' in contents: logger.info('Uninstalling published directories...') dirsfile = self.package_file.extractfile('_pubdir.xml') _dom = minidom.parse(dirsfile) dirsConfig = configfiles.PubDirManager() dir_nodes = _dom.getElementsByTagName('dir') for dir_node in dir_nodes: #app_node = app_node.cloneNode(True) dir_name = dir_node.getAttribute('name') logger.info('Uninstalling published directory "%s"' % dir_name) old_node = dirsConfig.getDirNode(dir_name) if old_node: dirsConfig.removeDirNode(old_node) else: logger.warning('Published directory "%s" does not exist' % dir_name) # update published directories if dir_name in pubdirs.dirs: del pubdirs.dirs[dir_name] # remove published directory in # multi-processing enviroments services.notify(('REMOVE_PUBDIR', dir_name)) dir_path = dir_node.getAttribute('path') if os.path.exists(dir_path): shutil.rmtree(dir_path, True) _dom.unlink() dirsConfig.close(True)
def install(self): logger.info('Installing [%s-%s] package...' % (self.name, self.version)) contents = self.package_file.getnames() # pre-install script if '_pre.py' in contents: logger.info('Running pre installation script...') self.package_file.extract('_pre.py', self.tmp_folder) self._execute_script(self.tmp_folder + '/_pre.py', 'Pre-installation script') os.remove(self.tmp_folder + '/_pre.py') # files and dirs for pfile in [x for x in contents if x[0] != '_']: logger.info('Extracting ' + pfile) self.package_file.extract(pfile) # published directories if '_pubdir.xml' in contents: logger.info('Installing published directories...') dirsfile = self.package_file.extractfile('_pubdir.xml') _dom = minidom.parse(dirsfile) dirsConfig = configfiles.PubDirManager() dir_nodes = _dom.getElementsByTagName('dir') for dir_node in dir_nodes: dir_node = dir_node.cloneNode(True) dir_name = dir_node.getAttribute('name') logger.info('Installing published directory "%s"' % dir_name) old_node = dirsConfig.getDirNode(dir_name) if old_node: dirsConfig.replaceDirNode(dir_node, old_node) else: dirsConfig.addDirNode(dir_node) # update published directories dir = pubdirs.Dir(dir_node) pubdirs.dirs[dir_name] = dir # add published directory in multi-processing enviroments services.notify(('ADD_PUBDIR', (dir_name, dir))) _dom.unlink() dirsConfig.close(True) # database dbfiles = [x for x in contents if x[:4] == '_db/'] if dbfiles: @db.transactional(auto_commit=True) def _import_items(): for dbfile in dbfiles: logger.info('Importing object ' + os.path.basename(dbfile)) fn = '%s/%s' % (self.tmp_folder, dbfile) self.package_file.extract(dbfile, self.tmp_folder) objfile = None try: objfile = open(fn, 'rb') self._import_item(objfile) finally: if objfile: objfile.close() # import objects try: _import_items() finally: if os.path.exists(self.tmp_folder + '/_db'): shutil.rmtree(self.tmp_folder + '/_db', True) # post-install script if '_post.py' in contents: logger.info('Running post installation script...') self.package_file.extract('_post.py', self.tmp_folder) self._execute_script(self.tmp_folder + '/_post.py', 'Post-installation script') os.remove(self.tmp_folder + '/_post.py')