示例#1
0
    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__))
示例#2
0
    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__))
示例#3
0
 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.')
示例#5
0
    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.')
示例#6
0
    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)
示例#7
0
    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')