mirror of
https://github.com/elastic/logstash.git
synced 2025-04-22 05:37:21 -04:00
Enables the following cops: * Layout/SpaceBeforeBlockBraces * Layout/SpaceBeforeBrackets * Layout/SpaceBeforeComma * Layout/SpaceBeforeComment * Layout/SpaceBeforeFirstArg * Layout/SpaceBeforeSemicolon
160 lines
6.4 KiB
Ruby
160 lines
6.4 KiB
Ruby
# Licensed to Elasticsearch B.V. under one or more contributor
|
|
# license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright
|
|
# ownership. Elasticsearch B.V. 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.
|
|
|
|
require "pluginmanager/command"
|
|
require "jar-dependencies"
|
|
require "jar_install_post_install_hook"
|
|
|
|
class LogStash::PluginManager::Update < LogStash::PluginManager::Command
|
|
REJECTED_OPTIONS = [:path, :git, :github]
|
|
# These are local gems used by LS and needs to be filtered out of other plugin gems
|
|
NON_PLUGIN_LOCAL_GEMS = ["logstash-core", "logstash-core-plugin-api"]
|
|
|
|
parameter "[PLUGIN] ...", "Plugin name(s) to upgrade to latest version", :attribute_name => :plugins_arg
|
|
option "--[no-]verify", :flag, "verify plugin validity before installation", :default => true
|
|
option "--local", :flag, "force local-only plugin update. see bin/logstash-plugin package|unpack", :default => false
|
|
option "--[no-]conservative", :flag, "do a conservative update of plugin's dependencies", :default => true
|
|
|
|
def execute
|
|
# Turn off any jar dependencies lookup when running with `--local`
|
|
ENV["JARS_SKIP"] = "true" if local?
|
|
|
|
# remove "system" local gems used by LS
|
|
local_gems = gemfile.locally_installed_gems.map(&:name) - NON_PLUGIN_LOCAL_GEMS
|
|
|
|
if local_gems.size > 0
|
|
if update_all?
|
|
plugins_with_path = local_gems
|
|
else
|
|
plugins_with_path = plugins_arg & local_gems
|
|
end
|
|
|
|
warn_local_gems(plugins_with_path) if plugins_with_path.size > 0
|
|
end
|
|
update_gems!
|
|
end
|
|
|
|
private
|
|
def update_all?
|
|
plugins_arg.size == 0
|
|
end
|
|
|
|
def warn_local_gems(plugins_with_path)
|
|
puts("Update is not supported for manually defined plugins or local .gem plugin installations, skipping: #{plugins_with_path.join(", ")}")
|
|
end
|
|
|
|
def update_gems!
|
|
# If any error is raise inside the block the Gemfile will restore a backup of the Gemfile
|
|
previous_gem_specs_map = find_latest_gem_specs
|
|
|
|
# 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) }
|
|
.compact
|
|
.reject { |plugin| REJECTED_OPTIONS.any? { |key| plugin.options.has_key?(key) } }
|
|
.each { |plugin| gemfile.update(plugin.name) }
|
|
|
|
# force a disk sync before running bundler
|
|
gemfile.save
|
|
|
|
puts("Updating #{filtered_plugins.collect(&:name).join(", ")}") unless filtered_plugins.empty?
|
|
|
|
output = nil
|
|
# any errors will be logged to $stderr by invoke!
|
|
# Bundler cannot update and clean gems in one operation so we have to call the CLI twice.
|
|
Bundler.settings.temporary(:frozen => false) do # Unfreeze the bundle when updating gems
|
|
output = LogStash::Bundler.invoke! update: plugins,
|
|
rubygems_source: gemfile.gemset.sources,
|
|
local: local?,
|
|
conservative: conservative?
|
|
output << LogStash::Bundler.genericize_platform unless output.nil?
|
|
end
|
|
|
|
# We currently dont removed unused gems from the logstash installation
|
|
# see: https://github.com/elastic/logstash/issues/6339
|
|
# output = LogStash::Bundler.invoke!(:clean => true)
|
|
display_updated_plugins(previous_gem_specs_map)
|
|
rescue => exception
|
|
gemfile.restore!
|
|
report_exception("Updated Aborted", exception)
|
|
ensure
|
|
display_bundler_output(output)
|
|
end
|
|
|
|
# create list of plugins to update
|
|
def plugins_to_update(previous_gem_specs_map)
|
|
if update_all?
|
|
previous_gem_specs_map.values.map {|spec| spec.name}
|
|
else
|
|
# 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) }
|
|
|
|
# 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?
|
|
|
|
# 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
|
|
|
|
# We compare the before the update and after the update
|
|
def display_updated_plugins(previous_gem_specs_map)
|
|
update_count = 0
|
|
find_latest_gem_specs.values.each do |spec|
|
|
name = spec.name.downcase
|
|
if previous_gem_specs_map.has_key?(name)
|
|
if spec.version != previous_gem_specs_map[name].version
|
|
puts("Updated #{spec.name} #{previous_gem_specs_map[name].version.to_s} to #{spec.version.to_s}")
|
|
update_count += 1
|
|
end
|
|
else
|
|
puts("Installed #{spec.name} #{spec.version.to_s}")
|
|
update_count += 1
|
|
end
|
|
end
|
|
|
|
puts("No plugin updated") if update_count.zero?
|
|
end
|
|
|
|
# retrieve only the latest spec for all locally installed plugins
|
|
# @return [Hash] result hash {plugin_name.downcase => plugin_spec}
|
|
def find_latest_gem_specs
|
|
LogStash::PluginManager.all_installed_plugins_gem_specs(gemfile).inject({}) do |result, spec|
|
|
previous = result[spec.name.downcase]
|
|
result[spec.name.downcase] = previous ? [previous, spec].max_by {|s| s.version} : spec
|
|
result
|
|
end
|
|
end
|
|
end
|