blob: 80e2197ec27f59c433fb0ee9f7dafe725e39448d [file] [log] [blame]
Aviv Keshet0b9cfc92013-02-05 11:36:02 -08001# pylint: disable-msg=C0111
2
mblighe8819cd2008-02-15 16:48:40 +00003"""\
4Functions to expose over the RPC interface.
5
6For all modify* and delete* functions that ask for an 'id' parameter to
7identify the object to operate on, the id may be either
8 * the database row ID
9 * the name of the object (label name, hostname, user login, etc.)
10 * a dictionary containing uniquely identifying field (this option should seldom
11 be used)
12
13When specifying foreign key fields (i.e. adding hosts to a label, or adding
14users to an ACL group), the given value may be either the database row ID or the
15name of the object.
16
17All get* functions return lists of dictionaries. Each dictionary represents one
18object and maps field names to values.
19
20Some examples:
21modify_host(2, hostname='myhost') # modify hostname of host with database ID 2
22modify_host('ipaj2', hostname='myhost') # modify hostname of host 'ipaj2'
23modify_test('sleeptest', test_type='Client', params=', seconds=60')
24delete_acl_group(1) # delete by ID
25delete_acl_group('Everyone') # delete by name
26acl_group_add_users('Everyone', ['mbligh', 'showard'])
27get_jobs(owner='showard', status='Queued')
28
mbligh93c80e62009-02-03 17:48:30 +000029See doctests/001_rpc_test.txt for (lots) more examples.
mblighe8819cd2008-02-15 16:48:40 +000030"""
31
32__author__ = 'showard@google.com (Steve Howard)'
33
showard29f7cd22009-04-29 21:16:24 +000034import datetime
showardcafd16e2009-05-29 18:37:49 +000035import common
Simran Basib6ec8ae2014-04-23 12:05:08 -070036from autotest_lib.client.common_lib import priorities
jamesrendd855242010-03-02 22:23:44 +000037from autotest_lib.frontend.afe import models, model_logic, model_attributes
showard6d7b2ff2009-06-10 00:16:47 +000038from autotest_lib.frontend.afe import control_file, rpc_utils
Simran Basib6ec8ae2014-04-23 12:05:08 -070039from autotest_lib.frontend.afe import site_rpc_interface
mblighe8819cd2008-02-15 16:48:40 +000040
Eric Lid23bc192011-02-09 14:38:57 -080041def get_parameterized_autoupdate_image_url(job):
42 """Get the parameterized autoupdate image url from a parameterized job."""
43 known_test_obj = models.Test.smart_get('autoupdate_ParameterizedJob')
44 image_parameter = known_test_obj.testparameter_set.get(test=known_test_obj,
beeps8bb1f7d2013-08-05 01:30:09 -070045 name='image')
Eric Lid23bc192011-02-09 14:38:57 -080046 para_set = job.parameterized_job.parameterizedjobparameter_set
47 job_test_para = para_set.get(test_parameter=image_parameter)
48 return job_test_para.parameter_value
49
50
mblighe8819cd2008-02-15 16:48:40 +000051# labels
52
showard989f25d2008-10-01 11:38:11 +000053def add_label(name, kernel_config=None, platform=None, only_if_needed=None):
showardc92da832009-04-07 18:14:34 +000054 return models.Label.add_object(
55 name=name, kernel_config=kernel_config, platform=platform,
56 only_if_needed=only_if_needed).id
mblighe8819cd2008-02-15 16:48:40 +000057
58
59def modify_label(id, **data):
jadmanski0afbb632008-06-06 21:10:57 +000060 models.Label.smart_get(id).update_object(data)
mblighe8819cd2008-02-15 16:48:40 +000061
62
63def delete_label(id):
jadmanski0afbb632008-06-06 21:10:57 +000064 models.Label.smart_get(id).delete()
mblighe8819cd2008-02-15 16:48:40 +000065
66
showardbbabf502008-06-06 00:02:02 +000067def label_add_hosts(id, hosts):
showardbe3ec042008-11-12 18:16:07 +000068 host_objs = models.Host.smart_get_bulk(hosts)
showardcafd16e2009-05-29 18:37:49 +000069 label = models.Label.smart_get(id)
70 if label.platform:
71 models.Host.check_no_platform(host_objs)
72 label.host_set.add(*host_objs)
showardbbabf502008-06-06 00:02:02 +000073
74
75def label_remove_hosts(id, hosts):
showardbe3ec042008-11-12 18:16:07 +000076 host_objs = models.Host.smart_get_bulk(hosts)
jadmanski0afbb632008-06-06 21:10:57 +000077 models.Label.smart_get(id).host_set.remove(*host_objs)
showardbbabf502008-06-06 00:02:02 +000078
79
mblighe8819cd2008-02-15 16:48:40 +000080def get_labels(**filter_data):
showardc92da832009-04-07 18:14:34 +000081 """\
82 @returns A sequence of nested dictionaries of label information.
83 """
84 return rpc_utils.prepare_rows_as_nested_dicts(
85 models.Label.query_objects(filter_data),
86 ('atomic_group',))
87
88
89# atomic groups
90
showarde9450c92009-06-30 01:58:52 +000091def add_atomic_group(name, max_number_of_machines=None, description=None):
showardc92da832009-04-07 18:14:34 +000092 return models.AtomicGroup.add_object(
93 name=name, max_number_of_machines=max_number_of_machines,
94 description=description).id
95
96
97def modify_atomic_group(id, **data):
98 models.AtomicGroup.smart_get(id).update_object(data)
99
100
101def delete_atomic_group(id):
102 models.AtomicGroup.smart_get(id).delete()
103
104
105def atomic_group_add_labels(id, labels):
106 label_objs = models.Label.smart_get_bulk(labels)
107 models.AtomicGroup.smart_get(id).label_set.add(*label_objs)
108
109
110def atomic_group_remove_labels(id, labels):
111 label_objs = models.Label.smart_get_bulk(labels)
112 models.AtomicGroup.smart_get(id).label_set.remove(*label_objs)
113
114
115def get_atomic_groups(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000116 return rpc_utils.prepare_for_serialization(
showardc92da832009-04-07 18:14:34 +0000117 models.AtomicGroup.list_objects(filter_data))
mblighe8819cd2008-02-15 16:48:40 +0000118
119
120# hosts
121
showarddf062562008-07-03 19:56:37 +0000122def add_host(hostname, status=None, locked=None, protection=None):
jadmanski0afbb632008-06-06 21:10:57 +0000123 return models.Host.add_object(hostname=hostname, status=status,
showarddf062562008-07-03 19:56:37 +0000124 locked=locked, protection=protection).id
mblighe8819cd2008-02-15 16:48:40 +0000125
126
127def modify_host(id, **data):
showardbe0d8692009-08-20 23:42:44 +0000128 rpc_utils.check_modify_host(data)
showardce7c0922009-09-11 18:39:24 +0000129 host = models.Host.smart_get(id)
130 rpc_utils.check_modify_host_locking(host, data)
131 host.update_object(data)
mblighe8819cd2008-02-15 16:48:40 +0000132
133
showard276f9442009-05-20 00:33:16 +0000134def modify_hosts(host_filter_data, update_data):
135 """
showardbe0d8692009-08-20 23:42:44 +0000136 @param host_filter_data: Filters out which hosts to modify.
137 @param update_data: A dictionary with the changes to make to the hosts.
showard276f9442009-05-20 00:33:16 +0000138 """
showardbe0d8692009-08-20 23:42:44 +0000139 rpc_utils.check_modify_host(update_data)
showard276f9442009-05-20 00:33:16 +0000140 hosts = models.Host.query_objects(host_filter_data)
Alex Miller9658a952013-05-14 16:40:02 -0700141 # Check all hosts before changing data for exception safety.
142 for host in hosts:
143 rpc_utils.check_modify_host_locking(host, update_data)
showard276f9442009-05-20 00:33:16 +0000144 for host in hosts:
145 host.update_object(update_data)
146
147
mblighe8819cd2008-02-15 16:48:40 +0000148def host_add_labels(id, labels):
showardbe3ec042008-11-12 18:16:07 +0000149 labels = models.Label.smart_get_bulk(labels)
showardcafd16e2009-05-29 18:37:49 +0000150 host = models.Host.smart_get(id)
151
152 platforms = [label.name for label in labels if label.platform]
153 if len(platforms) > 1:
154 raise model_logic.ValidationError(
155 {'labels': 'Adding more than one platform label: %s' %
156 ', '.join(platforms)})
157 if len(platforms) == 1:
158 models.Host.check_no_platform([host])
159 host.labels.add(*labels)
mblighe8819cd2008-02-15 16:48:40 +0000160
161
162def host_remove_labels(id, labels):
showardbe3ec042008-11-12 18:16:07 +0000163 labels = models.Label.smart_get_bulk(labels)
jadmanski0afbb632008-06-06 21:10:57 +0000164 models.Host.smart_get(id).labels.remove(*labels)
mblighe8819cd2008-02-15 16:48:40 +0000165
166
showard0957a842009-05-11 19:25:08 +0000167def set_host_attribute(attribute, value, **host_filter_data):
168 """
169 @param attribute string name of attribute
170 @param value string, or None to delete an attribute
171 @param host_filter_data filter data to apply to Hosts to choose hosts to act
172 upon
173 """
174 assert host_filter_data # disallow accidental actions on all hosts
175 hosts = models.Host.query_objects(host_filter_data)
176 models.AclGroup.check_for_acl_violation_hosts(hosts)
177
178 for host in hosts:
showardf8b19042009-05-12 17:22:49 +0000179 host.set_or_delete_attribute(attribute, value)
showard0957a842009-05-11 19:25:08 +0000180
181
mblighe8819cd2008-02-15 16:48:40 +0000182def delete_host(id):
jadmanski0afbb632008-06-06 21:10:57 +0000183 models.Host.smart_get(id).delete()
mblighe8819cd2008-02-15 16:48:40 +0000184
185
showard87cc38f2009-08-20 23:37:04 +0000186def get_hosts(multiple_labels=(), exclude_only_if_needed_labels=False,
showard8aa84fc2009-09-16 17:17:55 +0000187 exclude_atomic_group_hosts=False, valid_only=True, **filter_data):
showard87cc38f2009-08-20 23:37:04 +0000188 """
189 @param multiple_labels: match hosts in all of the labels given. Should
190 be a list of label names.
191 @param exclude_only_if_needed_labels: Exclude hosts with at least one
192 "only_if_needed" label applied.
193 @param exclude_atomic_group_hosts: Exclude hosts that have one or more
194 atomic group labels associated with them.
jadmanski0afbb632008-06-06 21:10:57 +0000195 """
showard43a3d262008-11-12 18:17:05 +0000196 hosts = rpc_utils.get_host_query(multiple_labels,
197 exclude_only_if_needed_labels,
showard87cc38f2009-08-20 23:37:04 +0000198 exclude_atomic_group_hosts,
showard8aa84fc2009-09-16 17:17:55 +0000199 valid_only, filter_data)
showard0957a842009-05-11 19:25:08 +0000200 hosts = list(hosts)
201 models.Host.objects.populate_relationships(hosts, models.Label,
202 'label_list')
203 models.Host.objects.populate_relationships(hosts, models.AclGroup,
204 'acl_list')
205 models.Host.objects.populate_relationships(hosts, models.HostAttribute,
206 'attribute_list')
showard43a3d262008-11-12 18:17:05 +0000207 host_dicts = []
208 for host_obj in hosts:
209 host_dict = host_obj.get_object_dict()
showard0957a842009-05-11 19:25:08 +0000210 host_dict['labels'] = [label.name for label in host_obj.label_list]
showard909c9142009-07-07 20:54:42 +0000211 host_dict['platform'], host_dict['atomic_group'] = (rpc_utils.
212 find_platform_and_atomic_group(host_obj))
showard0957a842009-05-11 19:25:08 +0000213 host_dict['acls'] = [acl.name for acl in host_obj.acl_list]
214 host_dict['attributes'] = dict((attribute.attribute, attribute.value)
215 for attribute in host_obj.attribute_list)
showard43a3d262008-11-12 18:17:05 +0000216 host_dicts.append(host_dict)
217 return rpc_utils.prepare_for_serialization(host_dicts)
mblighe8819cd2008-02-15 16:48:40 +0000218
219
showard87cc38f2009-08-20 23:37:04 +0000220def get_num_hosts(multiple_labels=(), exclude_only_if_needed_labels=False,
showard8aa84fc2009-09-16 17:17:55 +0000221 exclude_atomic_group_hosts=False, valid_only=True,
222 **filter_data):
showard87cc38f2009-08-20 23:37:04 +0000223 """
224 Same parameters as get_hosts().
225
226 @returns The number of matching hosts.
227 """
showard43a3d262008-11-12 18:17:05 +0000228 hosts = rpc_utils.get_host_query(multiple_labels,
229 exclude_only_if_needed_labels,
showard87cc38f2009-08-20 23:37:04 +0000230 exclude_atomic_group_hosts,
showard8aa84fc2009-09-16 17:17:55 +0000231 valid_only, filter_data)
showard43a3d262008-11-12 18:17:05 +0000232 return hosts.count()
showard1385b162008-03-13 15:59:40 +0000233
mblighe8819cd2008-02-15 16:48:40 +0000234
235# tests
236
showard909c7a62008-07-15 21:52:38 +0000237def add_test(name, test_type, path, author=None, dependencies=None,
showard3d9899a2008-07-31 02:11:58 +0000238 experimental=True, run_verify=None, test_class=None,
showard909c7a62008-07-15 21:52:38 +0000239 test_time=None, test_category=None, description=None,
240 sync_count=1):
jadmanski0afbb632008-06-06 21:10:57 +0000241 return models.Test.add_object(name=name, test_type=test_type, path=path,
showard909c7a62008-07-15 21:52:38 +0000242 author=author, dependencies=dependencies,
243 experimental=experimental,
244 run_verify=run_verify, test_time=test_time,
245 test_category=test_category,
246 sync_count=sync_count,
jadmanski0afbb632008-06-06 21:10:57 +0000247 test_class=test_class,
248 description=description).id
mblighe8819cd2008-02-15 16:48:40 +0000249
250
251def modify_test(id, **data):
jadmanski0afbb632008-06-06 21:10:57 +0000252 models.Test.smart_get(id).update_object(data)
mblighe8819cd2008-02-15 16:48:40 +0000253
254
255def delete_test(id):
jadmanski0afbb632008-06-06 21:10:57 +0000256 models.Test.smart_get(id).delete()
mblighe8819cd2008-02-15 16:48:40 +0000257
258
259def get_tests(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000260 return rpc_utils.prepare_for_serialization(
261 models.Test.list_objects(filter_data))
mblighe8819cd2008-02-15 16:48:40 +0000262
263
showard2b9a88b2008-06-13 20:55:03 +0000264# profilers
265
266def add_profiler(name, description=None):
267 return models.Profiler.add_object(name=name, description=description).id
268
269
270def modify_profiler(id, **data):
271 models.Profiler.smart_get(id).update_object(data)
272
273
274def delete_profiler(id):
275 models.Profiler.smart_get(id).delete()
276
277
278def get_profilers(**filter_data):
279 return rpc_utils.prepare_for_serialization(
280 models.Profiler.list_objects(filter_data))
281
282
mblighe8819cd2008-02-15 16:48:40 +0000283# users
284
285def add_user(login, access_level=None):
jadmanski0afbb632008-06-06 21:10:57 +0000286 return models.User.add_object(login=login, access_level=access_level).id
mblighe8819cd2008-02-15 16:48:40 +0000287
288
289def modify_user(id, **data):
jadmanski0afbb632008-06-06 21:10:57 +0000290 models.User.smart_get(id).update_object(data)
mblighe8819cd2008-02-15 16:48:40 +0000291
292
293def delete_user(id):
jadmanski0afbb632008-06-06 21:10:57 +0000294 models.User.smart_get(id).delete()
mblighe8819cd2008-02-15 16:48:40 +0000295
296
297def get_users(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000298 return rpc_utils.prepare_for_serialization(
299 models.User.list_objects(filter_data))
mblighe8819cd2008-02-15 16:48:40 +0000300
301
302# acl groups
303
304def add_acl_group(name, description=None):
showard04f2cd82008-07-25 20:53:31 +0000305 group = models.AclGroup.add_object(name=name, description=description)
showard64a95952010-01-13 21:27:16 +0000306 group.users.add(models.User.current_user())
showard04f2cd82008-07-25 20:53:31 +0000307 return group.id
mblighe8819cd2008-02-15 16:48:40 +0000308
309
310def modify_acl_group(id, **data):
showard04f2cd82008-07-25 20:53:31 +0000311 group = models.AclGroup.smart_get(id)
312 group.check_for_acl_violation_acl_group()
313 group.update_object(data)
314 group.add_current_user_if_empty()
mblighe8819cd2008-02-15 16:48:40 +0000315
316
317def acl_group_add_users(id, users):
jadmanski0afbb632008-06-06 21:10:57 +0000318 group = models.AclGroup.smart_get(id)
showard04f2cd82008-07-25 20:53:31 +0000319 group.check_for_acl_violation_acl_group()
showardbe3ec042008-11-12 18:16:07 +0000320 users = models.User.smart_get_bulk(users)
jadmanski0afbb632008-06-06 21:10:57 +0000321 group.users.add(*users)
mblighe8819cd2008-02-15 16:48:40 +0000322
323
324def acl_group_remove_users(id, users):
jadmanski0afbb632008-06-06 21:10:57 +0000325 group = models.AclGroup.smart_get(id)
showard04f2cd82008-07-25 20:53:31 +0000326 group.check_for_acl_violation_acl_group()
showardbe3ec042008-11-12 18:16:07 +0000327 users = models.User.smart_get_bulk(users)
jadmanski0afbb632008-06-06 21:10:57 +0000328 group.users.remove(*users)
showard04f2cd82008-07-25 20:53:31 +0000329 group.add_current_user_if_empty()
mblighe8819cd2008-02-15 16:48:40 +0000330
331
332def acl_group_add_hosts(id, hosts):
jadmanski0afbb632008-06-06 21:10:57 +0000333 group = models.AclGroup.smart_get(id)
showard04f2cd82008-07-25 20:53:31 +0000334 group.check_for_acl_violation_acl_group()
showardbe3ec042008-11-12 18:16:07 +0000335 hosts = models.Host.smart_get_bulk(hosts)
jadmanski0afbb632008-06-06 21:10:57 +0000336 group.hosts.add(*hosts)
showard08f981b2008-06-24 21:59:03 +0000337 group.on_host_membership_change()
mblighe8819cd2008-02-15 16:48:40 +0000338
339
340def acl_group_remove_hosts(id, hosts):
jadmanski0afbb632008-06-06 21:10:57 +0000341 group = models.AclGroup.smart_get(id)
showard04f2cd82008-07-25 20:53:31 +0000342 group.check_for_acl_violation_acl_group()
showardbe3ec042008-11-12 18:16:07 +0000343 hosts = models.Host.smart_get_bulk(hosts)
jadmanski0afbb632008-06-06 21:10:57 +0000344 group.hosts.remove(*hosts)
showard08f981b2008-06-24 21:59:03 +0000345 group.on_host_membership_change()
mblighe8819cd2008-02-15 16:48:40 +0000346
347
348def delete_acl_group(id):
jadmanski0afbb632008-06-06 21:10:57 +0000349 models.AclGroup.smart_get(id).delete()
mblighe8819cd2008-02-15 16:48:40 +0000350
351
352def get_acl_groups(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000353 acl_groups = models.AclGroup.list_objects(filter_data)
354 for acl_group in acl_groups:
355 acl_group_obj = models.AclGroup.objects.get(id=acl_group['id'])
356 acl_group['users'] = [user.login
357 for user in acl_group_obj.users.all()]
358 acl_group['hosts'] = [host.hostname
359 for host in acl_group_obj.hosts.all()]
360 return rpc_utils.prepare_for_serialization(acl_groups)
mblighe8819cd2008-02-15 16:48:40 +0000361
362
363# jobs
364
mbligh120351e2009-01-24 01:40:45 +0000365def generate_control_file(tests=(), kernel=None, label=None, profilers=(),
showard91f85102009-10-12 20:34:52 +0000366 client_control_file='', use_container=False,
showard232b7ae2009-11-10 00:46:48 +0000367 profile_only=None, upload_kernel_config=False):
jadmanski0afbb632008-06-06 21:10:57 +0000368 """
mbligh120351e2009-01-24 01:40:45 +0000369 Generates a client-side control file to load a kernel and run tests.
370
371 @param tests List of tests to run.
mbligha3c58d22009-08-24 22:01:51 +0000372 @param kernel A list of kernel info dictionaries configuring which kernels
373 to boot for this job and other options for them
mbligh120351e2009-01-24 01:40:45 +0000374 @param label Name of label to grab kernel config from.
375 @param profilers List of profilers to activate during the job.
376 @param client_control_file The contents of a client-side control file to
377 run at the end of all tests. If this is supplied, all tests must be
378 client side.
379 TODO: in the future we should support server control files directly
380 to wrap with a kernel. That'll require changing the parameter
381 name and adding a boolean to indicate if it is a client or server
382 control file.
383 @param use_container unused argument today. TODO: Enable containers
384 on the host during a client side test.
showard91f85102009-10-12 20:34:52 +0000385 @param profile_only A boolean that indicates what default profile_only
386 mode to use in the control file. Passing None will generate a
387 control file that does not explcitly set the default mode at all.
showard232b7ae2009-11-10 00:46:48 +0000388 @param upload_kernel_config: if enabled it will generate server control
389 file code that uploads the kernel config file to the client and
390 tells the client of the new (local) path when compiling the kernel;
391 the tests must be server side tests
mbligh120351e2009-01-24 01:40:45 +0000392
393 @returns a dict with the following keys:
394 control_file: str, The control file text.
395 is_server: bool, is the control file a server-side control file?
396 synch_count: How many machines the job uses per autoserv execution.
397 synch_count == 1 means the job is asynchronous.
398 dependencies: A list of the names of labels on which the job depends.
399 """
showardd86debe2009-06-10 17:37:56 +0000400 if not tests and not client_control_file:
showard2bab8f42008-11-12 18:15:22 +0000401 return dict(control_file='', is_server=False, synch_count=1,
showard989f25d2008-10-01 11:38:11 +0000402 dependencies=[])
mblighe8819cd2008-02-15 16:48:40 +0000403
showard989f25d2008-10-01 11:38:11 +0000404 cf_info, test_objects, profiler_objects, label = (
showard2b9a88b2008-06-13 20:55:03 +0000405 rpc_utils.prepare_generate_control_file(tests, kernel, label,
406 profilers))
showard989f25d2008-10-01 11:38:11 +0000407 cf_info['control_file'] = control_file.generate_control(
mbligha3c58d22009-08-24 22:01:51 +0000408 tests=test_objects, kernels=kernel, platform=label,
mbligh120351e2009-01-24 01:40:45 +0000409 profilers=profiler_objects, is_server=cf_info['is_server'],
showard232b7ae2009-11-10 00:46:48 +0000410 client_control_file=client_control_file, profile_only=profile_only,
411 upload_kernel_config=upload_kernel_config)
showard989f25d2008-10-01 11:38:11 +0000412 return cf_info
mblighe8819cd2008-02-15 16:48:40 +0000413
414
jamesren4a41e012010-07-16 22:33:48 +0000415def create_parameterized_job(name, priority, test, parameters, kernel=None,
416 label=None, profilers=(), profiler_parameters=None,
417 use_container=False, profile_only=None,
418 upload_kernel_config=False, hosts=(),
419 meta_hosts=(), one_time_hosts=(),
420 atomic_group_name=None, synch_count=None,
421 is_template=False, timeout=None,
Simran Basi7e605742013-11-12 13:43:36 -0800422 timeout_mins=None, max_runtime_mins=None,
423 run_verify=False, email_list='', dependencies=(),
424 reboot_before=None, reboot_after=None,
425 parse_failed_repair=None, hostless=False,
426 keyvals=None, drone_set=None, run_reset=True):
jamesren4a41e012010-07-16 22:33:48 +0000427 """
428 Creates and enqueues a parameterized job.
429
430 Most parameters a combination of the parameters for generate_control_file()
431 and create_job(), with the exception of:
432
433 @param test name or ID of the test to run
434 @param parameters a map of parameter name ->
435 tuple of (param value, param type)
436 @param profiler_parameters a dictionary of parameters for the profilers:
437 key: profiler name
438 value: dict of param name -> tuple of
439 (param value,
440 param type)
441 """
442 # Save the values of the passed arguments here. What we're going to do with
443 # them is pass them all to rpc_utils.get_create_job_common_args(), which
444 # will extract the subset of these arguments that apply for
445 # rpc_utils.create_job_common(), which we then pass in to that function.
446 args = locals()
447
448 # Set up the parameterized job configs
449 test_obj = models.Test.smart_get(test)
Aviv Keshet3dd8beb2013-05-13 17:36:04 -0700450 control_type = test_obj.test_type
jamesren4a41e012010-07-16 22:33:48 +0000451
452 try:
453 label = models.Label.smart_get(label)
454 except models.Label.DoesNotExist:
455 label = None
456
457 kernel_objs = models.Kernel.create_kernels(kernel)
458 profiler_objs = [models.Profiler.smart_get(profiler)
459 for profiler in profilers]
460
461 parameterized_job = models.ParameterizedJob.objects.create(
462 test=test_obj, label=label, use_container=use_container,
463 profile_only=profile_only,
464 upload_kernel_config=upload_kernel_config)
465 parameterized_job.kernels.add(*kernel_objs)
466
467 for profiler in profiler_objs:
468 parameterized_profiler = models.ParameterizedJobProfiler.objects.create(
469 parameterized_job=parameterized_job,
470 profiler=profiler)
471 profiler_params = profiler_parameters.get(profiler.name, {})
472 for name, (value, param_type) in profiler_params.iteritems():
473 models.ParameterizedJobProfilerParameter.objects.create(
474 parameterized_job_profiler=parameterized_profiler,
475 parameter_name=name,
476 parameter_value=value,
477 parameter_type=param_type)
478
479 try:
480 for parameter in test_obj.testparameter_set.all():
481 if parameter.name in parameters:
482 param_value, param_type = parameters.pop(parameter.name)
483 parameterized_job.parameterizedjobparameter_set.create(
484 test_parameter=parameter, parameter_value=param_value,
485 parameter_type=param_type)
486
487 if parameters:
488 raise Exception('Extra parameters remain: %r' % parameters)
489
490 return rpc_utils.create_job_common(
491 parameterized_job=parameterized_job.id,
492 control_type=control_type,
493 **rpc_utils.get_create_job_common_args(args))
494 except:
495 parameterized_job.delete()
496 raise
497
498
Simran Basib6ec8ae2014-04-23 12:05:08 -0700499def create_job_page_handler(name, priority, control_file, control_type,
500 image=None, hostless=False, **kwargs):
501 """\
502 Create and enqueue a job.
503
504 @param name name of this job
505 @param priority Integer priority of this job. Higher is more important.
506 @param control_file String contents of the control file.
507 @param control_type Type of control file, Client or Server.
508 @param kwargs extra args that will be required by create_suite_job or
509 create_job.
510
511 @returns The created Job id number.
512 """
513 control_file = rpc_utils.encode_ascii(control_file)
514
515 if image and hostless:
516 return site_rpc_interface.create_suite_job(
517 name=name, control_file=control_file, priority=priority,
518 build=image, **kwargs)
519 return create_job(name, priority, control_file, control_type, image=image,
520 hostless=hostless, **kwargs)
521
522
showard12f3e322009-05-13 21:27:42 +0000523def create_job(name, priority, control_file, control_type,
524 hosts=(), meta_hosts=(), one_time_hosts=(),
525 atomic_group_name=None, synch_count=None, is_template=False,
Simran Basi7e605742013-11-12 13:43:36 -0800526 timeout=None, timeout_mins=None, max_runtime_mins=None,
527 run_verify=False, email_list='', dependencies=(),
528 reboot_before=None, reboot_after=None, parse_failed_repair=None,
529 hostless=False, keyvals=None, drone_set=None, image=None,
Simran Basib6ec8ae2014-04-23 12:05:08 -0700530 parent_job_id=None, test_retry=0, run_reset=True, **kwargs):
jadmanski0afbb632008-06-06 21:10:57 +0000531 """\
532 Create and enqueue a job.
mblighe8819cd2008-02-15 16:48:40 +0000533
showarda1e74b32009-05-12 17:32:04 +0000534 @param name name of this job
Alex Miller7d658cf2013-09-04 16:00:35 -0700535 @param priority Integer priority of this job. Higher is more important.
showarda1e74b32009-05-12 17:32:04 +0000536 @param control_file String contents of the control file.
537 @param control_type Type of control file, Client or Server.
538 @param synch_count How many machines the job uses per autoserv execution.
539 synch_count == 1 means the job is asynchronous. If an atomic group is
540 given this value is treated as a minimum.
541 @param is_template If true then create a template job.
542 @param timeout Hours after this call returns until the job times out.
Simran Basi7e605742013-11-12 13:43:36 -0800543 @param timeout_mins Minutes after this call returns until the job times
544 out.
Simran Basi34217022012-11-06 13:43:15 -0800545 @param max_runtime_mins Minutes from job starting time until job times out
showarda1e74b32009-05-12 17:32:04 +0000546 @param run_verify Should the host be verified before running the test?
547 @param email_list String containing emails to mail when the job is done
548 @param dependencies List of label names on which this job depends
549 @param reboot_before Never, If dirty, or Always
550 @param reboot_after Never, If all tests passed, or Always
551 @param parse_failed_repair if true, results of failed repairs launched by
552 this job will be parsed as part of the job.
showarda9545c02009-12-18 22:44:26 +0000553 @param hostless if true, create a hostless job
showardc1a98d12010-01-15 00:22:22 +0000554 @param keyvals dict of keyvals to associate with the job
showarda1e74b32009-05-12 17:32:04 +0000555 @param hosts List of hosts to run job on.
556 @param meta_hosts List where each entry is a label name, and for each entry
557 one host will be chosen from that label to run the job on.
558 @param one_time_hosts List of hosts not in the database to run the job on.
559 @param atomic_group_name The name of an atomic group to schedule the job on.
jamesren76fcf192010-04-21 20:39:50 +0000560 @param drone_set The name of the drone set to run this test on.
Paul Pendlebury5a8c6ad2011-02-01 07:20:17 -0800561 @param image OS image to install before running job.
Aviv Keshet0b9cfc92013-02-05 11:36:02 -0800562 @param parent_job_id id of a job considered to be parent of created job.
Simran Basib6ec8ae2014-04-23 12:05:08 -0700563 @param test_retry Number of times to retry test if the test did not
Aviv Keshetcd1ff9b2013-03-01 14:55:19 -0800564 complete successfully. (optional, default: 0)
Simran Basib6ec8ae2014-04-23 12:05:08 -0700565 @param run_reset Should the host be reset before running the test?
566 @param kwargs extra keyword args. NOT USED.
showardc92da832009-04-07 18:14:34 +0000567
568 @returns The created Job id number.
jadmanski0afbb632008-06-06 21:10:57 +0000569 """
Simran Basiab5a1bf2014-05-28 15:39:44 -0700570 if image is None:
571 return rpc_utils.create_job_common(
572 **rpc_utils.get_create_job_common_args(locals()))
573
574 # When image is supplied use a known parameterized test already in the
575 # database to pass the OS image path from the front end, through the
576 # scheduler, and finally to autoserv as the --image parameter.
577
578 # The test autoupdate_ParameterizedJob is in afe_autotests and used to
579 # instantiate a Test object and from there a ParameterizedJob.
580 known_test_obj = models.Test.smart_get('autoupdate_ParameterizedJob')
581 known_parameterized_job = models.ParameterizedJob.objects.create(
582 test=known_test_obj)
583
584 # autoupdate_ParameterizedJob has a single parameter, the image parameter,
585 # stored in the table afe_test_parameters. We retrieve and set this
586 # instance of the parameter to the OS image path.
587 image_parameter = known_test_obj.testparameter_set.get(test=known_test_obj,
588 name='image')
589 known_parameterized_job.parameterizedjobparameter_set.create(
590 test_parameter=image_parameter, parameter_value=image,
591 parameter_type='string')
592
593 # By passing a parameterized_job to create_job_common the job entry in
594 # the afe_jobs table will have the field parameterized_job_id set.
595 # The scheduler uses this id in the afe_parameterized_jobs table to
596 # match this job to our known test, and then with the
597 # afe_parameterized_job_parameters table to get the actual image path.
jamesren4a41e012010-07-16 22:33:48 +0000598 return rpc_utils.create_job_common(
Simran Basiab5a1bf2014-05-28 15:39:44 -0700599 parameterized_job=known_parameterized_job.id,
jamesren4a41e012010-07-16 22:33:48 +0000600 **rpc_utils.get_create_job_common_args(locals()))
mblighe8819cd2008-02-15 16:48:40 +0000601
602
showard9dbdcda2008-10-14 17:34:36 +0000603def abort_host_queue_entries(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000604 """\
showard9dbdcda2008-10-14 17:34:36 +0000605 Abort a set of host queue entries.
jadmanski0afbb632008-06-06 21:10:57 +0000606 """
showard9dbdcda2008-10-14 17:34:36 +0000607 query = models.HostQueueEntry.query_objects(filter_data)
beepsfaecbce2013-10-29 11:35:10 -0700608
609 # Dont allow aborts on:
610 # 1. Jobs that have already completed (whether or not they were aborted)
611 # 2. Jobs that we have already been aborted (but may not have completed)
612 query = query.filter(complete=False).filter(aborted=False)
showarddc817512008-11-12 18:16:41 +0000613 models.AclGroup.check_abort_permissions(query)
showard9dbdcda2008-10-14 17:34:36 +0000614 host_queue_entries = list(query.select_related())
showard2bab8f42008-11-12 18:15:22 +0000615 rpc_utils.check_abort_synchronous_jobs(host_queue_entries)
mblighe8819cd2008-02-15 16:48:40 +0000616
Simran Basic1b26762013-06-26 14:23:21 -0700617 models.HostQueueEntry.abort_host_queue_entries(host_queue_entries)
showard9d821ab2008-07-11 16:54:29 +0000618
619
beeps8bb1f7d2013-08-05 01:30:09 -0700620def abort_special_tasks(**filter_data):
621 """\
622 Abort the special task, or tasks, specified in the filter.
623 """
624 query = models.SpecialTask.query_objects(filter_data)
625 special_tasks = query.filter(is_active=True)
626 for task in special_tasks:
627 task.abort()
628
629
Simran Basi73dae552013-02-25 14:57:46 -0800630def _call_special_tasks_on_hosts(task, hosts):
631 """\
632 Schedules a set of hosts for a special task.
633
634 @returns A list of hostnames that a special task was created for.
635 """
636 models.AclGroup.check_for_acl_violation_hosts(hosts)
637 for host in hosts:
638 models.SpecialTask.schedule_special_task(host, task)
639 return list(sorted(host.hostname for host in hosts))
640
641
showard1ff7b2e2009-05-15 23:17:18 +0000642def reverify_hosts(**filter_data):
643 """\
644 Schedules a set of hosts for verify.
mbligh4e545a52009-12-19 05:30:39 +0000645
646 @returns A list of hostnames that a verify task was created for.
showard1ff7b2e2009-05-15 23:17:18 +0000647 """
Simran Basi73dae552013-02-25 14:57:46 -0800648 return _call_special_tasks_on_hosts(models.SpecialTask.Task.VERIFY,
649 models.Host.query_objects(filter_data))
650
651
652def repair_hosts(**filter_data):
653 """\
654 Schedules a set of hosts for repair.
655
656 @returns A list of hostnames that a repair task was created for.
657 """
658 return _call_special_tasks_on_hosts(models.SpecialTask.Task.REPAIR,
659 models.Host.query_objects(filter_data))
showard1ff7b2e2009-05-15 23:17:18 +0000660
661
mblighe8819cd2008-02-15 16:48:40 +0000662def get_jobs(not_yet_run=False, running=False, finished=False, **filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000663 """\
664 Extra filter args for get_jobs:
665 -not_yet_run: Include only jobs that have not yet started running.
666 -running: Include only jobs that have start running but for which not
667 all hosts have completed.
668 -finished: Include only jobs for which all hosts have completed (or
669 aborted).
670 At most one of these three fields should be specified.
671 """
672 filter_data['extra_args'] = rpc_utils.extra_job_filters(not_yet_run,
673 running,
674 finished)
showard0957a842009-05-11 19:25:08 +0000675 job_dicts = []
676 jobs = list(models.Job.query_objects(filter_data))
677 models.Job.objects.populate_relationships(jobs, models.Label,
678 'dependencies')
showardc1a98d12010-01-15 00:22:22 +0000679 models.Job.objects.populate_relationships(jobs, models.JobKeyval, 'keyvals')
showard0957a842009-05-11 19:25:08 +0000680 for job in jobs:
681 job_dict = job.get_object_dict()
682 job_dict['dependencies'] = ','.join(label.name
683 for label in job.dependencies)
showardc1a98d12010-01-15 00:22:22 +0000684 job_dict['keyvals'] = dict((keyval.key, keyval.value)
685 for keyval in job.keyvals)
Eric Lid23bc192011-02-09 14:38:57 -0800686 if job.parameterized_job:
687 job_dict['image'] = get_parameterized_autoupdate_image_url(job)
showard0957a842009-05-11 19:25:08 +0000688 job_dicts.append(job_dict)
689 return rpc_utils.prepare_for_serialization(job_dicts)
mblighe8819cd2008-02-15 16:48:40 +0000690
691
692def get_num_jobs(not_yet_run=False, running=False, finished=False,
jadmanski0afbb632008-06-06 21:10:57 +0000693 **filter_data):
694 """\
695 See get_jobs() for documentation of extra filter parameters.
696 """
697 filter_data['extra_args'] = rpc_utils.extra_job_filters(not_yet_run,
698 running,
699 finished)
700 return models.Job.query_count(filter_data)
mblighe8819cd2008-02-15 16:48:40 +0000701
702
mblighe8819cd2008-02-15 16:48:40 +0000703def get_jobs_summary(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000704 """\
showarda8709c52008-07-03 19:44:54 +0000705 Like get_jobs(), but adds a 'status_counts' field, which is a dictionary
jadmanski0afbb632008-06-06 21:10:57 +0000706 mapping status strings to the number of hosts currently with that
707 status, i.e. {'Queued' : 4, 'Running' : 2}.
708 """
709 jobs = get_jobs(**filter_data)
710 ids = [job['id'] for job in jobs]
711 all_status_counts = models.Job.objects.get_status_counts(ids)
712 for job in jobs:
713 job['status_counts'] = all_status_counts[job['id']]
714 return rpc_utils.prepare_for_serialization(jobs)
mblighe8819cd2008-02-15 16:48:40 +0000715
716
showarda965cef2009-05-15 23:17:41 +0000717def get_info_for_clone(id, preserve_metahosts, queue_entry_filter_data=None):
showarda8709c52008-07-03 19:44:54 +0000718 """\
719 Retrieves all the information needed to clone a job.
720 """
showarda8709c52008-07-03 19:44:54 +0000721 job = models.Job.objects.get(id=id)
showard29f7cd22009-04-29 21:16:24 +0000722 job_info = rpc_utils.get_job_info(job,
showarda965cef2009-05-15 23:17:41 +0000723 preserve_metahosts,
724 queue_entry_filter_data)
showard945072f2008-09-03 20:34:59 +0000725
showardd9992fe2008-07-31 02:15:03 +0000726 host_dicts = []
showard29f7cd22009-04-29 21:16:24 +0000727 for host in job_info['hosts']:
728 host_dict = get_hosts(id=host.id)[0]
729 other_labels = host_dict['labels']
730 if host_dict['platform']:
731 other_labels.remove(host_dict['platform'])
732 host_dict['other_labels'] = ', '.join(other_labels)
showardd9992fe2008-07-31 02:15:03 +0000733 host_dicts.append(host_dict)
showarda8709c52008-07-03 19:44:54 +0000734
showard29f7cd22009-04-29 21:16:24 +0000735 for host in job_info['one_time_hosts']:
736 host_dict = dict(hostname=host.hostname,
737 id=host.id,
738 platform='(one-time host)',
739 locked_text='')
740 host_dicts.append(host_dict)
showarda8709c52008-07-03 19:44:54 +0000741
showard4d077562009-05-08 18:24:36 +0000742 # convert keys from Label objects to strings (names of labels)
showard29f7cd22009-04-29 21:16:24 +0000743 meta_host_counts = dict((meta_host.name, count) for meta_host, count
showard4d077562009-05-08 18:24:36 +0000744 in job_info['meta_host_counts'].iteritems())
showard29f7cd22009-04-29 21:16:24 +0000745
746 info = dict(job=job.get_object_dict(),
747 meta_host_counts=meta_host_counts,
748 hosts=host_dicts)
749 info['job']['dependencies'] = job_info['dependencies']
750 if job_info['atomic_group']:
751 info['atomic_group_name'] = (job_info['atomic_group']).name
752 else:
753 info['atomic_group_name'] = None
jamesren2275ef12010-04-12 18:25:06 +0000754 info['hostless'] = job_info['hostless']
jamesren76fcf192010-04-21 20:39:50 +0000755 info['drone_set'] = job.drone_set and job.drone_set.name
showarda8709c52008-07-03 19:44:54 +0000756
Eric Lid23bc192011-02-09 14:38:57 -0800757 if job.parameterized_job:
758 info['job']['image'] = get_parameterized_autoupdate_image_url(job)
759
showarda8709c52008-07-03 19:44:54 +0000760 return rpc_utils.prepare_for_serialization(info)
761
762
showard34dc5fa2008-04-24 20:58:40 +0000763# host queue entries
764
765def get_host_queue_entries(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000766 """\
showardc92da832009-04-07 18:14:34 +0000767 @returns A sequence of nested dictionaries of host and job information.
jadmanski0afbb632008-06-06 21:10:57 +0000768 """
showardc92da832009-04-07 18:14:34 +0000769 return rpc_utils.prepare_rows_as_nested_dicts(
770 models.HostQueueEntry.query_objects(filter_data),
771 ('host', 'atomic_group', 'job'))
showard34dc5fa2008-04-24 20:58:40 +0000772
773
774def get_num_host_queue_entries(**filter_data):
jadmanski0afbb632008-06-06 21:10:57 +0000775 """\
776 Get the number of host queue entries associated with this job.
777 """
778 return models.HostQueueEntry.query_count(filter_data)
showard34dc5fa2008-04-24 20:58:40 +0000779
780
showard1e935f12008-07-11 00:11:36 +0000781def get_hqe_percentage_complete(**filter_data):
782 """
showardc92da832009-04-07 18:14:34 +0000783 Computes the fraction of host queue entries matching the given filter data
showard1e935f12008-07-11 00:11:36 +0000784 that are complete.
785 """
786 query = models.HostQueueEntry.query_objects(filter_data)
787 complete_count = query.filter(complete=True).count()
788 total_count = query.count()
789 if total_count == 0:
790 return 1
791 return float(complete_count) / total_count
792
793
showard1a5a4082009-07-28 20:01:37 +0000794# special tasks
795
796def get_special_tasks(**filter_data):
797 return rpc_utils.prepare_rows_as_nested_dicts(
798 models.SpecialTask.query_objects(filter_data),
799 ('host', 'queue_entry'))
800
801
showardc0ac3a72009-07-08 21:14:45 +0000802# support for host detail view
803
804def get_host_queue_entries_and_special_tasks(hostname, query_start=None,
805 query_limit=None):
806 """
807 @returns an interleaved list of HostQueueEntries and SpecialTasks,
808 in approximate run order. each dict contains keys for type, host,
809 job, status, started_on, execution_path, and ID.
810 """
811 total_limit = None
812 if query_limit is not None:
813 total_limit = query_start + query_limit
814 filter_data = {'host__hostname': hostname,
815 'query_limit': total_limit,
816 'sort_by': ['-id']}
817
818 queue_entries = list(models.HostQueueEntry.query_objects(filter_data))
819 special_tasks = list(models.SpecialTask.query_objects(filter_data))
820
821 interleaved_entries = rpc_utils.interleave_entries(queue_entries,
822 special_tasks)
823 if query_start is not None:
824 interleaved_entries = interleaved_entries[query_start:]
825 if query_limit is not None:
826 interleaved_entries = interleaved_entries[:query_limit]
827 return rpc_utils.prepare_for_serialization(interleaved_entries)
828
829
830def get_num_host_queue_entries_and_special_tasks(hostname):
831 filter_data = {'host__hostname': hostname}
832 return (models.HostQueueEntry.query_count(filter_data)
833 + models.SpecialTask.query_count(filter_data))
834
835
showard29f7cd22009-04-29 21:16:24 +0000836# recurring run
837
838def get_recurring(**filter_data):
839 return rpc_utils.prepare_rows_as_nested_dicts(
840 models.RecurringRun.query_objects(filter_data),
841 ('job', 'owner'))
842
843
844def get_num_recurring(**filter_data):
845 return models.RecurringRun.query_count(filter_data)
846
847
848def delete_recurring_runs(**filter_data):
849 to_delete = models.RecurringRun.query_objects(filter_data)
850 to_delete.delete()
851
852
853def create_recurring_run(job_id, start_date, loop_period, loop_count):
showard64a95952010-01-13 21:27:16 +0000854 owner = models.User.current_user().login
showard29f7cd22009-04-29 21:16:24 +0000855 job = models.Job.objects.get(id=job_id)
856 return job.create_recurring_job(start_date=start_date,
857 loop_period=loop_period,
858 loop_count=loop_count,
859 owner=owner)
860
861
mblighe8819cd2008-02-15 16:48:40 +0000862# other
863
showarde0b63622008-08-04 20:58:47 +0000864def echo(data=""):
865 """\
866 Returns a passed in string. For doing a basic test to see if RPC calls
867 can successfully be made.
868 """
869 return data
870
871
showardb7a52fd2009-04-27 20:10:56 +0000872def get_motd():
873 """\
874 Returns the message of the day as a string.
875 """
876 return rpc_utils.get_motd()
877
878
mblighe8819cd2008-02-15 16:48:40 +0000879def get_static_data():
jadmanski0afbb632008-06-06 21:10:57 +0000880 """\
881 Returns a dictionary containing a bunch of data that shouldn't change
882 often and is otherwise inaccessible. This includes:
showardc92da832009-04-07 18:14:34 +0000883
884 priorities: List of job priority choices.
885 default_priority: Default priority value for new jobs.
886 users: Sorted list of all users.
887 labels: Sorted list of all labels.
888 atomic_groups: Sorted list of all atomic groups.
889 tests: Sorted list of all tests.
890 profilers: Sorted list of all profilers.
891 current_user: Logged-in username.
892 host_statuses: Sorted list of possible Host statuses.
893 job_statuses: Sorted list of possible HostQueueEntry statuses.
Simran Basi7e605742013-11-12 13:43:36 -0800894 job_timeout_default: The default job timeout length in minutes.
showarda1e74b32009-05-12 17:32:04 +0000895 parse_failed_repair_default: Default value for the parse_failed_repair job
896 option.
showardc92da832009-04-07 18:14:34 +0000897 reboot_before_options: A list of valid RebootBefore string enums.
898 reboot_after_options: A list of valid RebootAfter string enums.
899 motd: Server's message of the day.
900 status_dictionary: A mapping from one word job status names to a more
901 informative description.
jadmanski0afbb632008-06-06 21:10:57 +0000902 """
showard21baa452008-10-21 00:08:39 +0000903
904 job_fields = models.Job.get_field_dict()
jamesren76fcf192010-04-21 20:39:50 +0000905 default_drone_set_name = models.DroneSet.default_drone_set_name()
906 drone_sets = ([default_drone_set_name] +
907 sorted(drone_set.name for drone_set in
908 models.DroneSet.objects.exclude(
909 name=default_drone_set_name)))
showard21baa452008-10-21 00:08:39 +0000910
jadmanski0afbb632008-06-06 21:10:57 +0000911 result = {}
Alex Miller7d658cf2013-09-04 16:00:35 -0700912 result['priorities'] = priorities.Priority.choices()
913 default_priority = priorities.Priority.DEFAULT
914 result['default_priority'] = 'Default'
915 result['max_schedulable_priority'] = priorities.Priority.DEFAULT
jadmanski0afbb632008-06-06 21:10:57 +0000916 result['users'] = get_users(sort_by=['login'])
917 result['labels'] = get_labels(sort_by=['-platform', 'name'])
showardc92da832009-04-07 18:14:34 +0000918 result['atomic_groups'] = get_atomic_groups(sort_by=['name'])
jadmanski0afbb632008-06-06 21:10:57 +0000919 result['tests'] = get_tests(sort_by=['name'])
showard2b9a88b2008-06-13 20:55:03 +0000920 result['profilers'] = get_profilers(sort_by=['name'])
showard0fc38302008-10-23 00:44:07 +0000921 result['current_user'] = rpc_utils.prepare_for_serialization(
showard64a95952010-01-13 21:27:16 +0000922 models.User.current_user().get_object_dict())
showard2b9a88b2008-06-13 20:55:03 +0000923 result['host_statuses'] = sorted(models.Host.Status.names)
mbligh5a198b92008-12-11 19:33:29 +0000924 result['job_statuses'] = sorted(models.HostQueueEntry.Status.names)
Simran Basi7e605742013-11-12 13:43:36 -0800925 result['job_timeout_mins_default'] = models.Job.DEFAULT_TIMEOUT_MINS
Simran Basi34217022012-11-06 13:43:15 -0800926 result['job_max_runtime_mins_default'] = (
927 models.Job.DEFAULT_MAX_RUNTIME_MINS)
showarda1e74b32009-05-12 17:32:04 +0000928 result['parse_failed_repair_default'] = bool(
929 models.Job.DEFAULT_PARSE_FAILED_REPAIR)
jamesrendd855242010-03-02 22:23:44 +0000930 result['reboot_before_options'] = model_attributes.RebootBefore.names
931 result['reboot_after_options'] = model_attributes.RebootAfter.names
showard8fbae652009-01-20 23:23:10 +0000932 result['motd'] = rpc_utils.get_motd()
jamesren76fcf192010-04-21 20:39:50 +0000933 result['drone_sets_enabled'] = models.DroneSet.drone_sets_enabled()
934 result['drone_sets'] = drone_sets
jamesren4a41e012010-07-16 22:33:48 +0000935 result['parameterized_jobs'] = models.Job.parameterized_jobs_enabled()
showard8ac29b42008-07-17 17:01:55 +0000936
showardd3dc1992009-04-22 21:01:40 +0000937 result['status_dictionary'] = {"Aborted": "Aborted",
showard8ac29b42008-07-17 17:01:55 +0000938 "Verifying": "Verifying Host",
Alex Millerdfff2fd2013-05-28 13:05:06 -0700939 "Provisioning": "Provisioning Host",
showard8ac29b42008-07-17 17:01:55 +0000940 "Pending": "Waiting on other hosts",
941 "Running": "Running autoserv",
942 "Completed": "Autoserv completed",
943 "Failed": "Failed to complete",
showardd823b362008-07-24 16:35:46 +0000944 "Queued": "Queued",
showard5deb6772008-11-04 21:54:33 +0000945 "Starting": "Next in host's queue",
946 "Stopped": "Other host(s) failed verify",
showardd3dc1992009-04-22 21:01:40 +0000947 "Parsing": "Awaiting parse of final results",
showard29f7cd22009-04-29 21:16:24 +0000948 "Gathering": "Gathering log files",
showard8cc058f2009-09-08 16:26:33 +0000949 "Template": "Template job for recurring run",
mbligh4608b002010-01-05 18:22:35 +0000950 "Waiting": "Waiting for scheduler action",
Dan Shi07e09af2013-04-12 09:31:29 -0700951 "Archiving": "Archiving results",
952 "Resetting": "Resetting hosts"}
jadmanski0afbb632008-06-06 21:10:57 +0000953 return result
showard29f7cd22009-04-29 21:16:24 +0000954
955
956def get_server_time():
957 return datetime.datetime.now().strftime("%Y-%m-%d %H:%M")