blob: 277c3c9d03133b0002fea52cbfbfdd215c49c60f [file] [log] [blame]
#!/usr/bin/env python
"""
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.
"""
from ambari_commons.os_check import OSCheck
from resource_management.core.exceptions import ComponentIsNotRunning
from resource_management.core.exceptions import ExecutionFailed
from resource_management.core.logger import Logger
from resource_management.core.resources import User
from resource_management.core.resources.system import Directory
from resource_management.core.resources.system import Execute
from resource_management.core.resources.system import File
from resource_management.core.source import InlineTemplate
from resource_management.core.source import Template
from resource_management.libraries.functions.get_user_call_output import \
get_user_call_output
def service_check(cmd, user, label):
"""
Executes a SysV service check command that adheres to LSB-compliant
return codes. The return codes are interpreted as defined
by the LSB.
See http://refspecs.linuxbase.org/LSB_3.0.0/LSB-PDA/LSB-PDA/iniscrptact.html
for more information.
:param cmd: The service check command to execute.
:param label: The name of the service.
"""
Logger.info("Performing service check; cmd={0}, user={1}, label={2}".format(cmd, user, label))
rc, out, err = get_user_call_output(cmd, user, is_checked_call=False)
if rc in [1, 2, 3]:
# if return code in [1, 2, 3], then 'program is not running' or 'program is dead'
Logger.info("{0} is not running".format(label))
raise ComponentIsNotRunning()
elif rc == 0:
# if return code = 0, then 'program is running or service is OK'
Logger.info("{0} is running".format(label))
else:
# else service state is unknown
err_msg = "{0} service check failed; cmd '{1}' returned {2}".format(label, cmd, rc)
Logger.error(err_msg)
raise ExecutionFailed(err_msg, rc, out, err)
def is_systemd_running():
"""
Determines if the platform is running Systemd.
:return True, if the platform is running Systemd. False, otherwise.
"""
Logger.info("Is the platform running Systemd?")
rc, out, err = get_user_call_output("pidof systemd", "root", is_checked_call=False)
if rc == 0:
Logger.info("Systemd was found")
return True
else:
Logger.info("Systemd was NOT found")
return False
def configure_systemd(params):
"""
Configure Systemd for Elasticsearch.
"""
Logger.info("Configuring Systemd for Elasticsearch");
# ensure the systemd directory for elasticsearch overrides exists
Logger.info("Create Systemd directory for Elasticsearch: {0}".format(params.systemd_elasticsearch_dir))
Directory(params.systemd_elasticsearch_dir,
create_parents=True,
owner='root',
group='root')
# when using Elasticsearch packages on systems that use systemd, system
# limits must also be specified via systemd.
# see https://www.elastic.co/guide/en/elasticsearch/reference/5.6/setting-system-settings.html#systemd
Logger.info("Elasticsearch systemd limits: {0}".format(params.systemd_override_file))
File(params.systemd_override_file,
content=InlineTemplate(params.systemd_override_template),
owner="root",
group="root")
# reload the configuration
Execute("systemctl daemon-reload")
def create_user(params):
"""
Creates the user required for Elasticsearch.
"""
Logger.info("Creating user={0} in group={1}".format(params.elastic_user, params.elastic_group))
User(params.elastic_user, action = "create", groups = params.elastic_group)
def create_directories(params, directories):
"""
Creates one or more directories.
"""
Logger.info("Creating directories: {0}".format(directories))
Directory(directories,
create_parents=True,
mode=0755,
owner=params.elastic_user,
group=params.elastic_group
)
def create_elastic_env(params):
"""
Creates the Elasticsearch environment file.
"""
Logger.info("Create Elasticsearch environment file.")
File("{0}/elastic-env.sh".format(params.conf_dir),
owner=params.elastic_user,
group=params.elastic_group,
content=InlineTemplate(params.elastic_env_sh_template))
def create_elastic_site(params, template_name):
"""
Creates the Elasticsearch site file.
"""
Logger.info("Creating Elasticsearch site file; template={0}".format(template_name))
elastic_site = params.config['configurations']['elastic-site']
path = "{0}/elasticsearch.yml".format(params.conf_dir)
template = Template(template_name, configurations=elastic_site)
File(path,
content=template,
owner=params.elastic_user,
group=params.elastic_group)
def get_elastic_config_path(default="/etc/default/elasticsearch"):
"""
Defines the path to the Elasticsearch environment file. This path will
differ based on the OS family.
:param default: The path used if the OS family is not recognized.
"""
path = default
if OSCheck.is_redhat_family():
path = "/etc/sysconfig/elasticsearch"
elif OSCheck.is_ubuntu_family():
path = "/etc/default/elasticsearch"
else:
Logger.error("Unexpected OS family; using default path={0}".format(path))
return path
def create_elastic_config(params):
"""
Creates the Elasticsearch system config file. Usually lands at either
/etc/sysconfig/elasticsearch or /etc/default/elasticsearch.
"""
path = get_elastic_config_path()
Logger.info("Creating the Elasticsearch system config; path={0}".format(path))
File(path, owner="root", group="root", content=InlineTemplate(params.sysconfig_template))
def create_elastic_pam_limits(params):
"""
Creates the PAM limits for Elasticsearch.
"""
Logger.info("Creating Elasticsearch PAM limits.")
# in some OS this folder may not exist, so create it
Logger.info("Ensure PAM limits directory exists: {0}".format(params.limits_conf_dir))
Directory(params.limits_conf_dir,
create_parents=True,
owner='root',
group='root')
Logger.info("Creating Elasticsearch PAM limits; file={0}".format(params.limits_conf_file))
File(params.limits_conf_file,
content=Template('elasticsearch_limits.conf.j2'),
owner="root",
group="root")
def create_elastic_jvm_options(params):
"""
Defines the jvm.options file used to specify JVM options.
"""
path = "{0}/jvm.options".format(params.conf_dir)
Logger.info("Creating Elasticsearch JVM Options; file={0}".format(path))
File(path,
content=InlineTemplate(params.jvm_options_template),
owner=params.elastic_user,
group=params.elastic_group)
def get_data_directories(params):
"""
Returns the directories to use for storing Elasticsearch data.
"""
path = params.path_data
path = path.replace('"', '')
path = path.replace(' ', '')
path = path.split(',')
dirs = [p.replace('"', '') for p in path]
Logger.info("Elasticsearch data directories: dirs={0}".format(dirs))
return dirs
def configure_master():
"""
Configures the Elasticsearch master node.
"""
import params
# define the directories required
dirs = [
params.log_dir,
params.pid_dir,
params.conf_dir,
"{0}/scripts".format(params.conf_dir)
]
dirs += get_data_directories(params)
# configure the elasticsearch master
create_user(params)
create_directories(params, dirs)
create_elastic_env(params)
create_elastic_site(params, "elasticsearch.master.yaml.j2")
create_elastic_config(params)
create_elastic_pam_limits(params)
create_elastic_jvm_options(params)
if is_systemd_running():
configure_systemd(params)
def configure_slave():
"""
Configures the Elasticsearch slave node.
"""
import params
# define the directories required
dirs = [
params.log_dir,
params.pid_dir,
params.conf_dir,
]
dirs += get_data_directories(params)
# configure the elasticsearch slave
create_user(params)
create_directories(params, dirs)
create_elastic_env(params)
create_elastic_site(params, "elasticsearch.slave.yaml.j2")
create_elastic_config(params)
create_elastic_pam_limits(params)
create_elastic_jvm_options(params)
if is_systemd_running():
configure_systemd(params)