1*1fa4b3daSHector Dearman#!/usr/bin/env python 2*1fa4b3daSHector Dearman# Copyright 2015 The Chromium Authors. All rights reserved. 3*1fa4b3daSHector Dearman# Use of this source code is governed by a BSD-style license that can be 4*1fa4b3daSHector Dearman# found in the LICENSE file. 5*1fa4b3daSHector Dearman 6*1fa4b3daSHector Dearman"""Query build slave hardware info, and print it to stdout as csv.""" 7*1fa4b3daSHector Dearman 8*1fa4b3daSHector Dearmanimport csv 9*1fa4b3daSHector Dearmanimport json 10*1fa4b3daSHector Dearmanimport logging 11*1fa4b3daSHector Dearmanimport sys 12*1fa4b3daSHector Dearmanimport urllib2 13*1fa4b3daSHector Dearman 14*1fa4b3daSHector Dearman 15*1fa4b3daSHector Dearman_MASTERS = [ 16*1fa4b3daSHector Dearman 'chromium.perf', 17*1fa4b3daSHector Dearman 'chromium.perf.fyi', 18*1fa4b3daSHector Dearman 'client.catapult', 19*1fa4b3daSHector Dearman 'tryserver.chromium.perf', 20*1fa4b3daSHector Dearman 'tryserver.client.catapult', 21*1fa4b3daSHector Dearman] 22*1fa4b3daSHector Dearman 23*1fa4b3daSHector Dearman 24*1fa4b3daSHector Dearman_KEYS = [ 25*1fa4b3daSHector Dearman 'master', 'builder', 'hostname', 26*1fa4b3daSHector Dearman 27*1fa4b3daSHector Dearman 'os family', 'os version', 'bitness (userland)', 28*1fa4b3daSHector Dearman 29*1fa4b3daSHector Dearman 'product name', 'architecture', 'processor count', 'processor type', 30*1fa4b3daSHector Dearman 'memory total', 31*1fa4b3daSHector Dearman 32*1fa4b3daSHector Dearman 'facter version', 'git version', 'puppet version', 'python version', 33*1fa4b3daSHector Dearman 'ruby version', 34*1fa4b3daSHector Dearman 35*1fa4b3daSHector Dearman 'android device 1', 'android device 2', 'android device 3', 36*1fa4b3daSHector Dearman 'android device 4', 'android device 5', 'android device 6', 37*1fa4b3daSHector Dearman 'android device 7', 'android device 8', 38*1fa4b3daSHector Dearman] 39*1fa4b3daSHector Dearman_EXCLUDED_KEYS = frozenset([ 40*1fa4b3daSHector Dearman 'architecture (userland)', 41*1fa4b3daSHector Dearman 'b directory', 42*1fa4b3daSHector Dearman 'last puppet run', 43*1fa4b3daSHector Dearman 'uptime', 44*1fa4b3daSHector Dearman 'windows version', 45*1fa4b3daSHector Dearman]) 46*1fa4b3daSHector Dearman 47*1fa4b3daSHector Dearman 48*1fa4b3daSHector Dearmandef main(): 49*1fa4b3daSHector Dearman writer = csv.DictWriter(sys.stdout, _KEYS) 50*1fa4b3daSHector Dearman writer.writeheader() 51*1fa4b3daSHector Dearman 52*1fa4b3daSHector Dearman for master_name in _MASTERS: 53*1fa4b3daSHector Dearman master_data = json.load(urllib2.urlopen( 54*1fa4b3daSHector Dearman 'http://build.chromium.org/p/%s/json/slaves' % master_name)) 55*1fa4b3daSHector Dearman 56*1fa4b3daSHector Dearman slaves = sorted(master_data.iteritems(), 57*1fa4b3daSHector Dearman key=lambda x: (x[1]['builders'].keys(), x[0])) 58*1fa4b3daSHector Dearman for slave_name, slave_data in slaves: 59*1fa4b3daSHector Dearman for builder_name in slave_data['builders']: 60*1fa4b3daSHector Dearman row = { 61*1fa4b3daSHector Dearman 'master': master_name, 62*1fa4b3daSHector Dearman 'builder': builder_name, 63*1fa4b3daSHector Dearman 'hostname': slave_name, 64*1fa4b3daSHector Dearman } 65*1fa4b3daSHector Dearman 66*1fa4b3daSHector Dearman host_data = slave_data['host'] 67*1fa4b3daSHector Dearman if host_data: 68*1fa4b3daSHector Dearman host_data = host_data.splitlines() 69*1fa4b3daSHector Dearman if len(host_data) > 1: 70*1fa4b3daSHector Dearman for line in host_data: 71*1fa4b3daSHector Dearman if not line: 72*1fa4b3daSHector Dearman continue 73*1fa4b3daSHector Dearman key, value = line.split(': ') 74*1fa4b3daSHector Dearman if key in _EXCLUDED_KEYS: 75*1fa4b3daSHector Dearman continue 76*1fa4b3daSHector Dearman row[key] = value 77*1fa4b3daSHector Dearman 78*1fa4b3daSHector Dearman # Munge keys. 79*1fa4b3daSHector Dearman row = {key.replace('_', ' '): value for key, value in row.iteritems()} 80*1fa4b3daSHector Dearman if 'osfamily' in row: 81*1fa4b3daSHector Dearman row['os family'] = row.pop('osfamily') 82*1fa4b3daSHector Dearman if 'product name' not in row and slave_name.startswith('slave'): 83*1fa4b3daSHector Dearman row['product name'] = 'Google Compute Engine' 84*1fa4b3daSHector Dearman 85*1fa4b3daSHector Dearman try: 86*1fa4b3daSHector Dearman writer.writerow(row) 87*1fa4b3daSHector Dearman except ValueError: 88*1fa4b3daSHector Dearman logging.error(row) 89*1fa4b3daSHector Dearman raise 90*1fa4b3daSHector Dearman 91*1fa4b3daSHector Dearman 92*1fa4b3daSHector Dearmanif __name__ == '__main__': 93*1fa4b3daSHector Dearman main() 94