blob: 46a35918662ab03fc1e2d85dfa333b359286f5b1 [file] [log] [blame]
#!/usr/bin/env python2.6
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
'''
import optparse
import sys
import os
import signal
import subprocess
import re
import string
import glob
import platform
import xml.etree.ElementTree as ET
import shutil
import stat
import fileinput
import urllib2
import time
import getpass
# debug settings
VERBOSE = False
SILENT = False
SERVER_START_DEBUG = False
# action commands
SETUP_ACTION = "setup"
START_ACTION = "start"
STOP_ACTION = "stop"
RESET_ACTION = "reset"
#sudo check command
SUDO_CHECK_CMD = "rpm -qa | grep sudo"
# selinux commands
GET_SE_LINUX_ST_CMD = "/usr/sbin/sestatus"
SE_SETENFORCE_CMD = "setenforce 0"
SE_STATUS_DISABLED="disabled"
SE_STATUS_ENABLED="enabled"
SE_MODE_ENFORCING="enforcing"
SE_MODE_PERMISSIVE="permissive"
# iptables commands
IP_TBLS_ST_CMD = "/sbin/service iptables status"
IP_TBLS_STOP_CMD = "/sbin/service iptables stop"
IP_TBLS_ENABLED="Firewall is running"
IP_TBLS_DISABLED="Firewall is stopped.\n"
IP_TBLS_SRVC_NT_FND="iptables: unrecognized service"
# server commands
ambari_provider_module_option = ""
ambari_provider_module = os.environ.get('AMBARI_PROVIDER_MODULE')
if ambari_provider_module is not None:
ambari_provider_module_option = "-Dprovider.module.class=" + ambari_provider_module + " "
SERVER_START_CMD="{0}" + os.sep + "bin" + os.sep + "java -server -XX:NewRatio=2 -XX:+UseConcMarkSweepGC " + ambari_provider_module_option + os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') + " -cp {1}"+ os.pathsep + "{2}" + "/* org.apache.ambari.server.controller.AmbariServer >/var/log/ambari-server/ambari-server.out 2>&1"
SERVER_START_CMD_DEBUG="{0}" + os.sep + "bin" + os.sep + "java -server -XX:NewRatio=2 -XX:+UseConcMarkSweepGC " + ambari_provider_module_option + os.getenv('AMBARI_JVM_ARGS','-Xms512m -Xmx2048m') + " -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n -cp {1}"+ os.pathsep + ".." + os.sep + "lib" + os.sep + "ambari-server" + os.sep + "* org.apache.ambari.server.controller.AmbariServer"
AMBARI_CONF_VAR="AMBARI_CONF_DIR"
AMBARI_SERVER_LIB="AMBARI_SERVER_LIB"
JAVA_HOME="JAVA_HOME"
PID_DIR="/var/run/ambari-server"
PID_NAME="ambari-server.pid"
AMBARI_PROPERTIES_FILE="ambari.properties"
# database commands
SETUP_DB_CMD = "sudo -u postgres psql -f {0} -v username=\"{1}\" -v password=\'{2}\'"
PG_ST_CMD = "/sbin/service postgresql status"
PG_START_CMD = "/sbin/service postgresql start"
PG_RESTART_CMD = "/sbin/service postgresql restart"
PG_STATUS_RUNNING = "running"
PG_HBA_DIR = "/var/lib/pgsql/data/"
PG_HBA_CONF_FILE = PG_HBA_DIR + "pg_hba.conf"
PG_HBA_CONF_FILE_BACKUP = PG_HBA_DIR + "pg_hba_bak.conf.old"
POSTGRESQL_CONF_FILE = PG_HBA_DIR + "postgresql.conf"
PG_HBA_RELOAD_CMD = "sudo -u postgres pg_ctl -D {0} reload"
PG_DEFAULT_PASSWORD = "bigdata"
JDBC_USER_NAME_PROPERTY = "server.jdbc.user.name"
JDBC_PASSWORD_FILE_PROPERTY = "server.jdbc.user.passwd"
JDBC_PASSWORD_FILENAME = "password.dat"
# jdk commands
JDK_LOCAL_FILENAME="jdk-6u31-linux-x64.bin"
JDK_MIN_FILESIZE=5000
JDK_INSTALL_DIR="/usr/jdk64"
CREATE_JDK_DIR_CMD = "/bin/mkdir -p " + JDK_INSTALL_DIR
MAKE_FILE_EXECUTABLE_CMD = "chmod a+x {0}"
JAVA_HOME_PROPERTY = "java.home"
OS_TYPE_PROPERTY = "server.os_type"
def configure_pg_hba_ambaridb_users():
args = optparse.Values()
configurePostgresUsernamePassword(args)
with open(PG_HBA_CONF_FILE, "a") as pgHbaConf:
pgHbaConf.write("\n")
pgHbaConf.write("local all " + args.postgres_username + ",mapred md5")
pgHbaConf.write("\n")
pgHbaConf.write("host all " + args.postgres_username + ",mapred 0.0.0.0/0 md5")
pgHbaConf.write("\n")
pgHbaConf.write("host all " + args.postgres_username + ",mapred ::/0 md5")
pgHbaConf.write("\n")
command = PG_HBA_RELOAD_CMD.format(PG_HBA_DIR)
retcode, out, err = run_os_command(command)
if not retcode == 0:
print err
sys.exit(retcode)
def check_ambaridb_user_configured():
if 'ambari-server' in open(PG_HBA_CONF_FILE).read():
return True
else:
return False
def configure_pg_hba_postgres_user():
postgresString = "all postgres"
for line in fileinput.input(PG_HBA_CONF_FILE, inplace = 1):
print re.sub('all\s*all', postgresString, line),
os.chmod(PG_HBA_CONF_FILE, 0644)
def configure_postgresql_conf():
listenAddress = "listen_addresses = '*' #"
for line in fileinput.input(POSTGRESQL_CONF_FILE, inplace = 1):
print re.sub('#+listen_addresses.*?(#|$)', listenAddress, line),
os.chmod(POSTGRESQL_CONF_FILE, 0644)
def configure_postgres():
if os.path.isfile(PG_HBA_CONF_FILE):
if not os.path.isfile(PG_HBA_CONF_FILE_BACKUP) :
shutil.copyfile(PG_HBA_CONF_FILE, PG_HBA_CONF_FILE_BACKUP)
else :
#Postgres has been configured before, must not override backup
print "Backup for pg_hba found, reconfiguration not required"
return 0
configure_pg_hba_postgres_user()
configure_pg_hba_ambaridb_users()
os.chmod(PG_HBA_CONF_FILE, 0644)
configure_postgresql_conf()
#restart postgresql if already running
pg_status = get_postgre_status()
if pg_status == PG_STATUS_RUNNING:
retcode = restart_postgres()
return retcode
return 0
def restart_postgres():
print "Restarting PostgreSQL"
process = subprocess.Popen(PG_RESTART_CMD.split(' '),
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
)
time.sleep(5)
result = process.poll()
if result == "None" or result == "-N":
printInfoMsg("Killing restart PostgresSQL process")
process.kill()
pg_status = get_postgre_status()
# SUSE linux set status of stopped postgresql proc to unused
if pg_status == "unused" or pg_status == "stopped":
printInfoMsg("PostgreSQL is stopped. Restarting ...")
retcode, out, err = run_os_command(PG_START_CMD)
return retcode
return 0
def line_prepender(filename, lines):
for line in reversed(lines):
with open(filename,'r+') as f:
content = f.read()
f.seek(0,0)
f.write(line.rstrip('\r\n') + '\n' + content)
def run_os_command(cmd):
printInfoMsg( 'about to run command: ' + cmd)
process = subprocess.Popen(cmd.split(' '),
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE
)
(stdoutdata, stderrdata) = process.communicate()
return process.returncode, stdoutdata, stderrdata
# todo: check if the scheme is already exist
def writeProperty(key, value):
conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
with open(conf_file, 'a') as ambariConf:
ambariConf.write(key + "=" + value)
ambariConf.write("\n")
return 0
pass
def setup_db(args):
#password access to ambari-server and mapred
configurePostgresUsernamePassword(args)
dbname = args.postgredbname
file = args.init_script_file
username = args.postgres_username
password = args.postgres_password
command = SETUP_DB_CMD.format(file,username,password)
retcode, outdata, errdata = run_os_command(command)
if not retcode == 0:
print errdata
return retcode
#
# Checks SELinux
#
def check_selinux():
try:
retcode, out, err = run_os_command(GET_SE_LINUX_ST_CMD)
se_status = re.search('(disabled|enabled)', out).group(0)
print "SELinux status is '" + se_status + "'"
if se_status == SE_STATUS_DISABLED:
return 0
else:
se_mode = ''
try:
se_mode = re.search('(enforcing|permissive)', out).group(0)
except AttributeError:
printErrorMsg ("Error determining SELinux mode. Exiting.")
sys.exit (0)
print "SELinux mode is '" + se_mode + "'"
if se_mode == SE_MODE_ENFORCING:
print "Temporarily disabling SELinux"
run_os_command(SE_SETENFORCE_CMD)
printWarningMsg ("SELinux is set to 'permissive' mode and temporarily disabled. You should disable SELinux permanently.")
ok = getYNInput("OK to continue [y/n] (y)? ",True)
if ok == False:
sys.exit (0)
return 0
except OSError:
printWarningMsg("Could not run {0}: OK".format(GET_SE_LINUX_ST_CMD))
return 0
def get_ambari_jars():
try:
conf_dir = os.environ[AMBARI_SERVER_LIB]
return conf_dir
except KeyError:
default_jar_location = "/usr/lib/ambari-server"
printInfoMsg (AMBARI_SERVER_LIB + " is not set, using default "+ default_jar_location)
return default_jar_location
def get_conf_dir():
try:
conf_dir = os.environ[AMBARI_CONF_VAR]
return conf_dir
except KeyError:
default_conf_dir = "/etc/ambari-server/conf"
printInfoMsg (AMBARI_CONF_VAR + " is not set, using default "+default_conf_dir)
return default_conf_dir
def search_file(filename, search_path, pathsep=os.pathsep):
""" Given a search path, find file with requested name """
for path in string.split(search_path, pathsep):
candidate = os.path.join(path, filename)
if os.path.exists(candidate): return os.path.abspath(candidate)
return None
#
# Checks iptables
#
def check_iptables():
retcode, out, err = run_os_command(IP_TBLS_ST_CMD)
''' This check doesn't work on CentOS 6.2 if firewall AND iptables service are running
if out == IP_TBLS_ENABLED:
print 'iptables is enabled now'
print 'Stopping iptables service'
'''
retcode, out, err = run_os_command(IP_TBLS_STOP_CMD)
print 'iptables is disabled now'
if not retcode == 0 and err and len(err) > 0:
print err
if err.strip() == IP_TBLS_SRVC_NT_FND:
return 0
else:
return retcode, out
# A Python replacement for java.util.Properties
# Based on http://code.activestate.com/recipes/496795-a-python-replacement-for-javautilproperties/
class Properties(object):
def __init__(self, props=None):
self._props = {}
self._origprops = {}
self._keymap = {}
self.othercharre = re.compile(r'(?<!\\)(\s*\=)|(?<!\\)(\s*\:)')
self.othercharre2 = re.compile(r'(\s*\=)|(\s*\:)')
self.bspacere = re.compile(r'\\(?!\s$)')
def __parse(self, lines):
lineno=0
i = iter(lines)
for line in i:
lineno += 1
line = line.strip()
if not line: continue
if line[0] == '#': continue
escaped=False
sepidx = -1
flag = 0
m = self.othercharre.search(line)
if m:
first, last = m.span()
start, end = 0, first
flag = 1
wspacere = re.compile(r'(?<![\\\=\:])(\s)')
else:
if self.othercharre2.search(line):
wspacere = re.compile(r'(?<![\\])(\s)')
start, end = 0, len(line)
m2 = wspacere.search(line, start, end)
if m2:
first, last = m2.span()
sepidx = first
elif m:
first, last = m.span()
sepidx = last - 1
while line[-1] == '\\':
nextline = i.next()
nextline = nextline.strip()
lineno += 1
line = line[:-1] + nextline
if sepidx != -1:
key, value = line[:sepidx], line[sepidx+1:]
else:
key,value = line,''
self.processPair(key, value)
def processPair(self, key, value):
oldkey = key
oldvalue = value
keyparts = self.bspacere.split(key)
strippable = False
lastpart = keyparts[-1]
if lastpart.find('\\ ') != -1:
keyparts[-1] = lastpart.replace('\\','')
elif lastpart and lastpart[-1] == ' ':
strippable = True
key = ''.join(keyparts)
if strippable:
key = key.strip()
oldkey = oldkey.strip()
oldvalue = self.unescape(oldvalue)
value = self.unescape(value)
self._props[key] = value.strip()
if self._keymap.has_key(key):
oldkey = self._keymap.get(key)
self._origprops[oldkey] = oldvalue.strip()
else:
self._origprops[oldkey] = oldvalue.strip()
self._keymap[key] = oldkey
def unescape(self, value):
newvalue = value.replace('\:',':')
newvalue = newvalue.replace('\=','=')
return newvalue
def load(self, stream):
if type(stream) is not file:
raise TypeError,'Argument should be a file object!'
if stream.mode != 'r':
raise ValueError,'Stream should be opened in read-only mode!'
try:
lines = stream.readlines()
self.__parse(lines)
except IOError, e:
raise
def getProperty(self, key):
return self._props.get(key,'')
def propertyNames(self):
return self._props.keys()
def getPropertyDict(self):
return self._props
def __getitem__(self, name):
return self.getProperty(name)
def __getattr__(self, name):
try:
return self.__dict__[name]
except KeyError:
if hasattr(self._props,name):
return getattr(self._props, name)
JDK_DOWNLOAD_CMD = "curl --create-dirs -o {0} {1}"
JDK_DOWNLOAD_SIZE_CMD = "curl -I {0}"
def dlprogress(base_name, count, blockSize, totalSize):
percent=int(count*blockSize*100/totalSize)
if (totalSize < blockSize):
sys.stdout.write("\r" + base_name + "... %d%%" % (100))
else:
sys.stdout.write("\r" + base_name + "... %d%% (%.1f MB of %.1f MB)" % (percent, count*blockSize/1024/1024.0, totalSize/1024/1024.0))
if (percent == 100 or totalSize < blockSize):
sys.stdout.write("\n")
sys.stdout.flush()
def track_jdk(base_name, url, local_name):
u = urllib2.urlopen(url)
h = u.info()
totalSize = int(h["Content-Length"])
fp = open(local_name, "wb")
blockSize = 8192
count = 0
percent = 0
while True:
chunk = u.read(blockSize)
if not chunk:
break
fp.write(chunk)
count += 1
dlprogress(base_name, count, blockSize, totalSize)
fp.flush()
fp.close()
#
# Downloads the JDK
#
def download_jdk(args):
conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
if conf_file is None:
print 'File %s not found in search path $%s: %s' % (AMBARI_PROPERTIES_FILE, AMBARI_CONF_VAR, get_conf_dir())
return -1
printInfoMsg ('Loading properties from ' + conf_file)
if get_JAVA_HOME():
return 0
if args.java_home and os.path.exists(args.java_home):
printWarningMsg("JAVA_HOME " + args.java_home + " must be valid on ALL hosts")
writeProperty(JAVA_HOME_PROPERTY, args.java_home)
return 0
properties = None
try:
properties = Properties()
properties.load(open(conf_file))
except (Exception), e:
print 'Could not read "%s": %s' % (conf_file, e)
return -1
try:
jdk_url = properties['jdk.url']
resources_dir = properties['resources.dir']
except (KeyError), e:
print 'Property ' + str(e) + ' is not defined at ' + conf_file
return -1
dest_file = resources_dir + os.sep + JDK_LOCAL_FILENAME
if not os.path.exists(dest_file):
print 'Downloading JDK from ' + jdk_url + ' to ' + dest_file
try:
size_command =JDK_DOWNLOAD_SIZE_CMD.format(jdk_url) ;
retcode, out, err = run_os_command(size_command)#Get Header from url,to get file size then
if out.find("Content-Length") == -1:
print "Request headr doesn't contain Content-Length";
return -1
start_with = int( out.find("Content-Length")+len("Content-Length")+2)
end_with = out.find("\r\n",start_with)
src_size = int ( out[start_with:end_with] )
print 'JDK distribution size is ' + str(src_size) + ' bytes'
file_exists = os.path.isfile(dest_file)
file_size = -1
if file_exists:
file_size = os.stat(dest_file).st_size
if file_exists and file_size == src_size:
printInfoMsg ("File already exists")
else:
track_jdk(JDK_LOCAL_FILENAME, jdk_url, dest_file)
print 'Successfully downloaded JDK distribution to ' + dest_file
except Exception, e:
printErrorMsg ('Failed to download JDK: ' + str(e))
return -1
downloaded_size = os.stat(dest_file).st_size
if downloaded_size != src_size or downloaded_size < JDK_MIN_FILESIZE:
printErrorMsg ('Size of downloaded JDK distribution file is ' + str(downloaded_size) + ' bytes, it is probably \
damaged or incomplete')
return -1
else:
print "JDK already exists using " + dest_file
ok = getYNInput("To install the Oracle JDK you must accept the license terms found at \
http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u21-license-159167.txt. Not \
accepting will cancel the Ambari Server setup.\nDo you accept the Oracle Binary Code License Agreement [y/n] (y)? ", True)
if (ok == False):
return -1
print "Installing JDK to {0}".format(JDK_INSTALL_DIR)
retcode, out, err = run_os_command(CREATE_JDK_DIR_CMD)
savedPath = os.getcwd()
os.chdir(JDK_INSTALL_DIR)
retcode, out, err = run_os_command(MAKE_FILE_EXECUTABLE_CMD.format(dest_file))
retcode, out, err = run_os_command(dest_file + ' -noregister')
os.chdir(savedPath)
jdk_version = re.search('Creating (jdk.*)/jre', out).group(1)
print "Successfully installed JDK to {0}/{1}".format(JDK_INSTALL_DIR, jdk_version)
writeProperty(JAVA_HOME_PROPERTY, "{0}/{1}".format(JDK_INSTALL_DIR, jdk_version))
return 0
def get_postgre_status():
retcode, out, err = run_os_command(PG_ST_CMD)
try:
pg_status = re.search('(stopped|running)', out).group(0)
except AttributeError:
pg_status = None
return pg_status
def check_postgre_up():
pg_status = get_postgre_status()
if pg_status == PG_STATUS_RUNNING:
printInfoMsg ("PostgreSQL is running")
return 0
else:
print "About to start PostgreSQL"
retcode, out, err = run_os_command(PG_START_CMD)
return retcode
#
# Configures the OS settings in ambari properties.
#
def configure_os_settings():
conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
if conf_file is None:
printErrorMsg ('File %s not found in search path $%s: %s' % (AMBARI_PROPERTIES_FILE, AMBARI_CONF_VAR, get_conf_dir()))
return -1
printInfoMsg ('Loading properties from ' + conf_file)
properties = None
try:
properties = Properties()
properties.load(open(conf_file))
except (Exception), e:
printErrorMsg ('Could not read "%s": %s' % (conf_file, e))
return -1
try:
conf_os_type = properties[OS_TYPE_PROPERTY]
if conf_os_type != '':
printInfoMsg ("os_type already setting in properties file")
return 0
except (KeyError), e:
printErrorMsg ("os_type is not set in properties file")
os_system = platform.system()
if os_system != 'Linux':
printErrorMsg ("Non-Linux systems are not supported")
return -1
os_info = platform.linux_distribution(None, None, None, ['SuSE', 'redhat' ], 0)
os_name = os_info[0].lower()
if os_name == 'suse':
os_name = 'sles'
os_version = os_info[1].split('.', 1)[0]
master_os_type = os_name + os_version
with open(conf_file, "a") as ambariConf:
ambariConf.write(OS_TYPE_PROPERTY + "=" + master_os_type)
ambariConf.write("\n")
ambariConf.closed
return 0
def get_JAVA_HOME():
conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
properties = Properties()
try:
properties.load(open(conf_file))
java_home = properties[JAVA_HOME_PROPERTY]
if (not 0 == len(java_home)) and (os.path.exists(java_home)):
return java_home
except (Exception), e:
print 'Could not read "%s": %s' % (conf_file, e)
return None
#
# Finds the available JDKs.
#
def findJDK():
if get_JAVA_HOME():
return get_JAVA_HOME()
print "Looking for available JDKs at " + JDK_INSTALL_DIR
jdks = glob.glob(JDK_INSTALL_DIR + os.sep + "jdk*")
jdks.sort()
print "Found: " + str(jdks)
count = len(jdks)
if count == 0:
return
jdkPath = jdks[count - 1]
print "Selected JDK {0}".format(jdkPath)
return jdkPath
def check_sudo():
retcode, out, err = run_os_command(SUDO_CHECK_CMD)
if re.search('sudo', out) == None:
return 1
return 0
pass
#
# Setup the Ambari Server.
#
def setup(args):
retcode = check_sudo()
if not retcode == 0:
printErrorMsg('ERROR: sudo command not found on host. Please install sudo and re-run ambari-server setup. Exiting.')
sys.exit(retcode)
print 'Checking SELinux...'
retcode = check_selinux()
if not retcode == 0:
printErrorMsg ('Failed to disable SELinux. Exiting.')
sys.exit(retcode)
print 'Checking iptables...'
retcode, out = check_iptables()
if (not retcode == 0 and out == IP_TBLS_ENABLED):
printErrorMsg ('Failed to stop iptables. Exiting.')
sys.exit(retcode)
print 'Checking PostgreSQL...'
retcode = check_postgre_up()
if not retcode == 0:
printErrorMsg ('Unable to start PostgreSQL server. Exiting')
sys.exit(retcode)
print 'Configuring database...'
retcode = setup_db(args)
if not retcode == 0:
printErrorMsg ('Running database init script was failed. Exiting.')
sys.exit(retcode)
print 'Configuring PostgreSQL...'
retcode = configure_postgres()
if not retcode == 0:
printErrorMsg ('Unable to configure PostgreSQL server. Exiting')
sys.exit(retcode)
print 'Checking JDK...'
retcode = download_jdk(args)
if not retcode == 0:
printErrorMsg ('Downloading or installing JDK failed. Exiting.')
sys.exit(retcode)
print 'Completing setup...'
retcode = configure_os_settings()
if not retcode == 0:
printErrorMsg ('Configure of OS settings in ambari.properties failed. Exiting.')
sys.exit(retcode)
print "Ambari Server 'setup' finished successfully"
#
# Resets the Ambari Server.
#
def reset(args):
okToRun = False
choice = raw_input("**** WARNING **** You are about to reset and clear the Ambari Server database. This will \
remove all cluster host and configuration information from the database. You will be required to re-configure \
the Ambari server and re-run the cluster wizard. \nAre you SURE you want to perform the reset [yes/no]? ").lower()
if (choice in set(['yes'])):
okToRun = True
if (False == okToRun):
print "Ambari Server 'reset' cancelled"
return -1
okToRun = False
choice = raw_input("Confirm server reset [yes/no]? ").lower()
if (choice in set(['yes'])):
okToRun = True
if (False == okToRun):
print "Ambari Server 'reset' cancelled"
return -1
print "Reseting the Server database..."
configurePostgresUsernamePassword(args)
dbname = args.postgredbname
filename = args.drop_script_file
username = args.postgres_username
password = args.postgres_password
command = SETUP_DB_CMD.format(filename, username, password)
retcode, outdata, errdata = run_os_command(command)
if not retcode == 0:
print errdata
return retcode
printInfoMsg ("About to run database setup")
setup_db(args)
print "Ambari Server 'reset' complete"
#
# Starts the Ambari Server.
#
def start(args):
if os.path.exists(PID_DIR + os.sep + PID_NAME):
f = open(PID_DIR + os.sep + PID_NAME, "r")
pid = int(f.readline())
f.close()
try:
os.kill(pid, 0)
print("Server is already running.")
return
except OSError, e:
printInfoMsg("Server is not running, continue.")
conf_dir = get_conf_dir()
jdk_path = findJDK()
if jdk_path is None:
printErrorMsg("No JDK found, please run \"setup\" command to install JDK automatically or "\
"install any JDK manually to " + JDK_INSTALL_DIR)
return -1
retcode = check_postgre_up()
if not retcode == 0:
printErrorMsg("Unable to start PostgreSQL server. Exiting")
sys.exit(retcode)
print 'Checking iptables...'
retcode, out = check_iptables()
if (not retcode == 0 and out == IP_TBLS_ENABLED):
printErrorMsg ("Failed to stop iptables. Exiting")
sys.exit(retcode)
command = SERVER_START_CMD.format(jdk_path, conf_dir, get_ambari_jars())
print "Running server: " + command
server_process = subprocess.Popen(["/bin/sh", "-c", command])
f = open(PID_DIR + os.sep + PID_NAME, "w")
f.write(str(server_process.pid))
f.close()
#
# Stops the Ambari Server.
#
def stop(args):
if os.path.exists(PID_DIR + os.sep + PID_NAME):
f = open(PID_DIR + os.sep + PID_NAME, "r")
pid = int(f.readline())
try:
os.killpg(os.getpgid(pid), signal.SIGKILL)
except OSError, e:
printInfoMsg( "Unable to stop Ambari Server - " + str(e) )
return
f.close()
os.remove(f.name)
print "Ambari Server stopped"
else:
print "Ambari Server not running"
#
# Prints an "info" messsage.
#
def printInfoMsg(msg):
if (VERBOSE):
print("INFO: " + msg)
#
# Prints an "error" messsage.
#
def printErrorMsg(msg):
print("ERROR: " + msg)
#
# Prints a "warning" messsage.
#
def printWarningMsg(msg):
print("WARNING: " + msg)
#
# Gets the y/n input.
#
# return True if 'y' or False if 'n'
#
def getYNInput(prompt,default):
yes = set(['yes','ye', 'y'])
no = set(['no','n'])
return getChoiceStringInput(prompt,default,yes,no)
#
# Gets the yes/no input.
#
# return True if 'yes' or False if 'no/n'
#
def getYesNoInput(prompt,default):
yes = set(['yes'])
no = set(['no','n',''])
return getChoiceStringInput(prompt,default,yes,no)
def getChoiceStringInput(prompt,default,firstChoice,secondChoice):
if (SILENT):
print(prompt)
return default
choice = raw_input(prompt).lower()
if choice in firstChoice:
return True
elif choice in secondChoice:
return False
return default
def getValidatedStringInput(prompt, default, pattern, description, is_pass):
input =""
while (not input):
if (SILENT):
print (prompt)
input = default
elif is_pass:
input = getpass.getpass(prompt)
else:
input = raw_input(prompt)
if(not input.strip()):
input = default
break; #done here and picking up default
else:
if(not re.search(pattern,input.strip())):
print description
input=""
return input
def saveUsernamePassword(pathtofile, username, password):
tree = ET.parse(pathtofile)
root = tree.getroot()
for property in root.iter('{http://java.sun.com/xml/ns/persistence}property'):
if(property.get('name') == 'javax.persistence.jdbc.user'):
property.set('value', username)
print 'setting username to: ' + username
if(property.get('name') == 'javax.persistence.jdbc.password'):
print 'setting password to: ' + password
property.set('value', password)
#save copy of existing config
shutil.move(pathtofile, pathtofile+'.bak.ambari')
tree.write(pathtofile)
def configurePostgresPassword():
# setup password
passwordDefault = PG_DEFAULT_PASSWORD
passwordPrompt = 'Password [' + passwordDefault + ']: '
passwordPattern = "^[a-zA-Z0-9_-]*$"
passwordDescr = "Invalid characters in password. Use only alphanumeric or _ or - characters"
password = getValidatedStringInput(passwordPrompt, passwordDefault, passwordPattern, passwordDescr, True)
if password != passwordDefault:
password1 = getValidatedStringInput("Re-enter password: ", passwordDefault, passwordPattern, passwordDescr, True)
if password != password1:
print "Passwords do not match"
password = configurePostgresPassword()
return password
def configurePostgresUsernamePassword(args):
conf_file = search_file(AMBARI_PROPERTIES_FILE, get_conf_dir())
properties = Properties()
try:
properties.load(open(conf_file))
except (Exception), e:
print 'Could not read "%s": %s' % (conf_file, e)
return -1
username = properties[JDBC_USER_NAME_PROPERTY]
passFilePath = properties[JDBC_PASSWORD_FILE_PROPERTY]
if username and passFilePath:
printInfoMsg("Database username + password already configured - skipping")
args.postgres_username=username
with open(passFilePath) as passFile:
args.postgres_password=passFile.read()
return 1
# setup username
usernameDefault = 'ambari-server'
usernamePrompt = 'Username [' + usernameDefault + ']: '
usernamePattern = "^[a-zA-Z_][a-zA-Z0-9_\-]*$"
usernameDescr = "Invalid characters in username. Start with _ or alpha followed by alphanumeric or _ or - characters"
username = usernameDefault
# setup password
password = PG_DEFAULT_PASSWORD
ok = getYNInput("Enter advanced database configuration [y/n] (n)? ", False)
if ok == True:
username = getValidatedStringInput(usernamePrompt, usernameDefault, usernamePattern, usernameDescr, False)
print "Database username set to: " + username
password = configurePostgresPassword()
passFilePath = os.path.join(os.path.dirname(conf_file), JDBC_PASSWORD_FILENAME)
printInfoMsg ("Database username set to: " + username)
printInfoMsg ("Database password set to: " + password)
writeProperty(JDBC_USER_NAME_PROPERTY, username)
with open(passFilePath, 'w+') as passFile:
passFile.write(password)
pass
os.chmod(passFilePath, stat.S_IREAD | stat.S_IWRITE)
writeProperty(JDBC_PASSWORD_FILE_PROPERTY,passFilePath)
args.postgres_username=username
args.postgres_password=password
#
# Main.
#
def main():
parser = optparse.OptionParser(usage="usage: %prog [options] action",)
parser.add_option('-d', '--postgredbname', default='ambari',
help="Database name in postgresql")
parser.add_option('-f', '--init-script-file', default='/var/lib/ambari-server/resources/Ambari-DDL-Postgres-CREATE.sql',
help="File with setup script")
parser.add_option('-r', '--drop-script-file', default='/var/lib/ambari-server/resources/Ambari-DDL-Postgres-DROP.sql',
help="File with drop script")
parser.add_option('-j', '--java-home', default=None,
help="Use specified java_home. Must be valid on all hosts")
parser.add_option("-v", "--verbose",
action="store_true", dest="verbose", default=False,
help="Print verbose status messages")
parser.add_option("-s", "--silent",
action="store_true", dest="silent", default=False,
help="Silently accepts default prompt values")
(options, args) = parser.parse_args()
# set verbose
global VERBOSE
VERBOSE = options.verbose
# set silent
global SILENT
SILENT = options.silent
if not len(args) == 1:
print parser.print_help()
parser.error("Invalid number of arguments")
action = args[0]
if action == SETUP_ACTION:
setup(options)
elif action == START_ACTION:
start(options)
elif action == STOP_ACTION:
stop(options)
elif action == RESET_ACTION:
reset(options)
else:
parser.error("Invalid action")
if __name__ == "__main__":
main()