blob: 2c0df677bf9085c63a1c406214768f85711946c4 [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):
48 """Class for running atest shard list [--label <labels>]"""
49
50 def parse(self):
51 host_info = topic_common.item_parse_info(attribute_name='labels',
52 inline_option='labels')
53 return super(shard_list, self).parse([host_info])
54
55
56 def execute(self):
57 return super(shard_list, self).execute(op='get_shards')
58
59
60 def warn_if_label_assigned_to_multiple_shards(self, results):
61 """Prints a warning if one label is assigned to multiple shards.
62
63 This should never happen, but if it does, better be safe.
64
65 @param results: Results as passed to output().
66 """
67 assigned_labels = set()
68 for line in results:
69 for label in line['labels']:
70 if label in assigned_labels:
71 sys.stderr.write('WARNING: label %s is assigned to '
72 'multiple shards.\n'
73 'This will lead to unpredictable behavor '
74 'in which hosts and jobs will be assigned '
75 'to which shard.\n')
76 assigned_labels.add(label)
77
78
79 def output(self, results):
80 self.warn_if_label_assigned_to_multiple_shards(results)
81 super(shard_list, self).output(results, ['hostname', 'labels'])
82
83
84class shard_create(action_common.atest_create, shard):
85 """Class for running atest shard create -l <label> <shard>"""
86 def __init__(self):
87 super(shard_create, self).__init__()
88 self.parser.add_option('-l', '--label',
89 help=('Assign LABEL to the SHARD. All jobs that '
90 'require this label, will be run on the '
91 'shard.'),
92 type='string',
93 metavar='LABEL')
94
95
96 def parse(self):
97 (options, leftover) = super(shard_create,
98 self).parse(req_items='shards')
99 if not options.label:
100 print 'Must provide a label with -l <label>'
101 self.parser.print_help()
102 sys.exit(1)
103 self.data_item_key = 'hostname'
104 self.data['label'] = options.label
105 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)