예제 #1
0
    def _check_syncthing(self, services):
        status = INACTIVE_STATE
        display_name = 'File Sync Service'

        try:
            syncthing_config = syncthing_utils.config()
            device_stats = syncthing_utils.device_stats()
        except Exception as err:
            current_app.logger.error(
                'Syncthing check failed with {err_type}: {err_msg}'.format(
                    err_type=type(err),
                    err_msg=str(err),
                )
            )
            self._add_or_update_service(services, display_name, status)
            return status

        # Add 1 second to the interval for avoiding false negative
        interval = syncthing_config['options']['reconnectionIntervalS'] + 1
        min_last_seen = datetime.utcnow() - timedelta(seconds=interval)

        for device_id, stats in device_stats.items():
            last_seen = parse_datetime_string(stats['lastSeen'])

            # Syncthing is valid when at least one device was seen recently
            if last_seen > min_last_seen:
                status = ACTIVE_STATE
                break

        self._add_or_update_service(services, display_name, status)
        return status
예제 #2
0
def _is_status_report_updated(report):
    """
    The report is considered updated, if the time passed since the report was
    sent is maximum twice the frequency interval (Nyquist sampling theorem).
    """
    reporting_delta = int(report['reporting_freq']) * 2
    report_time = parse_datetime_string(report['timestamp'])
    return (report_time + timedelta(seconds=reporting_delta) >
            datetime.utcnow())
예제 #3
0
 def _parse_scheduled_time(self, scheduled_time):
     scheduled_utc = parse_datetime_string(scheduled_time)
     if scheduled_utc <= datetime.utcnow():
         raise manager_exceptions.BadParametersError(
             'Date `{0}` has already passed, please provide'
             ' valid date. \nExpected format: YYYYMMDDHHMM+HHMM or'
             ' YYYYMMDDHHMM-HHMM i.e: 201801012230-0500'
             ' (Jan-01-18 10:30pm EST)'.format(scheduled_time))
     return scheduled_utc
예제 #4
0
    def _update_manager_last_seen(node_id):
        report = request.json.get('report', {})
        if report.get('status') != ServiceStatus.HEALTHY:
            current_app.logger.debug(
                "The manager with node_id: {0} is not healthy, so it's "
                "last_seen is not updated".format(node_id))
            return

        storage_manager = get_storage_manager()
        manager = storage_manager.get(models.Manager,
                                      None,
                                      filters={'node_id': node_id})
        manager_time = parse_datetime_string(manager.last_seen)
        report_time = request.json.get('timestamp')
        if report_time and manager_time < parse_datetime_string(report_time):
            manager.last_seen = get_formatted_timestamp()
            manager.status_report_frequency = request.json.get(
                'reporting_freq')
            storage_manager.update(manager)
예제 #5
0
def _verify_report_newer_than_current(node_id, report_time, status_path):
    if not (path.exists(status_path) and path.isfile(status_path)):
        # Nothing to do if the file does not exists
        return
    with open(status_path) as current_report_file:
        current_report = json.load(current_report_file)
    if report_time < parse_datetime_string(current_report['timestamp']):
        current_app.logger.error('The status report for {0} at {1} is before'
                                 ' the latest report'.format(
                                     node_id, report_time))
예제 #6
0
def _other_device_was_seen(syncthing_config, device_stats):
    # Add 1 second to the interval for avoiding false negative
    interval = syncthing_config['options']['reconnectionIntervalS'] + 1
    min_last_seen = datetime.utcnow() - timedelta(seconds=interval)

    for device_id, stats in device_stats.items():
        last_seen = parse_datetime_string(stats['lastSeen'])

        # Syncthing is valid when at least one device was seen recently
        if last_seen > min_last_seen:
            return True
    return False
예제 #7
0
def write_status_report(node_id, model, node_type, report):
    current_app.logger.debug('Received new status report for '
                             '{0} of type {1}...'.format(node_id, node_type))
    _verify_syncthing_status()
    _create_statues_folder_if_needed()
    _verify_node_exists(node_id, model)
    _verify_status_report_schema(node_id, report)
    report_time = parse_datetime_string(report['timestamp'])
    _verify_timestamp(node_id, report_time)
    report_path = get_report_path(node_type, node_id)
    _verify_report_newer_than_current(node_id, report_time, report_path)
    _save_report(report_path, report)
    current_app.logger.debug('Successfully updated the status report for '
                             '{0} of type {1}'.format(node_id, node_type))
예제 #8
0
def _last_manager_in_cluster():
    storage_manager = get_storage_manager()
    managers = storage_manager.list(models.Manager, sort={'last_seen': 'desc'})
    active_managers = 0
    for manager in managers:
        # Probably new manager, first status report is yet to arrive
        if manager.status_report_frequency is None:
            active_managers += 1
        else:
            # The manager is considered active, if the time passed since
            # it's last_seen is maximum twice the frequency interval
            # (Nyquist sampling theorem)
            interval = manager.status_report_frequency * 2
            min_last_seen = datetime.utcnow() - timedelta(seconds=interval)

            if parse_datetime_string(manager.last_seen) > min_last_seen:
                active_managers += 1
        if active_managers > 1:
            return False
    return True