installer.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. import subprocess
  2. import os
  3. import os.path
  4. import time
  5. import traceback
  6. import sys
  7. import glob
  8. import logging
  9. class Installer:
  10. ############################################################
  11. # install_software
  12. ############################################################
  13. def install_software(self):
  14. if self.benchmarker.install == 'all' or self.benchmarker.install == 'server':
  15. self.__install_server_software()
  16. if self.benchmarker.install == 'all' or self.benchmarker.install == 'database':
  17. self.__install_database_software()
  18. if self.benchmarker.install == 'all' or self.benchmarker.install == 'client':
  19. self.__install_client_software()
  20. ############################################################
  21. # End install_software
  22. ############################################################
  23. ############################################################
  24. # __install_server_software
  25. ############################################################
  26. def __install_server_software(self):
  27. print("\nINSTALL: Installing server software\n")
  28. bash_functions_path='../toolset/setup/linux/bash_functions.sh'
  29. prereq_path='../toolset/setup/linux/prerequisites.sh'
  30. self.__run_command(". %s && . %s" % (bash_functions_path, prereq_path))
  31. # Pull in benchmarker include and exclude list
  32. exclude = self.benchmarker.exclude
  33. include = self.benchmarker.test
  34. if exclude == None:
  35. exclude = []
  36. # Assume we are running from FrameworkBenchmarks
  37. install_files = glob.glob('*/install.sh')
  38. for install_file in install_files:
  39. test = os.path.dirname(install_file)
  40. if test in exclude:
  41. logging.debug("%s has been excluded", test)
  42. continue
  43. elif include is not None and test not in include:
  44. logging.debug("%s not in include list", test)
  45. continue
  46. else:
  47. logging.debug("Running installer for %s", test)
  48. bash_functions_path="../toolset/setup/linux/bash_functions.sh"
  49. self.__run_command(". %s && . ../%s" % (bash_functions_path, install_file))
  50. self.__run_command("sudo apt-get -y autoremove");
  51. print("\nINSTALL: Finished installing server software\n")
  52. ############################################################
  53. # End __install_server_software
  54. ############################################################
  55. ############################################################
  56. # __install_error
  57. ############################################################
  58. def __install_error(self, message):
  59. print("\nINSTALL ERROR: %s\n" % message)
  60. if self.benchmarker.install_error_action == 'abort':
  61. sys.exit("Installation aborted.")
  62. ############################################################
  63. # End __install_error
  64. ############################################################
  65. ############################################################
  66. # __install_database_software
  67. ############################################################
  68. def __install_database_software(self):
  69. print("\nINSTALL: Installing database software\n")
  70. self.__run_command("cd .. && " + self.benchmarker.database_sftp_string(batch_file="../config/database_sftp_batch"), True)
  71. remote_script = """
  72. ##############################
  73. # Prerequisites
  74. ##############################
  75. sudo apt-get -y update
  76. sudo apt-get -y install build-essential git libev-dev libpq-dev libreadline6-dev postgresql
  77. sudo sh -c "echo '* - nofile 65535' >> /etc/security/limits.conf"
  78. sudo mkdir -p /ssd
  79. sudo mkdir -p /ssd/log
  80. ##############################
  81. # MySQL
  82. ##############################
  83. sudo sh -c "echo mysql-server mysql-server/root_password_again select secret | debconf-set-selections"
  84. sudo sh -c "echo mysql-server mysql-server/root_password select secret | debconf-set-selections"
  85. sudo apt-get -y install mysql-server
  86. sudo stop mysql
  87. # disable checking of disk size
  88. sudo cp mysql /etc/init.d/mysql
  89. sudo chmod +x /etc/init.d/mysql
  90. sudo cp mysql.conf /etc/init/mysql.conf
  91. # use the my.cnf file to overwrite /etc/mysql/my.cnf
  92. sudo mv /etc/mysql/my.cnf /etc/mysql/my.cnf.orig
  93. sudo mv my.cnf /etc/mysql/my.cnf
  94. sudo cp -R -p /var/lib/mysql /ssd/
  95. sudo cp -R -p /var/log/mysql /ssd/log
  96. sudo cp usr.sbin.mysqld /etc/apparmor.d/
  97. sudo /etc/init.d/apparmor reload
  98. sudo start mysql
  99. # Insert data
  100. mysql -uroot -psecret < create.sql
  101. ##############################
  102. # Postgres
  103. ##############################
  104. sudo useradd benchmarkdbuser -p benchmarkdbpass
  105. sudo -u postgres psql template1 < create-postgres-database.sql
  106. sudo -u benchmarkdbuser psql hello_world < create-postgres.sql
  107. sudo -u postgres -H /etc/init.d/postgresql stop
  108. sudo mv postgresql.conf /etc/postgresql/9.3/main/postgresql.conf
  109. sudo mv pg_hba.conf /etc/postgresql/9.3/main/pg_hba.conf
  110. sudo cp -R -p /var/lib/postgresql/9.3/main /ssd/postgresql
  111. sudo -u postgres -H /etc/init.d/postgresql start
  112. sudo mv 60-postgresql-shm.conf /etc/sysctl.d/60-postgresql-shm.conf
  113. ##############################
  114. # MongoDB
  115. ##############################
  116. sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
  117. sudo cp 10gen.list /etc/apt/sources.list.d/10gen.list
  118. sudo apt-get -y update
  119. sudo apt-get -y remove mongodb-clients
  120. sudo apt-get -y install mongodb-10gen
  121. sudo stop mongodb
  122. sudo mv /etc/mongodb.conf /etc/mongodb.conf.orig
  123. sudo mv mongodb.conf /etc/mongodb.conf
  124. sudo cp -R -p /var/lib/mongodb /ssd/
  125. sudo cp -R -p /var/log/mongodb /ssd/log/
  126. sudo start mongodb
  127. """
  128. print("\nINSTALL: %s" % self.benchmarker.database_ssh_string)
  129. p = subprocess.Popen(self.benchmarker.database_ssh_string.split(" "), stdin=subprocess.PIPE)
  130. p.communicate(remote_script)
  131. returncode = p.returncode
  132. if returncode != 0:
  133. self.__install_error("status code %s running subprocess '%s'." % (returncode, self.benchmarker.database_ssh_string))
  134. print("\nINSTALL: Finished installing database software\n")
  135. ############################################################
  136. # End __install_database_software
  137. ############################################################
  138. ############################################################
  139. # __install_client_software
  140. ############################################################
  141. def __install_client_software(self):
  142. print("\nINSTALL: Installing client software\n")
  143. remote_script = """
  144. ##############################
  145. # Prerequisites
  146. ##############################
  147. sudo apt-get -y update
  148. sudo apt-get -y install build-essential git libev-dev libpq-dev libreadline6-dev
  149. sudo sh -c "echo '* - nofile 65535' >> /etc/security/limits.conf"
  150. ##############################
  151. # wrk
  152. ##############################
  153. git clone https://github.com/wg/wrk.git
  154. cd wrk
  155. make
  156. sudo cp wrk /usr/local/bin
  157. cd ~
  158. #############################
  159. # pipeline.lua
  160. #############################
  161. cat << EOF | tee pipeline.lua
  162. init = function(args)
  163. wrk.init(args)
  164. local r = {}
  165. local depth = tonumber(args[1]) or 1
  166. for i=1,depth do
  167. r[i] = wrk.format()
  168. end
  169. req = table.concat(r)
  170. end
  171. request = function()
  172. return req
  173. end
  174. EOF
  175. """
  176. print("\nINSTALL: %s" % self.benchmarker.client_ssh_string)
  177. p = subprocess.Popen(self.benchmarker.client_ssh_string.split(" "), stdin=subprocess.PIPE)
  178. p.communicate(remote_script)
  179. returncode = p.returncode
  180. if returncode != 0:
  181. self.__install_error("status code %s running subprocess '%s'." % (returncode, self.benchmarker.client_ssh_string))
  182. print("\nINSTALL: Finished installing client software\n")
  183. ############################################################
  184. # End __install_client_software
  185. ############################################################
  186. ############################################################
  187. # __path_exists
  188. ############################################################
  189. def __path_exists(self, path, cwd=None):
  190. full_path = os.path.join(cwd or self.install_dir, path)
  191. if os.path.exists(full_path):
  192. print("\nEXISTS: %s " % full_path)
  193. return True
  194. print("\nNOT_EXISTS: %s" % full_path)
  195. return False
  196. ############################################################
  197. # End __path_exists
  198. ############################################################
  199. ############################################################
  200. # __run_command
  201. ############################################################
  202. def __run_command(self, command, send_yes=False, cwd=None, retry=False):
  203. try:
  204. cwd = os.path.join(self.install_dir, cwd)
  205. except AttributeError:
  206. cwd = self.install_dir
  207. if retry:
  208. max_attempts = 5
  209. else:
  210. max_attempts = 1
  211. attempt = 1
  212. delay = 0
  213. if send_yes:
  214. command = "yes yes | " + command
  215. print("\nINSTALL: %s (cwd=%s)" % (command, cwd))
  216. while attempt <= max_attempts:
  217. error_message = ""
  218. try:
  219. # Execute command.
  220. subprocess.check_call(command, shell=True, cwd=cwd, executable='/bin/bash')
  221. break # Exit loop if successful.
  222. except:
  223. exceptionType, exceptionValue, exceptionTraceBack = sys.exc_info()
  224. error_message = "".join(traceback.format_exception_only(exceptionType, exceptionValue))
  225. # Exit if there are no more attempts left.
  226. attempt += 1
  227. if attempt > max_attempts:
  228. break
  229. # Delay before next attempt.
  230. if delay == 0:
  231. delay = 5
  232. else:
  233. delay = delay * 2
  234. print("Attempt %s/%s starting in %s seconds." % (attempt, max_attempts, delay))
  235. time.sleep(delay)
  236. if error_message:
  237. self.__install_error(error_message)
  238. ############################################################
  239. # End __run_command
  240. ############################################################
  241. ############################################################
  242. # __bash_from_string
  243. # Runs bash -c "command" in install_dir.
  244. ############################################################
  245. def __bash_from_string(self, command):
  246. self.__run_command('bash -c "%s"' % command)
  247. ############################################################
  248. # End __bash_from_string
  249. ############################################################
  250. ############################################################
  251. # __download
  252. # Downloads a file from a URI.
  253. ############################################################
  254. def __download(self, uri, filename=""):
  255. if filename:
  256. if os.path.exists(filename):
  257. return
  258. filename_option = "-O %s " % filename
  259. else:
  260. filename_option = ""
  261. command = "wget -nv --no-check-certificate --trust-server-names %s%s" % (filename_option, uri)
  262. self.__run_command(command, retry=True)
  263. ############################################################
  264. # End __download
  265. ############################################################
  266. ############################################################
  267. # __init__(benchmarker)
  268. ############################################################
  269. def __init__(self, benchmarker):
  270. self.benchmarker = benchmarker
  271. self.install_dir = "installs"
  272. # setup logging
  273. logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
  274. try:
  275. os.mkdir(self.install_dir)
  276. except OSError:
  277. pass
  278. ############################################################
  279. # End __init__
  280. ############################################################
  281. # vim: sw=2