setupAgent.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #!/usr/bin/env python
  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 socket
  18. import time
  19. import sys
  20. import logging
  21. import pprint
  22. import os
  23. import subprocess
  24. import threading
  25. import traceback
  26. import stat
  27. from pprint import pformat
  28. import re
  29. AMBARI_PASSPHRASE_VAR = "AMBARI_PASSPHRASE"
  30. def execOsCommand(osCommand):
  31. osStat = subprocess.Popen(osCommand, stdout=subprocess.PIPE)
  32. log = osStat.communicate(0)
  33. ret = {"exitstatus": osStat.returncode, "log": log}
  34. return ret
  35. def is_suse():
  36. if os.path.isfile("/etc/issue"):
  37. if "suse" in open("/etc/issue").read().lower():
  38. return True
  39. return False
  40. def installAgentSuse(projectVersion):
  41. """ Run zypper install and make sure the agent install alright """
  42. zypperCommand = ["zypper", "install", "-y", "ambari-agent" + projectVersion]
  43. return execOsCommand(zypperCommand)
  44. def installAgent(projectVersion):
  45. """ Run yum install and make sure the agent install alright """
  46. # The command doesn't work with file mask ambari-agent*.rpm, so rename it on agent host
  47. rpmCommand = ["yum", "-y", "install", "--nogpgcheck", "ambari-agent" + projectVersion]
  48. return execOsCommand(rpmCommand)
  49. def configureAgent(server_hostname):
  50. """ Configure the agent so that it has all the configs knobs properly installed """
  51. osCommand = ["sed", "-i.bak", "s/hostname=localhost/hostname=" + server_hostname +\
  52. "/g", "/etc/ambari-agent/conf/ambari-agent.ini"]
  53. execOsCommand(osCommand)
  54. return
  55. def runAgent(passPhrase, expected_hostname):
  56. os.environ[AMBARI_PASSPHRASE_VAR] = passPhrase
  57. agent_retcode = subprocess.call("/usr/sbin/ambari-agent restart --expected-hostname=" +\
  58. expected_hostname, shell=True)
  59. try:
  60. ret = execOsCommand(["tail", "-20", "/var/log/ambari-agent/ambari-agent.log"])
  61. try:
  62. log = ret['log']
  63. except Exception:
  64. log = "Log not found"
  65. print log
  66. if not 0 == ret['exitstatus']:
  67. return ret['exitstatus']
  68. return agent_retcode
  69. except (Exception), e:
  70. return 1
  71. def getOptimalVersion(initialProjectVersion):
  72. optimalVersion = initialProjectVersion
  73. if is_suse():
  74. ret = findNearestAgentPackageVersionSuse(optimalVersion)
  75. else:
  76. ret = findNearestAgentPackageVersion(optimalVersion)
  77. if ret["exitstatus"] == 0 and ret["log"][0].strip() != "":
  78. optimalVersion = ret["log"][0].strip()
  79. retcode = 0
  80. else:
  81. if is_suse():
  82. ret = getAvaliableAgentPackageVersionsSuse()
  83. else:
  84. ret = getAvaliableAgentPackageVersions()
  85. retcode = 1
  86. optimalVersion = ret["log"]
  87. return {"exitstatus": retcode, "log": optimalVersion}
  88. def findNearestAgentPackageVersionSuse(projectVersion):
  89. if projectVersion == "":
  90. projectVersion = " "
  91. zypperCommand = ["bash", "-c", "zypper search -s --match-exact ambari-agent | grep '" + projectVersion +\
  92. "' | cut -d '|' -f 4 | head -n1 | sed -e 's/-\w[^:]*//1' "]
  93. return execOsCommand(zypperCommand)
  94. def findNearestAgentPackageVersion(projectVersion):
  95. if projectVersion == "":
  96. projectVersion = " "
  97. yumCommand = ["bash", "-c", "yum list all ambari-agent | grep '" + projectVersion +\
  98. "' | sed -re 's/\s+/ /g' | cut -d ' ' -f 2 | head -n1 | sed -e 's/-\w[^:]*//1' "]
  99. return execOsCommand(yumCommand)
  100. def isAgentPackageAlreadyInstalled(projectVersion):
  101. yumCommand = ["bash", "-c", "rpm -qa | grep ambari-agent"+projectVersion]
  102. ret = execOsCommand(yumCommand)
  103. res = False
  104. if ret["exitstatus"] == 0 and ret["log"][0].strip() != "":
  105. res = True
  106. return res
  107. def getAvaliableAgentPackageVersions():
  108. yumCommand = ["bash", "-c",
  109. """yum list all ambari-agent | grep -E '^ambari-agent' | sed -re 's/\s+/ /g' | cut -d ' ' -f 2 | tr '\\n' ', ' """]
  110. return execOsCommand(yumCommand)
  111. def getAvaliableAgentPackageVersionsSuse():
  112. yumCommand = ["bash", "-c",
  113. """zypper search -s --match-exact ambari-agent | grep -E '^ambari-agent' | sed -re 's/\s+/ /g' | cut -d '|' -f 4 | tr '\\n' ', ' """]
  114. return execOsCommand(yumCommand)
  115. def checkServerReachability(host, port):
  116. ret = {}
  117. s = socket.socket()
  118. try:
  119. s.connect((host, port))
  120. return
  121. except Exception:
  122. ret["exitstatus"] = 1
  123. ret["log"] = "Host registration aborted. Ambari Agent host cannot reach Ambari Server '" +\
  124. host+":"+str(port) + "'. "+\
  125. "Please check the network connectivity between the Ambari Agent host and the Ambari Server"
  126. sys.exit(ret)
  127. pass
  128. def main(argv=None):
  129. scriptDir = os.path.realpath(os.path.dirname(argv[0]))
  130. # Parse the input
  131. onlyargs = argv[1:]
  132. expected_hostname = onlyargs[0]
  133. passPhrase = onlyargs[1]
  134. hostname = onlyargs[2]
  135. projectVersion = None
  136. server_port = 8080
  137. if len(onlyargs) > 3:
  138. projectVersion = onlyargs[3]
  139. if len(onlyargs) > 4:
  140. server_port = onlyargs[4]
  141. try:
  142. server_port = int(server_port)
  143. except (Exception), e:
  144. server_port = 8080
  145. checkServerReachability(hostname, server_port)
  146. if projectVersion is None or projectVersion == "null" or projectVersion == "{ambariVersion}" or projectVersion == "":
  147. retcode = getOptimalVersion("")
  148. else:
  149. retcode = getOptimalVersion(projectVersion)
  150. if retcode["exitstatus"] == 0 and retcode["log"] != None and retcode["log"] != "" and retcode["log"][0].strip() != "":
  151. availiableProjectVersion = "-" + retcode["log"].strip()
  152. if not isAgentPackageAlreadyInstalled(availiableProjectVersion):
  153. if is_suse():
  154. ret = installAgentSuse(availiableProjectVersion)
  155. else:
  156. ret = installAgent(availiableProjectVersion)
  157. if (not ret["exitstatus"]== 0):
  158. sys.exit(ret)
  159. elif retcode["exitstatus"] == 1 and retcode["log"][0].strip() != "":
  160. sys.exit({"exitstatus": 1, "log": "Desired version ("+projectVersion+") of ambari-agent package"
  161. " is not available."
  162. " Repository has following "
  163. "versions of ambari-agent:"+retcode["log"][0].strip()})
  164. else:
  165. sys.exit(retcode)
  166. configureAgent(hostname)
  167. sys.exit(runAgent(passPhrase, expected_hostname))
  168. if __name__ == '__main__':
  169. logging.basicConfig(level=logging.DEBUG)
  170. main(sys.argv)