1 # 2 # Copyright 2008 Google Inc. All Rights Reserved. 3 4 """ 5 The label module contains the objects and methods used to 6 manage labels in Autotest. 7 8 The valid actions are: 9 add: adds label(s), or hosts to an LABEL 10 remove: deletes label(s), or hosts from an LABEL 11 list: lists label(s) 12 13 The common options are: 14 --blist / -B: file containing a list of LABELs 15 16 See topic_common.py for a High Level Design and Algorithm. 17 """ 18 19 import sys 20 from autotest_lib.cli import topic_common, action_common 21 22 23 class label(topic_common.atest): 24 """Label class 25 atest label [create|delete|list|add|remove] <options>""" 26 usage_action = '[create|delete|list|add|remove]' 27 topic = msg_topic = 'label' 28 msg_items = '<labels>' 29 30 def __init__(self): 31 """Add to the parser the options common to all the 32 label actions""" 33 super(label, self).__init__() 34 35 self.parser.add_option('-B', '--blist', 36 help='File listing the labels', 37 type='string', 38 default=None, 39 metavar='LABEL_FLIST') 40 41 self.topic_parse_info = topic_common.item_parse_info( 42 attribute_name='labels', 43 filename_option='blist', 44 use_leftover=True) 45 46 47 def get_items(self): 48 return self.labels 49 50 51 class label_help(label): 52 """Just here to get the atest logic working. 53 Usage is set by its parent""" 54 pass 55 56 57 class label_list(action_common.atest_list, label): 58 """atest label list [--platform] [--all] 59 [--valid-only] [--machine <machine>] 60 [--blist <file>] [<labels>]""" 61 def __init__(self): 62 super(label_list, self).__init__() 63 64 self.parser.add_option('-t', '--platform-only', 65 help='Display only platform labels', 66 action='store_true') 67 68 self.parser.add_option('-d', '--valid-only', 69 help='Display only valid labels', 70 action='store_true') 71 72 self.parser.add_option('-a', '--all', 73 help=('Display both normal & ' 74 'platform labels'), 75 action='store_true') 76 77 self.parser.add_option('-m', '--machine', 78 help='List LABELs of MACHINE', 79 type='string', 80 metavar='MACHINE') 81 82 83 def parse(self): 84 host_info = topic_common.item_parse_info(attribute_name='hosts', 85 inline_option='machine') 86 (options, leftover) = super(label_list, self).parse([host_info]) 87 88 exclusives = [options.all, options.platform_only] 89 if exclusives.count(True) > 1: 90 self.invalid_syntax('Only specify one of --all,' 91 '--platform') 92 93 if len(self.hosts) > 1: 94 self.invalid_syntax(('Only one machine name allowed. ' 95 '''Use '%s host list %s' ''' 96 'instead.') % 97 (sys.argv[0], ','.join(self.hosts))) 98 self.all = options.all 99 self.platform_only = options.platform_only 100 self.valid_only = options.valid_only 101 return (options, leftover) 102 103 104 def execute(self): 105 filters = {} 106 check_results = {} 107 if self.hosts: 108 filters['host__hostname__in'] = self.hosts 109 check_results['host__hostname__in'] = None 110 111 if self.labels: 112 filters['name__in'] = self.labels 113 check_results['name__in'] = 'name' 114 115 return super(label_list, self).execute(op='get_labels', 116 filters=filters, 117 check_results=check_results) 118 119 120 def output(self, results): 121 if self.valid_only: 122 results = [label for label in results 123 if not label['invalid']] 124 125 if self.platform_only: 126 results = [label for label in results 127 if label['platform']] 128 keys = ['name', 'invalid'] 129 elif not self.all: 130 results = [label for label in results 131 if not label['platform']] 132 keys = ['name', 'only_if_needed', 'invalid'] 133 else: 134 keys = ['name', 'platform', 'only_if_needed', 'invalid'] 135 136 super(label_list, self).output(results, keys) 137 138 139 class label_create(action_common.atest_create, label): 140 """atest label create <labels>|--blist <file> --platform""" 141 def __init__(self): 142 super(label_create, self).__init__() 143 self.parser.add_option('-t', '--platform', 144 help='To create this label as a platform', 145 default=False, 146 action='store_true') 147 self.parser.add_option('-o', '--only_if_needed', 148 help='To mark the label as "only use if needed', 149 default=False, 150 action='store_true') 151 152 153 def parse(self): 154 (options, leftover) = super(label_create, 155 self).parse(req_items='labels') 156 self.data_item_key = 'name' 157 self.data['platform'] = options.platform 158 self.data['only_if_needed'] = options.only_if_needed 159 return (options, leftover) 160 161 162 class label_delete(action_common.atest_delete, label): 163 """atest label delete <labels>|--blist <file>""" 164 pass 165 166 167 168 class label_add_or_remove(label): 169 """Parent for `atest label` add and `label remove`""" 170 def __init__(self): 171 super(label_add_or_remove, self).__init__() 172 lower_words = tuple(word.lower() for word in self.usage_words) 173 self.parser.add_option('-m', '--machine', 174 help=('%s MACHINE(s) %s the LABEL' % 175 self.usage_words), 176 type='string', 177 metavar='MACHINE') 178 self.parser.add_option('-M', '--mlist', 179 help='File containing machines to %s %s ' 180 'the LABEL' % lower_words, 181 type='string', 182 metavar='MACHINE_FLIST') 183 184 185 def parse(self): 186 host_info = topic_common.item_parse_info(attribute_name='hosts', 187 inline_option='machine', 188 filename_option='mlist') 189 (options, leftover) = super(label_add_or_remove, 190 self).parse([host_info], 191 req_items='labels') 192 193 if not getattr(self, 'hosts', None): 194 self.invalid_syntax('%s %s requires at least one host' % 195 (self.msg_topic, 196 self.usage_action)) 197 return (options, leftover) 198 199 200 class label_add(action_common.atest_add, label_add_or_remove): 201 """atest label add <labels>|--blist <file> 202 --platform [--machine <machine>] [--mlist <file>]""" 203 pass 204 205 206 class label_remove(action_common.atest_remove, label_add_or_remove): 207 """atest label remove <labels>|--blist <file> 208 [--machine <machine>] [--mlist <file>]""" 209 pass 210