Hardware.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/usr/bin/env python2.6
  2. '''
  3. Licensed to the Apache Software Foundation (ASF) under one
  4. or more contributor license agreements. See the NOTICE file
  5. distributed with this work for additional information
  6. regarding copyright ownership. The ASF licenses this file
  7. to you under the Apache License, Version 2.0 (the
  8. "License"); you may not use this file except in compliance
  9. with the License. You may obtain a copy of the License at
  10. http://www.apache.org/licenses/LICENSE-2.0
  11. Unless required by applicable law or agreed to in writing, software
  12. distributed under the License is distributed on an "AS IS" BASIS,
  13. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. See the License for the specific language governing permissions and
  15. limitations under the License.
  16. '''
  17. import os.path
  18. import logging
  19. import subprocess
  20. import pprint
  21. import traceback
  22. import AmbariConfig
  23. logger = logging.getLogger()
  24. class Hardware:
  25. def __init__(self):
  26. self.hardware = {}
  27. osdisks = self.osdisks()
  28. self.hardware['mounts'] = osdisks
  29. otherInfo = self.facterInfo()
  30. self.hardware.update(otherInfo)
  31. pass
  32. def osdisks(self):
  33. """ Run df to find out the disks on the host. Only works on linux
  34. platforms. Note that this parser ignores any filesystems with spaces
  35. and any mounts with spaces. """
  36. mounts = []
  37. df = subprocess.Popen(["df", "-kPT"], stdout=subprocess.PIPE)
  38. dfdata = df.communicate()[0]
  39. lines = dfdata.splitlines()
  40. for l in lines:
  41. split = l.split()
  42. """ this ignores any spaces in the filesystemname and mounts """
  43. if (len(split)) == 7:
  44. device, type, size, used, available, percent, mountpoint = split
  45. mountinfo = {
  46. 'size' : size,
  47. 'used' : used,
  48. 'available' : available,
  49. 'percent' : percent,
  50. 'mountpoint' : mountpoint,
  51. 'type': type,
  52. 'device' : device }
  53. if os.access(mountpoint, os.W_OK):
  54. mounts.append(mountinfo)
  55. pass
  56. pass
  57. return mounts
  58. def facterBin(self, facterHome):
  59. facterBin = facterHome + "/bin/facter"
  60. if (os.path.exists(facterBin)):
  61. return facterBin
  62. else:
  63. return "facter"
  64. pass
  65. def facterLib(self, facterHome):
  66. return facterHome + "/lib/"
  67. pass
  68. def configureEnviron(self, environ):
  69. if not AmbariConfig.config.has_option("puppet", "ruby_home"):
  70. return environ
  71. ruby_home = AmbariConfig.config.get("puppet", "ruby_home")
  72. if os.path.exists(ruby_home):
  73. """Only update ruby home if the config is configured"""
  74. path = os.environ["PATH"]
  75. if not ruby_home in path:
  76. environ["PATH"] = ruby_home + os.path.sep + "bin" + ":"+environ["PATH"]
  77. environ["MY_RUBY_HOME"] = ruby_home
  78. return environ
  79. def parseFacterOutput(self, facterOutput):
  80. retDict = {}
  81. allLines = facterOutput.splitlines()
  82. for line in allLines:
  83. keyValue = line.split("=>")
  84. if (len(keyValue) == 2):
  85. """Ignoring values that are just spaces or do not confirm to the
  86. format"""
  87. strippedKey = keyValue[0].strip()
  88. logger.info("Stripped key is " + strippedKey)
  89. if strippedKey in ["memoryfree", "memorysize", "memorytotal"]:
  90. value = keyValue[1].strip()
  91. """Convert to KB"""
  92. parts = value.split()
  93. if len(parts) == 2:
  94. mem_size = parts[1].upper()
  95. if mem_size in ["GB", "G"]:
  96. mem_in_kb = long(float(parts[0]) * 1024 * 1024)
  97. elif mem_size in ["MB", "M"]:
  98. mem_in_kb = long(float(parts[0]) * 1024)
  99. elif mem_size in ["KB", "K"]:
  100. mem_in_kb = long(float(parts[0]))
  101. else:
  102. mem_in_kb = long(float(parts[0]) / 1024)
  103. else:
  104. mem_in_kb = long(float(parts[0]) / 1024)
  105. retDict[strippedKey] = mem_in_kb
  106. pass
  107. else:
  108. retDict[strippedKey] = keyValue[1].strip()
  109. pass
  110. pass
  111. pass
  112. """ Convert the needed types to the true values """
  113. if 'physicalprocessorcount' in retDict.keys():
  114. retDict['physicalprocessorcount'] = int(retDict['physicalprocessorcount'])
  115. pass
  116. if 'is_virtual' in retDict.keys():
  117. retDict['is_virtual'] = ("true" == retDict['is_virtual'])
  118. pass
  119. logger.info("Facter info : \n" + pprint.pformat(retDict))
  120. return retDict
  121. def facterInfo(self):
  122. facterHome = AmbariConfig.config.get("puppet", "facter_home")
  123. facterEnv = os.environ
  124. logger.info("Using facter home as: " + facterHome)
  125. facterInfo = {}
  126. try:
  127. if os.path.exists(facterHome):
  128. rubyLib = ""
  129. if os.environ.has_key("RUBYLIB"):
  130. rubyLib = os.environ["RUBYLIB"]
  131. logger.info("RUBYLIB from Env " + rubyLib)
  132. if not (self.facterLib(facterHome) in rubyLib):
  133. rubyLib = rubyLib + ":" + self.facterLib(facterHome)
  134. facterEnv["RUBYLIB"] = rubyLib
  135. facterEnv = self.configureEnviron(facterEnv)
  136. logger.info("Setting RUBYLIB as: " + rubyLib)
  137. facter = subprocess.Popen([self.facterBin(facterHome)],
  138. stdout=subprocess.PIPE,
  139. stderr=subprocess.PIPE,
  140. env=facterEnv)
  141. stderr_out = facter.communicate()
  142. if facter.returncode != 0:
  143. logging.error("Error getting facter info: " + stderr_out[1])
  144. pass
  145. facterOutput = stderr_out[0]
  146. infoDict = self.parseFacterOutput(facterOutput)
  147. facterInfo = infoDict
  148. pass
  149. else:
  150. logger.error("Facter home at " + facterHome + " does not exist")
  151. except:
  152. logger.info("Traceback " + traceback.format_exc())
  153. pass
  154. return facterInfo
  155. def get(self):
  156. return self.hardware
  157. def main(argv=None):
  158. hardware = Hardware()
  159. print hardware.get()
  160. if __name__ == '__main__':
  161. main()