ambari-server.py 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987
  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. from pprint import pprint
  19. import shlex
  20. import sys
  21. import os
  22. import signal
  23. import subprocess
  24. import re
  25. import string
  26. import glob
  27. import platform
  28. import shutil
  29. import stat
  30. import fileinput
  31. import urllib2
  32. import time
  33. import getpass
  34. import socket
  35. import datetime
  36. import socket
  37. import tempfile
  38. # debug settings
  39. VERBOSE = False
  40. SILENT = False
  41. SERVER_START_DEBUG = False
  42. # action commands
  43. SETUP_ACTION = "setup"
  44. START_ACTION = "start"
  45. STOP_ACTION = "stop"
  46. RESET_ACTION = "reset"
  47. UPGRADE_ACTION = "upgrade"
  48. UPGRADE_STACK_ACTION = "upgradestack"
  49. UPDATE_METAINFO_ACTION = "update-metainfo"
  50. STATUS_ACTION = "status"
  51. SETUP_HTTPS_ACTION = "setup-https"
  52. LDAP_SETUP_ACTION = "setupldap"
  53. RESET_MASTER_KEY_ACTION = "resetmasterkey"
  54. # selinux commands
  55. GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
  56. SE_SETENFORCE_CMD = "setenforce 0"
  57. SE_STATUS_DISABLED = "disabled"
  58. SE_STATUS_ENABLED = "enabled"
  59. SE_MODE_ENFORCING = "enforcing"
  60. SE_MODE_PERMISSIVE = "permissive"
  61. # iptables commands
  62. IP_TBLS_ST_CMD = "/sbin/service iptables status"
  63. IP_TBLS_STOP_CMD = "/sbin/service iptables stop"
  64. IP_TBLS_ENABLED = "Firewall is running"
  65. IP_TBLS_DISABLED = "Firewall is stopped.\n"
  66. IP_TBLS_SRVC_NT_FND = "iptables: unrecognized service"
  67. # server commands
  68. ambari_provider_module_option = ""
  69. ambari_provider_module = os.environ.get('AMBARI_PROVIDER_MODULE')
  70. # Non-root user setup commands
  71. NR_USER_PROPERTY = "ambari-server.user"
  72. NR_USER_COMMENT = "Ambari user"
  73. NR_GET_OWNER_CMD = 'stat -c "%U" {0}'
  74. NR_USERADD_CMD = 'useradd -M -g {0} --comment "{1}" ' \
  75. '--shell /sbin/nologin -d /var/lib/ambari-server/keys/ {0}'
  76. NR_SET_USER_COMMENT_CMD = 'usermod -c "{0}" {1}'
  77. NR_GROUPADD_CMD = 'groupadd {0}'
  78. NR_ADD_USER_TO_GROUP = 'usermod -G {0} {0}'
  79. NR_CHMOD_CMD = 'chmod {0} {1} {2}'
  80. NR_CHOWN_CMD = 'chown {0} {1}:{2} {3}'
  81. RECURSIVE_RM_CMD = 'rm -rf {0}'
  82. # openssl command
  83. EXPRT_KSTR_CMD = "openssl pkcs12 -export -in {0} -inkey {1} -certfile {0} -out {3} -password pass:{2} -passin pass:{2}"
  84. # constants
  85. STACK_NAME_VER_SEP = "-"
  86. JAVA_SHARE_PATH="/usr/share/java"
  87. # terminal styles
  88. BOLD_ON='\033[1m'
  89. BOLD_OFF='\033[0m'
  90. #Common messages
  91. PRESS_ENTER_MSG="Press <enter> to continue."
  92. if ambari_provider_module is not None:
  93. ambari_provider_module_option = "-Dprovider.module.class=" +\
  94. ambari_provider_module + " "
  95. SERVER_START_CMD="{0}" + os.sep + "bin" + os.sep +\
  96. "java -server -XX:NewRatio=3 "\
  97. "-XX:+UseConcMarkSweepGC " +\
  98. "-XX:-UseGCOverheadLimit -XX:CMSInitiatingOccupancyFraction=60 " +\
  99. ambari_provider_module_option +\
  100. os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') +\
  101. " -cp {1}"+ os.pathsep + "{2}" +\
  102. " org.apache.ambari.server.controller.AmbariServer "\
  103. ">/var/log/ambari-server/ambari-server.out 2>&1 &" \
  104. " echo $! > {3}" # Writing pidfile
  105. SERVER_START_CMD_DEBUG="{0}" + os.sep + "bin" + os.sep +\
  106. "java -server -XX:NewRatio=2 -XX:+UseConcMarkSweepGC " +\
  107. ambari_provider_module_option +\
  108. os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') +\
  109. " -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,"\
  110. "server=y,suspend=n -cp {1}"+ os.pathsep + "{2}" +\
  111. " org.apache.ambari.server.controller.AmbariServer &" \
  112. " echo $! > {3}" # Writing pidfile
  113. SECURITY_PROVIDER_GET_CMD="{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
  114. os.pathsep + "{2} " +\
  115. "org.apache.ambari.server.security.encryption" +\
  116. ".CredentialProvider GET {3} {4} {5} " +\
  117. "> /var/log/ambari-server/ambari-server.out 2>&1"
  118. SECURITY_PROVIDER_PUT_CMD="{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
  119. os.pathsep + "{2} " +\
  120. "org.apache.ambari.server.security.encryption" +\
  121. ".CredentialProvider PUT {3} {4} {5} " +\
  122. "> /var/log/ambari-server/ambari-server.out 2>&1"
  123. SECURITY_PROVIDER_KEY_CMD="{0}" + os.sep + "bin" + os.sep + "java -cp {1}" +\
  124. os.pathsep + "{2} " +\
  125. "org.apache.ambari.server.security.encryption" +\
  126. ".MasterKeyServiceImpl {3} {4} {5} " +\
  127. "> /var/log/ambari-server/ambari-server.out 2>&1"
  128. SECURITY_KEYS_DIR = "security.server.keys_dir"
  129. SECURITY_MASTER_KEY_LOCATION = "security.master.key.location"
  130. SECURITY_KEY_IS_PERSISTED = "security.master.key.ispersisted"
  131. SECURITY_KEY_ENV_VAR_NAME = "ambari.security.master.key"
  132. SECURITY_MASTER_KEY_FILENAME = "master"
  133. SSL_KEY_DIR = 'security.server.keys_dir'
  134. SSL_API_PORT = 'client.api.ssl.port'
  135. SSL_API = 'api.ssl'
  136. SSL_SERVER_CERT_NAME = 'security.server.cert_name'
  137. SSL_SERVER_KEY_NAME = 'security.server.key_name'
  138. SSL_CERT_FILE_NAME = "ca.crt"
  139. SSL_KEY_FILE_NAME = "ca.key"
  140. SSL_KEYSTORE_FILE_NAME = "keystore.p12"
  141. SSL_KEY_PASSWORD_FILE_NAME = "pass.txt"
  142. DEFAULT_SSL_API_PORT = 8443
  143. JDBC_RCA_PASSWORD_ALIAS = "ambari.db.password"
  144. LDAP_MGR_PASSWORD_ALIAS = "ambari.ldap.manager.password"
  145. LDAP_MGR_PASSWORD_PROPERTY = "authentication.ldap.managerPassword"
  146. AMBARI_CONF_VAR="AMBARI_CONF_DIR"
  147. AMBARI_SERVER_LIB="AMBARI_SERVER_LIB"
  148. JAVA_HOME="JAVA_HOME"
  149. PID_DIR="/var/run/ambari-server"
  150. BOOTSTRAP_DIR_PROPERTY="bootstrap.dir"
  151. PID_NAME="ambari-server.pid"
  152. AMBARI_PROPERTIES_FILE="ambari.properties"
  153. AMBARI_PROPERTIES_RPMSAVE_FILE="ambari.properties.rpmsave"
  154. RESOURCES_DIR_PROPERTY="resources.dir"
  155. SETUP_DB_CMD = ['su', '-', 'postgres',
  156. '--command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'"']
  157. UPGRADE_STACK_CMD = ['su', 'postgres',
  158. '--command=psql -f {0} -v stack_name="\'{1}\'" -v stack_version="\'{2}\'"']
  159. UPDATE_METAINFO_CMD = 'curl -X PUT "http://{0}:{1}/api/v1/stacks2" -u "{2}":"{3}"'
  160. PG_ST_CMD = "/sbin/service postgresql status"
  161. PG_INITDB_CMD = "/sbin/service postgresql initdb"
  162. PG_START_CMD = "/sbin/service postgresql start"
  163. PG_RESTART_CMD = "/sbin/service postgresql restart"
  164. PG_STATUS_RUNNING = "running"
  165. PG_HBA_DIR = "/var/lib/pgsql/data/"
  166. PG_HBA_CONF_FILE = PG_HBA_DIR + "pg_hba.conf"
  167. PG_HBA_CONF_FILE_BACKUP = PG_HBA_DIR + "pg_hba_bak.conf.old"
  168. POSTGRESQL_CONF_FILE = PG_HBA_DIR + "postgresql.conf"
  169. PG_HBA_RELOAD_CMD = "su postgres --command='pg_ctl -D {0} reload'"
  170. PG_DEFAULT_PASSWORD = "bigdata"
  171. JDBC_DATABASE_PROPERTY = "server.jdbc.database"
  172. JDBC_HOSTNAME_PROPERTY = "server.jdbc.hostname"
  173. JDBC_PORT_PROPERTY = "server.jdbc.port"
  174. JDBC_SCHEMA_PROPERTY = "server.jdbc.schema"
  175. JDBC_USER_NAME_PROPERTY = "server.jdbc.user.name"
  176. JDBC_PASSWORD_PROPERTY = "server.jdbc.user.passwd"
  177. JDBC_PASSWORD_FILENAME = "password.dat"
  178. JDBC_RCA_PASSWORD_FILENAME = "rca_password.dat"
  179. CLIENT_API_PORT_PROPERTY = "client.api.port"
  180. CLIENT_API_PORT = "8080"
  181. PERSISTENCE_TYPE_PROPERTY = "server.persistence.type"
  182. JDBC_DRIVER_PROPERTY = "server.jdbc.driver"
  183. JDBC_URL_PROPERTY = "server.jdbc.url"
  184. JDBC_RCA_DATABASE_PROPERTY = "server.jdbc.database"
  185. JDBC_RCA_HOSTNAME_PROPERTY = "server.jdbc.hostname"
  186. JDBC_RCA_PORT_PROPERTY = "server.jdbc.port"
  187. JDBC_RCA_SCHEMA_PROPERTY = "server.jdbc.schema"
  188. JDBC_RCA_DRIVER_PROPERTY = "server.jdbc.rca.driver"
  189. JDBC_RCA_URL_PROPERTY = "server.jdbc.rca.url"
  190. JDBC_RCA_USER_NAME_PROPERTY = "server.jdbc.rca.user.name"
  191. JDBC_RCA_PASSWORD_FILE_PROPERTY = "server.jdbc.rca.user.passwd"
  192. CHECK_COMMAND_EXIST_CMD = "type {0}"
  193. DATABASE_INDEX = 0
  194. PROMPT_DATABASE_OPTIONS = False
  195. USERNAME_PATTERN = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
  196. PASSWORD_PATTERN = "^[a-zA-Z0-9_-]*$"
  197. DATABASE_NAMES =["postgres", "oracle"]
  198. DATABASE_STORAGE_NAMES =["Database","Service","Schema"]
  199. DATABASE_PORTS =["5432", "1521", "3306"]
  200. DATABASE_DRIVER_NAMES = ["org.postgresql.Driver", "oracle.jdbc.driver.OracleDriver", "com.mysql.jdbc.Driver"]
  201. DATABASE_CONNECTION_STRINGS = [
  202. "jdbc:postgresql://{0}:{1}/{2}",
  203. "jdbc:oracle:thin:@{0}:{1}/{2}",
  204. "jdbc:mysql://{0}:{1}/{2}"]
  205. DATABASE_CONNECTION_STRINGS_ALT = [
  206. "jdbc:postgresql://{0}:{1}/{2}",
  207. "jdbc:oracle:thin:@{0}:{1}:{2}",
  208. "jdbc:mysql://{0}:{1}/{2}"]
  209. DATABASE_CLI_TOOLS = [["psql"], ["sqlplus", "sqlplus64"], ["mysql"]]
  210. DATABASE_CLI_TOOLS_DESC = ["psql", "sqlplus", "mysql"]
  211. DATABASE_CLI_TOOLS_USAGE = ['su -postgres --command=psql -f {0} -v username=\'"{1}"\' -v password="\'{2}\'"',
  212. 'sqlplus {1}/{2} < {0} ',
  213. 'mysql --user={1} --password={2} {3}<{0}']
  214. DATABASE_INIT_SCRIPTS = ['/var/lib/ambari-server/resources/Ambari-DDL-Postgres-REMOTE-CREATE.sql',
  215. '/var/lib/ambari-server/resources/Ambari-DDL-Oracle-CREATE.sql',
  216. '/var/lib/ambari-server/resources/Ambari-DDL-MySQL-CREATE.sql']
  217. DATABASE_DROP_SCRIPTS = ['/var/lib/ambari-server/resources/Ambari-DDL-Postgres-REMOTE-DROP.sql',
  218. '/var/lib/ambari-server/resources/Ambari-DDL-Oracle-DROP.sql',
  219. '/var/lib/ambari-server/resources/Ambari-DDL-MySQL-DROP.sql']
  220. 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])$"
  221. 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])$"
  222. POSTGRES_EXEC_ARGS = "-h {0} -p {1} -d {2} -U {3} -f {4} -v username='\"{3}\"'"
  223. ORACLE_EXEC_ARGS = "-S '{0}/{1}@(description=(address=(protocol=TCP)(host={2})(port={3}))(connect_data=(sid={4})))' @{5} {0}"
  224. MYSQL_EXEC_ARGS = "--host={0} --port={1} --user={2} --password={3} {4} " \
  225. "-e\"set @schema=\'{4}\'; set @username=\'{2}\'; source {5};\""
  226. JDBC_PATTERNS = {"oracle":"*ojdbc*.jar", "mysql":"*mysql*.jar"}
  227. DATABASE_FULL_NAMES = {"oracle":"Oracle", "mysql":"MySQL", "postgres":"PostgreSQL"}
  228. ORACLE_DB_ID_TYPES = ["Service Name", "Service ID"]
  229. # jdk commands
  230. JDK_LOCAL_FILENAME = "jdk-6u31-linux-x64.bin"
  231. JDK_MIN_FILESIZE = 5000
  232. JDK_INSTALL_DIR = "/usr/jdk64"
  233. CREATE_JDK_DIR_CMD = "/bin/mkdir -p " + JDK_INSTALL_DIR
  234. MAKE_FILE_EXECUTABLE_CMD = "chmod a+x {0}"
  235. JAVA_HOME_PROPERTY = "java.home"
  236. JDK_URL_PROPERTY='jdk.url'
  237. JCE_URL_PROPERTY='jce_policy.url'
  238. OS_TYPE_PROPERTY = "server.os_type"
  239. JDK_DOWNLOAD_CMD = "curl --create-dirs -o {0} {1}"
  240. JDK_DOWNLOAD_SIZE_CMD = "curl -I {0}"
  241. #JCE Policy files
  242. JCE_POLICY_FILENAME = "jce_policy-6.zip"
  243. JCE_DOWNLOAD_CMD = "curl -o {0} {1}"
  244. JCE_MIN_FILESIZE = 5000
  245. #Apache License Header
  246. ASF_LICENSE_HEADER = '''
  247. # Copyright 2011 The Apache Software Foundation
  248. #
  249. # Licensed to the Apache Software Foundation (ASF) under one
  250. # or more contributor license agreements. See the NOTICE file
  251. # distributed with this work for additional information
  252. # regarding copyright ownership. The ASF licenses this file
  253. # to you under the Apache License, Version 2.0 (the
  254. # "License"); you may not use this file except in compliance
  255. # with the License. You may obtain a copy of the License at
  256. #
  257. # http://www.apache.org/licenses/LICENSE-2.0
  258. #
  259. # Unless required by applicable law or agreed to in writing, software
  260. # distributed under the License is distributed on an "AS IS" BASIS,
  261. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  262. # See the License for the specific language governing permissions and
  263. # limitations under the License.
  264. '''
  265. def get_conf_dir():
  266. try:
  267. conf_dir = os.environ[AMBARI_CONF_VAR]
  268. return conf_dir
  269. except KeyError:
  270. default_conf_dir = "/etc/ambari-server/conf"
  271. print AMBARI_CONF_VAR + " is not set, using default " + default_conf_dir
  272. return default_conf_dir
  273. def find_properties_file():
  274. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  275. if conf_file is None:
  276. err = 'File %s not found in search path $%s: %s' % (AMBARI_PROPERTIES_FILE,
  277. AMBARI_CONF_VAR, get_conf_dir())
  278. print err
  279. raise FatalException(1, err)
  280. else:
  281. print_info_msg ('Loading properties from ' + conf_file)
  282. return conf_file
  283. def update_ambari_properties():
  284. prev_conf_file = search_file(AMBARI_PROPERTIES_RPMSAVE_FILE, get_conf_dir())
  285. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  286. # Previous config file does not exist
  287. if (not prev_conf_file) or (prev_conf_file is None):
  288. print_warning_msg("Can not find ambari.properties.rpmsave file from previous version, skipping import of settings")
  289. return 0
  290. try:
  291. old_properties = Properties()
  292. old_properties.load(open(prev_conf_file))
  293. except Exception, e:
  294. print 'Could not read "%s": %s' % (prev_conf_file, e)
  295. return -1
  296. try:
  297. new_properties = Properties()
  298. new_properties.load(open(conf_file))
  299. for prop_key, prop_value in old_properties.getPropertyDict().items():
  300. new_properties.process_pair(prop_key,prop_value)
  301. new_properties.store(open(conf_file,'w'))
  302. except Exception, e:
  303. print 'Could not write "%s": %s' % (conf_file, e)
  304. return -1
  305. timestamp = datetime.datetime.now()
  306. format = '%Y%m%d%H%M%S'
  307. os.rename(prev_conf_file, prev_conf_file + '.' + timestamp.strftime(format))
  308. return 0
  309. NR_CONF_DIR = get_conf_dir()
  310. # ownership/permissions mapping
  311. # path - permissions - user - group - recursive
  312. # Rules are executed in the same order as they are listed
  313. # {0} in user/group will be replaced by customized ambari-server username
  314. NR_ADJUST_OWNERSHIP_LIST =[
  315. ( "/var/log/ambari-server", "644", "{0}", "{0}", True ),
  316. ( "/var/log/ambari-server", "755", "{0}", "{0}", False ),
  317. ( "/var/run/ambari-server", "644", "{0}", "{0}" , True),
  318. ( "/var/run/ambari-server", "755", "{0}", "{0}" , False),
  319. ( "/var/run/ambari-server/bootstrap", "755", "{0}", "{0}", False ),
  320. ( "/var/lib/ambari-server/keys", "600", "{0}", "{0}", True ),
  321. ( "/var/lib/ambari-server/keys", "700", "{0}", "{0}", False ),
  322. ( "/var/lib/ambari-server/keys/db", "700", "{0}", "{0}", False ),
  323. ( "/var/lib/ambari-server/keys/db/newcerts", "700", "{0}", "{0}", False ),
  324. ( "/var/lib/ambari-server/keys/.ssh", "700", "{0}", "{0}", False ),
  325. ( "/etc/ambari-server/conf", "644", "{0}", "{0}", True ),
  326. ( "/etc/ambari-server/conf", "755", "{0}", "{0}", False ),
  327. ( "/etc/ambari-server/conf/password.dat", "640", "{0}", "{0}", False ),
  328. # Also, /etc/ambari-server/conf/password.dat
  329. # is generated later at store_password_file
  330. ]
  331. ### System interaction ###
  332. class FatalException(Exception):
  333. def __init__(self, code, reason):
  334. self.code = code
  335. self.reason = reason
  336. def __str__(self):
  337. return repr("Fatal exception: %s, exit code %s" % (self.reason, self.code))
  338. def _get_message(self):
  339. return str(self)
  340. def is_root():
  341. '''
  342. Checks effective UUID
  343. Returns True if a program is running under root-level privileges.
  344. '''
  345. return os.geteuid() == 0
  346. def get_exec_path(cmd):
  347. cmd = 'which {0}'.format(cmd)
  348. ret, out, err = run_in_shell(cmd)
  349. if ret == 0:
  350. return out.strip()
  351. else:
  352. return None
  353. def run_in_shell(cmd):
  354. print_info_msg('about to run command: ' + str(cmd))
  355. process = subprocess.Popen(cmd,
  356. stdout=subprocess.PIPE,
  357. stdin=subprocess.PIPE,
  358. stderr=subprocess.PIPE,
  359. shell=True
  360. )
  361. (stdoutdata, stderrdata) = process.communicate()
  362. return process.returncode, stdoutdata, stderrdata
  363. def run_os_command(cmd):
  364. print_info_msg('about to run command: ' + str(cmd))
  365. if type(cmd) == str:
  366. cmd = shlex.split(cmd)
  367. process = subprocess.Popen(cmd,
  368. stdout=subprocess.PIPE,
  369. stdin=subprocess.PIPE,
  370. stderr=subprocess.PIPE
  371. )
  372. (stdoutdata, stderrdata) = process.communicate()
  373. return process.returncode, stdoutdata, stderrdata
  374. #
  375. # Updates metainfo information from stack root. Re-cache information from
  376. # repoinfo.xml , metainfo.xml files , etc.
  377. #
  378. def update_metainfo(args):
  379. configure_update_metainfo_args(args)
  380. hostname = args.hostname
  381. port = args.port
  382. username = args.username
  383. password = args.password
  384. command = UPDATE_METAINFO_CMD
  385. command = command.format(hostname, port, username, password)
  386. retcode, outdata, errdata = run_os_command(command)
  387. if outdata.find("Bad credentials") > 0:
  388. print 'Incorrect credential provided. Please try again.'
  389. if not retcode == 0:
  390. print errdata
  391. return retcode
  392. def configure_update_metainfo_args(args):
  393. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  394. properties = Properties()
  395. try:
  396. properties.load(open(conf_file))
  397. except Exception, e:
  398. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  399. return -1
  400. default_username = "admin"
  401. username_prompt = 'Username [' + default_username + ']: '
  402. password_prompt = 'Password: '
  403. input_pattern = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
  404. hostname = socket.gethostname()
  405. port = properties[CLIENT_API_PORT_PROPERTY]
  406. if not port:
  407. port = CLIENT_API_PORT
  408. input_descr = "Invalid characters in received. Start with _ or alpha "\
  409. "followed by alphanumeric or _ or - characters"
  410. print 'Full authentication is required to access the Ambari API'
  411. username = get_validated_string_input(username_prompt, default_username,
  412. input_pattern, input_descr, False)
  413. password = get_validated_string_input(password_prompt, "", input_pattern,
  414. input_descr, True)
  415. args.hostname = hostname
  416. args.port = port
  417. args.username = username
  418. args.password = password
  419. #
  420. # Checks SELinux
  421. #
  422. def check_selinux():
  423. try:
  424. retcode, out, err = run_os_command(GET_SE_LINUX_ST_CMD)
  425. se_status = re.search('(disabled|enabled)', out).group(0)
  426. print "SELinux status is '" + se_status + "'"
  427. if se_status == SE_STATUS_DISABLED:
  428. return 0
  429. else:
  430. try:
  431. se_mode = re.search('(enforcing|permissive)', out).group(0)
  432. except AttributeError:
  433. err = "Error determining SELinux mode. Exiting."
  434. raise FatalException(1, err)
  435. print "SELinux mode is '" + se_mode + "'"
  436. if se_mode == SE_MODE_ENFORCING:
  437. print "Temporarily disabling SELinux"
  438. run_os_command(SE_SETENFORCE_CMD)
  439. print_warning_msg(
  440. "SELinux is set to 'permissive' mode and temporarily disabled."
  441. " You should disable SELinux permanently.")
  442. ok = get_YN_input("OK to continue [y/n] (y)? ", True)
  443. if not ok:
  444. raise FatalException(1, None)
  445. return 0
  446. except OSError:
  447. print_warning_msg("Could not run {0}: OK".format(GET_SE_LINUX_ST_CMD))
  448. return 0
  449. def read_ambari_user():
  450. '''
  451. Reads ambari user from properties file
  452. '''
  453. conf_file = find_properties_file()
  454. try:
  455. properties = Properties()
  456. properties.load(open(conf_file))
  457. user = properties[NR_USER_PROPERTY]
  458. if user:
  459. return user
  460. else:
  461. return None
  462. except Exception, e:
  463. print_error_msg('Could not read "%s": %s' % (conf_file, e))
  464. return None
  465. def adjust_directory_permissions(ambari_user):
  466. properties = get_ambari_properties()
  467. bootstrap_dir = get_value_from_properties(properties, BOOTSTRAP_DIR_PROPERTY)
  468. print "Wiping bootstrap dir ({0}) contents...".format(bootstrap_dir)
  469. cmd = RECURSIVE_RM_CMD.format(bootstrap_dir)
  470. run_os_command(cmd)
  471. os.mkdir(bootstrap_dir)
  472. print "adjusting permissions and ownership..."
  473. for pack in NR_ADJUST_OWNERSHIP_LIST:
  474. file = pack[0]
  475. mod = pack[1]
  476. user = pack[2].format(ambari_user)
  477. group = pack[3].format(ambari_user)
  478. recursive = pack[4]
  479. set_file_permissions(file, mod, user, group, recursive)
  480. def set_file_permissions(file, mod, user, group, recursive):
  481. WARN_MSG = "Command {0} returned exit code {1} with message: {2}"
  482. if recursive:
  483. params = " -R "
  484. else:
  485. params = ""
  486. if os.path.exists(file):
  487. command = NR_CHMOD_CMD.format(params, mod, file)
  488. retcode, out, err = run_os_command(command)
  489. if retcode != 0 :
  490. print_warning_msg(WARN_MSG.format(command, file, err))
  491. command = NR_CHOWN_CMD.format(params, user, group, file)
  492. retcode, out, err = run_os_command(command)
  493. if retcode != 0 :
  494. print_warning_msg(WARN_MSG.format(command, file, err))
  495. else:
  496. print_info_msg("File %s does not exist" % file)
  497. def create_custom_user():
  498. user = get_validated_string_input(
  499. "Please choose user name for ambari-server process: ",
  500. "ambari",
  501. "^[a-z_][a-z0-9_-]{1,31}$",
  502. "Invalid username.",
  503. False
  504. )
  505. print_info_msg("Trying to create group {0}".format(user))
  506. command = NR_GROUPADD_CMD.format(user)
  507. retcode, out, err = run_os_command(command)
  508. if retcode == 9: # 9 = group already exists
  509. print_warning_msg("Group {0} already exists, "
  510. "skipping group creation".format(user))
  511. elif retcode != 0: # fail:
  512. print_warning_msg("Can't create group {0}. Command {1} "
  513. "finished with {2}: \n{3}".format(user, command, retcode, err))
  514. return retcode, None
  515. print_info_msg("Trying to create user {0}".format(user))
  516. command = NR_USERADD_CMD.format(user, NR_USER_COMMENT)
  517. retcode, out, err = run_os_command(command)
  518. if retcode == 9: # 9 = username already in use
  519. print_warning_msg("User {0} already exists, "
  520. "skipping user creation".format(user))
  521. print_info_msg("Trying to add user {0} to group {0}".format(user))
  522. command = NR_ADD_USER_TO_GROUP.format(user)
  523. retcode, out, err = run_os_command(command)
  524. if retcode != 0: # fail:
  525. print_warning_msg("Can't add user {0} to group {0}. Command {1} "
  526. "finished with {2}: \n{3}".format(user, command, retcode, err))
  527. return retcode, None
  528. elif retcode != 0: # fail
  529. print_warning_msg("Can't create user {0}. Command {1} "
  530. "finished with {2}: \n{3}".format(user, command, retcode, err))
  531. return retcode, None
  532. print_info_msg("User/group configuration is done.")
  533. return 0, user
  534. def check_ambari_user():
  535. try:
  536. user = read_ambari_user()
  537. create_user = False
  538. update_user_setting = False
  539. if user is not None:
  540. create_user = get_YN_input("Ambari-server process is configured run under user {0}."
  541. " Change this setting [y/n] (n)? ".format(user), False)
  542. update_user_setting = create_user # Only if we will create another user
  543. else: # user is not configured yet
  544. update_user_setting = True # Write configuration anyway
  545. create_user = get_YN_input("Create a separate user for ambari-server "
  546. "daemon [y/n] (n)? ", False)
  547. if not create_user:
  548. user = "root"
  549. if create_user:
  550. (retcode, user) = create_custom_user()
  551. if retcode != 0:
  552. return retcode
  553. if update_user_setting:
  554. write_property(NR_USER_PROPERTY, user)
  555. adjust_directory_permissions(user)
  556. except OSError:
  557. print_error_msg("Failed: %s" % OSError.message)
  558. return 4
  559. except Exception as e:
  560. print_error_msg("Unexpected error %s" % e.message)
  561. return 1
  562. return 0
  563. #
  564. # Checks iptables
  565. #
  566. def check_iptables():
  567. # not used
  568. # retcode, out, err = run_os_command(IP_TBLS_ST_CMD)
  569. ''' This check doesn't work on CentOS 6.2 if firewall AND
  570. iptables service are running if out == IP_TBLS_ENABLED:
  571. print 'iptables is enabled now'
  572. print 'Stopping iptables service'
  573. '''
  574. retcode, out, err = run_os_command(IP_TBLS_STOP_CMD)
  575. print 'iptables is disabled now'
  576. if not retcode == 0 and err and len(err) > 0:
  577. print err
  578. if err.strip() == IP_TBLS_SRVC_NT_FND:
  579. return 0
  580. else:
  581. return retcode, out
  582. ### Postgres ###
  583. def configure_pg_hba_ambaridb_users():
  584. args = optparse.Values()
  585. configure_database_username_password(args)
  586. with open(PG_HBA_CONF_FILE, "a") as pgHbaConf:
  587. pgHbaConf.write("\n")
  588. pgHbaConf.write("local all " + args.database_username +
  589. ",mapred md5")
  590. pgHbaConf.write("\n")
  591. pgHbaConf.write("host all " + args.database_username +
  592. ",mapred 0.0.0.0/0 md5")
  593. pgHbaConf.write("\n")
  594. pgHbaConf.write("host all " + args.database_username +
  595. ",mapred ::/0 md5")
  596. pgHbaConf.write("\n")
  597. command = PG_HBA_RELOAD_CMD.format(PG_HBA_DIR)
  598. retcode, out, err = run_os_command(command)
  599. if not retcode == 0:
  600. raise FatalException(retcode, err)
  601. def configure_pg_hba_postgres_user():
  602. postgresString = "all postgres"
  603. for line in fileinput.input(PG_HBA_CONF_FILE, inplace=1):
  604. print re.sub('all\s*all', postgresString, line),
  605. os.chmod(PG_HBA_CONF_FILE, 0644)
  606. def configure_postgresql_conf():
  607. listenAddress = "listen_addresses = '*' #"
  608. for line in fileinput.input(POSTGRESQL_CONF_FILE, inplace=1):
  609. print re.sub('#+listen_addresses.*?(#|$)', listenAddress, line),
  610. os.chmod(POSTGRESQL_CONF_FILE, 0644)
  611. def configure_postgres():
  612. if os.path.isfile(PG_HBA_CONF_FILE):
  613. if not os.path.isfile(PG_HBA_CONF_FILE_BACKUP):
  614. shutil.copyfile(PG_HBA_CONF_FILE, PG_HBA_CONF_FILE_BACKUP)
  615. else:
  616. #Postgres has been configured before, must not override backup
  617. print "Backup for pg_hba found, reconfiguration not required"
  618. return 0
  619. configure_pg_hba_postgres_user()
  620. configure_pg_hba_ambaridb_users()
  621. os.chmod(PG_HBA_CONF_FILE, 0644)
  622. configure_postgresql_conf()
  623. #restart postgresql if already running
  624. pg_status = get_postgre_status()
  625. if pg_status == PG_STATUS_RUNNING:
  626. retcode = restart_postgres()
  627. return retcode
  628. return 0
  629. def restart_postgres():
  630. print "Restarting PostgreSQL"
  631. process = subprocess.Popen(PG_RESTART_CMD.split(' '),
  632. stdout=subprocess.PIPE,
  633. stdin=subprocess.PIPE,
  634. stderr=subprocess.PIPE
  635. )
  636. time.sleep(5)
  637. result = process.poll()
  638. if result is None:
  639. print_info_msg("Killing restart PostgresSQL process")
  640. process.kill()
  641. pg_status = get_postgre_status()
  642. # SUSE linux set status of stopped postgresql proc to unused
  643. if pg_status == "unused" or pg_status == "stopped":
  644. print_info_msg("PostgreSQL is stopped. Restarting ...")
  645. retcode, out, err = run_os_command(PG_START_CMD)
  646. return retcode
  647. return 0
  648. # todo: check if the scheme is already exist
  649. def write_property(key, value):
  650. conf_file = find_properties_file()
  651. properties = Properties()
  652. try:
  653. properties.load(open(conf_file))
  654. except Exception, e:
  655. print_error_msg('Could not read ambari config file "%s": %s' % (conf_file, e))
  656. return -1
  657. properties.process_pair(key, value)
  658. try:
  659. properties.store(open(conf_file, "w"))
  660. except Exception, e:
  661. print_error_msg('Could not write ambari config file "%s": %s' % (conf_file, e))
  662. return -1
  663. return 0
  664. def setup_db(args):
  665. #password access to ambari-server and mapred
  666. configure_database_username_password(args)
  667. dbname = args.database_name
  668. scriptFile = args.init_script_file
  669. username = args.database_username
  670. password = args.database_password
  671. command = SETUP_DB_CMD[:]
  672. command[-1] = command[-1].format(scriptFile, username, password)
  673. retcode, outdata, errdata = run_os_command(command)
  674. if not retcode == 0:
  675. print errdata
  676. return retcode
  677. def store_password_file(password, filename):
  678. conf_file = find_properties_file()
  679. passFilePath = os.path.join(os.path.dirname(conf_file),
  680. filename)
  681. with open(passFilePath, 'w+') as passFile:
  682. passFile.write(password)
  683. print_info_msg("Adjusting filesystem permissions")
  684. ambari_user = read_ambari_user()
  685. set_file_permissions(passFilePath, "660", ambari_user, "root", False)
  686. return passFilePath
  687. def execute_db_script(args, file):
  688. #password access to ambari-server and mapred
  689. configure_database_username_password(args)
  690. dbname = args.database_name
  691. username = args.database_username
  692. password = args.database_password
  693. command = SETUP_DB_CMD[:]
  694. command[-1] = command[-1].format(file, username, password)
  695. retcode, outdata, errdata = run_os_command(command)
  696. if not retcode == 0:
  697. print errdata
  698. return retcode
  699. def check_db_consistency(args, file):
  700. #password access to ambari-server and mapred
  701. configure_database_username_password(args)
  702. dbname = args.database_name
  703. username = args.database_username
  704. password = args.database_password
  705. command = SETUP_DB_CMD[:]
  706. command[-1] = command[-1].format(file, username, password)
  707. retcode, outdata, errdata = run_os_command(command)
  708. if not retcode == 0:
  709. print errdata
  710. return retcode
  711. else:
  712. # Assumes that the output is of the form ...\n<count>
  713. print_info_msg("Parsing output: " + outdata)
  714. lines = outdata.splitlines()
  715. if (lines[-1] == '3' or lines[-1] == '0'):
  716. return 0
  717. return -1
  718. def get_postgre_status():
  719. retcode, out, err = run_os_command(PG_ST_CMD)
  720. try:
  721. pg_status = re.search('(stopped|running)', out).group(0)
  722. except AttributeError:
  723. pg_status = None
  724. return pg_status
  725. def check_postgre_up():
  726. pg_status = get_postgre_status()
  727. if pg_status == PG_STATUS_RUNNING:
  728. print_info_msg ("PostgreSQL is running")
  729. return 0
  730. else:
  731. print "Running initdb: This may take upto a minute."
  732. retcode, out, err = run_os_command(PG_INITDB_CMD)
  733. if retcode == 0:
  734. print out
  735. print "About to start PostgreSQL"
  736. try:
  737. process = subprocess.Popen(PG_START_CMD.split(' '),
  738. stdout=subprocess.PIPE,
  739. stdin=subprocess.PIPE,
  740. stderr=subprocess.PIPE
  741. )
  742. time.sleep(20)
  743. result = process.poll()
  744. print_info_msg("Result of postgres start cmd: " + str(result))
  745. if result is None:
  746. process.kill()
  747. pg_status = get_postgre_status()
  748. if pg_status == PG_STATUS_RUNNING:
  749. print_info_msg("Postgres process is running. Returning...")
  750. return 0
  751. else:
  752. retcode = result
  753. except (Exception), e:
  754. pg_status = get_postgre_status()
  755. if pg_status == PG_STATUS_RUNNING:
  756. return 0
  757. else:
  758. print_error_msg("Postgres start failed. " + str(e))
  759. return 1
  760. return retcode
  761. def read_password(passwordDefault=PG_DEFAULT_PASSWORD,
  762. passwordPattern=PASSWORD_PATTERN,
  763. passwordPrompt=None,
  764. passwordDescr=None):
  765. # setup password
  766. if passwordPrompt is None:
  767. passwordPrompt = 'Password [' + passwordDefault + ']: '
  768. if passwordDescr is None:
  769. passwordDescr = "Invalid characters in password. Use only alphanumeric or " \
  770. "_ or - characters"
  771. password = get_validated_string_input(passwordPrompt, passwordDefault,
  772. passwordPattern, passwordDescr, True)
  773. if password != passwordDefault:
  774. password1 = get_validated_string_input("Re-enter password: ",
  775. passwordDefault, passwordPattern, passwordDescr, True)
  776. if password != password1:
  777. print "Passwords do not match"
  778. password = read_password()
  779. return password
  780. def get_pass_file_path(conf_file):
  781. return os.path.join(os.path.dirname(conf_file),
  782. JDBC_PASSWORD_FILENAME)
  783. # Set database properties to default values
  784. def load_default_db_properties(args):
  785. args.database=DATABASE_NAMES[DATABASE_INDEX]
  786. args.database_host = "localhost"
  787. args.database_port = DATABASE_PORTS[DATABASE_INDEX]
  788. args.database_name = "ambari"
  789. args.database_username = "ambari"
  790. args.database_password = "bigdata"
  791. args.sid_or_sname = "sname"
  792. pass
  793. # Ask user for database conenction properties
  794. def prompt_db_properties(args):
  795. global DATABASE_INDEX
  796. if PROMPT_DATABASE_OPTIONS:
  797. load_default_db_properties(args)
  798. ok = get_YN_input("Enter advanced database configuration [y/n] (n)? ", False)
  799. if ok:
  800. database_num = str(DATABASE_INDEX + 1)
  801. database_num = get_validated_string_input(
  802. "Select database:\n1 - Postgres(Embedded)\n2 - Oracle\n[" + database_num + "]:",
  803. database_num,
  804. "^[12]$",
  805. "Invalid number.",
  806. False
  807. )
  808. DATABASE_INDEX = int(database_num) - 1
  809. args.database = DATABASE_NAMES[DATABASE_INDEX]
  810. if args.database != "postgres" :
  811. args.database_host = get_validated_string_input(
  812. "Hostname [" + args.database_host + "]:",
  813. args.database_host,
  814. "^[a-zA-Z0-9.\-]*$",
  815. "Invalid hostname.",
  816. False
  817. )
  818. args.database_port=DATABASE_PORTS[DATABASE_INDEX]
  819. args.database_port = get_validated_string_input(
  820. "Port [" + args.database_port + "]:",
  821. args.database_port,
  822. "^([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])$",
  823. "Invalid port.",
  824. False
  825. )
  826. if args.database == "oracle":
  827. # Oracle uses service name or service id
  828. idType = "1"
  829. idType = get_validated_string_input(
  830. "Select type of id to use:\n1 - " + ORACLE_DB_ID_TYPES[0] +
  831. "\n2 - " + ORACLE_DB_ID_TYPES[1] + "\n[" + idType + "]:",
  832. idType,
  833. "^[12]$",
  834. "Invalid number.",
  835. False
  836. )
  837. if idType == "2":
  838. args.sid_or_sname = "sid"
  839. IDTYPE_INDEX = int(idType) - 1
  840. args.database_name = get_validated_string_input(
  841. ORACLE_DB_ID_TYPES[IDTYPE_INDEX] + " [" + args.database_name + "]:",
  842. args.database_name,
  843. "^[a-zA-Z0-9.\-]*$",
  844. "Invalid " + ORACLE_DB_ID_TYPES[IDTYPE_INDEX] + ".",
  845. False
  846. )
  847. else:
  848. # MySQL and other DB types
  849. pass
  850. pass
  851. else:
  852. args.database_host = "localhost"
  853. args.database_port = DATABASE_PORTS[DATABASE_INDEX]
  854. args.database_name = get_validated_string_input(
  855. DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " Name [" + args.database_name + "]:",
  856. args.database_name,
  857. "^[a-zA-z\-\"]+$",
  858. "Invalid " + DATABASE_STORAGE_NAMES[DATABASE_INDEX] + " name.",
  859. False
  860. )
  861. pass
  862. args.database_username = get_validated_string_input(
  863. 'Username [' + args.database_username + ']: ',
  864. args.database_username,
  865. USERNAME_PATTERN,
  866. "Invalid characters in username. Start with _ or alpha "
  867. "followed by alphanumeric or _ or - characters",
  868. False
  869. )
  870. (masterKey, isSecure, isPersisted) = setup_master_key()
  871. (password, passwordAlias) = configure_database_password(isSecure,
  872. masterKey, True)
  873. args.database_password = password
  874. if passwordAlias:
  875. setattr(args, 'database_password_alias', passwordAlias) # Store alias if present
  876. print_info_msg('Using database options: {database},{host},{port},{schema},{user},{password}'.format(
  877. database=args.database,
  878. host=args.database_host,
  879. port=args.database_port,
  880. schema=args.database_name,
  881. user=args.database_username,
  882. password=args.database_password
  883. ))
  884. # Store set of properties for remote database connection
  885. def store_remote_properties(args):
  886. properties = get_ambari_properties()
  887. if properties == -1:
  888. print_error_msg ("Error getting ambari properties")
  889. return -1
  890. properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "remote")
  891. properties.process_pair(JDBC_DATABASE_PROPERTY, args.database)
  892. properties.process_pair(JDBC_HOSTNAME_PROPERTY, args.database_host)
  893. properties.process_pair(JDBC_PORT_PROPERTY, args.database_port)
  894. properties.process_pair(JDBC_SCHEMA_PROPERTY, args.database_name)
  895. properties.process_pair(JDBC_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
  896. # fully qualify the hostname to make sure all the other hosts can connect
  897. # to the jdbc hostname since its passed onto the agents for RCA
  898. jdbc_hostname = args.database_host
  899. if (args.database_host == "localhost"):
  900. jdbc_hostname = socket.getfqdn();
  901. connectionStringFormat = DATABASE_CONNECTION_STRINGS
  902. if args.sid_or_sname == "sid":
  903. connectionStringFormat = DATABASE_CONNECTION_STRINGS_ALT
  904. properties.process_pair(JDBC_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
  905. properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
  906. if hasattr(args, 'database_password_alias') and args.database_password_alias:
  907. properties.process_pair(JDBC_PASSWORD_PROPERTY, args.database_password_alias)
  908. else:
  909. properties.process_pair(JDBC_PASSWORD_PROPERTY,
  910. store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  911. properties.process_pair(JDBC_RCA_DRIVER_PROPERTY, DATABASE_DRIVER_NAMES[DATABASE_INDEX])
  912. properties.process_pair(JDBC_RCA_URL_PROPERTY, connectionStringFormat[DATABASE_INDEX].format(jdbc_hostname, args.database_port, args.database_name))
  913. properties.process_pair(JDBC_RCA_USER_NAME_PROPERTY, args.database_username)
  914. if hasattr(args, 'database_password_alias') and args.database_password_alias:
  915. properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
  916. args.database_password_alias)
  917. else:
  918. properties.process_pair(JDBC_RCA_PASSWORD_FILE_PROPERTY,
  919. store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  920. conf_file = properties.fileName
  921. try:
  922. properties.store(open(conf_file, "w"))
  923. except Exception, e:
  924. print 'Could not write ambari config file "%s": %s' % (conf_file, e)
  925. return -1
  926. return 0
  927. # Initialize remote database schema
  928. def setup_remote_db(args):
  929. not_found_msg = "Cannot find {0} {1} client in the path to load the Ambari Server schema.\
  930. Before starting Ambari Server, you must run the following DDL against the database to create \
  931. the schema ".format(DATABASE_NAMES[DATABASE_INDEX], str(DATABASE_CLI_TOOLS_DESC[DATABASE_INDEX]))
  932. client_usage_cmd = DATABASE_CLI_TOOLS_USAGE[DATABASE_INDEX].format(DATABASE_INIT_SCRIPTS[DATABASE_INDEX], args.database_username,
  933. args.database_password, args.database_name)
  934. retcode, out, err = execute_remote_script(args, DATABASE_INIT_SCRIPTS[DATABASE_INDEX])
  935. if retcode != 0:
  936. if retcode == -1:
  937. print_warning_msg(not_found_msg + os.linesep + client_usage_cmd)
  938. if not SILENT:
  939. raw_input(PRESS_ENTER_MSG)
  940. return retcode
  941. print err
  942. print_error_msg('Database bootstrap failed. Please, provide correct connection properties.')
  943. return retcode
  944. return 0
  945. # Get database client executable path
  946. def get_db_cli_tool(args):
  947. for tool in DATABASE_CLI_TOOLS[DATABASE_INDEX]:
  948. cmd =CHECK_COMMAND_EXIST_CMD.format(tool)
  949. ret, out, err = run_in_shell(cmd)
  950. if ret == 0:
  951. return get_exec_path(tool)
  952. return None
  953. #execute SQL script on remote database
  954. def execute_remote_script(args, scriptPath):
  955. tool = get_db_cli_tool(args)
  956. if not tool:
  957. args.warnings.append('{0} not found. Please, run DDL script manually'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX]))
  958. if VERBOSE:
  959. print_warning_msg('{0} not found'.format(DATABASE_CLI_TOOLS[DATABASE_INDEX]))
  960. return -1, "Client wasn't found", "Client wasn't found"
  961. if args.database == "postgres":
  962. os.environ["PGPASSWORD"] = args.database_password
  963. retcode, out, err = run_in_shell('{0} {1}'.format(tool, POSTGRES_EXEC_ARGS.format(
  964. args.database_host,
  965. args.database_port,
  966. args.database_name,
  967. args.database_username,
  968. scriptPath
  969. )))
  970. return retcode, out, err
  971. elif args.database == "oracle":
  972. retcode, out, err = run_in_shell('{0} {1}'.format(tool, ORACLE_EXEC_ARGS.format(
  973. args.database_username,
  974. args.database_password,
  975. args.database_host,
  976. args.database_port,
  977. args.database_name,
  978. scriptPath
  979. )))
  980. return retcode, out, err
  981. elif args.database=="mysql":
  982. retcode, out, err = run_in_shell('{0} {1}'.format(tool, MYSQL_EXEC_ARGS.format(
  983. args.database_host,
  984. args.database_port,
  985. args.database_username,
  986. args.database_password,
  987. args.database_name,
  988. scriptPath
  989. )))
  990. return retcode, out, err
  991. return -2, "Wrong database", "Wrong database"
  992. def configure_database_password(isSecure=False, masterKey=None, showDefault=True):
  993. passwordDefault = PG_DEFAULT_PASSWORD
  994. if showDefault:
  995. passwordPrompt = 'Enter Database Password [' + passwordDefault + ']: '
  996. else:
  997. passwordPrompt = 'Enter Database Password: '
  998. passwordPattern = "^[a-zA-Z0-9_-]*$"
  999. passwordDescr = "Invalid characters in password. Use only alphanumeric or "\
  1000. "_ or - characters"
  1001. password = read_password(passwordDefault, passwordPattern, passwordPrompt,
  1002. passwordDescr)
  1003. aliasStr = None
  1004. if isSecure:
  1005. retCode = save_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS, password, masterKey)
  1006. if retCode != 0:
  1007. print 'Saving secure database password failed.'
  1008. return password, aliasStr
  1009. return password, get_alias_string(JDBC_RCA_PASSWORD_ALIAS)
  1010. return password, aliasStr
  1011. def configure_database_username_password(args):
  1012. properties = get_ambari_properties()
  1013. if properties == -1:
  1014. print_error_msg ("Error getting ambari properties")
  1015. return -1
  1016. username = properties[JDBC_USER_NAME_PROPERTY]
  1017. passwordProp = properties[JDBC_PASSWORD_PROPERTY]
  1018. isPersisted = get_master_key_ispersisted(properties)
  1019. if username and passwordProp:
  1020. print_info_msg("Database username + password already configured")
  1021. args.database_username=username
  1022. if is_alias_string(passwordProp):
  1023. if isPersisted:
  1024. # No need to prompt for key
  1025. args.database_password = read_passwd_for_alias(JDBC_RCA_PASSWORD_ALIAS)
  1026. else:
  1027. (masterKey, isSecure, isPersisted) = setup_master_key()
  1028. args.database_password = read_passwd_for_alias(
  1029. JDBC_RCA_PASSWORD_ALIAS, masterKey)
  1030. return 1
  1031. else:
  1032. print_error_msg("Connection properties not set in config file.")
  1033. # Store local database connection properties
  1034. def store_local_properties(args):
  1035. properties = get_ambari_properties()
  1036. if properties == -1:
  1037. print_error_msg ("Error getting ambari properties")
  1038. return -1
  1039. properties.removeOldProp(JDBC_SCHEMA_PROPERTY)
  1040. properties.removeOldProp(JDBC_HOSTNAME_PROPERTY)
  1041. properties.removeOldProp(JDBC_DATABASE_PROPERTY)
  1042. properties.removeOldProp(JDBC_RCA_DRIVER_PROPERTY)
  1043. properties.removeOldProp(JDBC_RCA_URL_PROPERTY)
  1044. properties.removeOldProp(JDBC_PORT_PROPERTY)
  1045. properties.removeOldProp(JDBC_PORT_PROPERTY)
  1046. properties.removeOldProp(JDBC_DRIVER_PROPERTY)
  1047. properties.removeOldProp(JDBC_URL_PROPERTY)
  1048. properties.removeOldProp(JDBC_DATABASE_PROPERTY)
  1049. properties.process_pair(PERSISTENCE_TYPE_PROPERTY, "local")
  1050. properties.process_pair(JDBC_USER_NAME_PROPERTY, args.database_username)
  1051. if hasattr(args, 'database_password_alias') and args.database_password_alias:
  1052. properties.process_pair(JDBC_PASSWORD_PROPERTY,
  1053. args.database_password_alias)
  1054. else:
  1055. properties.process_pair(JDBC_PASSWORD_PROPERTY,
  1056. store_password_file(args.database_password, JDBC_PASSWORD_FILENAME))
  1057. conf_file = properties.fileName
  1058. try:
  1059. properties.store(open(conf_file, "w"))
  1060. except Exception, e:
  1061. print 'Could not write ambari config file "%s": %s' % (conf_file, e)
  1062. return -1
  1063. return 0
  1064. # Load ambari properties and return dict with values
  1065. def get_ambari_properties():
  1066. conf_file = find_properties_file()
  1067. properties = None
  1068. try:
  1069. properties = Properties()
  1070. properties.load(open(conf_file))
  1071. except (Exception), e:
  1072. print 'Could not read "%s": %s' % (conf_file, e)
  1073. return -1
  1074. return properties
  1075. # Load database connection properties from conf file
  1076. def parse_properties_file(args):
  1077. conf_file = find_properties_file()
  1078. properties = Properties()
  1079. try:
  1080. properties.load(open(conf_file))
  1081. except Exception, e:
  1082. print 'Could not read ambari config file "%s": %s' % (conf_file, e)
  1083. return -1
  1084. args.persistence_type = properties[PERSISTENCE_TYPE_PROPERTY]
  1085. if not args.persistence_type:
  1086. args.persistence_type = "local"
  1087. if args.persistence_type == 'remote':
  1088. args.database = properties[JDBC_DATABASE_PROPERTY]
  1089. args.database_host = properties[JDBC_HOSTNAME_PROPERTY]
  1090. args.database_port = properties[JDBC_PORT_PROPERTY]
  1091. args.database_name = properties[JDBC_SCHEMA_PROPERTY]
  1092. global DATABASE_INDEX
  1093. try:
  1094. DATABASE_INDEX = DATABASE_NAMES.index(args.database)
  1095. except ValueError:
  1096. pass
  1097. args.database_username = properties[JDBC_USER_NAME_PROPERTY]
  1098. args.database_password_file = properties[JDBC_PASSWORD_PROPERTY]
  1099. if args.database_password_file:
  1100. if not is_alias_string(args.database_password_file):
  1101. args.database_password = open(properties[JDBC_PASSWORD_PROPERTY]).read()
  1102. else:
  1103. args.database_password = args.database_password_file
  1104. return 0
  1105. ### JDK ###
  1106. def get_ambari_jars():
  1107. try:
  1108. conf_dir = os.environ[AMBARI_SERVER_LIB]
  1109. return conf_dir
  1110. except KeyError:
  1111. default_jar_location = "/usr/lib/ambari-server"
  1112. print_info_msg(AMBARI_SERVER_LIB + " is not set, using default "
  1113. + default_jar_location)
  1114. return default_jar_location
  1115. def get_share_jars():
  1116. share_jars = ""
  1117. file_list = []
  1118. file_list.extend(glob.glob(JAVA_SHARE_PATH + os.sep + "*mysql*"))
  1119. file_list.extend(glob.glob(JAVA_SHARE_PATH + os.sep + "*ojdbc*"))
  1120. if len(file_list) > 0:
  1121. share_jars = string.join(file_list, os.pathsep)
  1122. return share_jars
  1123. def get_ambari_classpath():
  1124. ambari_cp = get_ambari_jars() + os.sep + "*"
  1125. share_cp = get_share_jars()
  1126. if len(share_cp) > 0:
  1127. ambari_cp = ambari_cp + os.pathsep + share_cp
  1128. return ambari_cp
  1129. def search_file(filename, search_path, pathsep=os.pathsep):
  1130. """ Given a search path, find file with requested name """
  1131. for path in string.split(search_path, pathsep):
  1132. candidate = os.path.join(path, filename)
  1133. if os.path.exists(candidate): return os.path.abspath(candidate)
  1134. return None
  1135. def dlprogress(base_name, count, blockSize, totalSize):
  1136. percent = int(count * blockSize * 100 / totalSize)
  1137. if (totalSize < blockSize):
  1138. sys.stdout.write("\r" + base_name + "... %d%%" % (100))
  1139. else:
  1140. sys.stdout.write("\r" + base_name + "... %d%% (%.1f MB of %.1f MB)" % (
  1141. percent, count * blockSize / 1024 / 1024.0, totalSize / 1024 / 1024.0))
  1142. if (percent == 100 or totalSize < blockSize):
  1143. sys.stdout.write("\n")
  1144. sys.stdout.flush()
  1145. def track_jdk(base_name, url, local_name):
  1146. u = urllib2.urlopen(url)
  1147. h = u.info()
  1148. totalSize = int(h["Content-Length"])
  1149. fp = open(local_name, "wb")
  1150. blockSize = 8192
  1151. count = 0
  1152. percent = 0
  1153. while True:
  1154. chunk = u.read(blockSize)
  1155. if not chunk:
  1156. break
  1157. fp.write(chunk)
  1158. count += 1
  1159. dlprogress(base_name, count, blockSize, totalSize)
  1160. fp.flush()
  1161. fp.close()
  1162. def install_jce_manualy(args):
  1163. properties = get_ambari_properties()
  1164. if properties == -1:
  1165. err = "Error getting ambari properties"
  1166. raise FatalException(-1, err)
  1167. if args.jce_policy and os.path.exists(args.jce_policy):
  1168. jce_destination = os.path.join(properties[RESOURCES_DIR_PROPERTY], JCE_POLICY_FILENAME)
  1169. shutil.copy(args.jce_policy, jce_destination)
  1170. print "JCE policy copied from " + args.jce_policy + " to " + jce_destination
  1171. return 0
  1172. else:
  1173. return 1
  1174. #
  1175. # Downloads the JDK
  1176. #
  1177. def download_jdk(args):
  1178. jce_installed = install_jce_manualy(args)
  1179. if get_JAVA_HOME():
  1180. return 0
  1181. if args.java_home and os.path.exists(args.java_home):
  1182. print_warning_msg("JAVA_HOME " + args.java_home
  1183. + " must be valid on ALL hosts")
  1184. write_property(JAVA_HOME_PROPERTY, args.java_home)
  1185. return 0
  1186. properties = get_ambari_properties()
  1187. if properties == -1:
  1188. err = "Error getting ambari properties"
  1189. raise FatalException(-1, err)
  1190. conf_file = properties.fileName
  1191. try:
  1192. jdk_url = properties[JDK_URL_PROPERTY]
  1193. resources_dir = properties[RESOURCES_DIR_PROPERTY]
  1194. except (KeyError), e:
  1195. err = 'Property ' + str(e) + ' is not defined at ' + conf_file
  1196. raise FatalException(1, err)
  1197. dest_file = resources_dir + os.sep + JDK_LOCAL_FILENAME
  1198. if not os.path.exists(dest_file):
  1199. print 'Downloading JDK from ' + jdk_url + ' to ' + dest_file
  1200. try:
  1201. size_command = JDK_DOWNLOAD_SIZE_CMD.format(jdk_url);
  1202. #Get Header from url,to get file size then
  1203. retcode, out, err = run_os_command(size_command)
  1204. if out.find("Content-Length") == -1:
  1205. err = "Request header doesn't contain Content-Length"
  1206. raise FatalException(1, err)
  1207. start_with = int(out.find("Content-Length") + len("Content-Length") + 2)
  1208. end_with = out.find("\r\n", start_with)
  1209. src_size = int(out[start_with:end_with])
  1210. print 'JDK distribution size is ' + str(src_size) + ' bytes'
  1211. file_exists = os.path.isfile(dest_file)
  1212. file_size = -1
  1213. if file_exists:
  1214. file_size = os.stat(dest_file).st_size
  1215. if file_exists and file_size == src_size:
  1216. print_info_msg("File already exists")
  1217. else:
  1218. track_jdk(JDK_LOCAL_FILENAME, jdk_url, dest_file)
  1219. print 'Successfully downloaded JDK distribution to ' + dest_file
  1220. except FatalException:
  1221. raise
  1222. except Exception, e:
  1223. err = 'Failed to download JDK: ' + str(e)
  1224. raise FatalException(1, err)
  1225. downloaded_size = os.stat(dest_file).st_size
  1226. if downloaded_size != src_size or downloaded_size < JDK_MIN_FILESIZE:
  1227. err = 'Size of downloaded JDK distribution file is ' \
  1228. + str(downloaded_size) + ' bytes, it is probably \
  1229. damaged or incomplete'
  1230. raise FatalException(1, err)
  1231. else:
  1232. print "JDK already exists using " + dest_file
  1233. try:
  1234. out, ok = install_jdk(dest_file)
  1235. jdk_version = re.search('Creating (jdk.*)/jre', out).group(1)
  1236. except Exception, e:
  1237. print "Installation of JDK has failed: %s\n" % e.message
  1238. file_exists = os.path.isfile(dest_file)
  1239. if file_exists:
  1240. ok = get_YN_input("JDK found at "+dest_file+". "
  1241. "Would you like to re-download the JDK [y/n] (y)? ", True)
  1242. if not ok:
  1243. err = "Unable to install JDK. Please remove JDK file found at "+ dest_file +" and re-run Ambari Server setup"
  1244. raise FatalException(1, err)
  1245. else:
  1246. track_jdk(JDK_LOCAL_FILENAME, jdk_url, dest_file)
  1247. print 'Successfully re-downloaded JDK distribution to ' + dest_file
  1248. try:
  1249. out, ok = install_jdk(dest_file)
  1250. jdk_version = re.search('Creating (jdk.*)/jre', out).group(1)
  1251. except Exception, e:
  1252. print "Installation of JDK was failed: %s\n" % e.message
  1253. err = "Unable to install JDK. Please remove JDK, file found at "+ dest_file +" and re-run Ambari Server setup"
  1254. raise FatalException(1, err)
  1255. else:
  1256. err = "Unable to install JDK. File "+ dest_file +" does not exist, please re-run Ambari Server setup"
  1257. raise FatalException(1, err)
  1258. print "Successfully installed JDK to {0}/{1}".\
  1259. format(JDK_INSTALL_DIR, jdk_version)
  1260. write_property(JAVA_HOME_PROPERTY, "{0}/{1}".
  1261. format(JDK_INSTALL_DIR, jdk_version))
  1262. if jce_installed != 0:
  1263. try:
  1264. download_jce_policy(properties, ok)
  1265. except FatalException as e:
  1266. print "JCE Policy files are required for secure HDP setup. Please ensure " \
  1267. " all hosts have the JCE unlimited strength policy 6, files."
  1268. print_error_msg("Failed to download JCE policy files:")
  1269. if e.reason is not None:
  1270. print_error_msg("Reason: {0}".format(e.reason))
  1271. # TODO: We don't fail installation if download_jce_policy fails. Is it OK?
  1272. return 0
  1273. def download_jce_policy(properties, accpeted_bcl):
  1274. try:
  1275. jce_url = properties[JCE_URL_PROPERTY]
  1276. resources_dir = properties[RESOURCES_DIR_PROPERTY]
  1277. except KeyError, e:
  1278. err = 'Property ' + str(e) + ' is not defined in properties file'
  1279. raise FatalException(1, err)
  1280. dest_file = resources_dir + os.sep + JCE_POLICY_FILENAME
  1281. if not os.path.exists(dest_file):
  1282. print 'Downloading JCE Policy archive from ' + jce_url + ' to ' + dest_file
  1283. try:
  1284. size_command = JDK_DOWNLOAD_SIZE_CMD.format(jce_url);
  1285. #Get Header from url,to get file size then
  1286. retcode, out, err = run_os_command(size_command)
  1287. if out.find("Content-Length") == -1:
  1288. err = "Request header doesn't contain Content-Length";
  1289. raise FatalException(1, err)
  1290. start_with = int(out.find("Content-Length") + len("Content-Length") + 2)
  1291. end_with = out.find("\r\n", start_with)
  1292. src_size = int(out[start_with:end_with])
  1293. print_info_msg('JCE zip distribution size is ' + str(src_size) + ' bytes')
  1294. file_exists = os.path.isfile(dest_file)
  1295. file_size = -1
  1296. if file_exists:
  1297. file_size = os.stat(dest_file).st_size
  1298. if file_exists and file_size == src_size:
  1299. print_info_msg("File already exists")
  1300. else:
  1301. #BCL license before download
  1302. jce_download_cmd = JCE_DOWNLOAD_CMD.format(dest_file, jce_url)
  1303. print_info_msg("JCE download cmd: " + jce_download_cmd)
  1304. if accpeted_bcl:
  1305. retcode, out, err = run_os_command(jce_download_cmd)
  1306. if retcode == 0:
  1307. print 'Successfully downloaded JCE Policy archive to ' + dest_file
  1308. else:
  1309. raise FatalException(1, err)
  1310. else:
  1311. ok = get_YN_input("To download the JCE Policy archive you must "
  1312. "accept the license terms found at "
  1313. "http://www.oracle.com/technetwork/java/javase"
  1314. "/terms/license/index.html"
  1315. "Not accepting might result in failure when "
  1316. "setting up HDP security. \nDo you accept the "
  1317. "Oracle Binary Code License Agreement [y/n] (y)? ", True)
  1318. if ok:
  1319. retcode, out, err = run_os_command(jce_download_cmd)
  1320. if retcode == 0:
  1321. print 'Successfully downloaded JCE Policy archive to ' + dest_file
  1322. else:
  1323. raise FatalException(1, None)
  1324. except FatalException:
  1325. raise
  1326. except Exception, e:
  1327. err = 'Failed to download JCE Policy archive: ' + str(e)
  1328. raise FatalException(1, err)
  1329. downloaded_size = os.stat(dest_file).st_size
  1330. if downloaded_size != src_size or downloaded_size < JCE_MIN_FILESIZE:
  1331. err = 'Size of downloaded JCE Policy archive is ' \
  1332. + str(downloaded_size) + ' bytes, it is probably \
  1333. damaged or incomplete'
  1334. raise FatalException(1, err)
  1335. else:
  1336. print "JCE Policy archive already exists, using " + dest_file
  1337. class RetCodeException(Exception): pass
  1338. def install_jdk(dest_file):
  1339. ok = get_YN_input("To install the Oracle JDK you must accept the "
  1340. "license terms found at "
  1341. "http://www.oracle.com/technetwork/java/javase/"
  1342. "downloads/jdk-6u21-license-159167.txt. Not accepting will "
  1343. "cancel the Ambari Server setup.\nDo you accept the "
  1344. "Oracle Binary Code License Agreement [y/n] (y)? ", True)
  1345. if not ok:
  1346. raise FatalException(1, None)
  1347. print "Installing JDK to {0}".format(JDK_INSTALL_DIR)
  1348. retcode, out, err = run_os_command(CREATE_JDK_DIR_CMD)
  1349. savedPath = os.getcwd()
  1350. os.chdir(JDK_INSTALL_DIR)
  1351. retcode, out, err = run_os_command(MAKE_FILE_EXECUTABLE_CMD.format(dest_file))
  1352. retcode, out, err = run_os_command(dest_file + ' -noregister')
  1353. os.chdir(savedPath)
  1354. if retcode != 0:
  1355. err = "Installation of JDK returned exit code %s" % retcode
  1356. raise FatalException(retcode, err)
  1357. return out, ok
  1358. #
  1359. # Configures the OS settings in ambari properties.
  1360. #
  1361. def configure_os_settings():
  1362. properties = get_ambari_properties()
  1363. if properties == -1:
  1364. print_error_msg ("Error getting ambari properties")
  1365. return -1
  1366. try:
  1367. conf_os_type = properties[OS_TYPE_PROPERTY]
  1368. if conf_os_type != '':
  1369. print_info_msg ("os_type already setting in properties file")
  1370. return 0
  1371. except (KeyError), e:
  1372. print_error_msg ("os_type is not set in properties file")
  1373. os_system = platform.system()
  1374. if os_system != 'Linux':
  1375. print_error_msg ("Non-Linux systems are not supported")
  1376. return -1
  1377. os_info = platform.linux_distribution(
  1378. None, None, None, ['SuSE', 'redhat' ], 0
  1379. )
  1380. os_name = os_info[0].lower()
  1381. if os_name == 'suse':
  1382. os_name = 'sles'
  1383. os_version = os_info[1].split('.', 1)[0]
  1384. master_os_type = os_name + os_version
  1385. write_property(OS_TYPE_PROPERTY, master_os_type)
  1386. return 0
  1387. def get_JAVA_HOME():
  1388. properties = get_ambari_properties()
  1389. if properties == -1:
  1390. print_error_msg ("Error getting ambari properties")
  1391. return None
  1392. java_home = properties[JAVA_HOME_PROPERTY]
  1393. if (not 0 == len(java_home)) and (os.path.exists(java_home)):
  1394. return java_home
  1395. return None
  1396. #
  1397. # Finds the available JDKs.
  1398. #
  1399. def find_jdk():
  1400. if get_JAVA_HOME():
  1401. return get_JAVA_HOME()
  1402. print "Looking for available JDKs at " + JDK_INSTALL_DIR
  1403. jdks = glob.glob(JDK_INSTALL_DIR + os.sep + "jdk*")
  1404. jdks.sort()
  1405. print "Found: " + str(jdks)
  1406. count = len(jdks)
  1407. if count == 0:
  1408. return
  1409. jdkPath = jdks[count - 1]
  1410. print "Selected JDK {0}".format(jdkPath)
  1411. return jdkPath
  1412. #
  1413. # Checks if options determine local DB configuration
  1414. #
  1415. def is_local_database(options):
  1416. if options.database == DATABASE_NAMES[0] \
  1417. and options.database_host == "localhost" \
  1418. and options.database_port == DATABASE_PORTS[0] \
  1419. and options.database_name == "ambari":
  1420. return True
  1421. return False
  1422. #Check if required jdbc drivers present
  1423. def find_jdbc_driver(args):
  1424. if args.database in JDBC_PATTERNS.keys():
  1425. drivers = []
  1426. drivers.extend(glob.glob(JAVA_SHARE_PATH + os.sep + JDBC_PATTERNS[args.database]))
  1427. if drivers:
  1428. return drivers
  1429. return -1
  1430. return 0
  1431. def copy_files(files, dest_dir):
  1432. if os.path.isdir(dest_dir):
  1433. for filepath in files:
  1434. shutil.copy(filepath, dest_dir)
  1435. return 0
  1436. else:
  1437. return -1
  1438. def check_jdbc_drivers(args):
  1439. properties = get_ambari_properties()
  1440. ## ask user twice
  1441. for i in range(0,2):
  1442. result = find_jdbc_driver(args)
  1443. if result == -1:
  1444. msg = 'WARNING: Before starting Ambari Server, ' \
  1445. 'the {0} JDBC driver JAR file must be copied to {1}. Press enter to continue.'.format(
  1446. DATABASE_FULL_NAMES[args.database],
  1447. JAVA_SHARE_PATH
  1448. )
  1449. if not SILENT:
  1450. raw_input(msg)
  1451. else:
  1452. print_warning_msg(msg)
  1453. # check if user provided drivers
  1454. result = find_jdbc_driver(args)
  1455. if type(result) is not int:
  1456. print 'Copying JDBC drivers to server resources...'
  1457. try:
  1458. resources_dir = properties[RESOURCES_DIR_PROPERTY]
  1459. except KeyError:
  1460. print_error_msg("There is no value for " + RESOURCES_DIR_PROPERTY + "in " + AMBARI_PROPERTIES_FILE)
  1461. return -1
  1462. copy_files(result, resources_dir)
  1463. break
  1464. return 0
  1465. #
  1466. # Setup the Ambari Server.
  1467. #
  1468. def setup(args):
  1469. if not is_root():
  1470. err = 'Ambari-server setup should be run with '\
  1471. 'root-level privileges'
  1472. raise FatalException(4, err)
  1473. print 'Checking SELinux...'
  1474. retcode = check_selinux()
  1475. if not retcode == 0:
  1476. err = 'Failed to disable SELinux. Exiting.'
  1477. raise FatalException(retcode, err)
  1478. # Create ambari user, if needed
  1479. retcode = check_ambari_user()
  1480. if not retcode == 0:
  1481. err = 'Failed to create user. Exiting.'
  1482. raise FatalException(retcode, err)
  1483. print 'Checking iptables...'
  1484. retcode, out = check_iptables()
  1485. if not retcode == 0 and out == IP_TBLS_ENABLED:
  1486. err = 'Failed to stop iptables. Exiting.'
  1487. raise FatalException(retcode, err)
  1488. print 'Checking JDK...'
  1489. try:
  1490. download_jdk(args)
  1491. except FatalException as e:
  1492. err = 'Downloading or installing JDK failed: {0}. Exiting.'.format(e)
  1493. raise FatalException(e.code, err)
  1494. print 'Completing setup...'
  1495. retcode = configure_os_settings()
  1496. if not retcode == 0:
  1497. err = 'Configure of OS settings in ambari.properties failed. Exiting.'
  1498. raise FatalException(retcode, err)
  1499. print 'Configuring database...'
  1500. prompt_db_properties(args)
  1501. #DB setup should be done last after doing any setup.
  1502. if is_local_database(args):
  1503. print 'Default properties detected. Using built-in database.'
  1504. store_local_properties(args)
  1505. print 'Checking PostgreSQL...'
  1506. retcode = check_postgre_up()
  1507. if not retcode == 0:
  1508. err = 'Unable to start PostgreSQL server. Exiting'
  1509. raise FatalException(retcode, err)
  1510. print 'Configuring database...'
  1511. retcode = setup_db(args)
  1512. if not retcode == 0:
  1513. err = 'Running database init script was failed. Exiting.'
  1514. raise FatalException(retcode, err)
  1515. print 'Configuring PostgreSQL...'
  1516. retcode = configure_postgres()
  1517. if not retcode == 0:
  1518. err = 'Unable to configure PostgreSQL server. Exiting'
  1519. raise FatalException(retcode, err)
  1520. else:
  1521. retcode = store_remote_properties(args)
  1522. if retcode != 0:
  1523. err = 'Unable to save config file'
  1524. raise FatalException(retcode, err)
  1525. check_jdbc_drivers(args)
  1526. print 'Configuring remote database connection properties...'
  1527. retcode = setup_remote_db(args)
  1528. if retcode == -1:
  1529. err = "The cli was not found"
  1530. raise FatalException(retcode, err)
  1531. if not retcode == 0:
  1532. err = 'Error while configuring connection properties. Exiting'
  1533. raise FatalException(retcode, err)
  1534. check_jdbc_drivers(args)
  1535. if args.warnings:
  1536. print "Ambari Server 'setup' finished with warnings:"
  1537. for warning in args.warnings:
  1538. print warning
  1539. else:
  1540. print "Ambari Server 'setup' finished successfully"
  1541. #
  1542. # Resets the Ambari Server.
  1543. #
  1544. def reset(args):
  1545. if not is_root():
  1546. err = 'Ambari-server reset should be run with ' \
  1547. 'root-level privileges'
  1548. raise FatalException(4, err)
  1549. choice = get_YN_input("**** WARNING **** You are about to reset and clear the "
  1550. "Ambari Server database. This will remove all cluster "
  1551. "host and configuration information from the database. "
  1552. "You will be required to re-configure the Ambari server "
  1553. "and re-run the cluster wizard. \n"
  1554. "Are you SURE you want to perform the reset "
  1555. "[yes/no]? ", True)
  1556. okToRun = choice
  1557. if not okToRun:
  1558. err = "Ambari Server 'reset' cancelled"
  1559. raise FatalException(1, err)
  1560. okToRun = get_YN_input("Confirm server reset [yes/no]? ", True)
  1561. if not okToRun:
  1562. err = "Ambari Server 'reset' cancelled"
  1563. raise FatalException(1, err)
  1564. print "Resetting the Server database..."
  1565. parse_properties_file(args)
  1566. # configure_database_username_password(args)
  1567. if args.persistence_type=="remote":
  1568. client_desc = DATABASE_NAMES[DATABASE_INDEX] + ' ' + DATABASE_CLI_TOOLS_DESC[DATABASE_INDEX]
  1569. client_usage_cmd_drop = DATABASE_CLI_TOOLS_USAGE[DATABASE_INDEX].format(DATABASE_DROP_SCRIPTS[DATABASE_INDEX], args.database_username,
  1570. args.database_password, args.database_name)
  1571. client_usage_cmd_init = DATABASE_CLI_TOOLS_USAGE[DATABASE_INDEX].format(DATABASE_INIT_SCRIPTS[DATABASE_INDEX], args.database_username,
  1572. args.database_password, args.database_name)
  1573. if get_db_cli_tool(args) != -1:
  1574. retcode, out, err = execute_remote_script(args, DATABASE_DROP_SCRIPTS[DATABASE_INDEX])
  1575. if not retcode == 0:
  1576. if retcode == -1:
  1577. print_warning_msg('Cannot find ' + client_desc + ' client in the path to reset the Ambari Server schema. To reset Ambari Server schema ' +
  1578. 'you must run the following DDL against the database to drop the schema:' + os.linesep + client_usage_cmd_drop + os.linesep +
  1579. ', then you must run the following DDL against the database to create the schema ' + os.linesep + client_usage_cmd_init + os.linesep )
  1580. raise FatalException(retcode, err)
  1581. retcode, out, err = execute_remote_script(args, DATABASE_INIT_SCRIPTS[DATABASE_INDEX])
  1582. if not retcode == 0:
  1583. if retcode == -1:
  1584. print_warning_msg('Cannot find ' + client_desc + ' client in the path to reset the Ambari Server schema. To reset Ambari Server schema ' +
  1585. 'you must run the following DDL against the database to drop the schema:' + os.linesep + client_usage_cmd_drop + os.linesep +
  1586. ', then you must run the following DDL against the database to create the schema ' + os.linesep + client_usage_cmd_init + os.linesep )
  1587. raise FatalException(retcode, err)
  1588. else:
  1589. err = 'Cannot find ' + client_desc + ' client in the path to reset the Ambari Server schema. To reset Ambari Server schema ' + \
  1590. 'you must run the following DDL against the database to drop the schema:' + os.linesep + client_usage_cmd_drop + os.linesep + \
  1591. ', then you must run the following DDL against the database to create the schema ' + os.linesep + client_usage_cmd_init + os.linesep
  1592. raise FatalException(-1, err)
  1593. else:
  1594. dbname = args.database_name
  1595. filename = args.drop_script_file
  1596. username = args.database_username
  1597. password = args.database_password
  1598. command = SETUP_DB_CMD[:]
  1599. command[-1] = command[-1].format(filename, username, password)
  1600. retcode, outdata, errdata = run_os_command(command)
  1601. if not retcode == 0:
  1602. raise FatalException(1, errdata)
  1603. print_info_msg ("About to run database setup")
  1604. setup_db(args)
  1605. print "Ambari Server 'reset' complete"
  1606. #
  1607. # Starts the Ambari Server.
  1608. #
  1609. def start(args):
  1610. current_user = getpass.getuser()
  1611. ambari_user = read_ambari_user()
  1612. if ambari_user is None:
  1613. err = "Can not detect a system user for Ambari. " \
  1614. "Please run \"setup\" command to create such user "
  1615. raise FatalException(1, err)
  1616. if current_user != ambari_user and not is_root():
  1617. err = "Can not start ambari-server as user {0}. Please either run \"start\" " \
  1618. "command as root or as user {1}".format(current_user, ambari_user)
  1619. raise FatalException(1, err)
  1620. parse_properties_file(args)
  1621. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  1622. f = open(PID_DIR + os.sep + PID_NAME, "r")
  1623. pid = int(f.readline())
  1624. f.close()
  1625. try:
  1626. os.kill(pid, 0)
  1627. err = "Server is already running."
  1628. raise FatalException(1, err)
  1629. except OSError as e:
  1630. print_info_msg("Server is not running...")
  1631. conf_dir = get_conf_dir()
  1632. jdk_path = find_jdk()
  1633. if jdk_path is None:
  1634. err = "No JDK found, please run the \"setup\" " \
  1635. "command to install a JDK automatically or install any " \
  1636. "JDK manually to " + JDK_INSTALL_DIR
  1637. raise FatalException(1, err)
  1638. # Preparations
  1639. if is_root():
  1640. print "Have root privileges."
  1641. if args.persistence_type == "local":
  1642. retcode = check_postgre_up()
  1643. if not retcode == 0:
  1644. err = "Unable to start PostgreSQL server. Exiting"
  1645. raise FatalException(retcode, err)
  1646. print 'Checking iptables...'
  1647. retcode, out = check_iptables()
  1648. if not retcode == 0 and out == IP_TBLS_ENABLED:
  1649. err = "Failed to stop iptables. Exiting"
  1650. raise FatalException(retcode, err)
  1651. else: # Skipping actions that require root permissions
  1652. print "Can not check iptables status when starting "\
  1653. "without root privileges."
  1654. print "Please don't forget to disable or adjust iptables if needed"
  1655. if args.persistence_type == "local":
  1656. print "Can not check PostgreSQL server status when starting " \
  1657. "without root privileges."
  1658. print "Please don't forget to start PostgreSQL server."
  1659. properties = get_ambari_properties()
  1660. persist = get_master_key_ispersisted(properties)
  1661. environ = os.environ.copy()
  1662. # Need to handle master key not persisted scenario
  1663. if persist is not None and not persist:
  1664. prompt = False
  1665. try:
  1666. masterKey = environ[SECURITY_KEY_ENV_VAR_NAME]
  1667. except KeyError:
  1668. masterKey = None
  1669. if masterKey is not None and masterKey != "":
  1670. pass
  1671. else:
  1672. try:
  1673. keyLocation = environ[SECURITY_MASTER_KEY_LOCATION]
  1674. except KeyError:
  1675. keyLocation = None
  1676. if keyLocation is not None:
  1677. try:
  1678. # Verify master key can be read by the java process
  1679. with open(keyLocation, 'r') : pass
  1680. except IOError:
  1681. print_warning_msg("Cannot read Master key from path specified in "
  1682. "environemnt.")
  1683. prompt = True
  1684. else:
  1685. # Key not provided in the environment
  1686. prompt = True
  1687. if prompt:
  1688. masterKey = get_validated_string_input("Please provide master key " +\
  1689. "for unlocking credential store: ", "", ".*", "", False)
  1690. tempDir = tempfile.gettempdir()
  1691. tempFilePath = tempDir + os.sep + "masterkey"
  1692. save_master_key(masterKey, tempFilePath, True)
  1693. os.chmod(tempFilePath, stat.S_IREAD | stat.S_IWRITE)
  1694. if tempFilePath is not None:
  1695. environ[SECURITY_MASTER_KEY_LOCATION] = tempFilePath
  1696. pidfile = PID_DIR + os.sep + PID_NAME
  1697. command_base = SERVER_START_CMD_DEBUG if (SERVER_DEBUG_MODE or SERVER_START_DEBUG) else SERVER_START_CMD
  1698. command = command_base.format(jdk_path, conf_dir, get_ambari_classpath(), pidfile)
  1699. if is_root() and ambari_user != "root":
  1700. # To inherit exported environment variables (especially AMBARI_PASSPHRASE),
  1701. # from subprocess, we have to skip --login option of su command. That's why
  1702. # we change dir to / (otherwise subprocess can face with 'permission denied'
  1703. # errors while trying to list current directory
  1704. os.chdir("/")
  1705. param_list = ["/bin/su", ambari_user, "-s", "/bin/sh", "-c", command]
  1706. else:
  1707. param_list = ["/bin/sh", "-c", command]
  1708. print "Running server: " + str(param_list)
  1709. server_process = subprocess.Popen(param_list, env=environ)
  1710. print "done."
  1711. #
  1712. # Stops the Ambari Server.
  1713. #
  1714. def stop(args):
  1715. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  1716. f = open(PID_DIR + os.sep + PID_NAME, "r")
  1717. pid = int(f.readline())
  1718. try:
  1719. os.killpg(os.getpgid(pid), signal.SIGKILL)
  1720. except OSError, e:
  1721. print_info_msg( "Unable to stop Ambari Server - " + str(e) )
  1722. return
  1723. f.close()
  1724. os.remove(f.name)
  1725. print "Ambari Server stopped"
  1726. else:
  1727. print "Ambari Server is not running"
  1728. ### Stack upgrade ###
  1729. def upgrade_stack(args, stack_id):
  1730. if not is_root():
  1731. err = 'Ambari-server upgradestack should be run with ' \
  1732. 'root-level privileges'
  1733. raise FatalException(4, err)
  1734. #password access to ambari-server and mapred
  1735. configure_database_username_password(args)
  1736. dbname = args.database_name
  1737. file = args.upgrade_stack_script_file
  1738. stack_name, stack_version = stack_id.split(STACK_NAME_VER_SEP)
  1739. command = UPGRADE_STACK_CMD[:]
  1740. command[-1] = command[-1].format(file, stack_name, stack_version)
  1741. retcode, outdata, errdata = run_os_command(command)
  1742. if not retcode == 0:
  1743. raise FatalException(retcode, errdata)
  1744. return retcode
  1745. #
  1746. # Upgrades the Ambari Server.
  1747. #
  1748. def upgrade(args):
  1749. if not is_root():
  1750. err = 'Ambari-server upgrade should be run with ' \
  1751. 'root-level privileges'
  1752. raise FatalException(4, err)
  1753. print 'Updating properties in ' + AMBARI_PROPERTIES_FILE + ' ...'
  1754. retcode = update_ambari_properties()
  1755. if not retcode == 0:
  1756. err = AMBARI_PROPERTIES_FILE + ' file can\'t be updated. Exiting'
  1757. raise FatalException(retcode, err)
  1758. parse_properties_file(args)
  1759. if args.persistence_type == "remote":
  1760. pass
  1761. else:
  1762. print 'Checking PostgreSQL...'
  1763. retcode = check_postgre_up()
  1764. if not retcode == 0:
  1765. err = 'PostgreSQL server not running. Exiting'
  1766. raise FatalException(retcode, err)
  1767. file = args.upgrade_script_file
  1768. print 'Upgrading database...'
  1769. retcode = execute_db_script(args, file)
  1770. if not retcode == 0:
  1771. err = 'Database upgrade script has failed. Exiting.'
  1772. raise FatalException(retcode, err)
  1773. print 'Checking database integrity...'
  1774. check_file = file[:-3] + "Check" + file[-4:]
  1775. retcode = check_db_consistency(args, check_file)
  1776. if not retcode == 0:
  1777. print 'Found inconsistency. Trying to fix...'
  1778. fix_file = file[:-3] + "Fix" + file[-4:]
  1779. retcode = execute_db_script(args, fix_file)
  1780. if not retcode == 0:
  1781. err = 'Database cannot be fixed. Exiting.'
  1782. raise FatalException(retcode, err)
  1783. else:
  1784. print 'Database is consistent.'
  1785. user = read_ambari_user()
  1786. if user is None:
  1787. warn = 'Can not determine custom ambari user. Please run ' \
  1788. '"ambari-server setup" before starting server'
  1789. print_warning_msg(warn)
  1790. else:
  1791. adjust_directory_permissions(user)
  1792. print "Ambari Server 'upgrade' finished successfully"
  1793. #
  1794. # The Ambari Server status.
  1795. #
  1796. def status(args):
  1797. status, pid = is_server_runing()
  1798. if status:
  1799. print "Ambari Server running"
  1800. print "Found Ambari Server PID: '" + str(pid) + " at: " + PID_DIR + os.sep + PID_NAME
  1801. else:
  1802. print "Ambari Server not running. Stale PID File at: " + PID_DIR + os.sep + PID_NAME
  1803. #
  1804. # Prints an "info" messsage.
  1805. #
  1806. def print_info_msg(msg):
  1807. if VERBOSE:
  1808. print("INFO: " + msg)
  1809. #
  1810. # Prints an "error" messsage.
  1811. #
  1812. def print_error_msg(msg):
  1813. print("ERROR: " + msg)
  1814. #
  1815. # Prints a "warning" messsage.
  1816. #
  1817. def print_warning_msg(msg, bold=False):
  1818. if bold:
  1819. print(BOLD_ON + "WARNING: " + msg + BOLD_OFF)
  1820. else:
  1821. print("WARNING: " + msg)
  1822. #
  1823. # Gets the y/n input.
  1824. #
  1825. # return True if 'y' or False if 'n'
  1826. #
  1827. def get_YN_input(prompt,default):
  1828. yes = set(['yes','ye', 'y'])
  1829. no = set(['no','n'])
  1830. return get_choice_string_input(prompt,default,yes,no)
  1831. def get_choice_string_input(prompt,default,firstChoice,secondChoice):
  1832. if SILENT:
  1833. print(prompt)
  1834. return default
  1835. choice = raw_input(prompt).lower()
  1836. if choice in firstChoice:
  1837. return True
  1838. elif choice in secondChoice:
  1839. return False
  1840. elif choice is "": # Just enter pressed
  1841. return default
  1842. else:
  1843. print "input not recognized, please try again: "
  1844. return get_choice_string_input(prompt,default,firstChoice,secondChoice)
  1845. def get_validated_string_input(prompt, default, pattern, description, is_pass):
  1846. input =""
  1847. while not input:
  1848. if SILENT:
  1849. print (prompt)
  1850. input = default
  1851. elif is_pass:
  1852. input = getpass.getpass(prompt)
  1853. else:
  1854. input = raw_input(prompt)
  1855. if not input.strip():
  1856. input = default
  1857. break #done here and picking up default
  1858. else:
  1859. if not pattern==None and not re.search(pattern,input.strip()):
  1860. print description
  1861. input=""
  1862. return input
  1863. def get_value_from_properties(properties, key):
  1864. try:
  1865. value = properties[key]
  1866. except KeyError:
  1867. return ""
  1868. return value
  1869. def setup_ldap():
  1870. properties = get_ambari_properties()
  1871. # Setup secure key
  1872. (masterKey, isSecure, isPersisted) = setup_master_key(False)
  1873. LDAP_PRIMARY_URL_DEFAULT = get_value_from_properties(properties,
  1874. "authentication.ldap.primaryUrl")
  1875. LDAP_SECONDARY_URL_DEFAULT = get_value_from_properties(properties,
  1876. "authentication.ldap.secondaryUrl")
  1877. LDAP_BASE_DN_DEFAULT = get_value_from_properties(properties,
  1878. "authentication.ldap.baseDn")
  1879. LDAP_BIND_DEFAULT = get_value_from_properties(properties,
  1880. "authentication.ldap.bindAnonymously")
  1881. LDAP_USER_ATT_DEFAULT = get_value_from_properties(properties,
  1882. "authentication.ldap.usernameAttribute")
  1883. LDAP_GROUP_BASE_DEFAULT = get_value_from_properties(properties,
  1884. "authorization.ldap.groupBase")
  1885. LDAP_GROUP_OBJ_DEFAULT = get_value_from_properties(properties,
  1886. "authorization.ldap.groupObjectClass")
  1887. LDAP_GROUP_NAME_DEFAULT = get_value_from_properties(properties,
  1888. "authorization.ldap.groupNamingAttr")
  1889. LDAP_GROUP_MEM_DEFAULT = get_value_from_properties(properties,
  1890. "authorization.ldap.groupMembershipAttr")
  1891. LDAP_GROUP_MAP_DEFAULT = get_value_from_properties(properties,
  1892. "authorization.ldap.adminGroupMappingRules")
  1893. LDAP_GROUP_SEARCH_DEFAULT = get_value_from_properties(properties,
  1894. "authorization.ldap.groupSearchFilter")
  1895. LDAP_USER_ROLE_DEFAULT = get_value_from_properties(properties,
  1896. "authorization.userRoleName")
  1897. LDAP_ADMIN_ROLE_DEFAULT = get_value_from_properties(properties,
  1898. "authorization.adminRoleName")
  1899. LDAP_MGR_DN_DEFAULT = get_value_from_properties(properties,
  1900. "authentication.ldap.managerDn")
  1901. ldap_properties_map =\
  1902. {
  1903. "authentication.ldap.primaryUrl":(LDAP_PRIMARY_URL_DEFAULT, "Primary URL: "),\
  1904. "authentication.ldap.secondaryUrl":(LDAP_SECONDARY_URL_DEFAULT, "Secondary URL: "),\
  1905. "authentication.ldap.baseDn":(LDAP_BASE_DN_DEFAULT, "Base DN: "),\
  1906. "authentication.ldap.bindAnonymously":(LDAP_BIND_DEFAULT, "Bind anonymously? [true/alse]?: "),\
  1907. "authentication.ldap.usernameAttribute":(LDAP_USER_ATT_DEFAULT, "User name attribute uid): "),\
  1908. "authorization.ldap.groupBase":(LDAP_GROUP_BASE_DEFAULT, "Group base ou=groups,dc=ambari): "),\
  1909. "authorization.ldap.groupObjectClass":(LDAP_GROUP_OBJ_DEFAULT, "Group object class group): "),\
  1910. "authorization.ldap.groupNamingAttr":(LDAP_GROUP_NAME_DEFAULT, "Group name attribute cn): "),\
  1911. "authorization.ldap.groupMembershipAttr":(LDAP_GROUP_MEM_DEFAULT, "Group membership ttribute (member): "),\
  1912. "authorization.ldap.adminGroupMappingRules":(LDAP_GROUP_MAP_DEFAULT, "Admin group apping rules: "),\
  1913. "authorization.ldap.groupSearchFilter":(LDAP_GROUP_SEARCH_DEFAULT, "Group search filter: "),\
  1914. "authorization.userRoleName":(LDAP_USER_ROLE_DEFAULT, "User role name (user): "),\
  1915. "authorization.adminRoleName":(LDAP_ADMIN_ROLE_DEFAULT, "Admin role name (admin): "),
  1916. "authentication.ldap.managerDn":(LDAP_MGR_DN_DEFAULT, "Manager DN: ")
  1917. }
  1918. print "Input LDAP properties. Hit [Enter] to skip property."
  1919. ldap_property_value_map = {}
  1920. for key in ldap_properties_map.keys():
  1921. input = get_validated_string_input(ldap_properties_map[key][1],
  1922. ldap_properties_map[key][0], ".*", "", False)
  1923. if input is not None and input != "":
  1924. ldap_property_value_map[key] = input
  1925. ldap_property_value_map[LDAP_MGR_PASSWORD_PROPERTY] =\
  1926. configure_ldap_password(isSecure, masterKey)
  1927. # Persisting values
  1928. update_properties(ldap_property_value_map)
  1929. return 0
  1930. def reset_master_key():
  1931. setup_master_key(resetKey=True)
  1932. def setup_master_key(resetKey=False):
  1933. properties = get_ambari_properties()
  1934. passwordPattern = "^[a-zA-Z0-9_-]*$"
  1935. passwordDescr = "Invalid characters in password. Use only alphanumeric or "\
  1936. "_ or - characters"
  1937. passwordDefault = "hadooprocks!"
  1938. # check configuration for location of master key
  1939. keyLocation = get_master_key_location(properties)
  1940. persist = get_master_key_ispersisted(properties)
  1941. masterKeyFile = search_file(SECURITY_MASTER_KEY_FILENAME, keyLocation)
  1942. if persist is not None:
  1943. if persist and masterKeyFile is not None and not resetKey:
  1944. return None, True, True # setup is secure and key persisted
  1945. elif not persist and not resetKey:
  1946. masterKey = get_validated_string_input("Please provide master key " +\
  1947. "for unlocking credential store: ", "", ".*", "", False)
  1948. return masterKey, True, False # return master key for saving passwords
  1949. else:
  1950. if masterKeyFile is not None:
  1951. print_info_msg("Master key file exists. Updating property...")
  1952. update_properties({SECURITY_KEY_IS_PERSISTED : True})
  1953. return None, True, True
  1954. enable_ok = True
  1955. if not resetKey:
  1956. enable_ok = get_YN_input("Do you want encryption enabled for saving " +\
  1957. "passwords [y/n] (n)? ", False)
  1958. if not enable_ok:
  1959. return None, False, None
  1960. key = None
  1961. if masterKeyFile is None or resetKey:
  1962. key = get_validated_string_input(
  1963. "Please provide master key for the credential store: ",
  1964. passwordDefault, passwordPattern, passwordDescr, True)
  1965. if key != passwordDefault:
  1966. key = get_validated_string_input("Please re-enter master key: ",
  1967. passwordDefault, passwordPattern, passwordDescr, True)
  1968. persist = get_YN_input("Do you want to persist master key. If you choose "\
  1969. "not to persist, you need to provide the master "\
  1970. "key while starting the ambari server as a env "\
  1971. "variable named " + SECURITY_KEY_ENV_VAR_NAME +\
  1972. " or the start will prompt for the master key."
  1973. " Persist [y/n] (y)? ", True)
  1974. if persist:
  1975. save_master_key(key, keyLocation + os.sep + SECURITY_MASTER_KEY_FILENAME,
  1976. persist)
  1977. elif not persist and masterKeyFile is not None:
  1978. try:
  1979. os.remove(masterKeyFile)
  1980. print_warning_msg("Master key exists although security " +\
  1981. "is disabled. location: " + str(masterKeyFile))
  1982. except Exception, e:
  1983. print 'Could not remove master key file. %s' % e
  1984. if persist is not None:
  1985. update_properties({SECURITY_KEY_IS_PERSISTED : persist})
  1986. if resetKey:
  1987. # Blow up the credential store made with previous key
  1988. store_file = get_credential_store_location(properties)
  1989. if os.path.exists(store_file):
  1990. os.remove(store_file)
  1991. # Encrypt the passwords with new key
  1992. try:
  1993. db_password_alias = properties[JDBC_PASSWORD_PROPERTY]
  1994. ldap_password_alias = properties[LDAP_MGR_PASSWORD_PROPERTY]
  1995. except (KeyError), e:
  1996. print_warning_msg("KeyError: " + str(e))
  1997. if db_password_alias is not None and is_alias_string(db_password_alias):
  1998. configure_database_password(True, key, True)
  1999. if ldap_password_alias is not None and is_alias_string(ldap_password_alias):
  2000. configure_ldap_password(True)
  2001. return key, True, persist
  2002. def get_credential_store_location(properties):
  2003. store_loc = properties[SECURITY_KEYS_DIR]
  2004. if store_loc is None or store_loc == "":
  2005. store_loc = "/var/lib/ambari-server/keys/credentials.jceks"
  2006. else:
  2007. store_loc += os.sep + "credentials.jceks"
  2008. return store_loc
  2009. def get_master_key_location(properties):
  2010. keyLocation = properties[SECURITY_MASTER_KEY_LOCATION]
  2011. if keyLocation is None or keyLocation == "":
  2012. keyLocation = properties[SECURITY_KEYS_DIR]
  2013. return keyLocation
  2014. def get_master_key_ispersisted(properties):
  2015. try:
  2016. isPersisted = properties[SECURITY_KEY_IS_PERSISTED]
  2017. except (KeyError), e:
  2018. return None
  2019. if isPersisted is not None and isPersisted != "":
  2020. return isPersisted == 'true' or isPersisted == 'TRUE' or\
  2021. isPersisted == 'True'
  2022. return None
  2023. def is_alias_string(passwdStr):
  2024. regex = re.compile("\$\{alias=[\w\.]+\}")
  2025. # Match implies string at beginning of word
  2026. r = regex.match(passwdStr)
  2027. if r is not None:
  2028. return True
  2029. else:
  2030. return False
  2031. def get_alias_string(alias):
  2032. return "${alias=" + alias + "}"
  2033. def read_passwd_for_alias(alias, masterKey=""):
  2034. if alias:
  2035. jdk_path = find_jdk()
  2036. if jdk_path is None:
  2037. print_error_msg("No JDK found, please run the \"setup\" "
  2038. "command to install a JDK automatically or install any "
  2039. "JDK manually to " + JDK_INSTALL_DIR)
  2040. return 1
  2041. tempFileName = "ambari.passwd"
  2042. passwd = ""
  2043. tempDir = tempfile.gettempdir()
  2044. #create temporary file for writing
  2045. tempFilePath = tempDir + os.sep + tempFileName
  2046. file = open(tempFilePath, 'w+')
  2047. os.chmod(tempFilePath, stat.S_IREAD | stat.S_IWRITE)
  2048. file.close()
  2049. if masterKey is None or masterKey == "":
  2050. masterKey = "None"
  2051. command = SECURITY_PROVIDER_GET_CMD.format(jdk_path,
  2052. get_conf_dir(), get_ambari_classpath(), alias, tempFilePath, masterKey)
  2053. (retcode, stdout, stderr) = run_os_command(command)
  2054. print_info_msg("Return code from credential provider get passwd: " +
  2055. str(retcode))
  2056. if retcode != 0:
  2057. print 'Unable to read password from store. alias = ' + alias
  2058. else:
  2059. passwd = open(tempFilePath, 'r').read()
  2060. # Remove temporary file
  2061. os.remove(tempFilePath)
  2062. return passwd
  2063. else:
  2064. print_error_msg("Alias is unreadable.")
  2065. def save_passwd_for_alias(alias, passwd, masterKey=""):
  2066. if alias and passwd:
  2067. jdk_path = find_jdk()
  2068. if jdk_path is None:
  2069. print_error_msg("No JDK found, please run the \"setup\" "
  2070. "command to install a JDK automatically or install any "
  2071. "JDK manually to " + JDK_INSTALL_DIR)
  2072. return 1
  2073. if masterKey is None or masterKey == "":
  2074. masterKey = "None"
  2075. command = SECURITY_PROVIDER_PUT_CMD.format(jdk_path, get_conf_dir(),
  2076. get_ambari_classpath(), alias, passwd, masterKey)
  2077. (retcode, stdout, stderr) = run_os_command(command)
  2078. print_info_msg("Return code from credential provider save passwd: " +
  2079. str(retcode))
  2080. return retcode
  2081. else:
  2082. print_error_msg("Alias or password is unreadable.")
  2083. def save_master_key(master_key, key_location, persist=True):
  2084. if master_key:
  2085. jdk_path = find_jdk()
  2086. if jdk_path is None:
  2087. print_error_msg("No JDK found, please run the \"setup\" "
  2088. "command to install a JDK automatically or install any "
  2089. "JDK manually to " + JDK_INSTALL_DIR)
  2090. return 1
  2091. command = SECURITY_PROVIDER_KEY_CMD.format(jdk_path,
  2092. get_ambari_classpath(), get_conf_dir(), master_key, key_location, persist)
  2093. (retcode, stdout, stderr) = run_os_command(command)
  2094. print_info_msg("Return code from credential provider save KEY: " +
  2095. str(retcode))
  2096. else:
  2097. print_error_msg("Master key cannot be None.")
  2098. def configure_ldap_password(isSecure=False, masterKey=None):
  2099. passwordDefault = ""
  2100. passwordPrompt = 'Enter LDAP Password: '
  2101. passwordPattern = ".*"
  2102. passwordDescr = "Invalid characters in password."
  2103. password = read_password(passwordDefault, passwordPattern, passwordPrompt,
  2104. passwordDescr)
  2105. if isSecure:
  2106. retCode = save_passwd_for_alias(LDAP_MGR_PASSWORD_ALIAS, password, masterKey)
  2107. if retCode != 0:
  2108. print 'Saving secure ldap password failed.'
  2109. return password
  2110. return get_alias_string(LDAP_MGR_PASSWORD_ALIAS)
  2111. return password
  2112. # Copy file to /tmp and save with file.# (largest # is latest file)
  2113. def backup_file_in_temp(filePath):
  2114. if filePath is not None:
  2115. tmpDir = tempfile.gettempdir()
  2116. back_up_file_count = len(glob.glob1(tmpDir, AMBARI_PROPERTIES_FILE + "*"))
  2117. try:
  2118. shutil.copyfile(filePath, tmpDir + os.sep +
  2119. AMBARI_PROPERTIES_FILE + "." + str(back_up_file_count + 1))
  2120. except (Exception), e:
  2121. print_error_msg('Could not backup file in temp "%s": %s' % (str(
  2122. back_up_file_count, e)))
  2123. return 0
  2124. # update properties in a section-less properties file
  2125. # Cannot use ConfigParser due to bugs in version 2.6
  2126. def update_properties(propertyMap):
  2127. conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
  2128. backup_file_in_temp(conf_file)
  2129. if propertyMap is not None and conf_file is not None:
  2130. properties = Properties()
  2131. try:
  2132. with open(conf_file, 'r') as file:
  2133. properties.load(file)
  2134. except (Exception), e:
  2135. print_error_msg ('Could not read "%s": %s' % (conf_file, e))
  2136. return -1
  2137. #for key in propertyMap.keys():
  2138. #properties[key] = propertyMap[key]
  2139. for key in propertyMap.keys():
  2140. properties.removeOldProp(key)
  2141. properties.process_pair(key, str(propertyMap[key]))
  2142. with open(conf_file, 'w') as file:
  2143. properties.store(file)
  2144. return 0
  2145. def setup_https(args):
  2146. if not SILENT:
  2147. properties = get_ambari_properties()
  2148. try:
  2149. security_server_keys_dir = properties.get_property(SSL_KEY_DIR)
  2150. client_api_ssl_port = DEFAULT_SSL_API_PORT if properties.get_property(SSL_API_PORT) in ("")\
  2151. else properties.get_property(SSL_API_PORT)
  2152. api_ssl = properties.get_property(SSL_API) in ['true']
  2153. cert_was_imported = False
  2154. if api_ssl:
  2155. if get_YN_input("Do you want to disable SSL (y/n) n? ", False):
  2156. properties.process_pair(SSL_API, "false")
  2157. else:
  2158. properties.process_pair(SSL_API_PORT, \
  2159. get_validated_string_input(\
  2160. "SSL port ["+str(client_api_ssl_port)+"] ? ",\
  2161. str(client_api_ssl_port),\
  2162. "^[0-9]{1,5}$", "Invalid port.", False))
  2163. if get_YN_input(\
  2164. "Do you want to import trusted certificate and private key (y/n) y? ",\
  2165. True):
  2166. import_cert_and_key_action(security_server_keys_dir, properties)
  2167. cert_was_imported = True
  2168. else:
  2169. if get_YN_input("Do you want to configure HTTPS (y/n) y? ", True):
  2170. properties.process_pair(SSL_API_PORT,\
  2171. get_validated_string_input("SSL port ["+str(client_api_ssl_port)+"] ? ",\
  2172. str(client_api_ssl_port), "^[0-9]{1,5}$", "Invalid port.", False))
  2173. if get_YN_input(\
  2174. "Do you want to import trusted certificate and private key (y/n) y? ",\
  2175. True):
  2176. import_cert_and_key_action(security_server_keys_dir, properties)
  2177. cert_was_imported = True
  2178. else:
  2179. return
  2180. conf_file = find_properties_file()
  2181. f = open(conf_file, 'w')
  2182. properties.store(f, "Changed by 'ambari-server setup-https' command")
  2183. if cert_was_imported:
  2184. print "NOTE: If cluster have been already created,"+\
  2185. " agent's keystors should be cleared manually!"
  2186. if is_server_runing():
  2187. print "To apply changes server should be restarted"+\
  2188. " by command: ambari-server restart|(stop|start)"
  2189. except (KeyError), e:
  2190. err = 'Property ' + str(e) + ' is not defined at ' + conf_file
  2191. raise FatalException(1, err)
  2192. else:
  2193. print "setup-https is not enabled in silent mode."
  2194. def is_server_runing():
  2195. if os.path.exists(PID_DIR + os.sep + PID_NAME):
  2196. f = open(PID_DIR + os.sep + PID_NAME, "r")
  2197. pid = int(f.readline())
  2198. f.close()
  2199. retcode, out, err = run_os_command("ps -p " + str(pid))
  2200. if retcode == 0:
  2201. return True, pid
  2202. else:
  2203. return False, None
  2204. else:
  2205. return False, None
  2206. def import_cert_and_key_action(security_server_keys_dir, properties):
  2207. if import_cert_and_key(security_server_keys_dir):
  2208. properties.process_pair(SSL_SERVER_CERT_NAME, SSL_CERT_FILE_NAME)
  2209. properties.process_pair(SSL_SERVER_KEY_NAME, SSL_KEY_FILE_NAME)
  2210. properties.process_pair(SSL_API, "true")
  2211. def import_cert_and_key(security_server_keys_dir):
  2212. import_cert_path = get_validated_filepath_input(\
  2213. "Please enter path to certificate: ",\
  2214. "Certificate not found")
  2215. import_key_path = get_validated_filepath_input(\
  2216. "Please enter path to key: ", "Key not found")
  2217. pem_password = get_validated_string_input("Please enter password for private key: ", "", None, None, True)
  2218. keystoreFilePath = os.path.join(security_server_keys_dir,\
  2219. SSL_KEYSTORE_FILE_NAME)
  2220. passFilePath = os.path.join(security_server_keys_dir,\
  2221. SSL_KEY_PASSWORD_FILE_NAME)
  2222. retcode, out, err = run_os_command(EXPRT_KSTR_CMD.format(import_cert_path,\
  2223. import_key_path, pem_password, keystoreFilePath))
  2224. if retcode == 0:
  2225. print 'Successfully imported trusted cerificate and private key'
  2226. set_file_permissions(keystoreFilePath, "660", read_ambari_user(), "root", False)
  2227. with open(passFilePath, 'w+') as passFile:
  2228. passFile.write(pem_password)
  2229. pass
  2230. set_file_permissions(passFilePath, "660", read_ambari_user(), "root", False)
  2231. import_file_to_keystore(import_cert_path, os.path.join(\
  2232. security_server_keys_dir, SSL_CERT_FILE_NAME))
  2233. import_file_to_keystore(import_key_path, os.path.join(\
  2234. security_server_keys_dir, SSL_KEY_FILE_NAME))
  2235. return True
  2236. else:
  2237. print 'Could not import trusted cerificate and private key:'
  2238. print err
  2239. return False
  2240. def import_file_to_keystore(source, destination):
  2241. shutil.copy(source, destination)
  2242. set_file_permissions(destination, "660", read_ambari_user(), "root", False)
  2243. def get_validated_filepath_input(prompt, description, default=None):
  2244. input = False
  2245. while not input:
  2246. if SILENT:
  2247. print (prompt)
  2248. return default
  2249. else:
  2250. input = raw_input(prompt)
  2251. if not input==None:
  2252. input = input.strip()
  2253. if not input==None and not ""==input and os.path.exists(input):
  2254. return input
  2255. else:
  2256. print description
  2257. input=False
  2258. #
  2259. # Main.
  2260. #
  2261. def main():
  2262. parser = optparse.OptionParser(usage="usage: %prog [options] action [stack_id]",)
  2263. parser.add_option('-f', '--init-script-file',
  2264. default='/var/lib/ambari-server/'
  2265. 'resources/Ambari-DDL-Postgres-CREATE.sql',
  2266. help="File with setup script")
  2267. parser.add_option('-r', '--drop-script-file', default="/var/lib/"
  2268. "ambari-server/resources/"
  2269. "Ambari-DDL-Postgres-DROP.sql",
  2270. help="File with drop script")
  2271. parser.add_option('-u', '--upgrade-script-file', default="/var/lib/"
  2272. "ambari-server/resources/upgrade/ddl/"
  2273. "Ambari-DDL-Postgres-UPGRADE-1.3.0.sql",
  2274. help="File with upgrade script")
  2275. parser.add_option('-t', '--upgrade-stack-script-file', default="/var/lib/"
  2276. "ambari-server/resources/upgrade/dml/"
  2277. "Ambari-DML-Postgres-UPGRADE_STACK.sql",
  2278. help="File with stack upgrade script")
  2279. parser.add_option('-j', '--java-home', default=None,
  2280. help="Use specified java_home. Must be valid on all hosts")
  2281. parser.add_option('-c', '--jce-policy', default=None,
  2282. help="Use specified jce_policy. Must be valid on all hosts", dest="jce_policy")
  2283. parser.add_option("-v", "--verbose",
  2284. action="store_true", dest="verbose", default=False,
  2285. help="Print verbose status messages")
  2286. parser.add_option("-s", "--silent",
  2287. action="store_true", dest="silent", default=False,
  2288. help="Silently accepts default prompt values")
  2289. parser.add_option('-g', '--debug', action="store_true", dest='debug', default=False,
  2290. help="Start ambari-server in debug mode")
  2291. parser.add_option('--database', default=None, help ="Database to use postgres|oracle", dest="database")
  2292. parser.add_option('--databasehost', default=None, help="Hostname of database server", dest="database_host")
  2293. parser.add_option('--databaseport', default=None, help="Database port", dest="database_port")
  2294. parser.add_option('--databasename', default=None, help="Database/Schema/Service name or ServiceID",
  2295. dest="database_name")
  2296. parser.add_option('--databaseusername', default=None, help="Database user login", dest="database_username")
  2297. parser.add_option('--databasepassword', default=None, help="Database user password", dest="database_password")
  2298. parser.add_option('--sidorsname', default="sname", help="Oracle database identifier type, Service ID/Service "
  2299. "Name sid|sname", dest="sid_or_sname")
  2300. (options, args) = parser.parse_args()
  2301. # set verbose
  2302. global VERBOSE
  2303. VERBOSE = options.verbose
  2304. # set silent
  2305. global SILENT
  2306. SILENT = options.silent
  2307. # debug mode
  2308. global SERVER_DEBUG_MODE
  2309. SERVER_DEBUG_MODE = options.debug
  2310. global DATABASE_INDEX
  2311. global PROMPT_DATABASE_OPTIONS
  2312. #perform checks
  2313. options.warnings = []
  2314. if options.database is None \
  2315. and options.database_host is None \
  2316. and options.database_port is None \
  2317. and options.database_name is None \
  2318. and options.database_username is None \
  2319. and options.database_password is None:
  2320. PROMPT_DATABASE_OPTIONS = True
  2321. elif not (options.database is not None
  2322. and options.database_host is not None
  2323. and options.database_port is not None
  2324. and options.database_name is not None
  2325. and options.database_username is not None
  2326. and options.database_password is not None):
  2327. parser.error('All database options should be set. Please see help for the options.')
  2328. #correct database
  2329. if options.database is not None and options.database not in DATABASE_NAMES:
  2330. parser.print_help()
  2331. parser.error("Unsupported Database " + options.database)
  2332. elif options.database is not None:
  2333. options.database = options.database.lower()
  2334. DATABASE_INDEX = DATABASE_NAMES.index(options.database)
  2335. #correct port
  2336. if options.database_port is not None:
  2337. correct=False
  2338. try:
  2339. port = int(options.database_port)
  2340. if 65536 > port > 0:
  2341. correct = True
  2342. except ValueError:
  2343. pass
  2344. if not correct:
  2345. parser.print_help()
  2346. parser.error("Incorrect database port " + options.database_port)
  2347. if options.database is not None and options.database == "postgres":
  2348. print "WARNING: HostName for postgres server " + options.database_host + \
  2349. " will be ignored: using localhost."
  2350. options.database_host = "localhost"
  2351. if options.sid_or_sname.lower() not in ["sid", "sname"]:
  2352. print "WARNING: Valid values for sid_or_sname are 'sid' or 'sname'. Use 'sid' if the db identifier type is " \
  2353. "Service ID. Use 'sname' if the db identifier type is Service Name"
  2354. parser.print_help()
  2355. exit(-1)
  2356. else:
  2357. options.sid_or_sname = options.sid_or_sname.lower()
  2358. if len(args) == 0:
  2359. print parser.print_help()
  2360. parser.error("No action entered")
  2361. action = args[0]
  2362. if action == UPGRADE_STACK_ACTION:
  2363. args_number_required = 2
  2364. else:
  2365. args_number_required = 1
  2366. if len(args) < args_number_required:
  2367. print parser.print_help()
  2368. parser.error("Invalid number of arguments. Entered: " + str(len(args)) + ", required: " + str(args_number_required))
  2369. try:
  2370. if action == SETUP_ACTION:
  2371. setup(options)
  2372. elif action == START_ACTION:
  2373. start(options)
  2374. elif action == STOP_ACTION:
  2375. stop(options)
  2376. elif action == RESET_ACTION:
  2377. reset(options)
  2378. elif action == STATUS_ACTION:
  2379. status(options)
  2380. elif action == UPGRADE_ACTION:
  2381. upgrade(options)
  2382. elif action == UPGRADE_STACK_ACTION:
  2383. stack_id = args[1]
  2384. upgrade_stack(options, stack_id)
  2385. elif action == LDAP_SETUP_ACTION:
  2386. setup_ldap()
  2387. elif action == RESET_MASTER_KEY_ACTION:
  2388. reset_master_key()
  2389. elif action == UPDATE_METAINFO_ACTION:
  2390. update_metainfo(options)
  2391. elif action == SETUP_HTTPS_ACTION:
  2392. setup_https(options)
  2393. else:
  2394. parser.error("Invalid action")
  2395. except FatalException as e:
  2396. if e.reason is not None:
  2397. print_error_msg("Exiting with exit code {0}. Reason: {1}".format(e.code, e.reason))
  2398. sys.exit(e.code)
  2399. # A Python replacement for java.util.Properties
  2400. # Based on http://code.activestate.com/recipes
  2401. # /496795-a-python-replacement-for-javautilproperties/
  2402. class Properties(object):
  2403. def __init__(self, props=None):
  2404. self._props = {}
  2405. self._origprops = {}
  2406. self._keymap = {}
  2407. self.othercharre = re.compile(r'(?<!\\)(\s*\=)|(?<!\\)(\s*\:)')
  2408. self.othercharre2 = re.compile(r'(\s*\=)|(\s*\:)')
  2409. self.bspacere = re.compile(r'\\(?!\s$)')
  2410. def __parse(self, lines):
  2411. lineno = 0
  2412. i = iter(lines)
  2413. for line in i:
  2414. lineno += 1
  2415. line = line.strip()
  2416. if not line: continue
  2417. if line[0] == '#': continue
  2418. escaped = False
  2419. sepidx = -1
  2420. flag = 0
  2421. m = self.othercharre.search(line)
  2422. if m:
  2423. first, last = m.span()
  2424. start, end = 0, first
  2425. flag = 1
  2426. wspacere = re.compile(r'(?<![\\\=\:])(\s)')
  2427. else:
  2428. if self.othercharre2.search(line):
  2429. wspacere = re.compile(r'(?<![\\])(\s)')
  2430. start, end = 0, len(line)
  2431. m2 = wspacere.search(line, start, end)
  2432. if m2:
  2433. first, last = m2.span()
  2434. sepidx = first
  2435. elif m:
  2436. first, last = m.span()
  2437. sepidx = last - 1
  2438. while line[-1] == '\\':
  2439. nextline = i.next()
  2440. nextline = nextline.strip()
  2441. lineno += 1
  2442. line = line[:-1] + nextline
  2443. if sepidx != -1:
  2444. key, value = line[:sepidx], line[sepidx + 1:]
  2445. else:
  2446. key, value = line, ''
  2447. self.process_pair(key, value)
  2448. def process_pair(self, key, value):
  2449. oldkey = key
  2450. oldvalue = value
  2451. keyparts = self.bspacere.split(key)
  2452. strippable = False
  2453. lastpart = keyparts[-1]
  2454. if lastpart.find('\\ ') != -1:
  2455. keyparts[-1] = lastpart.replace('\\', '')
  2456. elif lastpart and lastpart[-1] == ' ':
  2457. strippable = True
  2458. key = ''.join(keyparts)
  2459. if strippable:
  2460. key = key.strip()
  2461. oldkey = oldkey.strip()
  2462. oldvalue = self.unescape(oldvalue)
  2463. value = self.unescape(value)
  2464. self._props[key] = None if value is None else value.strip()
  2465. if self._keymap.has_key(key):
  2466. oldkey = self._keymap.get(key)
  2467. self._origprops[oldkey] = None if oldvalue is None else oldvalue.strip()
  2468. else:
  2469. self._origprops[oldkey] = None if oldvalue is None else oldvalue.strip()
  2470. self._keymap[key] = oldkey
  2471. def unescape(self, value):
  2472. newvalue = value
  2473. if not value is None:
  2474. newvalue = value.replace('\:', ':')
  2475. newvalue = newvalue.replace('\=', '=')
  2476. return newvalue
  2477. def removeOldProp(self, key):
  2478. if self._origprops.has_key(key):
  2479. del self._origprops[key]
  2480. pass
  2481. def load(self, stream):
  2482. if type(stream) is not file:
  2483. raise TypeError, 'Argument should be a file object!'
  2484. if stream.mode != 'r':
  2485. raise ValueError, 'Stream should be opened in read-only mode!'
  2486. try:
  2487. self.fileName = os.path.abspath(stream.name)
  2488. lines = stream.readlines()
  2489. self.__parse(lines)
  2490. except IOError, e:
  2491. raise
  2492. def get_property(self, key):
  2493. return self._props.get(key, '')
  2494. def propertyNames(self):
  2495. return self._props.keys()
  2496. def getPropertyDict(self):
  2497. return self._props
  2498. def __getitem__(self, name):
  2499. return self.get_property(name)
  2500. def __getattr__(self, name):
  2501. try:
  2502. return self.__dict__[name]
  2503. except KeyError:
  2504. if hasattr(self._props, name):
  2505. return getattr(self._props, name)
  2506. def store(self, out, header=""):
  2507. """ Write the properties list to the stream 'out' along
  2508. with the optional 'header' """
  2509. if out.mode[0] != 'w':
  2510. raise ValueError,'Steam should be opened in write mode!'
  2511. try:
  2512. out.write(''.join(('#', ASF_LICENSE_HEADER, '\n')))
  2513. out.write(''.join(('#',header,'\n')))
  2514. # Write timestamp
  2515. tstamp = time.strftime('%a %b %d %H:%M:%S %Z %Y', time.localtime())
  2516. out.write(''.join(('#',tstamp,'\n')))
  2517. # Write properties from the pristine dictionary
  2518. for prop, val in self._origprops.items():
  2519. if val is not None:
  2520. out.write(''.join((prop,'=',val,'\n')))
  2521. out.close()
  2522. except IOError, e:
  2523. raise
  2524. if __name__ == "__main__":
  2525. main()