ambari-server.py 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878
  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 optparse
  18. import shlex
  19. import sys
  20. import os
  21. import signal
  22. import subprocess
  23. import re
  24. import string
  25. import glob
  26. import platform
  27. import shutil
  28. import stat
  29. import fileinput
  30. import urllib2
  31. import time
  32. import getpass
  33. import datetime
  34. # debug settings
  35. VERBOSE = False
  36. SILENT = False
  37. SERVER_START_DEBUG = False
  38. # action commands
  39. SETUP_ACTION = "setup"
  40. START_ACTION = "start"
  41. STOP_ACTION = "stop"
  42. RESET_ACTION = "reset"
  43. UPGRADE_ACTION = "upgrade"
  44. UPGRADE_STACK_ACTION = "upgradestack"
  45. STATUS_ACTION = "status"
  46. # selinux commands
  47. GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
  48. SE_SETENFORCE_CMD = "setenforce 0"
  49. SE_STATUS_DISABLED = "disabled"
  50. SE_STATUS_ENABLED = "enabled"
  51. SE_MODE_ENFORCING = "enforcing"
  52. SE_MODE_PERMISSIVE = "permissive"
  53. # iptables commands
  54. IP_TBLS_ST_CMD = "/sbin/service iptables status"
  55. IP_TBLS_STOP_CMD = "/sbin/service iptables stop"
  56. IP_TBLS_ENABLED = "Firewall is running"
  57. IP_TBLS_DISABLED = "Firewall is stopped.\n"
  58. IP_TBLS_SRVC_NT_FND = "iptables: unrecognized service"
  59. # server commands
  60. ambari_provider_module_option = ""
  61. ambari_provider_module = os.environ.get('AMBARI_PROVIDER_MODULE')
  62. # constants
  63. STACK_NAME_VER_SEP = "-"
  64. JAVA_SHARE_PATH="/usr/share/java"
  65. # terminal styles
  66. BOLD_ON='\033[1m'
  67. BOLD_OFF='\033[0m'
  68. if ambari_provider_module is not None:
  69. ambari_provider_module_option = "-Dprovider.module.class=" +\
  70. ambari_provider_module + " "
  71. SERVER_START_CMD="{0}" + os.sep + "bin" + os.sep +\
  72. "java -server -XX:NewRatio=3 "\
  73. "-XX:+UseConcMarkSweepGC " +\
  74. "-XX:-UseGCOverheadLimit -XX:CMSInitiatingOccupancyFraction=60 " +\
  75. ambari_provider_module_option +\
  76. os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') +\
  77. " -cp {1}"+ os.pathsep + "{2}" +\
  78. " org.apache.ambari.server.controller.AmbariServer "\
  79. ">/var/log/ambari-server/ambari-server.out 2>&1"
  80. SERVER_START_CMD_DEBUG="{0}" + os.sep + "bin" + os.sep +\
  81. "java -server -XX:NewRatio=2 -XX:+UseConcMarkSweepGC " +\
  82. ambari_provider_module_option +\
  83. os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') +\
  84. " -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,"\
  85. "server=y,suspend=n -cp {1}"+ os.pathsep + "{2}" +\
  86. " org.apache.ambari.server.controller.AmbariServer"
  87. AMBARI_CONF_VAR="AMBARI_CONF_DIR"
  88. AMBARI_SERVER_LIB="AMBARI_SERVER_LIB"
  89. JAVA_HOME="JAVA_HOME"
  90. PID_DIR="/var/run/ambari-server"
  91. PID_NAME="ambari-server.pid"
  92. AMBARI_PROPERTIES_FILE="ambari.properties"
  93. AMBARI_PROPERTIES_RPMSAVE_FILE="ambari.properties.rpmsave"
  94. RESOURCES_DIR="/var/lib/ambari-server/resources"
  95. SETUP_DB_CMD = ['su', '-', 'postgres',
  96. '--command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'"']
  97. UPGRADE_STACK_CMD = ['su', 'postgres',
  98. '--command=psql -f {0} -v stack_name="\'{1}\'" -v stack_version="\'{2}\'"']
  99. PG_ST_CMD = "/sbin/service postgresql status"
  100. PG_INITDB_CMD = "/sbin/service postgresql initdb"
  101. PG_START_CMD = "/sbin/service postgresql start"
  102. PG_RESTART_CMD = "/sbin/service postgresql restart"
  103. PG_STATUS_RUNNING = "running"
  104. PG_HBA_DIR = "/var/lib/pgsql/data/"
  105. PG_HBA_CONF_FILE = PG_HBA_DIR + "pg_hba.conf"
  106. PG_HBA_CONF_FILE_BACKUP = PG_HBA_DIR + "pg_hba_bak.conf.old"
  107. POSTGRESQL_CONF_FILE = PG_HBA_DIR + "postgresql.conf"
  108. PG_HBA_RELOAD_CMD = "su postgres --command='pg_ctl -D {0} reload'"
  109. PG_DEFAULT_PASSWORD = "bigdata"
  110. JDBC_DATABASE_PROPERTY = "server.jdbc.database"
  111. JDBC_HOSTNAME_PROPERTY = "server.jdbc.hostname"
  112. JDBC_PORT_PROPERTY = "server.jdbc.port"
  113. JDBC_SCHEMA_PROPERTY = "server.jdbc.schema"
  114. JDBC_USER_NAME_PROPERTY = "server.jdbc.user.name"
  115. JDBC_PASSWORD_FILE_PROPERTY = "server.jdbc.user.passwd"
  116. JDBC_PASSWORD_FILENAME = "password.dat"
  117. JDBC_RCA_PASSWORD_FILENAME = "rca_password.dat"
  118. PERSISTENCE_TYPE_PROPERTY = "server.persistence.type"
  119. JDBC_DRIVER_PROPERTY = "server.jdbc.driver"
  120. JDBC_URL_PROPERTY = "server.jdbc.url"
  121. JDBC_RCA_DATABASE_PROPERTY = "server.jdbc.database"
  122. JDBC_RCA_HOSTNAME_PROPERTY = "server.jdbc.hostname"
  123. JDBC_RCA_PORT_PROPERTY = "server.jdbc.port"
  124. JDBC_RCA_SCHEMA_PROPERTY = "server.jdbc.schema"
  125. JDBC_RCA_DRIVER_PROPERTY = "server.jdbc.rca.driver"
  126. JDBC_RCA_URL_PROPERTY = "server.jdbc.rca.url"
  127. JDBC_RCA_USER_NAME_PROPERTY = "server.jdbc.rca.user.name"
  128. JDBC_RCA_PASSWORD_FILE_PROPERTY = "server.jdbc.rca.user.passwd"
  129. CHECK_COMMAND_EXIST_CMD = "type {0}"
  130. DATABASE_INDEX = 0
  131. PROMPT_DATABASE_OPTIONS = False
  132. USERNAME_PATTERN = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
  133. PASSWORD_PATTERN = "^[a-zA-Z0-9_-]*$"
  134. DATABASE_NAMES =["postgres", "oracle", "mysql"]
  135. DATABASE_STORAGE_NAMES =["database","service","schema"]
  136. DATABASE_PORTS =["5432", "1521", "3306"]
  137. DATABASE_DRIVER_NAMES = ["org.postgresql.Driver", "oracle.jdbc.driver.OracleDriver", "com.mysql.jdbc.Driver"]
  138. DATABASE_CONNECTION_STRINGS = ["jdbc:postgresql://{0}:{1}/{2}", "jdbc:oracle:thin:@{0}:{1}/{2}", "jdbc:mysql://{0}:{1}/{2}"]
  139. DATABASE_CLI_TOOLS = [["psql"], ["sqlplus", "sqlplus64"], ["mysql"]]
  140. DATABASE_INIT_SCRIPTS = ['/var/lib/ambari-server/resources/Ambari-DDL-Postgres-REMOTE-CREATE.sql',
  141. '/var/lib/ambari-server/resources/Ambari-DDL-Oracle-CREATE.sql',
  142. '/var/lib/ambari-server/resources/Ambari-DDL-MySQL-CREATE.sql']
  143. DATABASE_DROP_SCRIPTS = ['/var/lib/ambari-server/resources/Ambari-DDL-Postgres-REMOTE-DROP.sql',
  144. '/var/lib/ambari-server/resources/Ambari-DDL-Oracle-DROP.sql',
  145. '/var/lib/ambari-server/resources/Ambari-DDL-MySQL-DROP.sql']
  146. DATABASE_URL_REGEX = ["jdbc:postgresql://([a-zA-Z0-9._]+):(\d+)/(.+)",
  147. "jdbc:oracle:thin:@([a-zA-Z0-9._]+):(\d+)/(.+)",
  148. "jdbc:mysql://([a-zA-Z0-9._]+):(\d*)/(.+)"]
  149. REGEX_IP_ADDRESS = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$"
  150. REGEX_HOSTNAME = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
  151. POSTGRES_EXEC_ARGS = "-h {0} -p {1} -d {2} -U {3} -f {4} -v username='\"{3}\"'"
  152. ORACLE_EXEC_ARGS = "-S '{0}/{1}@(description=(address=(protocol=TCP)(host={2})(port={3}))(connect_data=(sid={4})))' @{5} {0}"
  153. MYSQL_EXEC_ARGS = "--host={0} --port={1} --user={2} --password={3} {4} " \
  154. "-e\"set @schema=\'{4}\'; set @username=\'{2}\'; source {5};\""
  155. JDBC_PATTERNS = {"oracle":"*ojdbc*.jar", "mysql":"*mysql*.jar"}
  156. DATABASE_FULL_NAMES = {"oracle":"Oracle", "mysql":"MySQL", "postgres":"PostgreSQL"}
  157. # jdk commands
  158. JDK_LOCAL_FILENAME = "jdk-6u31-linux-x64.bin"
  159. JDK_MIN_FILESIZE = 5000
  160. JDK_INSTALL_DIR = "/usr/jdk64"
  161. CREATE_JDK_DIR_CMD = "/bin/mkdir -p " + JDK_INSTALL_DIR
  162. MAKE_FILE_EXECUTABLE_CMD = "chmod a+x {0}"
  163. JAVA_HOME_PROPERTY = "java.home"
  164. OS_TYPE_PROPERTY = "server.os_type"
  165. JDK_DOWNLOAD_CMD = "curl --create-dirs -o {0} {1}"
  166. JDK_DOWNLOAD_SIZE_CMD = "curl -I {0}"
  167. #JCE Policy files
  168. JCE_POLICY_FILENAME = "jce_policy-6.zip"
  169. JCE_DOWNLOAD_CMD = "curl -o {0} {1}"
  170. JCE_MIN_FILESIZE = 5000
  171. #Apache License Header
  172. ASF_LICENSE_HEADER = '''
  173. # Copyright 2011 The Apache Software Foundation
  174. #
  175. # Licensed to the Apache Software Foundation (ASF) under one
  176. # or more contributor license agreements. See the NOTICE file
  177. # distributed with this work for additional information
  178. # regarding copyright ownership. The ASF licenses this file
  179. # to you under the Apache License, Version 2.0 (the
  180. # "License"); you may not use this file except in compliance
  181. # with the License. You may obtain a copy of the License at
  182. #
  183. # http://www.apache.org/licenses/LICENSE-2.0
  184. #
  185. # Unless required by applicable law or agreed to in writing, software
  186. # distributed under the License is distributed on an "AS IS" BASIS,
  187. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  188. # See the License for the specific language governing permissions and
  189. # limitations under the License.
  190. '''
  191. def configure_pg_hba_ambaridb_users():
  192. args = optparse.Values()
  193. configure_database_username_password(args)
  194. with open(PG_HBA_CONF_FILE, "a") as pgHbaConf:
  195. pgHbaConf.write("\n")
  196. pgHbaConf.write("local all " + args.database_username +
  197. ",mapred md5")
  198. pgHbaConf.write("\n")
  199. pgHbaConf.write("host all " + args.database_username +
  200. ",mapred 0.0.0.0/0 md5")
  201. pgHbaConf.write("\n")
  202. pgHbaConf.write("host all " + args.database_username +
  203. ",mapred ::/0 md5")
  204. pgHbaConf.write("\n")
  205. command = PG_HBA_RELOAD_CMD.format(PG_HBA_DIR)
  206. retcode, out, err = run_os_command(command)
  207. if not retcode == 0:
  208. print err
  209. sys.exit(retcode)
  210. def configure_pg_hba_postgres_user():
  211. postgresString = "all postgres"
  212. for line in fileinput.input(PG_HBA_CONF_FILE, inplace=1):
  213. print re.sub('all\s*all', postgresString, line),
  214. os.chmod(PG_HBA_CONF_FILE, 0644)
  215. def configure_postgresql_conf():
  216. listenAddress = "listen_addresses = '*' #"
  217. for line in fileinput.input(POSTGRESQL_CONF_FILE, inplace=1):
  218. print re.sub('#+listen_addresses.*?(#|$)', listenAddress, line),
  219. os.chmod(POSTGRESQL_CONF_FILE, 0644)
  220. def configure_postgres():
  221. if os.path.isfile(PG_HBA_CONF_FILE):
  222. if not os.path.isfile(PG_HBA_CONF_FILE_BACKUP):
  223. shutil.copyfile(PG_HBA_CONF_FILE, PG_HBA_CONF_FILE_BACKUP)
  224. else:
  225. #Postgres has been configured before, must not override backup
  226. print "Backup for pg_hba found, reconfiguration not required"
  227. return 0
  228. configure_pg_hba_postgres_user()
  229. configure_pg_hba_ambaridb_users()
  230. os.chmod(PG_HBA_CONF_FILE, 0644)
  231. configure_postgresql_conf()
  232. #restart postgresql if already running
  233. pg_status = get_postgre_status()
  234. if pg_status == PG_STATUS_RUNNING:
  235. retcode = restart_postgres()
  236. return retcode
  237. return 0
  238. def restart_postgres():
  239. print "Restarting PostgreSQL"
  240. process = subprocess.Popen(PG_RESTART_CMD.split(' '),
  241. stdout=subprocess.PIPE,
  242. stdin=subprocess.PIPE,
  243. stderr=subprocess.PIPE
  244. )
  245. time.sleep(5)
  246. result = process.poll()
  247. if result is None:
  248. print_info_msg("Killing restart PostgresSQL process")
  249. process.kill()
  250. pg_status = get_postgre_status()
  251. # SUSE linux set status of stopped postgresql proc to unused
  252. if pg_status == "unused" or pg_status == "stopped":
  253. print_info_msg("PostgreSQL is stopped. Restarting ...")
  254. retcode, out, err = run_os_command(PG_START_CMD)
  255. return retcode
  256. return 0
  257. def run_os_command(cmd):
  258. print_info_msg('about to run command: ' + str(cmd))
  259. if type(cmd) == str:
  260. cmd = shlex.split(cmd)
  261. process = subprocess.Popen(cmd,
  262. stdout=subprocess.PIPE,
  263. stdin=subprocess.PIPE,
  264. stderr=subprocess.PIPE
  265. )
  266. (stdoutdata, stderrdata) = process.communicate()
  267. return process.returncode, stdoutdata, stderrdata
  268. # todo: check if the scheme is already exist
  269. def write_property(key, value):
  270. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  271. with open(conf_file, 'a') as ambariConf:
  272. ambariConf.write(key + "=" + value)
  273. ambariConf.write("\n")
  274. return 0
  275. def setup_db(args):
  276. #password access to ambari-server and mapred
  277. configure_database_username_password(args)
  278. dbname = args.database_name
  279. scriptFile = args.init_script_file
  280. username = args.database_username
  281. password = args.database_password
  282. command = SETUP_DB_CMD[:]
  283. command[-1] = command[-1].format(scriptFile, username, password)
  284. retcode, outdata, errdata = run_os_command(command)
  285. if not retcode == 0:
  286. print errdata
  287. return retcode
  288. def store_password_file(password, filename):
  289. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  290. passFilePath = os.path.join(os.path.dirname(conf_file),
  291. filename)
  292. with open(passFilePath, 'w+') as passFile:
  293. passFile.write(password)
  294. pass
  295. os.chmod(passFilePath, stat.S_IREAD | stat.S_IWRITE)
  296. return passFilePath
  297. def execute_db_script(args, file):
  298. #password access to ambari-server and mapred
  299. configure_database_username_password(args)
  300. dbname = args.database_name
  301. username = args.database_username
  302. password = args.database_password
  303. command = SETUP_DB_CMD[:]
  304. command[-1] = command[-1].format(file, username, password)
  305. retcode, outdata, errdata = run_os_command(command)
  306. if not retcode == 0:
  307. print errdata
  308. return retcode
  309. def check_db_consistency(args, file):
  310. #password access to ambari-server and mapred
  311. configure_database_username_password(args)
  312. dbname = args.database_name
  313. username = args.database_username
  314. password = args.database_password
  315. command = SETUP_DB_CMD[:]
  316. command[-1] = command[-1].format(file, username, password)
  317. retcode, outdata, errdata = run_os_command(command)
  318. if not retcode == 0:
  319. print errdata
  320. return retcode
  321. else:
  322. # Assumes that the output is of the form ...\n<count>
  323. print_info_msg("Parsing output: " + outdata)
  324. lines = outdata.splitlines()
  325. if (lines[-1] == '3' or lines[-1] == '0'):
  326. return 0
  327. return -1
  328. def upgrade_stack(args, stack_id):
  329. #password access to ambari-server and mapred
  330. configure_database_username_password(args)
  331. dbname = args.database_name
  332. file = args.upgrade_stack_script_file
  333. stack_name, stack_version = stack_id.split(STACK_NAME_VER_SEP)
  334. command = UPGRADE_STACK_CMD[:]
  335. command[-1] = command[-1].format(file, stack_name, stack_version)
  336. retcode, outdata, errdata = run_os_command(command)
  337. if not retcode == 0:
  338. print errdata
  339. return retcode
  340. #
  341. # Checks SELinux
  342. #
  343. def check_selinux():
  344. try:
  345. retcode, out, err = run_os_command(GET_SE_LINUX_ST_CMD)
  346. se_status = re.search('(disabled|enabled)', out).group(0)
  347. print "SELinux status is '" + se_status + "'"
  348. if se_status == SE_STATUS_DISABLED:
  349. return 0
  350. else:
  351. se_mode = ''
  352. try:
  353. se_mode = re.search('(enforcing|permissive)', out).group(0)
  354. except AttributeError:
  355. print_error_msg("Error determining SELinux mode. Exiting.")
  356. sys.exit(0)
  357. print "SELinux mode is '" + se_mode + "'"
  358. if se_mode == SE_MODE_ENFORCING:
  359. print "Temporarily disabling SELinux"
  360. run_os_command(SE_SETENFORCE_CMD)
  361. print_warning_msg(
  362. "SELinux is set to 'permissive' mode and temporarily disabled."
  363. " You should disable SELinux permanently.")
  364. ok = get_YN_input("OK to continue [y/n] (y)? ", True)
  365. if ok == False:
  366. sys.exit(0)
  367. return 0
  368. except OSError:
  369. print_warning_msg("Could not run {0}: OK".format(GET_SE_LINUX_ST_CMD))
  370. return 0
  371. def get_ambari_jars():
  372. try:
  373. conf_dir = os.environ[AMBARI_SERVER_LIB]
  374. return conf_dir
  375. except KeyError:
  376. default_jar_location = "/usr/lib/ambari-server"
  377. print_info_msg(AMBARI_SERVER_LIB + " is not set, using default "
  378. + default_jar_location)
  379. return default_jar_location
  380. def get_share_jars():
  381. share_jars = ""
  382. file_list = []
  383. file_list.extend(glob.glob(JAVA_SHARE_PATH + os.sep + "*mysql*"))
  384. file_list.extend(glob.glob(JAVA_SHARE_PATH + os.sep + "*ojdbc*"))
  385. if len(file_list) > 0:
  386. share_jars = string.join(file_list, os.pathsep)
  387. return share_jars
  388. def get_ambari_classpath():
  389. ambari_cp = get_ambari_jars() + os.sep + "*"
  390. share_cp = get_share_jars()
  391. if len(share_cp) > 0:
  392. ambari_cp = ambari_cp + os.pathsep + share_cp
  393. return ambari_cp
  394. def get_conf_dir():
  395. try:
  396. conf_dir = os.environ[AMBARI_CONF_VAR]
  397. return conf_dir
  398. except KeyError:
  399. default_conf_dir = "/etc/ambari-server/conf"
  400. print_info_msg(AMBARI_CONF_VAR + " is not set, using default "
  401. + default_conf_dir)
  402. return default_conf_dir
  403. def search_file(filename, search_path, pathsep=os.pathsep):
  404. """ Given a search path, find file with requested name """
  405. for path in string.split(search_path, pathsep):
  406. candidate = os.path.join(path, filename)
  407. if os.path.exists(candidate): return os.path.abspath(candidate)
  408. return None
  409. #
  410. # Checks iptables
  411. #
  412. def check_iptables():
  413. # not used
  414. # retcode, out, err = run_os_command(IP_TBLS_ST_CMD)
  415. ''' This check doesn't work on CentOS 6.2 if firewall AND
  416. iptables service are running if out == IP_TBLS_ENABLED:
  417. print 'iptables is enabled now'
  418. print 'Stopping iptables service'
  419. '''
  420. retcode, out, err = run_os_command(IP_TBLS_STOP_CMD)
  421. print 'iptables is disabled now'
  422. if not retcode == 0 and err and len(err) > 0:
  423. print err
  424. if err.strip() == IP_TBLS_SRVC_NT_FND:
  425. return 0
  426. else:
  427. return retcode, out
  428. def dlprogress(base_name, count, blockSize, totalSize):
  429. percent = int(count * blockSize * 100 / totalSize)
  430. if (totalSize < blockSize):
  431. sys.stdout.write("\r" + base_name + "... %d%%" % (100))
  432. else:
  433. sys.stdout.write("\r" + base_name + "... %d%% (%.1f MB of %.1f MB)" % (
  434. percent, count * blockSize / 1024 / 1024.0, totalSize / 1024 / 1024.0))
  435. if (percent == 100 or totalSize < blockSize):
  436. sys.stdout.write("\n")
  437. sys.stdout.flush()
  438. def track_jdk(base_name, url, local_name):
  439. u = urllib2.urlopen(url)
  440. h = u.info()
  441. totalSize = int(h["Content-Length"])
  442. fp = open(local_name, "wb")
  443. blockSize = 8192
  444. count = 0
  445. percent = 0
  446. while True:
  447. chunk = u.read(blockSize)
  448. if not chunk:
  449. break
  450. fp.write(chunk)
  451. count += 1
  452. dlprogress(base_name, count, blockSize, totalSize)
  453. fp.flush()
  454. fp.close()
  455. #
  456. # Downloads the JDK
  457. #
  458. def download_jdk(args):
  459. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  460. if conf_file is None:
  461. print 'File %s not found in search path $%s: %s' %\
  462. (AMBARI_PROPERTIES_FILE, AMBARI_CONF_VAR, get_conf_dir())
  463. return -1
  464. print_info_msg('Loading properties from ' + conf_file)
  465. if get_JAVA_HOME():
  466. return 0
  467. if args.java_home and os.path.exists(args.java_home):
  468. print_warning_msg("JAVA_HOME " + args.java_home
  469. + " must be valid on ALL hosts")
  470. print_warning_msg("Please make sure the JCE Unlimited Strength "
  471. "Jurisdiction Policy Files 6, "
  472. "are dwonloaded on all "
  473. "hosts")
  474. write_property(JAVA_HOME_PROPERTY, args.java_home)
  475. return 0
  476. properties = None
  477. try:
  478. properties = Properties()
  479. properties.load(open(conf_file))
  480. except (Exception), e:
  481. print 'Could not read "%s": %s' % (conf_file, e)
  482. return -1
  483. try:
  484. jdk_url = properties['jdk.url']
  485. resources_dir = properties['resources.dir']
  486. except (KeyError), e:
  487. print 'Property ' + str(e) + ' is not defined at ' + conf_file
  488. return -1
  489. dest_file = resources_dir + os.sep + JDK_LOCAL_FILENAME
  490. if not os.path.exists(dest_file):
  491. print 'Downloading JDK from ' + jdk_url + ' to ' + dest_file
  492. try:
  493. size_command = JDK_DOWNLOAD_SIZE_CMD.format(jdk_url);
  494. #Get Header from url,to get file size then
  495. retcode, out, err = run_os_command(size_command)
  496. if out.find("Content-Length") == -1:
  497. print "Request header doesn't contain Content-Length";
  498. return -1
  499. start_with = int(out.find("Content-Length") + len("Content-Length") + 2)
  500. end_with = out.find("\r\n", start_with)
  501. src_size = int(out[start_with:end_with])
  502. print 'JDK distribution size is ' + str(src_size) + ' bytes'
  503. file_exists = os.path.isfile(dest_file)
  504. file_size = -1
  505. if file_exists:
  506. file_size = os.stat(dest_file).st_size
  507. if file_exists and file_size == src_size:
  508. print_info_msg("File already exists")
  509. else:
  510. track_jdk(JDK_LOCAL_FILENAME, jdk_url, dest_file)
  511. print 'Successfully downloaded JDK distribution to ' + dest_file
  512. except Exception, e:
  513. print_error_msg('Failed to download JDK: ' + str(e))
  514. return -1
  515. downloaded_size = os.stat(dest_file).st_size
  516. if downloaded_size != src_size or downloaded_size < JDK_MIN_FILESIZE:
  517. print_error_msg('Size of downloaded JDK distribution file is '
  518. + str(downloaded_size) + ' bytes, it is probably \
  519. damaged or incomplete')
  520. return -1
  521. else:
  522. print "JDK already exists using " + dest_file
  523. try:
  524. out, ok = install_jdk(dest_file)
  525. jdk_version = re.search('Creating (jdk.*)/jre', out).group(1)
  526. except Exception, e:
  527. print "Installation of JDK has failed: %s\n" % e.message
  528. file_exists = os.path.isfile(dest_file)
  529. if file_exists:
  530. ok = get_YN_input("JDK found at "+dest_file+". "
  531. "Would you like to re-download the JDK [y/n] (y)? ", True)
  532. if (ok == False):
  533. print "Unable to install JDK. Please remove JDK file found at "+ dest_file +" and re-run Ambari Server setup"
  534. return -1
  535. else:
  536. track_jdk(JDK_LOCAL_FILENAME, jdk_url, dest_file)
  537. print 'Successfully re-downloaded JDK distribution to ' + dest_file
  538. try:
  539. out, ok = install_jdk(dest_file)
  540. jdk_version = re.search('Creating (jdk.*)/jre', out).group(1)
  541. except Exception, e:
  542. print "Installation of JDK was failed: %s\n" % e.message
  543. print "Unable to install JDK. Please remove JDK, file found at "+ dest_file +" and re-run Ambari Server setup"
  544. return -1
  545. else:
  546. print "Unable to install JDK. File "+ dest_file +"does not exist, please re-run Ambari Server setup"
  547. return -1
  548. print "Successfully installed JDK to {0}/{1}".\
  549. format(JDK_INSTALL_DIR, jdk_version)
  550. write_property(JAVA_HOME_PROPERTY, "{0}/{1}".
  551. format(JDK_INSTALL_DIR, jdk_version))
  552. jce_download = download_jce_policy(properties, ok)
  553. if (jce_download == -1):
  554. print "JCE Policy files are required for secure HDP setup. Please ensure " \
  555. " all hosts have the JCE unlimited strength policy 6, files."
  556. return 0
  557. def download_jce_policy(properties, accpeted_bcl):
  558. try:
  559. jce_url = properties['jce_policy.url']
  560. resources_dir = properties['resources.dir']
  561. except (KeyError), e:
  562. print 'Property ' + str(e) + ' is not defined in properties file'
  563. return -1
  564. dest_file = resources_dir + os.sep + JCE_POLICY_FILENAME
  565. if not os.path.exists(dest_file):
  566. print 'Downloading JCE Policy archive from ' + jce_url + ' to ' + dest_file
  567. try:
  568. size_command = JDK_DOWNLOAD_SIZE_CMD.format(jce_url);
  569. #Get Header from url,to get file size then
  570. retcode, out, err = run_os_command(size_command)
  571. if out.find("Content-Length") == -1:
  572. print "Request header doesn't contain Content-Length";
  573. return -1
  574. start_with = int(out.find("Content-Length") + len("Content-Length") + 2)
  575. end_with = out.find("\r\n", start_with)
  576. src_size = int(out[start_with:end_with])
  577. print_info_msg('JCE zip distribution size is ' + str(src_size) + 'bytes')
  578. file_exists = os.path.isfile(dest_file)
  579. file_size = -1
  580. if file_exists:
  581. file_size = os.stat(dest_file).st_size
  582. if file_exists and file_size == src_size:
  583. print_info_msg("File already exists")
  584. else:
  585. #BCL license before download
  586. jce_download_cmd = JCE_DOWNLOAD_CMD.format(dest_file, jce_url)
  587. print_info_msg("JCE download cmd: " + jce_download_cmd)
  588. if (accpeted_bcl == True):
  589. retcode, out, err = run_os_command(jce_download_cmd)
  590. if retcode == 0:
  591. print 'Successfully downloaded JCE Policy archive to ' + dest_file
  592. else:
  593. return -1
  594. else:
  595. ok = get_YN_input("To download the JCE Policy archive you must "
  596. "accept the license terms found at "
  597. "http://www.oracle.com/technetwork/java/javase"
  598. "/terms/license/index.html"
  599. "Not accepting might result in failure when "
  600. "setting up HDP security. \nDo you accept the "
  601. "Oracle Binary Code License Agreement [y/n] (y)? ", True)
  602. if (ok == True):
  603. retcode, out, err = run_os_command(jce_download_cmd)
  604. if retcode == 0:
  605. print 'Successfully downloaded JCE Policy archive to ' + dest_file
  606. else:
  607. return -1
  608. except Exception, e:
  609. print_error_msg('Failed to download JCE Policy archive: ' + str(e))
  610. return -1
  611. downloaded_size = os.stat(dest_file).st_size
  612. if downloaded_size != src_size or downloaded_size < JCE_MIN_FILESIZE:
  613. print_error_msg('Size of downloaded JCE Policy archive is '
  614. + str(downloaded_size) + ' bytes, it is probably \
  615. damaged or incomplete')
  616. return -1
  617. else:
  618. print "JCE Policy archive already exists, using " + dest_file
  619. class RetCodeException(Exception): pass
  620. def install_jdk(dest_file):
  621. ok = get_YN_input("To install the Oracle JDK you must accept the "
  622. "license terms found at "
  623. "http://www.oracle.com/technetwork/java/javase/"
  624. "downloads/jdk-6u21-license-159167.txt. Not accepting will "
  625. "cancel the Ambari Server setup.\nDo you accept the "
  626. "Oracle Binary Code License Agreement [y/n] (y)? ", True)
  627. if (ok == False):
  628. return -1
  629. print "Installing JDK to {0}".format(JDK_INSTALL_DIR)
  630. retcode, out, err = run_os_command(CREATE_JDK_DIR_CMD)
  631. savedPath = os.getcwd()
  632. os.chdir(JDK_INSTALL_DIR)
  633. retcode, out, err = run_os_command(MAKE_FILE_EXECUTABLE_CMD.format(dest_file))
  634. retcode, out, err = run_os_command(dest_file + ' -noregister')
  635. os.chdir(savedPath)
  636. if (retcode != 0):
  637. raise RetCodeException("Installation JDK returned code %s" % retcode)
  638. return out, ok
  639. def get_postgre_status():
  640. retcode, out, err = run_os_command(PG_ST_CMD)
  641. try:
  642. pg_status = re.search('(stopped|running)', out).group(0)
  643. except AttributeError:
  644. pg_status = None
  645. return pg_status
  646. def check_postgre_up():
  647. pg_status = get_postgre_status()
  648. if pg_status == PG_STATUS_RUNNING:
  649. print_info_msg ("PostgreSQL is running")
  650. return 0
  651. else:
  652. print "Run initdb"
  653. retcode, out, err = run_os_command(PG_INITDB_CMD)
  654. if retcode == 0:
  655. print out
  656. print "About to start PostgreSQL"
  657. retcode, out, err = run_os_command(PG_START_CMD)
  658. return retcode
  659. def update_ambari_properties():
  660. prev_conf_file = search_file(AMBARI_PROPERTIES_RPMSAVE_FILE, get_conf_dir())
  661. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  662. old_properties = None
  663. new_properties = None
  664. try:
  665. old_properties = Properties()
  666. old_properties.load(open(prev_conf_file))
  667. except (Exception), e:
  668. print 'Could not read "%s": %s' % (prev_conf_file, e)
  669. return -1
  670. try:
  671. new_properties = Properties()
  672. new_properties.load(open(conf_file))
  673. for prop_key, prop_value in old_properties.getPropertyDict().items():
  674. new_properties.process_pair(prop_key,prop_value)
  675. new_properties.store(open(conf_file,'w'))
  676. except (Exception), e:
  677. print 'Could not write "%s": %s' % (conf_file, e)
  678. return -1
  679. timestamp = datetime.datetime.now()
  680. format = '%Y%m%d%H%M%S'
  681. os.rename(AMBARI_PROPERTIES_RPMSAVE_FILE, AMBARI_PROPERTIES_RPMSAVE_FILE +
  682. '.' + timestamp.strftime(format))
  683. return 0
  684. #
  685. # Configures the OS settings in ambari properties.
  686. #
  687. def configure_os_settings():
  688. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  689. if conf_file is None:
  690. print_error_msg ('File %s not found in search path $%s: %s'
  691. % (AMBARI_PROPERTIES_FILE, AMBARI_CONF_VAR, get_conf_dir()))
  692. return -1
  693. print_info_msg ('Loading properties from ' + conf_file)
  694. properties = None
  695. try:
  696. properties = Properties()
  697. properties.load(open(conf_file))
  698. except (Exception), e:
  699. print_error_msg ('Could not read "%s": %s' % (conf_file, e))
  700. return -1
  701. try:
  702. conf_os_type = properties[OS_TYPE_PROPERTY]
  703. if conf_os_type != '':
  704. print_info_msg ("os_type already setting in properties file")
  705. return 0
  706. except (KeyError), e:
  707. print_error_msg ("os_type is not set in properties file")
  708. os_system = platform.system()
  709. if os_system != 'Linux':
  710. print_error_msg ("Non-Linux systems are not supported")
  711. return -1
  712. os_info = platform.linux_distribution(
  713. None, None, None, ['SuSE', 'redhat' ], 0
  714. )
  715. os_name = os_info[0].lower()
  716. if os_name == 'suse':
  717. os_name = 'sles'
  718. os_version = os_info[1].split('.', 1)[0]
  719. master_os_type = os_name + os_version
  720. with open(conf_file, "a") as ambariConf:
  721. ambariConf.write(OS_TYPE_PROPERTY + "=" + master_os_type)
  722. ambariConf.write("\n")
  723. ambariConf.closed
  724. return 0
  725. def get_JAVA_HOME():
  726. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  727. properties = Properties()
  728. try:
  729. properties.load(open(conf_file))
  730. java_home = properties[JAVA_HOME_PROPERTY]
  731. if (not 0 == len(java_home)) and (os.path.exists(java_home)):
  732. return java_home
  733. except (Exception), e:
  734. print 'Could not read "%s": %s' % (conf_file, e)
  735. return None
  736. #
  737. # Finds the available JDKs.
  738. #
  739. def find_jdk():
  740. if get_JAVA_HOME():
  741. return get_JAVA_HOME()
  742. print "Looking for available JDKs at " + JDK_INSTALL_DIR
  743. jdks = glob.glob(JDK_INSTALL_DIR + os.sep + "jdk*")
  744. jdks.sort()
  745. print "Found: " + str(jdks)
  746. count = len(jdks)
  747. if count == 0:
  748. return
  749. jdkPath = jdks[count - 1]
  750. print "Selected JDK {0}".format(jdkPath)
  751. return jdkPath
  752. #
  753. # Checks if options determine local DB configuration
  754. #
  755. def is_local_database(options):
  756. if options.database == DATABASE_NAMES[0] \
  757. and options.database_host == "localhost" \
  758. and options.database_port == DATABASE_PORTS[0] \
  759. and options.database_name == "ambari":
  760. return True
  761. return False
  762. #Check if required jdbc drivers present
  763. def find_jdbc_driver(args):
  764. if args.database in JDBC_PATTERNS.keys():
  765. drivers = []
  766. drivers.extend(glob.glob(JAVA_SHARE_PATH + os.sep + JDBC_PATTERNS[args.database]))
  767. if drivers:
  768. return drivers
  769. return -1
  770. return 0
  771. def copy_files(files, dest_dir):
  772. if os.path.isdir(dest_dir):
  773. for filepath in files:
  774. shutil.copy(filepath, dest_dir)
  775. return 0
  776. else:
  777. return -1
  778. def check_jdbc_drivers(args):
  779. result = find_jdbc_driver(args)
  780. if result == -1:
  781. msg = 'WARNING: Before starting Ambari Server, ' \
  782. 'the {0} JDBC driver JAR file must be placed to {1}. Press enter to continue.'.format(
  783. DATABASE_FULL_NAMES[args.database],
  784. JAVA_SHARE_PATH
  785. )
  786. if not SILENT:
  787. raw_input(msg)
  788. else:
  789. print_warning_msg(msg)
  790. elif type(result) is not int:
  791. print 'Copying JDBC drivers to server resources...'
  792. copy_files(result, RESOURCES_DIR)
  793. pass
  794. return 0
  795. #
  796. # Setup the Ambari Server.
  797. #
  798. def setup(args):
  799. print 'Checking SELinux...'
  800. retcode = check_selinux()
  801. if not retcode == 0:
  802. print_error_msg ('Failed to disable SELinux. Exiting.')
  803. sys.exit(retcode)
  804. print 'Checking iptables...'
  805. retcode, out = check_iptables()
  806. if not retcode == 0 and out == IP_TBLS_ENABLED:
  807. print_error_msg ('Failed to stop iptables. Exiting.')
  808. sys.exit(retcode)
  809. print 'Configuring database...'
  810. prompt_db_properties(args)
  811. if is_local_database(args):
  812. print 'Default properties detected. Using built-in database.'
  813. store_local_properties(args)
  814. print 'Checking PostgreSQL...'
  815. retcode = check_postgre_up()
  816. if not retcode == 0:
  817. print_error_msg ('Unable to start PostgreSQL server. Exiting')
  818. sys.exit(retcode)
  819. print 'Configuring database...'
  820. retcode = setup_db(args)
  821. if not retcode == 0:
  822. print_error_msg ('Running database init script was failed. Exiting.')
  823. sys.exit(retcode)
  824. print 'Configuring PostgreSQL...'
  825. retcode = configure_postgres()
  826. if not retcode == 0:
  827. print_error_msg ('Unable to configure PostgreSQL server. Exiting')
  828. sys.exit(retcode)
  829. else:
  830. retcode = store_remote_properties(args)
  831. if retcode != 0:
  832. print_error_msg('Unable to save config file')
  833. sys.exit(retcode)
  834. print_warning_msg('Before starting server JDBC driver for {0} should be placed to {1}.'.format(args.database, JAVA_SHARE_PATH))
  835. print 'Configuring remote database connection properties...'
  836. retcode = setup_remote_db(args)
  837. if not retcode == 0:
  838. print_error_msg ('Error while configuring connection properties. Exiting')
  839. sys.exit(retcode)
  840. check_jdbc_drivers(args)
  841. print 'Checking JDK...'
  842. retcode = download_jdk(args)
  843. if not retcode == 0:
  844. print_error_msg ('Downloading or installing JDK failed. Exiting.')
  845. sys.exit(retcode)
  846. print 'Completing setup...'
  847. retcode = configure_os_settings()
  848. if not retcode == 0:
  849. print_error_msg ('Configure of OS settings in '
  850. 'ambari.properties failed. Exiting.')
  851. sys.exit(retcode)
  852. if args.warnings:
  853. print "Ambari Server 'setup' finished with warnings:"
  854. for warning in args.warnings:
  855. print warning
  856. else:
  857. print "Ambari Server 'setup' finished successfully"
  858. #
  859. # Resets the Ambari Server.
  860. #
  861. def reset(args):
  862. okToRun = False
  863. choice = get_YN_input("**** WARNING **** You are about to reset and clear the "
  864. "Ambari Server database. This will remove all cluster "
  865. "host and configuration information from the database. "
  866. "You will be required to re-configure the Ambari server "
  867. "and re-run the cluster wizard. \n"
  868. "Are you SURE you want to perform the reset "
  869. "[yes/no]? ", True)
  870. okToRun = choice
  871. if not okToRun:
  872. print "Ambari Server 'reset' cancelled"
  873. return -1
  874. okToRun = False
  875. choice = get_YN_input("Confirm server reset [yes/no]? ", True)
  876. okToRun = choice
  877. if not okToRun:
  878. print "Ambari Server 'reset' cancelled"
  879. return -1
  880. print "Reseting the Server database..."
  881. parse_properties_file(args)
  882. # configure_database_username_password(args)
  883. if args.persistence_type=="remote":
  884. if get_db_cli_tool(args) != -1:
  885. retcode, out, err = execute_remote_script(args, DATABASE_DROP_SCRIPTS[DATABASE_INDEX])
  886. if not retcode == 0:
  887. if retcode == -1:
  888. print_warning_msg('Cannot find ' + DATABASE_NAMES[DATABASE_INDEX] + ' client in the path, for reset please run the following DDL against the DB: ' +
  889. DATABASE_DROP_SCRIPTS[DATABASE_INDEX] + ", then: " + DATABASE_INIT_SCRIPTS[DATABASE_INDEX], True)
  890. print err
  891. return retcode
  892. retcode, out, err = execute_remote_script(args, DATABASE_INIT_SCRIPTS[DATABASE_INDEX])
  893. if not retcode == 0:
  894. if retcode == -1:
  895. print_warning_msg('Cannot find ' + DATABASE_NAMES[DATABASE_INDEX] + ' client in the path, for reset please run the following DDL against the DB: ' +
  896. DATABASE_DROP_SCRIPTS[DATABASE_INDEX] + ", then: " + DATABASE_INIT_SCRIPTS[DATABASE_INDEX], True)
  897. print err
  898. return retcode
  899. else:
  900. print_warning_msg('Cannot find ' + DATABASE_NAMES[DATABASE_INDEX] + ' client in the path, for reset please run the following DDL against the DB: ' +
  901. DATABASE_INIT_SCRIPTS[DATABASE_INDEX] + ", then: " + DATABASE_DROP_SCRIPTS[DATABASE_INDEX], True)
  902. print_error_msg(DATABASE_CLI_TOOLS[DATABASE_INDEX] + " not found. Unable to perform automatic reset.")
  903. return -1
  904. else:
  905. dbname = args.database_name
  906. filename = args.drop_script_file
  907. username = args.database_username
  908. password = args.database_password
  909. command = SETUP_DB_CMD[:]
  910. command[-1] = command[-1].format(filename, username, password)
  911. retcode, outdata, errdata = run_os_command(command)
  912. if not retcode == 0:
  913. print errdata
  914. return retcode
  915. print_info_msg ("About to run database setup")
  916. setup_db(args)
  917. print "Ambari Server 'reset' complete"
  918. #
  919. # Starts the Ambari Server.
  920. #
  921. def start(args):
  922. parse_properties_file(args)
  923. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  924. f = open(PID_DIR + os.sep + PID_NAME, "r")
  925. pid = int(f.readline())
  926. f.close()
  927. try:
  928. os.kill(pid, 0)
  929. print("Server is already running.")
  930. return
  931. except OSError, e:
  932. print_info_msg("Server is not running, continue.")
  933. conf_dir = get_conf_dir()
  934. jdk_path = find_jdk()
  935. if jdk_path is None:
  936. print_error_msg("No JDK found, please run the \"setup\" "
  937. "command to install a JDK automatically or install any "
  938. "JDK manually to " + JDK_INSTALL_DIR)
  939. return -1
  940. if args.persistence_type == "local":
  941. retcode = check_postgre_up()
  942. if not retcode == 0:
  943. print_error_msg("Unable to start PostgreSQL server. Exiting")
  944. sys.exit(retcode)
  945. print 'Checking iptables...'
  946. retcode, out = check_iptables()
  947. if not retcode == 0 and out == IP_TBLS_ENABLED:
  948. print_error_msg ("Failed to stop iptables. Exiting")
  949. sys.exit(retcode)
  950. command_base = SERVER_START_CMD_DEBUG if (SERVER_DEBUG_MODE or SERVER_START_DEBUG) else SERVER_START_CMD
  951. command = command_base.format(jdk_path, conf_dir, get_ambari_classpath())
  952. print "Running server: " + command
  953. server_process = subprocess.Popen(["/bin/sh", "-c", command])
  954. f = open(PID_DIR + os.sep + PID_NAME, "w")
  955. f.write(str(server_process.pid))
  956. f.close()
  957. #
  958. # Stops the Ambari Server.
  959. #
  960. def stop(args):
  961. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  962. f = open(PID_DIR + os.sep + PID_NAME, "r")
  963. pid = int(f.readline())
  964. try:
  965. os.killpg(os.getpgid(pid), signal.SIGKILL)
  966. except OSError, e:
  967. print_info_msg( "Unable to stop Ambari Server - " + str(e) )
  968. return
  969. f.close()
  970. os.remove(f.name)
  971. print "Ambari Server stopped"
  972. else:
  973. print "Ambari Server not running"
  974. #
  975. # Upgrades the Ambari Server.
  976. #
  977. def upgrade(args):
  978. print 'Updating properties in ' + AMBARI_PROPERTIES_FILE + ' ...'
  979. retcode = update_ambari_properties()
  980. if not retcode == 0:
  981. print_error_msg(AMBARI_PROPERTIES_FILE + ' file can\'t be updated. Exiting')
  982. sys.exit(retcode)
  983. parse_properties_file(args)
  984. if args.persistence_type == "remote":
  985. pass
  986. else:
  987. print 'Checking PostgreSQL...'
  988. retcode = check_postgre_up()
  989. if not retcode == 0:
  990. print_error_msg('PostgreSQL server not running. Exiting')
  991. sys.exit(retcode)
  992. file = args.upgrade_script_file
  993. print 'Upgrading database...'
  994. retcode = execute_db_script(args, file)
  995. if not retcode == 0:
  996. print_error_msg('Database upgrade script has failed. Exiting.')
  997. sys.exit(retcode)
  998. print 'Checking database integrity...'
  999. check_file = file[:-3] + "Check" + file[-4:]
  1000. retcode = check_db_consistency(args, check_file)
  1001. if not retcode == 0:
  1002. print 'Found inconsistency. Trying to fix...'
  1003. fix_file = file[:-3] + "Fix" + file[-4:]
  1004. retcode = execute_db_script(args, fix_file)
  1005. if not retcode == 0:
  1006. print_error_msg('Database cannot be fixed. Exiting.')
  1007. sys.exit(retcode)
  1008. else:
  1009. print 'Database is consistent.'
  1010. print "Ambari Server 'upgrade' finished successfully"
  1011. #
  1012. # The Ambari Server status.
  1013. #
  1014. def status(args):
  1015. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  1016. f = open(PID_DIR + os.sep + PID_NAME, "r")
  1017. pid = int(f.readline())
  1018. print "Found Ambari Server PID: '" + str(pid) + "'"
  1019. f.close()
  1020. retcode, out, err = run_os_command("ps -p " + str(pid))
  1021. if retcode == 0:
  1022. print "Ambari Server running"
  1023. print "Ambari Server PID at: " + PID_DIR + os.sep + PID_NAME
  1024. else:
  1025. print "Ambari Server not running. Stale PID File at: " + PID_DIR + os.sep + PID_NAME
  1026. else:
  1027. print "Ambari Server not running"
  1028. #
  1029. # Prints an "info" messsage.
  1030. #
  1031. def print_info_msg(msg):
  1032. if VERBOSE:
  1033. print("INFO: " + msg)
  1034. #
  1035. # Prints an "error" messsage.
  1036. #
  1037. def print_error_msg(msg):
  1038. print("ERROR: " + msg)
  1039. #
  1040. # Prints a "warning" messsage.
  1041. #
  1042. def print_warning_msg(msg, bold=False):
  1043. if bold:
  1044. print(BOLD_ON + "WARNING: " + msg + BOLD_OFF)
  1045. else:
  1046. print("WARNING: " + msg)
  1047. #
  1048. # Gets the y/n input.
  1049. #
  1050. # return True if 'y' or False if 'n'
  1051. #
  1052. def get_YN_input(prompt,default):
  1053. yes = set(['yes','ye', 'y'])
  1054. no = set(['no','n'])
  1055. return get_choice_string_input(prompt,default,yes,no)
  1056. def get_choice_string_input(prompt,default,firstChoice,secondChoice):
  1057. if SILENT:
  1058. print(prompt)
  1059. return default
  1060. choice = raw_input(prompt).lower()
  1061. if choice in firstChoice:
  1062. return True
  1063. elif choice in secondChoice:
  1064. return False
  1065. elif choice is "": # Just enter pressed
  1066. return default
  1067. else:
  1068. print "input not recognized, please try again: "
  1069. return get_choice_string_input(prompt,default,firstChoice,secondChoice)
  1070. def get_validated_string_input(prompt, default, pattern, description, is_pass):
  1071. input =""
  1072. while not input:
  1073. if SILENT:
  1074. print (prompt)
  1075. input = default
  1076. elif is_pass:
  1077. input = getpass.getpass(prompt)
  1078. else:
  1079. input = raw_input(prompt)
  1080. if not input.strip():
  1081. input = default
  1082. break #done here and picking up default
  1083. else:
  1084. if not re.search(pattern,input.strip()):
  1085. print description
  1086. input=""
  1087. return input
  1088. def read_password(passwordDefault = PG_DEFAULT_PASSWORD):
  1089. # setup password
  1090. passwordPrompt = 'Password [' + passwordDefault + ']: '
  1091. passwordPattern = PASSWORD_PATTERN
  1092. passwordDescr = "Invalid characters in password. Use only alphanumeric or " \
  1093. "_ or - characters"
  1094. password = get_validated_string_input(passwordPrompt, passwordDefault,
  1095. passwordPattern, passwordDescr, True)
  1096. if password != passwordDefault:
  1097. password1 = get_validated_string_input("Re-enter password: ",
  1098. passwordDefault, passwordPattern, passwordDescr, True)
  1099. if password != password1:
  1100. print "Passwords do not match"
  1101. password = read_password()
  1102. return password
  1103. def get_pass_file_path(conf_file):
  1104. return os.path.join(os.path.dirname(conf_file),
  1105. JDBC_PASSWORD_FILENAME)
  1106. # Set database properties to default values
  1107. def load_default_db_properties(args):
  1108. args.database=DATABASE_NAMES[DATABASE_INDEX]
  1109. args.database_host = "localhost"
  1110. args.database_port = DATABASE_PORTS[DATABASE_INDEX]
  1111. args.database_name = "ambari"
  1112. args.database_username = "ambari"
  1113. args.database_password = "bigdata"
  1114. pass
  1115. # Ask user for database conenction properties
  1116. def prompt_db_properties(args):
  1117. global DATABASE_INDEX
  1118. if PROMPT_DATABASE_OPTIONS:
  1119. load_default_db_properties(args)
  1120. ok = get_YN_input("Enter advanced database configuration [y/n] (n)? ", False)
  1121. if ok:
  1122. database_num = str(DATABASE_INDEX + 1)
  1123. database_num = get_validated_string_input(
  1124. "Select database:\n1 - Postgres\n2 - Oracle\n3 - MySQL \n[" + database_num + "]:",
  1125. database_num,
  1126. "^[123]$",
  1127. "Invalid number.",
  1128. False
  1129. )
  1130. DATABASE_INDEX = int(database_num) - 1
  1131. args.database = DATABASE_NAMES[DATABASE_INDEX]
  1132. args.database_host = get_validated_string_input(
  1133. "Hostname [" + args.database_host + "]:",
  1134. args.database_host,
  1135. "^[a-zA-Z0-9.\-]*$",
  1136. "Invalid hostname.",
  1137. False
  1138. )
  1139. args.database_port=DATABASE_PORTS[DATABASE_INDEX]
  1140. args.database_port = get_validated_string_input(
  1141. "Port [" + args.database_port + "]:",
  1142. args.database_port,
  1143. "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$",
  1144. "Invalid port.",
  1145. False
  1146. )
  1147. args.database_name = get_validated_string_input(
  1148. DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " name [" + args.database_name + "]:",
  1149. args.database_name,
  1150. "^[a-zA-z\-\"]+$",
  1151. "Invalid " + DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " name.",
  1152. False
  1153. )
  1154. args.database_username = get_validated_string_input(
  1155. 'Username [' + args.database_username + ']: ',
  1156. args.database_username,
  1157. USERNAME_PATTERN,
  1158. "Invalid characters in username. Start with _ or alpha "
  1159. "followed by alphanumeric or _ or - characters",
  1160. False
  1161. )
  1162. args.database_password = read_password(args.database_password)
  1163. print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format(
  1164. database=args.database,
  1165. host=args.database_host,
  1166. port=args.database_port,
  1167. schema=args.database_name,
  1168. user=args.database_username,
  1169. password=args.database_password
  1170. ))
  1171. # Store set of properties for remote database connection
  1172. def store_remote_properties(args):
  1173. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  1174. properties = Properties()
  1175. try:
  1176. properties.load(open(conf_file))
  1177. except Exception, e:
  1178. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  1179. return -1
  1180. properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "remote")
  1181. properties.process_pair(JDBC_DATABASE_PROPERTY, args.database)
  1182. properties.process_pair(JDBC_HOSTNAME_PROPERTY, args.database_host)
  1183. properties.process_pair(JDBC_PORT_PROPERTY, args.database_port)
  1184. properties.process_pair(JDBC_SCHEMA_PROPERTY, args.database_name)
  1185. properties.process_pair(JDBC_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
  1186. properties.process_pair(JDBC_URL_PROPERTY, DATABASE_CONNECTION_STRINGS[DATABASE_INDEX].format(args.database_host, args.database_port, args.database_name))
  1187. properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
  1188. properties.process_pair(JDBC_PASSWORD_FILE_PROPERTY, store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  1189. properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
  1190. properties.process_pair(JDBC_RCA_URL_PROPERTY, DATABASE_CONNECTION_STRINGS[DATABASE_INDEX].format(args.database_host, args.database_port, args.database_name))
  1191. properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, args.database_username)
  1192. properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY, store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  1193. try:
  1194. properties.store(open(conf_file, "w"))
  1195. except Exception, e:
  1196. print 'Could not write ambari config file "%s": %s' % (conf_file, e)
  1197. return -1
  1198. return 0
  1199. # Initialize remote database schema
  1200. def setup_remote_db(args):
  1201. retcode, out, err = execute_remote_script(args, DATABASE_INIT_SCRIPTS[DATABASE_INDEX])
  1202. if retcode != 0:
  1203. if retcode == -1:
  1204. print_warning_msg('Cannot find ' + DATABASE_NAMES[DATABASE_INDEX] +
  1205. ' client in the path, for setup please run the following DDL against the DB: ' +
  1206. DATABASE_INIT_SCRIPTS[DATABASE_INDEX], True)
  1207. print err
  1208. print_error_msg('Database bootstrap failed. Please, provide correct connection properties.')
  1209. return retcode
  1210. pass
  1211. return 0
  1212. # Get database client executable path
  1213. def get_db_cli_tool(args):
  1214. for tool in DATABASE_CLI_TOOLS[DATABASE_INDEX]:
  1215. cmd =CHECK_COMMAND_EXIST_CMD.format(tool)
  1216. ret, out, err = run_in_shell(cmd)
  1217. if ret == 0:
  1218. return get_exec_path(tool)
  1219. return None
  1220. def get_exec_path(cmd):
  1221. cmd = 'which {0}'.format(cmd)
  1222. ret, out, err = run_in_shell(cmd)
  1223. if ret == 0:
  1224. return out.strip()
  1225. else:
  1226. return None
  1227. def run_in_shell(cmd):
  1228. print_info_msg('about to run command: ' + str(cmd))
  1229. process = subprocess.Popen(cmd,
  1230. stdout=subprocess.PIPE,
  1231. stdin=subprocess.PIPE,
  1232. stderr=subprocess.PIPE,
  1233. shell=True
  1234. )
  1235. (stdoutdata, stderrdata) = process.communicate()
  1236. return process.returncode, stdoutdata, stderrdata
  1237. #execute SQL script on remote database
  1238. def execute_remote_script(args, scriptPath):
  1239. tool = get_db_cli_tool(args)
  1240. if not tool:
  1241. args.warnings.append('{0} not found. Please, run DDL script manually'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX]))
  1242. print_warning_msg('{0} not found'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX]))
  1243. return -1, "Client wasn't found", "Client wasn't found"
  1244. if args.database == "postgres":
  1245. os.environ["PGPASSWORD"] = args.database_password
  1246. retcode, out, err = run_in_shell('{0} {1}'.format(tool, POSTGRES_EXEC_ARGS.format(
  1247. args.database_host,
  1248. args.database_port,
  1249. args.database_name,
  1250. args.database_username,
  1251. scriptPath
  1252. )))
  1253. return retcode, out, err
  1254. elif args.database == "oracle":
  1255. retcode, out, err = run_in_shell('{0} {1}'.format(tool, ORACLE_EXEC_ARGS.format(
  1256. args.database_username,
  1257. args.database_password,
  1258. args.database_host,
  1259. args.database_port,
  1260. args.database_name,
  1261. scriptPath
  1262. )))
  1263. return retcode, out, err
  1264. elif args.database=="mysql":
  1265. retcode, out, err = run_in_shell('{0} {1}'.format(tool, MYSQL_EXEC_ARGS.format(
  1266. args.database_host,
  1267. args.database_port,
  1268. args.database_username,
  1269. args.database_password,
  1270. args.database_name,
  1271. scriptPath
  1272. )))
  1273. return retcode, out, err
  1274. return -2, "Wrong database", "Wrong database"
  1275. def configure_database_username_password(args):
  1276. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  1277. properties = Properties()
  1278. try:
  1279. properties.load(open(conf_file))
  1280. except Exception, e:
  1281. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  1282. return -1
  1283. username = properties[JDBC_USER_NAME_PROPERTY]
  1284. passFilePath = properties[JDBC_PASSWORD_FILE_PROPERTY]
  1285. if username and passFilePath:
  1286. print_info_msg("Database username + password already configured - skipping")
  1287. args.database_username=username
  1288. args.database_password = open(passFilePath).read()
  1289. return 1
  1290. else:
  1291. print_error_msg("Connection properties not set in config file.")
  1292. # Store local database connection properties
  1293. def store_local_properties(args):
  1294. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  1295. properties = Properties()
  1296. try:
  1297. properties.load(open(conf_file))
  1298. except Exception, e:
  1299. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  1300. return -1
  1301. properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "local")
  1302. properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
  1303. properties.process_pair(JDBC_PASSWORD_FILE_PROPERTY, store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  1304. try:
  1305. properties.store(open(conf_file, "w"))
  1306. except Exception, e:
  1307. print 'Could not write ambari config file "%s": %s' % (conf_file, e)
  1308. return -1
  1309. return 0
  1310. # Load database connection properties from conf file
  1311. def parse_properties_file(args):
  1312. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  1313. properties = Properties()
  1314. try:
  1315. properties.load(open(conf_file))
  1316. except Exception, e:
  1317. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  1318. return -1
  1319. args.persistence_type = properties[PERSISTENCE_TYPE_PROPERTY]
  1320. if not args.persistence_type:
  1321. args.persistence_type = "local"
  1322. if args.persistence_type == 'remote':
  1323. args.database = properties[JDBC_DATABASE_PROPERTY]
  1324. args.database_host = properties[JDBC_HOSTNAME_PROPERTY]
  1325. args.database_port = properties[JDBC_PORT_PROPERTY]
  1326. args.database_name = properties[JDBC_SCHEMA_PROPERTY]
  1327. global DATABASE_INDEX
  1328. try:
  1329. DATABASE_INDEX = DATABASE_NAMES.index(args.database)
  1330. except ValueError:
  1331. pass
  1332. args.database_username = properties[JDBC_USER_NAME_PROPERTY]
  1333. args.database_password_file = properties[JDBC_PASSWORD_FILE_PROPERTY]
  1334. if args.database_password_file:
  1335. args.database_password = open(properties[JDBC_PASSWORD_FILE_PROPERTY]).read()
  1336. return 0
  1337. #
  1338. # Main.
  1339. #
  1340. def main():
  1341. parser = optparse.OptionParser(usage="usage: %prog [options] action [stack_id]",)
  1342. parser.add_option('-f', '--init-script-file',
  1343. default='/var/lib/ambari-server/'
  1344. 'resources/Ambari-DDL-Postgres-CREATE.sql',
  1345. help="File with setup script")
  1346. parser.add_option('-r', '--drop-script-file', default="/var/lib/"
  1347. "ambari-server/resources/"
  1348. "Ambari-DDL-Postgres-DROP.sql",
  1349. help="File with drop script")
  1350. parser.add_option('-u', '--upgrade-script-file', default="/var/lib/"
  1351. "ambari-server/resources/upgrade/ddl/"
  1352. "Ambari-DDL-Postgres-UPGRADE-1.3.0.sql",
  1353. help="File with upgrade script")
  1354. parser.add_option('-t', '--upgrade-stack-script-file', default="/var/lib/"
  1355. "ambari-server/resources/upgrade/dml/"
  1356. "Ambari-DML-Postgres-UPGRADE_STACK.sql",
  1357. help="File with stack upgrade script")
  1358. parser.add_option('-j', '--java-home', default=None,
  1359. help="Use specified java_home. Must be valid on all hosts")
  1360. parser.add_option("-v", "--verbose",
  1361. action="store_true", dest="verbose", default=False,
  1362. help="Print verbose status messages")
  1363. parser.add_option("-s", "--silent",
  1364. action="store_true", dest="silent", default=False,
  1365. help="Silently accepts default prompt values")
  1366. parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
  1367. help="Start ambari-server in debug mode")
  1368. parser.add_option('--database', default=None, help ="Database to use postgres|oracle|mysql", dest="database")
  1369. parser.add_option('--databasehost', default=None, help="Hostname of database server", dest="database_host")
  1370. parser.add_option('--databaseport', default=None, help="Database port", dest="database_port")
  1371. parser.add_option('--databasename', default=None, help="Database/Schema/Service name", dest="database_name")
  1372. parser.add_option('--databaseusername', default=None, help="Database user login", dest="database_username")
  1373. parser.add_option('--databasepassword', default=None, help="Database user password", dest="database_password")
  1374. (options, args) = parser.parse_args()
  1375. # set verbose
  1376. global VERBOSE
  1377. VERBOSE = options.verbose
  1378. # set silent
  1379. global SILENT
  1380. SILENT = options.silent
  1381. # debug mode
  1382. global SERVER_DEBUG_MODE
  1383. SERVER_DEBUG_MODE = options.debug
  1384. global DATABASE_INDEX
  1385. global PROMPT_DATABASE_OPTIONS
  1386. #perform checks
  1387. options.warnings = []
  1388. if options.database is None \
  1389. and options.database_host is None \
  1390. and options.database_port is None \
  1391. and options.database_name is None \
  1392. and options.database_username is None \
  1393. and options.database_password is None:
  1394. PROMPT_DATABASE_OPTIONS = True
  1395. elif not (options.database is not None
  1396. and options.database_host is not None
  1397. and options.database_port is not None
  1398. and options.database_name is not None
  1399. and options.database_username is not None
  1400. and options.database_password is not None):
  1401. parser.error('All database options should be set.')
  1402. pass
  1403. #correct database
  1404. if options.database is not None and options.database not in DATABASE_NAMES:
  1405. print "Incorrect database"
  1406. parser.print_help()
  1407. exit(-1)
  1408. elif options.database is not None:
  1409. options.database = options.database.lower()
  1410. DATABASE_INDEX = DATABASE_NAMES.index(options.database)
  1411. #correct port
  1412. if options.database_port is not None:
  1413. correct=False
  1414. try:
  1415. port = int(options.database_port)
  1416. if 65536 > port > 0:
  1417. correct = True
  1418. except ValueError:
  1419. pass
  1420. if not correct:
  1421. print "Incorrect database port " + options.database_port
  1422. parser.print_help()
  1423. exit(-1)
  1424. if len(args) == 0:
  1425. print parser.print_help()
  1426. parser.error("No action entered")
  1427. action = args[0]
  1428. if action == UPGRADE_STACK_ACTION:
  1429. args_number_required = 2
  1430. else:
  1431. args_number_required = 1
  1432. if len(args) < args_number_required:
  1433. print parser.print_help()
  1434. parser.error("Invalid number of arguments. Entered: " + str(len(args)) + ", required: " + str(args_number_required))
  1435. if action == SETUP_ACTION:
  1436. setup(options)
  1437. elif action == START_ACTION:
  1438. start(options)
  1439. elif action == STOP_ACTION:
  1440. stop(options)
  1441. elif action == RESET_ACTION:
  1442. reset(options)
  1443. elif action == STATUS_ACTION:
  1444. status(options)
  1445. elif action == UPGRADE_ACTION:
  1446. upgrade(options)
  1447. elif action == UPGRADE_STACK_ACTION:
  1448. stack_id = args[1]
  1449. upgrade_stack(options, stack_id)
  1450. else:
  1451. parser.error("Invalid action")
  1452. # A Python replacement for java.util.Properties
  1453. # Based on http://code.activestate.com/recipes
  1454. # /496795-a-python-replacement-for-javautilproperties/
  1455. class Properties(object):
  1456. def __init__(self, props=None):
  1457. self._props = {}
  1458. self._origprops = {}
  1459. self._keymap = {}
  1460. self.othercharre = re.compile(r'(?<!\\)(\s*\=)|(?<!\\)(\s*\:)')
  1461. self.othercharre2 = re.compile(r'(\s*\=)|(\s*\:)')
  1462. self.bspacere = re.compile(r'\\(?!\s$)')
  1463. def __parse(self, lines):
  1464. lineno = 0
  1465. i = iter(lines)
  1466. for line in i:
  1467. lineno += 1
  1468. line = line.strip()
  1469. if not line: continue
  1470. if line[0] == '#': continue
  1471. escaped = False
  1472. sepidx = -1
  1473. flag = 0
  1474. m = self.othercharre.search(line)
  1475. if m:
  1476. first, last = m.span()
  1477. start, end = 0, first
  1478. flag = 1
  1479. wspacere = re.compile(r'(?<![\\\=\:])(\s)')
  1480. else:
  1481. if self.othercharre2.search(line):
  1482. wspacere = re.compile(r'(?<![\\])(\s)')
  1483. start, end = 0, len(line)
  1484. m2 = wspacere.search(line, start, end)
  1485. if m2:
  1486. first, last = m2.span()
  1487. sepidx = first
  1488. elif m:
  1489. first, last = m.span()
  1490. sepidx = last - 1
  1491. while line[-1] == '\\':
  1492. nextline = i.next()
  1493. nextline = nextline.strip()
  1494. lineno += 1
  1495. line = line[:-1] + nextline
  1496. if sepidx != -1:
  1497. key, value = line[:sepidx], line[sepidx + 1:]
  1498. else:
  1499. key, value = line, ''
  1500. self.process_pair(key, value)
  1501. def process_pair(self, key, value):
  1502. oldkey = key
  1503. oldvalue = value
  1504. keyparts = self.bspacere.split(key)
  1505. strippable = False
  1506. lastpart = keyparts[-1]
  1507. if lastpart.find('\\ ') != -1:
  1508. keyparts[-1] = lastpart.replace('\\', '')
  1509. elif lastpart and lastpart[-1] == ' ':
  1510. strippable = True
  1511. key = ''.join(keyparts)
  1512. if strippable:
  1513. key = key.strip()
  1514. oldkey = oldkey.strip()
  1515. oldvalue = self.unescape(oldvalue)
  1516. value = self.unescape(value)
  1517. self._props[key] = value.strip()
  1518. if self._keymap.has_key(key):
  1519. oldkey = self._keymap.get(key)
  1520. self._origprops[oldkey] = oldvalue.strip()
  1521. else:
  1522. self._origprops[oldkey] = oldvalue.strip()
  1523. self._keymap[key] = oldkey
  1524. def unescape(self, value):
  1525. newvalue = value.replace('\:', ':')
  1526. newvalue = newvalue.replace('\=', '=')
  1527. return newvalue
  1528. def load(self, stream):
  1529. if type(stream) is not file:
  1530. raise TypeError, 'Argument should be a file object!'
  1531. if stream.mode != 'r':
  1532. raise ValueError, 'Stream should be opened in read-only mode!'
  1533. try:
  1534. lines = stream.readlines()
  1535. self.__parse(lines)
  1536. except IOError, e:
  1537. raise
  1538. def get_property(self, key):
  1539. return self._props.get(key, '')
  1540. def propertyNames(self):
  1541. return self._props.keys()
  1542. def getPropertyDict(self):
  1543. return self._props
  1544. def __getitem__(self, name):
  1545. return self.get_property(name)
  1546. def __getattr__(self, name):
  1547. try:
  1548. return self.__dict__[name]
  1549. except KeyError:
  1550. if hasattr(self._props, name):
  1551. return getattr(self._props, name)
  1552. def store(self, out, header=""):
  1553. """ Write the properties list to the stream 'out' along
  1554. with the optional 'header' """
  1555. if out.mode[0] != 'w':
  1556. raise ValueError,'Steam should be opened in write mode!'
  1557. try:
  1558. out.write(''.join(('#', ASF_LICENSE_HEADER, '\n')))
  1559. out.write(''.join(('#',header,'\n')))
  1560. # Write timestamp
  1561. tstamp = time.strftime('%a %b %d %H:%M:%S %Z %Y', time.localtime())
  1562. out.write(''.join(('#',tstamp,'\n')))
  1563. # Write properties from the pristine dictionary
  1564. for prop, val in self._origprops.items():
  1565. if val is not None:
  1566. out.write(''.join((prop,'=',val,'\n')))
  1567. out.close()
  1568. except IOError, e:
  1569. raise
  1570. if __name__ == "__main__":
  1571. main()