| OLD | NEW |
| 1 """ | 1 """ |
| 2 Autotest AFE Cleanup used by the scheduler | 2 Autotest AFE Cleanup used by the scheduler |
| 3 """ | 3 """ |
| 4 | 4 |
| 5 | 5 |
| 6 import datetime, time, logging | 6 import datetime, time, logging, random |
| 7 from autotest_lib.database import database_connection | 7 from autotest_lib.database import database_connection |
| 8 from autotest_lib.frontend.afe import models | 8 from autotest_lib.frontend.afe import models |
| 9 from autotest_lib.scheduler import email_manager, scheduler_config | 9 from autotest_lib.scheduler import email_manager, scheduler_config |
| 10 from autotest_lib.client.common_lib import host_protections | 10 from autotest_lib.client.common_lib import host_protections |
| 11 | 11 |
| 12 | 12 |
| 13 class PeriodicCleanup(object): | 13 class PeriodicCleanup(object): |
| 14 | 14 |
| 15 | 15 |
| 16 def __init__(self, db, clean_interval, run_at_initialize=False): | 16 def __init__(self, db, clean_interval, run_at_initialize=False): |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 | 155 |
| 156 | 156 |
| 157 def _should_reverify_hosts_now(self): | 157 def _should_reverify_hosts_now(self): |
| 158 reverify_period_sec = (scheduler_config.config.reverify_period_minutes | 158 reverify_period_sec = (scheduler_config.config.reverify_period_minutes |
| 159 * 60) | 159 * 60) |
| 160 if reverify_period_sec == 0: | 160 if reverify_period_sec == 0: |
| 161 return False | 161 return False |
| 162 return (self._last_reverify_time + reverify_period_sec) <= time.time() | 162 return (self._last_reverify_time + reverify_period_sec) <= time.time() |
| 163 | 163 |
| 164 | 164 |
| 165 def _choose_subset_of_hosts_to_reverify(self, hosts): |
| 166 """Given hosts needing verification, return a subset to reverify.""" |
| 167 max_at_once = scheduler_config.config.reverify_max_hosts_at_once |
| 168 if (max_at_once > 0 and len(hosts) > max_at_once): |
| 169 return random.sample(hosts, max_at_once) |
| 170 return sorted(hosts) |
| 171 |
| 172 |
| 165 def _reverify_dead_hosts(self): | 173 def _reverify_dead_hosts(self): |
| 166 if not self._should_reverify_hosts_now(): | 174 if not self._should_reverify_hosts_now(): |
| 167 return | 175 return |
| 168 | 176 |
| 169 self._last_reverify_time = time.time() | 177 self._last_reverify_time = time.time() |
| 170 logging.info('Checking for dead hosts to reverify') | 178 logging.info('Checking for dead hosts to reverify') |
| 171 hosts = models.Host.objects.filter( | 179 hosts = models.Host.objects.filter( |
| 172 status=models.Host.Status.REPAIR_FAILED, | 180 status=models.Host.Status.REPAIR_FAILED, |
| 173 locked=False, | 181 locked=False, |
| 174 invalid=False) | 182 invalid=False) |
| 175 hosts = hosts.exclude( | 183 hosts = hosts.exclude( |
| 176 protection=host_protections.Protection.DO_NOT_VERIFY) | 184 protection=host_protections.Protection.DO_NOT_VERIFY) |
| 177 if not hosts: | 185 if not hosts: |
| 178 return | 186 return |
| 179 | 187 |
| 180 logging.info('Reverifying dead hosts %s' | 188 hosts = list(hosts) |
| 181 % ', '.join(host.hostname for host in hosts)) | 189 total_hosts = len(hosts) |
| 190 hosts = self._choose_subset_of_hosts_to_reverify(hosts) |
| 191 logging.info('Reverifying dead hosts (%d of %d) %s', len(hosts), |
| 192 total_hosts, ', '.join(host.hostname for host in hosts)) |
| 182 for host in hosts: | 193 for host in hosts: |
| 183 models.SpecialTask.schedule_special_task( | 194 models.SpecialTask.schedule_special_task( |
| 184 host=host, task=models.SpecialTask.Task.VERIFY) | 195 host=host, task=models.SpecialTask.Task.VERIFY) |
| 185 | 196 |
| 186 | 197 |
| 187 class TwentyFourHourUpkeep(PeriodicCleanup): | 198 class TwentyFourHourUpkeep(PeriodicCleanup): |
| 188 """Cleanup that runs at the startup of monitor_db and every subsequent | 199 """Cleanup that runs at the startup of monitor_db and every subsequent |
| 189 twenty four hours. | 200 twenty four hours. |
| 190 """ | 201 """ |
| 191 | 202 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 for row in rows] | 294 for row in rows] |
| 284 self._send_inconsistency_message(subject, lines) | 295 self._send_inconsistency_message(subject, lines) |
| 285 | 296 |
| 286 | 297 |
| 287 def _send_inconsistency_message(self, subject, lines): | 298 def _send_inconsistency_message(self, subject, lines): |
| 288 logging.error(subject) | 299 logging.error(subject) |
| 289 message = '\n'.join(lines) | 300 message = '\n'.join(lines) |
| 290 if len(message) > 5000: | 301 if len(message) > 5000: |
| 291 message = message[:5000] + '\n(truncated)\n' | 302 message = message[:5000] + '\n(truncated)\n' |
| 292 email_manager.manager.enqueue_notify_email(subject, message) | 303 email_manager.manager.enqueue_notify_email(subject, message) |
| OLD | NEW |