def global_auditor(self):
        if not self._global_auditor:
            ac = get_mbs().audit_collection
            self._global_auditor = GlobalAuditor(audit_collection=ac)
            # register auditors with global auditor
            if self.auditors:
                for auditor in self.auditors:
                    self._global_auditor.register_auditor(auditor)

        return self._global_auditor
    def global_auditor(self):
        if not self._global_auditor:
            ac = get_mbs().audit_collection
            nh = self.audit_notification_handler
            self._global_auditor = GlobalAuditor(audit_collection=ac,
                                                 notification_handler=nh)
            # register auditors with global auditor
            if self.auditors:
                for auditor in self.auditors:
                    self._global_auditor.register_auditor(auditor)

        return self._global_auditor
class BackupSystem(Thread):
    ###########################################################################
    def __init__(self, sleep_time=10):

        Thread.__init__(self)
        self._sleep_time = sleep_time

        self._plan_generators = []

        self._stop_requested = False
        self._stopped = False
        self._backup_expiration_manager = None
        self._backup_sweeper = None
        # auditing stuff

        # init global editor
        self._auditors = None
        self._global_auditor = None
        self._audit_schedule = None
        self._audit_next_occurrence = None

        self._port = DEFAULT_BACKUP_SYSTEM_PORT
        self._command_server = BackupSystemCommandServer(self)
        self._backup_monitor = BackupMonitor(self)
        self._scheduler = BackupScheduler(self)

        self._master_monitor = MbsMasterMonitor(self)

    ###########################################################################
    @property
    def plan_generators(self):
        return self._plan_generators

    @plan_generators.setter
    def plan_generators(self, value):
        self._plan_generators = value
        # set backup system to this
        if self._plan_generators:
            for pg in self._plan_generators:
                pg.backup_system = self

    ###########################################################################
    @property
    def auditors(self):
        return self._auditors

    @auditors.setter
    def auditors(self, value):
        self._auditors = value

    ###########################################################################
    @property
    def audit_schedule(self):
        return self._audit_schedule

    @audit_schedule.setter
    def audit_schedule(self, schedule):
        self._audit_schedule = schedule

    ###########################################################################
    @property
    def global_auditor(self):
        if not self._global_auditor:
            ac = get_mbs().audit_collection
            self._global_auditor = GlobalAuditor(audit_collection=ac)
            # register auditors with global auditor
            if self.auditors:
                for auditor in self.auditors:
                    self._global_auditor.register_auditor(auditor)

        return self._global_auditor

    ###########################################################################
    @property
    def backup_expiration_manager(self):
        return self._backup_expiration_manager

    @backup_expiration_manager.setter
    def backup_expiration_manager(self, val):
        self._backup_expiration_manager = val

    ####################################################################################################################
    @property
    def backup_sweeper(self):
        return self._backup_sweeper

    @backup_sweeper.setter
    def backup_sweeper(self, val):
        self._backup_sweeper = val

    ###########################################################################
    @property
    def port(self):
        return self._port

    @port.setter
    def port(self, port):
        self._port = port

    ###########################################################################
    @property
    def backup_monitor(self):
        return self._backup_monitor

    ###########################################################################
    # Behaviors
    ###########################################################################
    def run(self):
        self.info("Starting up... ")
        self.info("PID is %s" % os.getpid())
        #self._update_pid_file()

        # Start the command server
        self._start_command_server()

        logger.info("Starting as Master instance")
        self.master_instance_run()
        self.master_instance_wait_for_stop_request()
        self.master_instance_stopped()


    ###########################################################################
    def master_instance_run(self):
        # ensure mbs indexes
        get_mbs().ensure_mbs_indexes()
        # Start expiration managers
        self._start_expiration_managers()

        # Start plan generators
        self._start_plan_generators()

        # start backup monitor
        self._start_backup_monitor()

        # start the scheduler
        self._start_scheduler()


        # start the master monitor
        self._start_master_monitor()

    ###########################################################################
    def master_instance_wait_for_stop_request(self):
        while not self._stop_requested:
            time.sleep(self._sleep_time)
        self.info('Stop request received by Master instance')

    ###########################################################################
    def master_instance_stopped(self):
        self.info('Stopping backup system Master threads...')
        self._stop_expiration_managers()
        self._stop_plan_generators()
        self._stop_backup_monitor()
        self._stop_scheduler()
        self._stop_master_monitor()
        self.info('All backup system Master threads stopped')
        self._stopped = True

    ###########################################################################
    def reschedule_all_failed_backups(self, force=False,
                                      reset_try_count=False):
        self.info("Rescheduling all failed backups")

        q = {
            "state": State.FAILED
        }

        for backup in get_mbs().backup_collection.find_iter(q):
            try:
                self.reschedule_backup(backup, force=force,
                                       reset_try_count=reset_try_count)
            except Exception, e:
                logger.error(e)
class BackupSystem(Thread):
    ###########################################################################
    def __init__(self, sleep_time=10, command_port=9003):

        Thread.__init__(self)
        self._sleep_time = sleep_time

        self._plan_generators = []
        self._tick_count = 0
        self._stopped = False
        self._command_port = command_port
        self._command_server = BackupSystemCommandServer(self)

        # auditing stuff

        # init global editor
        self._audit_notification_handler = None
        self._auditors = None
        self._global_auditor = None
        self._audit_schedule = None
        self._audit_next_occurrence = None

    ###########################################################################
    @property
    def plan_generators(self):
        return self._plan_generators

    @plan_generators.setter
    def plan_generators(self, value):
        self._plan_generators = value

    ###########################################################################
    @property
    def auditors(self):
        return self._auditors

    @auditors.setter
    def auditors(self, value):
        self._auditors = value

    ###########################################################################
    @property
    def audit_notification_handler(self):
        return self._audit_notification_handler

    @audit_notification_handler.setter
    def audit_notification_handler(self, handler):
        self._audit_notification_handler = handler

    ###########################################################################
    @property
    def audit_schedule(self):
        return self._audit_schedule

    @audit_schedule.setter
    def audit_schedule(self, schedule):
        self._audit_schedule = schedule

    ###########################################################################
    @property
    def global_auditor(self):
        if not self._global_auditor:
            ac = get_mbs().audit_collection
            nh = self.audit_notification_handler
            self._global_auditor = GlobalAuditor(audit_collection=ac,
                                                 notification_handler=nh)
            # register auditors with global auditor
            if self.auditors:
                for auditor in self.auditors:
                    self._global_auditor.register_auditor(auditor)

        return self._global_auditor

    ###########################################################################
    # Behaviors
    ###########################################################################
    def run(self):
        self.info("Starting up... ")
        self.info("PID is %s" % os.getpid())
        self._update_pid_file()

        # Start the command server
        self._start_command_server()

        while not self._stopped:
            try:
                self._tick()
                time.sleep(self._sleep_time)
            except Exception, e:
                self.error("Caught an error: '%s'.\nStack Trace:\n%s" %
                           (e, traceback.format_exc()))
                self._notify_error(e)

        self.info("Exited main loop")
        self._pre_shutdown()