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 |