Adapted install/uninstall/list PluginManager's command to respect the alised plugins (#12821) (#12836)

Adapted install/uninstall/list PluginManager's CLI commands to respect the alised plugins
- adapt install plugin to resolve an alias giving precedence on a real plugin
- changed list to mark alised plugins
- uninstall avoid to remove the alias and ask the user to remove the original plugin
- update update the original plugin in case of alias, else fallback on usual behavior

Co-authored-by: Ry Biesemeyer <ry.biesemeyer@elastic.co>
(cherry picked from commit 1e08341e1e)
This commit is contained in:
Andrea Selva 2021-04-20 23:43:47 +02:00 committed by GitHub
parent 4086d427c0
commit 0bc53b4b8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 55 additions and 3 deletions

View file

@ -70,7 +70,7 @@ class LogStash::PluginManager::Install < LogStash::PluginManager::Command
gems = plugins_development_gems
else
gems = plugins_gems
verify_remote!(gems) if !local? && verify?
gems = verify_remote!(gems) if !local? && verify?
end
check_for_integrations(gems)
@ -123,12 +123,30 @@ class LogStash::PluginManager::Install < LogStash::PluginManager::Command
# Check if the specified gems contains
# the logstash `metadata`
def verify_remote!(gems)
gems_swap = {}
options = { :rubygems_source => gemfile.gemset.sources }
gems.each do |plugin, version|
puts("Validating #{[plugin, version].compact.join("-")}")
next if validate_plugin(plugin, version, options)
signal_usage_error("Installs of an alias doesn't require version specification --version") if version
# if the plugin is an alias then fallback to the original name
if LogStash::PluginManager::ALIASES.has_key?(plugin)
resolved_plugin = LogStash::PluginManager::ALIASES[plugin]
if validate_plugin(resolved_plugin, version, options)
puts "Remapping alias #{plugin} to #{resolved_plugin}"
gems_swap[plugin] = resolved_plugin
next
end
end
signal_error("Installation aborted, verification failed for #{plugin} #{version}")
end
# substitute in gems the list the alias plugin with the original
gems.collect do |plugin, version|
[gems_swap.fetch(plugin, plugin), version]
end
end
def validate_plugin(plugin, version, options)

View file

@ -34,10 +34,16 @@ class LogStash::PluginManager::List < LogStash::PluginManager::Command
signal_error("No plugins found") if filtered_specs.empty?
installed_plugin_names = filtered_specs.collect {|spec| spec.name}
filtered_specs.sort_by{|spec| spec.name}.each do |spec|
line = "#{spec.name}"
line += " (#{spec.version})" if verbose?
puts(line)
if LogStash::PluginManager::ALIASES.has_value?(spec.name)
alias_plugin = LogStash::PluginManager::ALIASES.key(spec.name)
puts("└── #{alias_plugin} (alias)") unless installed_plugin_names.include?(alias_plugin)
end
if spec.metadata.fetch("logstash_group", "") == "integration"
integration_plugins = spec.metadata.fetch("integration_plugins", "").split(",")
integration_plugins.each_with_index do |integration_plugin, i|

View file

@ -32,6 +32,14 @@ class LogStash::PluginManager::Remove < LogStash::PluginManager::Command
##
LogStash::Bundler.setup!({:without => [:build, :development]})
if LogStash::PluginManager::ALIASES.has_key?(plugin)
unless LogStash::PluginManager.installed_plugin?(plugin, gemfile)
aliased_plugin = LogStash::PluginManager::ALIASES[plugin]
puts "Cannot remove the alias #{plugin}, which is an alias for #{aliased_plugin}; if you wish to remove it, you must remove the aliased plugin instead."
return
end
end
# If a user is attempting to uninstall X-Pack, present helpful output to guide
# them toward the OSS-only distribution of Logstash
LogStash::PluginManager::XPackInterceptor::Remove.intercept!(plugin)

View file

@ -63,6 +63,7 @@ class LogStash::PluginManager::Update < LogStash::PluginManager::Command
# remove any version constrain from the Gemfile so the plugin(s) can be updated to latest version
# calling update without requirements will remove any previous requirements
plugins = plugins_to_update(previous_gem_specs_map)
# Skipping the major version validation when using a local cache as we can have situations
# without internet connection.
filtered_plugins = plugins.map { |plugin| gemfile.find(plugin) }
@ -99,9 +100,25 @@ class LogStash::PluginManager::Update < LogStash::PluginManager::Command
# If the plugins isn't available in the gemspec or in
# the gemfile defined with a local path, we assume the plugins is not
# installed.
not_installed = plugins_arg.select{|plugin| !previous_gem_specs_map.has_key?(plugin.downcase) && !gemfile.find(plugin) }
not_installed = plugins_arg.select { |plugin| !previous_gem_specs_map.has_key?(plugin.downcase) && !gemfile.find(plugin) }
# find only the not installed that doesn't correspond to an alias
not_installed_aliases = not_installed.select { |plugin| LogStash::PluginManager::ALIASES.has_key?(plugin)}
not_installed -= not_installed_aliases
signal_error("Plugin #{not_installed.join(', ')} is not installed so it cannot be updated, aborting") unless not_installed.empty?
plugins_arg
# resolve aliases that doesn't correspond to a real gem
plugins_to_update = plugins_arg.map do |plugin|
if not_installed_aliases.include?(plugin)
resolved_plugin = LogStash::PluginManager::ALIASES[plugin]
puts "Remapping alias #{plugin} to #{resolved_plugin}"
resolved_plugin
else
plugin
end
end
plugins_to_update
end
end

View file

@ -20,6 +20,9 @@ require_relative "../bootstrap/patches/remote_fetcher"
module LogStash::PluginManager
# Defines the plugin alias, must be kept in synch with Java class org.logstash.plugins.AliasRegistry
ALIASES = {"logstash-input-elastic_agent" => "logstash-input-beats"}
class ValidationError < StandardError; end
# check for valid logstash plugin gem name & version or .gem file, logs errors to $stdout