1# Copyright 2015 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import cStringIO 6import mimetools 7 8from common.buildbot import network 9 10 11def Slaves(master_name): 12 slave_data = network.FetchData(network.BuildUrl(master_name, 'json/slaves')) 13 return sorted(Slave(master_name, slave_name, slave_info) 14 for slave_name, slave_info in slave_data.iteritems()) 15 16 17class Slave(object): 18 19 def __init__(self, master_name, name, data): 20 self._master_name = master_name 21 self._name = name 22 23 self._builders = frozenset(data['builders'].keys()) 24 self._connected = data['connected'] 25 26 if data['host']: 27 host_data = dict(mimetools.Message(cStringIO.StringIO(data['host']))) 28 self._bitness = 64 if '64' in host_data['architecture'] else 32 29 self._git_version = host_data['git version'] 30 self._hardware = host_data['product name'] 31 self._memory = float(host_data['memory total'].split()[0]) 32 self._os = _ParseOs(host_data['osfamily']) 33 self._os_version = _ParseOsVersion(self._os, host_data['os version']) 34 self._processor_count = host_data['processor count'] 35 else: 36 # The information is populated by Puppet. Puppet doesn't run on our GCE 37 # instances, so if the info is missing, assume it's in GCE. 38 self._bitness = 64 39 self._git_version = None 40 self._hardware = 'Compute Engine' 41 self._memory = None 42 self._os = 'linux' 43 self._os_version = None 44 self._processor_count = None 45 46 def __lt__(self, other): 47 return self.name < other.name 48 49 def __str__(self): 50 return self.name 51 52 @property 53 def master_name(self): 54 return self._master_name 55 56 @property 57 def name(self): 58 return self._name 59 60 @property 61 def builders(self): 62 return self._builders 63 64 @property 65 def bitness(self): 66 return self._bitness 67 68 @property 69 def git_version(self): 70 return self._git_version 71 72 @property 73 def hardware(self): 74 """Returns the model of the hardware. 75 76 For example, "MacBookPro11,2", "PowerEdge R220", or "Compute Engine". 77 """ 78 return self._hardware 79 80 @property 81 def memory(self): 82 """Returns the quantity of RAM, in GB, as a float.""" 83 return self._memory 84 85 @property 86 def os(self): 87 """Returns the canonical os name string. 88 89 The return value must be in the following list: 90 https://chromium.googlesource.com/infra/infra/+/HEAD/doc/users/services/buildbot/builders.pyl.md#os 91 """ 92 return self._os 93 94 @property 95 def os_version(self): 96 """Returns the canonical major os version name string. 97 98 The return value must be in the following table: 99 https://chromium.googlesource.com/infra/infra/+/HEAD/doc/users/services/buildbot/builders.pyl.md#version 100 """ 101 return self._os_version 102 103 @property 104 def processor_count(self): 105 return self._processor_count 106 107 108def _ParseOs(os_family): 109 return { 110 'darwin': 'mac', 111 'debian': 'linux', 112 'windows': 'win', 113 }[os_family.lower()] 114 115 116def _ParseOsVersion(os, os_version): 117 if os == 'mac': 118 return '.'.join(os_version.split('.')[:2]) 119 elif os == 'linux': 120 return { 121 '12.04': 'precise', 122 '14.04': 'trusty', 123 }[os_version] 124 elif os == 'win': 125 return { 126 '5.1.2600': 'xp', 127 '6.0.6001': 'vista', 128 '2008 R2': '2008', # 2008 R2 129 '7': 'win7', 130 '6.3.9600': 'win8', # 8.1 131 '10.0.10240': 'win10', 132 }[os_version] 133 else: 134 raise ValueError('"%s" is not a valid os string.' % os) 135