logstash/lib/pluginmanager/offline_plugin_packager.rb
João Duarte e9c9865f40
Add apache and elastic license headers to source code files (#11673)
* add license header to ruby and java files
* add license header to erb and rake files
* add license headers to gradle files
2020-03-11 11:53:38 +00:00

134 lines
4.2 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/ui"
require "pluginmanager/errors"
require "bootstrap/environment"
require "bootstrap/util/compress"
require "paquet"
require "stud/temporary"
require "fileutils"
module LogStash module PluginManager
class SpecificationHelpers
WILDCARD = "*"
WILDCARD_INTO_RE = ".*"
def self.find_by_name_with_wildcards(pattern)
re = transform_pattern_into_re(pattern)
::Gem::Specification.find_all.select do |specification|
specification.name =~ re
end
end
def self.transform_pattern_into_re(pattern)
Regexp.new("^#{pattern.gsub(WILDCARD, WILDCARD_INTO_RE)}$")
end
end
class OfflinePluginPackager
LOGSTASH_DIR = "logstash"
DEPENDENCIES_DIR = ::File.join(LOGSTASH_DIR, "dependencies")
# To make sure we have the maximum compatibility
# we will ignore theses gems and they won't be included in the pack
IGNORE_GEMS_IN_PACK = %w(
logstash-core
logstash-core-plugin-api
jar-dependencies
)
INVALID_PLUGINS_TO_EXPLICIT_PACK = IGNORE_GEMS_IN_PACK.collect { |name| /^#{name}/ } + [
/mixin/
]
def initialize(plugins_to_package, target)
@plugins_to_package = Array(plugins_to_package)
@target = target
validate_plugins!
end
def validate_plugins!
@plugins_to_package.each do |plugin_name|
if INVALID_PLUGINS_TO_EXPLICIT_PACK.any? { |invalid_name| plugin_name =~ invalid_name }
raise UnpackablePluginError, "Cannot explicitly pack `#{plugin_name}` for offline installation"
end
end
end
def generate_temporary_path
Stud::Temporary.pathname
end
def explicitly_declared_plugins_specs
@plugins_to_package.collect do |plugin_pattern|
specs = SpecificationHelpers.find_by_name_with_wildcards(plugin_pattern)
if specs.size > 0
specs
else
raise LogStash::PluginManager::PluginNotFoundError, "Cannot find plugins matching: `#{plugin_pattern}`. Please install these before creating the offline pack"
end
end.flatten
end
def execute
temp_path = generate_temporary_path
packet_gem = Paquet::Gem.new(temp_path, LogStash::Environment::CACHE_PATH)
explicit_plugins_specs = explicitly_declared_plugins_specs
explicit_plugins_specs.each do |spec|
packet_gem.add(spec.name)
end
IGNORE_GEMS_IN_PACK.each do |gem_name|
packet_gem.ignore(gem_name)
end
packet_gem.pack
prepare_package(explicit_plugins_specs, temp_path)
LogStash::Util::Zip.compress(temp_path, @target)
ensure
FileUtils.rm_rf(temp_path)
end
def prepare_package(explicit_plugins, temp_path)
FileUtils.mkdir_p(::File.join(temp_path, LOGSTASH_DIR))
FileUtils.mkdir_p(::File.join(temp_path, DEPENDENCIES_DIR))
explicit_path = ::File.join(temp_path, LOGSTASH_DIR)
dependencies_path = ::File.join(temp_path, DEPENDENCIES_DIR)
Dir.glob(::File.join(temp_path, "*.gem")).each do |gem_file|
filename = ::File.basename(gem_file)
if explicit_plugins.any? { |spec| filename =~ /^#{spec.name}/ }
FileUtils.mv(gem_file, ::File.join(explicit_path, filename))
else
FileUtils.mv(gem_file, ::File.join(dependencies_path, filename))
end
end
end
def self.package(plugins_args, target)
OfflinePluginPackager.new(plugins_args, target).execute
end
end
end end