blob: 69f62a4ee86dd74a3dcbd6a94720788aab0f52f1 [file] [log] [blame]
Jakob Juelich8b110ee2014-09-15 16:13:42 -07001#
2# Copyright 2008 Google Inc. All Rights Reserved.
3
4"""
5The shard module contains the objects and methods used to
6manage shards in Autotest.
7
8The valid actions are:
9create: creates shard
10remove: deletes shard(s)
11list: lists shards with label
12
13See topic_common.py for a High Level Design and Algorithm.
14"""
15
Dan Shi25e1fd42014-12-19 14:36:42 -080016import sys
Jakob Juelich8b110ee2014-09-15 16:13:42 -070017from autotest_lib.cli import topic_common, action_common
18
19
20class shard(topic_common.atest):
21 """shard class
22 atest shard [create|delete|list] <options>"""
23 usage_action = '[create|delete|list]'
24 topic = msg_topic = 'shard'
25 msg_items = '<shards>'
26
27 def __init__(self):
28 """Add to the parser the options common to all the
29 shard actions"""
30 super(shard, self).__init__()
31
32 self.topic_parse_info = topic_common.item_parse_info(
33 attribute_name='shards',
34 use_leftover=True)
35
36
37 def get_items(self):
38 return self.shards
39
40
41class shard_help(shard):
42 """Just here to get the atest logic working.
43 Usage is set by its parent"""
44 pass
45
46
47class shard_list(action_common.atest_list, shard):
MK Ryu5dfcc892015-07-16 15:34:04 -070048 """Class for running atest shard list"""
Jakob Juelich8b110ee2014-09-15 16:13:42 -070049
50 def execute(self):
MK Ryu5dfcc892015-07-16 15:34:04 -070051 filters = {}
52 if self.shards:
53 filters['hostname__in'] = self.shards
54 return super(shard_list, self).execute(op='get_shards',
55 filters=filters)
Jakob Juelich8b110ee2014-09-15 16:13:42 -070056
57
58 def warn_if_label_assigned_to_multiple_shards(self, results):
59 """Prints a warning if one label is assigned to multiple shards.
60
61 This should never happen, but if it does, better be safe.
62
63 @param results: Results as passed to output().
64 """
65 assigned_labels = set()
66 for line in results:
67 for label in line['labels']:
68 if label in assigned_labels:
69 sys.stderr.write('WARNING: label %s is assigned to '
70 'multiple shards.\n'
71 'This will lead to unpredictable behavor '
72 'in which hosts and jobs will be assigned '
73 'to which shard.\n')
74 assigned_labels.add(label)
75
76
77 def output(self, results):
78 self.warn_if_label_assigned_to_multiple_shards(results)
79 super(shard_list, self).output(results, ['hostname', 'labels'])
80
81
82class shard_create(action_common.atest_create, shard):
83 """Class for running atest shard create -l <label> <shard>"""
84 def __init__(self):
85 super(shard_create, self).__init__()
MK Ryu5dfcc892015-07-16 15:34:04 -070086 self.parser.add_option('-l', '--labels',
87 help=('Assign LABELs to the SHARD. All jobs that '
88 'require one of the labels will be run on '
89 'the shard. List multiple labels separated '
90 'by a comma.'),
Jakob Juelich8b110ee2014-09-15 16:13:42 -070091 type='string',
MK Ryu5dfcc892015-07-16 15:34:04 -070092 metavar='LABELS')
Jakob Juelich8b110ee2014-09-15 16:13:42 -070093
94
95 def parse(self):
MK Ryu5dfcc892015-07-16 15:34:04 -070096 (options, leftover) = super(shard_create, self).parse(
97 req_items='shards')
98 if not options.labels:
99 print ('Must provide one or more labels separated by a comma '
100 'with -l <labels>')
Jakob Juelich8b110ee2014-09-15 16:13:42 -0700101 self.parser.print_help()
102 sys.exit(1)
103 self.data_item_key = 'hostname'
MK Ryu5dfcc892015-07-16 15:34:04 -0700104 self.data['labels'] = options.labels
Jakob Juelich8b110ee2014-09-15 16:13:42 -0700105 return (options, leftover)
106
107
108class shard_delete(action_common.atest_delete, shard):
109 """Class for running atest shard delete <shards>"""
Jakob Juelich8b110ee2014-09-15 16:13:42 -0700110
111 def parse(self):
112 (options, leftover) = super(shard_delete, self).parse()
Jakob Juelich8b110ee2014-09-15 16:13:42 -0700113 self.data_item_key = 'hostname'
114 return (options, leftover)
115
116
117 def execute(self, *args, **kwargs):
Jakob Juelich8b110ee2014-09-15 16:13:42 -0700118 print 'Please ensure the shard host is powered off.'
119 print ('Otherwise DUTs might be used by multiple shards at the same '
120 'time, which will lead to serious correctness problems.')
Dan Shi25e1fd42014-12-19 14:36:42 -0800121 return super(shard_delete, self).execute(*args, **kwargs)