chef/cookbooks/elasticsearch/libraries/provider_plugin.rb
Greg Karékinian a32f34b408 Vendor the external cookbooks
Knife-Zero doesn't include Berkshelf support, so vendoring everything in
the repo is convenient again
2019-10-13 19:17:42 +02:00

109 lines
4.2 KiB
Ruby

# Chef Provider for installing an elasticsearch plugin
class ElasticsearchCookbook::PluginProvider < Chef::Provider::LWRPBase
include ElasticsearchCookbook::Helpers
include Chef::Mixin::ShellOut
provides :elasticsearch_plugin
def whyrun_supported?
true # we only use core Chef resources that also support whyrun, or guard
end
def action_install
return if plugin_exists(new_resource.plugin_name)
# since install can take a URL argument instead
url_or_name = new_resource.url || new_resource.plugin_name
manage_plugin("install #{url_or_name}")
end # action
def action_remove
return unless plugin_exists(new_resource.plugin_name)
manage_plugin("remove #{new_resource.plugin_name}")
end # action
def manage_plugin(arguments)
es_user = find_es_resource(Chef.run_context, :elasticsearch_user, new_resource)
es_install = find_es_resource(Chef.run_context, :elasticsearch_install, new_resource)
es_conf = find_es_resource(Chef.run_context, :elasticsearch_configure, new_resource)
assert_state_is_valid(es_user, es_install, es_conf) unless whyrun_mode?
# shell_out! automatically raises on error, logs command output
# required for package installs that show up with parent dir owned by root
plugin_dir_exists = ::File.exist?(es_conf.path_plugins)
unless plugin_dir_exists
cmd_str = "mkdir -p #{es_conf.path_plugins}"
if whyrun_mode?
Chef::Log.info("Would run command: #{cmd_str}")
else
shell_out_as_user!(cmd_str, Chef.run_context)
new_resource.updated_by_last_action(true)
end
end
unless plugin_exists(new_resource.plugin_name)
cmd_str = "#{es_conf.path_bin}/elasticsearch-plugin #{arguments.chomp(' ')} #{new_resource.options}".chomp(' ')
if whyrun_mode?
Chef::Log.info("Would run command: #{cmd_str}")
else
command_array = cmd_str.split(' ')
shell_out_as_user!(command_array, Chef.run_context)
new_resource.updated_by_last_action(true)
end
end
end
def plugin_exists(name)
es_conf = find_es_resource(Chef.run_context, :elasticsearch_configure, new_resource)
path = es_conf.path_plugins
Dir.entries(path).any? do |plugin|
next if plugin =~ /^\./
name == plugin
end
rescue
false
end
def assert_state_is_valid(_es_user, _es_install, es_conf)
unless es_conf.path_plugins # we do not check existence (may not exist if no plugins installed)
raise "Could not determine the plugin directory (#{es_conf.path_plugins}). Please check elasticsearch_configure[#{es_conf.name}]."
end
unless es_conf.path_bin && ::File.exist?(es_conf.path_bin)
raise "Could not determine the binary directory (#{es_conf.path_bin}). Please check elasticsearch_configure[#{es_conf.name}]."
end
true
end
def shell_out_as_user!(command, run_ctx)
es_install = find_es_resource(run_ctx, :elasticsearch_install, new_resource)
es_conf = find_es_resource(run_ctx, :elasticsearch_configure, new_resource)
es_svc = find_es_resource(run_ctx, :elasticsearch_service, new_resource)
# we need to figure out the env file path to set environment for plugins
default_config_name = es_svc.service_name || es_svc.instance_name || es_conf.instance_name || 'elasticsearch'
include_file_resource = find_exact_resource(run_ctx, :template, "elasticsearch.in.sh-#{default_config_name}")
env = { 'ES_INCLUDE' => include_file_resource.path }
# Add HTTP Proxy vars unless explicitly told not to
if new_resource.chef_proxy
env['ES_JAVA_OPTS'] = "#{ENV['ES_JAVA_OPTS']} #{get_java_proxy_arguments}"
end
# See this link for an explanation:
# https://www.elastic.co/guide/en/elasticsearch/plugins/2.1/plugin-management.html
if es_install.type == 'package' || es_install.type == 'repository'
# package installations should install plugins as root
shell_out!(command, :env => env, :timeout => 1200)
else
# non-package installations should install plugins as the ES user
es_user = find_es_resource(run_ctx, :elasticsearch_user, new_resource)
shell_out!(command, user: es_user.username, group: es_user.groupname, :env => env, :timeout => 1200)
end
end
end # provider