From 0bc53b4b8aac54bb2a88e1a6be58d57e80cda9ed Mon Sep 17 00:00:00 2001 From: Andrea Selva Date: Tue, 20 Apr 2021 23:43:47 +0200 Subject: [PATCH] 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 (cherry picked from commit 1e08341e1ea7e269182cd40e70d13bd95bd6e9b2) --- lib/pluginmanager/install.rb | 20 +++++++++++++++++++- lib/pluginmanager/list.rb | 6 ++++++ lib/pluginmanager/remove.rb | 8 ++++++++ lib/pluginmanager/update.rb | 21 +++++++++++++++++++-- lib/pluginmanager/util.rb | 3 +++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/lib/pluginmanager/install.rb b/lib/pluginmanager/install.rb index a6f080fea..4a1dc4d7b 100644 --- a/lib/pluginmanager/install.rb +++ b/lib/pluginmanager/install.rb @@ -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) diff --git a/lib/pluginmanager/list.rb b/lib/pluginmanager/list.rb index f89647f29..3d03f1942 100644 --- a/lib/pluginmanager/list.rb +++ b/lib/pluginmanager/list.rb @@ -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| diff --git a/lib/pluginmanager/remove.rb b/lib/pluginmanager/remove.rb index 72fb35835..cde193fdf 100644 --- a/lib/pluginmanager/remove.rb +++ b/lib/pluginmanager/remove.rb @@ -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) diff --git a/lib/pluginmanager/update.rb b/lib/pluginmanager/update.rb index e78012f1a..028948fad 100644 --- a/lib/pluginmanager/update.rb +++ b/lib/pluginmanager/update.rb @@ -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 diff --git a/lib/pluginmanager/util.rb b/lib/pluginmanager/util.rb index ebbb43146..6a88aad4f 100644 --- a/lib/pluginmanager/util.rb +++ b/lib/pluginmanager/util.rb @@ -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