blob: 98f49bed8f9fc8cd8c8e63c3f79bcd955ffe1d9e [file] [log] [blame]
jamesren883492a2010-02-12 00:45:18 +00001from autotest_lib.client.common_lib import utils
2
3class HostSchedulingUtility(object):
4 """Interface to host availability information from the scheduler."""
5 def hosts_in_label(self, label_id):
6 """Return potentially usable hosts with the given label."""
7 raise NotImplementedError
8
9
10 def remove_host_from_label(self, host_id, label_id):
11 """Remove this host from the internal list of usable hosts in the label.
12
13 This is provided as an optimization -- when code gets a host from a
14 label and concludes it's unusable, it can call this to avoid getting
15 that host again in the future (within this tick). This function should
16 not affect correctness.
17 """
18 raise NotImplementedError
19
20
21 def pop_host(self, host_id):
22 """Remove and return a host from the internal list of available hosts.
23 """
24 raise NotImplementedError
25
26
27 def ineligible_hosts_for_entry(self, queue_entry):
28 """Get the list of hosts ineligible to run the given queue entry."""
29 raise NotImplementedError
30
31
32 def is_host_usable(self, host_id):
33 """Determine if the host is currently usable at all."""
34 raise NotImplementedError
35
36
37 def is_host_eligible_for_job(self, host_id, queue_entry):
38 """Determine if the host is eligible specifically for this queue entry.
39
40 @param queue_entry: a HostQueueEntry DBObject
41 """
42 raise NotImplementedError
43
44
45class MetahostScheduler(object):
46 def can_schedule_metahost(self, queue_entry):
47 """Return true if this object can schedule the given queue entry.
48
49 At most one MetahostScheduler should return true for any given entry.
50
51 @param queue_entry: a HostQueueEntry DBObject
52 """
53 raise NotImplementedError
54
55
56 def schedule_metahost(self, queue_entry, scheduling_utility):
Eric Li861b2d52011-02-04 14:50:35 -080057 """Schedule the given queue entry, if possible.
jamesren883492a2010-02-12 00:45:18 +000058
Eric Li861b2d52011-02-04 14:50:35 -080059 This method should make necessary database changes culminating in
60 assigning a host to the given queue entry in the database. It may
61 take no action if no host can be assigned currently.
jamesren883492a2010-02-12 00:45:18 +000062
Eric Li861b2d52011-02-04 14:50:35 -080063 @param queue_entry: a HostQueueEntry DBObject
64 @param scheduling_utility: a HostSchedulingUtility object
65 """
66 raise NotImplementedError
jamesren883492a2010-02-12 00:45:18 +000067
68
69 def recovery_on_startup(self):
70 """Perform any necessary recovery upon scheduler startup."""
71 pass
72
73
74 def tick(self):
75 """Called once per scheduler cycle; any actions are allowed."""
76 pass
77
78
79class LabelMetahostScheduler(MetahostScheduler):
80 def can_schedule_metahost(self, queue_entry):
81 return bool(queue_entry.meta_host)
82
83
84 def schedule_metahost(self, queue_entry, scheduling_utility):
85 label_id = queue_entry.meta_host
86 hosts_in_label = scheduling_utility.hosts_in_label(label_id)
87 ineligible_host_ids = scheduling_utility.ineligible_hosts_for_entry(
88 queue_entry)
89
90 for host_id in hosts_in_label:
91 if not scheduling_utility.is_host_usable(host_id):
92 scheduling_utility.remove_host_from_label(host_id, label_id)
93 continue
94 if host_id in ineligible_host_ids:
95 continue
96 if not scheduling_utility.is_host_eligible_for_job(host_id,
97 queue_entry):
98 continue
99
100 # Remove the host from our cached internal state before returning
101 scheduling_utility.remove_host_from_label(host_id, label_id)
102 host = scheduling_utility.pop_host(host_id)
103 queue_entry.set_host(host)
104 return
105
106
107def get_metahost_schedulers():
108 return [LabelMetahostScheduler()]