# 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. namespace "artifact" do SNAPSHOT_BUILD = ENV["RELEASE"] != "1" VERSION_QUALIFIER = ENV["VERSION_QUALIFIER"] if VERSION_QUALIFIER PACKAGE_SUFFIX = SNAPSHOT_BUILD ? "-#{VERSION_QUALIFIER}-SNAPSHOT" : "-#{VERSION_QUALIFIER}" else PACKAGE_SUFFIX = SNAPSHOT_BUILD ? "-SNAPSHOT" : "" end ## TODO: Install new service files def package_files res = [ "NOTICE.TXT", "CONTRIBUTORS", "bin/**/*", "config/**/*", "data", "modules/**/*", "lib/bootstrap/**/*", "lib/pluginmanager/**/*", "lib/systeminstall/**/*", "lib/secretstore/**/*", "logstash-core/lib/**/*", "logstash-core/locales/**/*", "logstash-core/vendor/**/*", "logstash-core/versions-gem-copy.yml", "logstash-core/*.gemspec", "logstash-core-plugin-api/lib/**/*", "logstash-core-plugin-api/versions-gem-copy.yml", "logstash-core-plugin-api/*.gemspec", "patterns/**/*", "tools/ingest-converter/build/libs/ingest-converter.jar", "vendor/??*/**/*", # To include ruby-maven's hidden ".mvn" directory, we need to # do add the line below. This directory contains a file called # "extensions.xml", which loads the ruby DSL for POMs. # Failing to include this file results in updates breaking for # plugins which use jar-dependencies. # See more in https://github.com/elastic/logstash/issues/4818 "vendor/??*/**/.mvn/**/*", # Without this when JRuby runs 'pleaserun' gem using the AdoptOpenJDK, during the post install script # it claims that modules are not open for private introspection and suggest it's missing --add-opens # so including these files JRuby run with modules opened to private introspection. "vendor/jruby/bin/.jruby.java_opts", "vendor/jruby/bin/.jruby.module_opts", "Gemfile", "Gemfile.lock", "x-pack/**/*", ] if @bundles_jdk res += [ "JDK_VERSION", "jdk/**/*", "jdk.app/**/*", ] end res end def default_exclude_paths return @exclude_paths if @exclude_paths @exclude_paths = [] @exclude_paths << "**/*.gem" @exclude_paths << "**/test/files/slow-xpath.xml" @exclude_paths << "**/logstash-*/spec" @exclude_paths << "bin/bundle" @exclude_paths << "bin/rspec" @exclude_paths << "bin/rspec.bat" # vendored test/spec artifacts from upstream @exclude_paths << 'vendor/**/gems/*/test/**/*' @exclude_paths << 'vendor/**/gems/*/spec/**/*' # vulnerability scanners shouldn't pick dependency Gemfile(s) @exclude_paths << 'vendor/**/gems/**/Gemfile.lock' @exclude_paths << 'vendor/**/gems/**/Gemfile' @exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rake-*' # exclude ruby-maven-libs 3.3.9 jars until JRuby ships with >= 3.8.9 @exclude_paths << 'vendor/bundle/jruby/**/gems/ruby-maven-libs-3.3.9/**/*' # remove this after JRuby includes rexml 3.3.x @exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rexml-3.2.5/**/*' @exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/specifications/rexml-3.2.5.gemspec' @exclude_paths end def oss_exclude_paths return @oss_excludes if @oss_excludes @oss_excludes = default_exclude_paths + ["x-pack/**/*"] end def files(exclude_paths = default_exclude_paths) Rake::FileList.new(*package_files).exclude(*exclude_paths) end def source_modified_since?(time, exclude_paths = default_exclude_paths) skip_list = ["logstash-core-plugin-api/versions-gem-copy.yml", "logstash-core/versions-gem-copy.yml"] result = false files(exclude_paths).each do |file| next if File.mtime(file) < time || skip_list.include?(file) puts "file modified #{file}" result = true break end result end # execute Kernel#system call,checking the exist status of the executed command and eventually reporting as exception def safe_system(*args) if !system(*args) status = $? raise "Got exit status #{status.exitstatus} attempting to execute #{args.inspect}!" end end desc "Generate rpm, deb, tar and zip artifacts" task "all" => ["prepare", "build"] task "docker_only" => ["prepare", "build_docker_full", "build_docker_oss", "build_docker_ubi8", "build_docker_wolfi"] desc "Build all (jdk bundled and not) tar.gz and zip of default logstash plugins with all dependencies" task "archives" => ["prepare", "generate_build_metadata"] do #with bundled JDKs license_details = ['ELASTIC-LICENSE'] @bundles_jdk = true create_archive_pack(license_details, "x86_64", "linux", "windows", "darwin") create_archive_pack(license_details, "arm64", "linux", "darwin") #without JDK safe_system("./gradlew bootstrap") #force the build of Logstash jars @bundles_jdk = false build_tar(*license_details, platform: '-no-jdk') build_zip(*license_details, platform: '-no-jdk') end def create_archive_pack(license_details, arch, *oses) oses.each do |os_name| puts("[artifact:archives] Building tar.gz/zip of default plugins for OS: #{os_name}, arch: #{arch}") create_single_archive_pack(os_name, arch, license_details) end end def create_single_archive_pack(os_name, arch, license_details) safe_system("./gradlew copyJdk -Pjdk_bundle_os=#{os_name} -Pjdk_arch=#{arch}") if arch == 'arm64' arch = 'aarch64' end case os_name when "linux" build_tar(*license_details, platform: "-linux-#{arch}") when "windows" build_zip(*license_details, platform: "-windows-#{arch}") when "darwin" build_tar(*license_details, platform: "-darwin-#{arch}") end safe_system("./gradlew deleteLocalJdk -Pjdk_bundle_os=#{os_name}") end # Create an archive pack using settings appropriate for the running machine def create_local_archive_pack(bundle_jdk) @bundles_jdk = bundle_jdk safe_system("./gradlew copyJdk") if bundle_jdk build_tar('ELASTIC-LICENSE') safe_system("./gradlew deleteLocalJdk") if bundle_jdk end desc "Build a not JDK bundled tar.gz of default logstash plugins with all dependencies" task "no_bundle_jdk_tar" => ["prepare", "generate_build_metadata"] do create_local_archive_pack(false) end desc "Build a JDK bundled tar.gz of default logstash plugins with all dependencies" task "bundle_jdk_tar" => ["prepare", "generate_build_metadata"] do create_local_archive_pack(true) end desc "Build all (jdk bundled and not) OSS tar.gz and zip of default logstash plugins with all dependencies" task "archives_oss" => ["prepare-oss", "generate_build_metadata"] do #with bundled JDKs @bundles_jdk = true license_details = ['APACHE-LICENSE-2.0', "-oss", oss_exclude_paths] create_archive_pack(license_details, "x86_64", "linux", "windows", "darwin") create_archive_pack(license_details, "arm64", "linux", "darwin") #without JDK @bundles_jdk = false safe_system("./gradlew bootstrap") #force the build of Logstash jars build_tar(*license_details, platform: '-no-jdk') build_zip(*license_details, platform: '-no-jdk') end desc "Build an RPM of logstash with all dependencies" task "rpm" => ["prepare", "generate_build_metadata"] do #with bundled JDKs @bundles_jdk = true puts("[artifact:rpm] building rpm package x86_64") package_with_jdk("centos", "x86_64") puts("[artifact:rpm] building rpm package arm64") package_with_jdk("centos", "arm64") #without JDKs @bundles_jdk = false safe_system("./gradlew bootstrap") #force the build of Logstash jars package("centos") end desc "Build an RPM of logstash with all dependencies" task "rpm_oss" => ["prepare-oss", "generate_build_metadata"] do #with bundled JDKs @bundles_jdk = true puts("[artifact:rpm] building rpm OSS package x86_64") package_with_jdk("centos", "x86_64", :oss) puts("[artifact:rpm] building rpm OSS package arm64") package_with_jdk("centos", "arm64", :oss) #without JDKs @bundles_jdk = false safe_system("./gradlew bootstrap") #force the build of Logstash jars package("centos", :oss) end desc "Build a DEB of logstash with all dependencies" task "deb" => ["prepare", "generate_build_metadata"] do #with bundled JDKs @bundles_jdk = true puts("[artifact:deb] building deb package for x86_64") package_with_jdk("ubuntu", "x86_64") puts("[artifact:deb] building deb package for OS: linux arm64") package_with_jdk("ubuntu", "arm64") #without JDKs @bundles_jdk = false safe_system("./gradlew bootstrap") #force the build of Logstash jars package("ubuntu") end desc "Build a DEB of logstash with all dependencies" task "deb_oss" => ["prepare-oss", "generate_build_metadata"] do #with bundled JDKs @bundles_jdk = true puts("[artifact:deb_oss] building deb OSS package x86_64") package_with_jdk("ubuntu", "x86_64", :oss) puts("[artifact:deb_oss] building deb OSS package arm64") package_with_jdk("ubuntu", "arm64", :oss) #without JDKs @bundles_jdk = false safe_system("./gradlew bootstrap") #force the build of Logstash jars package("ubuntu", :oss) end desc "Generate logstash core gems" task "gems" => ["prepare"] do Rake::Task["artifact:build-logstash-core"].invoke Rake::Task["artifact:build-logstash-core-plugin-api"].invoke end # "all-plugins" version of tasks desc "Generate rpm, deb, tar and zip artifacts (\"all-plugins\" version)" task "all-all-plugins" => ["prepare-all", "build"] desc "Build a zip of all logstash plugins from logstash-plugins github repo" task "zip-all-plugins" => ["prepare-all", "generate_build_metadata"] do puts("[artifact:zip] Building zip of all plugins") build_zip('ELASTIC-LICENSE', "-all-plugins") end desc "Build a tar.gz of all logstash plugins from logstash-plugins github repo" task "tar-all-plugins" => ["prepare-all", "generate_build_metadata"] do puts("[artifact:tar] Building tar.gz of all plugins") build_tar('ELASTIC-LICENSE', "-all-plugins") end desc "Build docker image" task "docker" => ["prepare", "generate_build_metadata", "archives"] do puts("[docker] Building docker image") build_docker('full') end desc "Build OSS docker image" task "docker_oss" => ["prepare-oss", "generate_build_metadata", "archives_oss"] do puts("[docker_oss] Building OSS docker image") build_docker('oss') end desc "Build UBI8 docker image" task "docker_ubi8" => %w(prepare generate_build_metadata archives) do puts("[docker_ubi8] Building UBI docker image") build_docker('ubi8') end desc "Build wolfi docker image" task "docker_wolfi" => %w(prepare generate_build_metadata archives) do puts("[docker_wolfi] Building Wolfi docker image") build_docker('wolfi') end desc "Generate Dockerfiles for full and oss images" task "dockerfiles" => ["prepare", "generate_build_metadata"] do puts("[dockerfiles] Building Dockerfiles") build_dockerfile('oss') build_dockerfile('full') build_dockerfile('ubi8') build_dockerfile('wolfi') build_dockerfile('ironbank') end desc "Generate Dockerfile for oss images" task "dockerfile_oss" => ["prepare-oss", "generate_build_metadata"] do puts("[dockerfiles] Building oss Dockerfile") build_dockerfile('oss') end desc "Generate Dockerfile for full images" task "dockerfile_full" => ["prepare", "generate_build_metadata"] do puts("[dockerfiles] Building full Dockerfiles") build_dockerfile('full') end desc "Generate Dockerfile for UBI8 images" task "dockerfile_ubi8" => ["prepare", "generate_build_metadata"] do puts("[dockerfiles] Building ubi8 Dockerfiles") build_dockerfile('ubi8') end desc "Generate Dockerfile for wolfi images" task "dockerfile_wolfi" => ["prepare", "generate_build_metadata"] do puts("[dockerfiles] Building wolfi Dockerfiles") build_dockerfile('wolfi') end desc "Generate build context for ironbank" task "dockerfile_ironbank" => ["prepare", "generate_build_metadata"] do puts("[dockerfiles] Building ironbank Dockerfiles") build_dockerfile('ironbank') end # Auxiliary tasks task "build" => [:generate_build_metadata] do Rake::Task["artifact:gems"].invoke unless SNAPSHOT_BUILD Rake::Task["artifact:deb"].invoke Rake::Task["artifact:rpm"].invoke Rake::Task["artifact:archives"].invoke unless ENV['SKIP_DOCKER'] == "1" Rake::Task["artifact:docker"].invoke Rake::Task["artifact:docker_ubi8"].invoke Rake::Task["artifact:docker_wolfi"].invoke Rake::Task["artifact:dockerfiles"].invoke Rake::Task["artifact:docker_oss"].invoke end Rake::Task["artifact:deb_oss"].invoke Rake::Task["artifact:rpm_oss"].invoke Rake::Task["artifact:archives_oss"].invoke end task "build_docker_full" => [:generate_build_metadata] do Rake::Task["artifact:docker"].invoke Rake::Task["artifact:dockerfile_full"].invoke end task "build_docker_oss" => [:generate_build_metadata] do Rake::Task["artifact:docker_oss"].invoke Rake::Task["artifact:dockerfile_oss"].invoke end task "build_docker_ubi8" => [:generate_build_metadata] do Rake::Task["artifact:docker_ubi8"].invoke Rake::Task["artifact:dockerfile_ubi8"].invoke end task "build_docker_wolfi" => [:generate_build_metadata] do Rake::Task["artifact:docker_wolfi"].invoke Rake::Task["artifact:dockerfile_wolfi"].invoke end task "generate_build_metadata" do require 'time' require 'tempfile' return if defined?(BUILD_METADATA_FILE) BUILD_METADATA_FILE = Tempfile.new('build.rb') BUILD_DATE = Time.now.iso8601 build_info = { "build_date" => BUILD_DATE, "build_sha" => `git rev-parse HEAD`.chomp, "build_snapshot" => SNAPSHOT_BUILD } metadata = ["# encoding: utf-8", "BUILD_INFO = #{build_info}"] IO.write(BUILD_METADATA_FILE.path, metadata.join("\n")) end # We create an empty bundle config file # This will allow the deb and rpm to create a file # with the correct user group and permission. task "clean-bundle-config" do FileUtils.mkdir_p(".bundle") File.open(".bundle/config", "w") { } end # locate the "gem "logstash-core" ..." line in Gemfile, and if the :path => "..." option if specified # build the local logstash-core gem otherwise just do nothing, bundler will deal with it. task "build-logstash-core" do # regex which matches a Gemfile gem definition for the logstash-core gem and captures the :path option gem_line_regex = /^\s*gem\s+["']logstash-core["'](?:\s*,\s*["'][^"^']+["'])?(?:\s*,\s*:path\s*=>\s*["']([^"^']+)["'])?/i lines = File.readlines("Gemfile") matches = lines.select {|line| line[gem_line_regex]} abort("ERROR: Gemfile format error, need a single logstash-core gem specification") if matches.size != 1 path = matches.first[gem_line_regex, 1] if path Rake::Task["plugin:build-local-core-gem"].invoke("logstash-core", path) else puts "The Gemfile should reference \"logstash-core\" gem locally through :path, but found instead: #{matches}" exit(1) end end # locate the "gem "logstash-core-plugin-api" ..." line in Gemfile, and if the :path => "..." option if specified # build the local logstash-core-plugin-api gem otherwise just do nothing, bundler will deal with it. task "build-logstash-core-plugin-api" do # regex which matches a Gemfile gem definition for the logstash-core gem and captures the :path option gem_line_regex = /^\s*gem\s+["']logstash-core-plugin-api["'](?:\s*,\s*["'][^"^']+["'])?(?:\s*,\s*:path\s*=>\s*["']([^"^']+)["'])?/i lines = File.readlines("Gemfile") matches = lines.select {|line| line[gem_line_regex]} abort("ERROR: Gemfile format error, need a single logstash-core-plugin-api gem specification") if matches.size != 1 path = matches.first[gem_line_regex, 1] if path Rake::Task["plugin:build-local-core-gem"].invoke("logstash-core-plugin-api", path) else puts "The Gemfile should reference \"logstash-core-plugin-api\" gem locally through :path, but found instead: #{matches}" exit(1) end end task "prepare" do if ENV['SKIP_PREPARE'] != "1" ["bootstrap", "plugin:install-default", "artifact:clean-bundle-config"].each {|task| Rake::Task[task].invoke } end end task "prepare-oss" do if ENV['SKIP_PREPARE'] != "1" %w[bootstrap plugin:install-default plugin:remove-non-oss-plugins artifact:clean-bundle-config].each {|task| Rake::Task[task].invoke } end end def ensure_logstash_version_constant_defined # we do not want this file required when rake (ruby) parses this file # only when there is a task executing, not at the very top of this file if !defined?(LOGSTASH_VERSION) require "logstash/version" end end def build_tar(license, tar_suffix = nil, exclude_paths = default_exclude_paths, platform: '') require "zlib" require 'rubygems' require 'rubygems/package' require 'minitar' ensure_logstash_version_constant_defined tarpath = "build/logstash#{tar_suffix}-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}#{platform}.tar.gz" if File.exist?(tarpath) && ENV['SKIP_PREPARE'] == "1" && !source_modified_since?(File.mtime(tarpath)) puts("[artifact:tar] Source code not modified. Skipping build of #{tarpath}") return end puts("[artifact:tar] building #{tarpath}") gz = Zlib::GzipWriter.new(File.new(tarpath, "wb"), Zlib::BEST_COMPRESSION) Minitar::Writer.open(gz) do |tar| files(exclude_paths).each do |path| write_to_tar(tar, path, "logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}/#{path}") end source_license_path = "licenses/#{license}.txt" fail("Missing source license: #{source_license_path}") unless File.exist?(source_license_path) write_to_tar(tar, source_license_path, "logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}/LICENSE.txt") # add build.rb to tar metadata_file_path_in_tar = File.join("logstash-core", "lib", "logstash", "build.rb") path_in_tar = File.join("logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}", metadata_file_path_in_tar) write_to_tar(tar, BUILD_METADATA_FILE.path, path_in_tar) end gz.close end def write_to_tar(tar, path, path_in_tar) stat = File.lstat(path) if stat.directory? tar.mkdir(path_in_tar, :mode => stat.mode) elsif stat.symlink? tar.symlink(path_in_tar, File.readlink(path), :mode => stat.mode) else tar.add_file_simple(path_in_tar, :mode => stat.mode, :size => stat.size) do |io| File.open(path, 'rb') do |fd| chunk = nil size = 0 size += io.write(chunk) while chunk = fd.read(16384) if stat.size != size raise "Failure to write the entire file (#{path}) to the tarball. Expected to write #{stat.size} bytes; actually write #{size}" end end end end end def build_zip(license, zip_suffix = "", exclude_paths = default_exclude_paths, platform: '') require 'zip' ensure_logstash_version_constant_defined zippath = "build/logstash#{zip_suffix}-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}#{platform}.zip" puts("[artifact:zip] building #{zippath}") File.unlink(zippath) if File.exist?(zippath) Zip::File.open(zippath, Zip::File::CREATE) do |zipfile| files(exclude_paths).each do |path| path_in_zip = "logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}/#{path}" zipfile.add(path_in_zip, path) end source_license_path = "licenses/#{license}.txt" fail("Missing source license: #{source_license_path}") unless File.exist?(source_license_path) zipfile.add("logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}/LICENSE.txt", source_license_path) # add build.rb to zip metadata_file_path_in_zip = File.join("logstash-core", "lib", "logstash", "build.rb") path_in_zip = File.join("logstash-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}", metadata_file_path_in_zip) path = BUILD_METADATA_FILE.path Zip.continue_on_exists_proc = true zipfile.add(path_in_zip, path) end puts "Complete: #{zippath}" end def package_with_jdk(platform, jdk_arch, variant = :standard) safe_system("./gradlew copyJdk -Pjdk_bundle_os=linux -Pjdk_arch=#{jdk_arch}") package(platform, variant, true, jdk_arch) safe_system('./gradlew deleteLocalJdk -Pjdk_bundle_os=linux') end def package(platform, variant = :standard, bundle_jdk = false, jdk_arch = 'x86_64') oss = variant == :oss require "stud/temporary" require "fpm/errors" # TODO(sissel): fix this in fpm require "fpm/package/dir" require "fpm/package/gem" # TODO(sissel): fix this in fpm; rpm needs it. basedir = File.join(File.dirname(__FILE__), "..") dir = FPM::Package::Dir.new dir.attributes[:workdir] = File.join(basedir, "build", "fpm") metadata_file_path = File.join("logstash-core", "lib", "logstash", "build.rb") metadata_source_file_path = BUILD_METADATA_FILE.path dir.input("#{metadata_source_file_path}=/usr/share/logstash/#{metadata_file_path}") suffix = "" if oss suffix = "-oss" exclude_paths = oss_exclude_paths else exclude_paths = default_exclude_paths end files(exclude_paths).each do |path| next if File.directory?(path) # Omit any config dir from /usr/share/logstash for packages, since we're # using /etc/logstash below next if path.start_with?("config/") dir.input("#{path}=/usr/share/logstash/#{path}") end if oss # Artifacts whose sources are exclusively licensed under the Apache License and # Apache-compatible licenses are distributed under the Apache License 2.0 dir.input("licenses/APACHE-LICENSE-2.0.txt=/usr/share/logstash/LICENSE.txt") else # Artifacts whose sources include Elastic Commercial Software are distributed # under the Elastic License. dir.input("licenses/ELASTIC-LICENSE.txt=/usr/share/logstash/LICENSE.txt") end # Create an empty /var/log/logstash/ directory in the package # This is a bit obtuse, I suppose, but it is necessary until # we find a better way to do this with fpm. Stud::Temporary.directory do |empty| dir.input("#{empty}/=/usr/share/logstash/data") dir.input("#{empty}/=/var/log/logstash") dir.input("#{empty}/=/var/lib/logstash") dir.input("#{empty}/=/etc/logstash/conf.d") dir.input("#{empty}/=/lib/systemd/system") dir.input("#{empty}/=/etc/default") end File.join(basedir, "config", "log4j2.properties").tap do |path| dir.input("#{path}=/etc/logstash") end arch_suffix = bundle_jdk ? map_architecture_for_package_type(platform, jdk_arch) : "no-jdk" ensure_logstash_version_constant_defined package_filename = "logstash#{suffix}-#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}-#{arch_suffix}.TYPE" File.join(basedir, "config", "startup.options").tap do |path| dir.input("#{path}=/etc/logstash") end File.join(basedir, "config", "jvm.options").tap do |path| dir.input("#{path}=/etc/logstash") end File.join(basedir, "config", "logstash.yml").tap do |path| dir.input("#{path}=/etc/logstash") end File.join(basedir, "config", "logstash-sample.conf").tap do |path| dir.input("#{path}=/etc/logstash") end File.join(basedir, "pkg", "pipelines.yml").tap do |path| dir.input("#{path}=/etc/logstash") end File.join(basedir, "pkg", "service_templates", "systemd", "lib", "systemd", "system", "logstash.service").tap do |path| dir.input("#{path}=/lib/systemd/system") end File.join(basedir, "pkg", "service_templates", "sysv", "etc", "default", "logstash").tap do |path| dir.input("#{path}=/etc/default") end case platform when "redhat", "centos" require "fpm/package/rpm" # Red Hat calls 'Apache Software License' == ASL license = oss ? "ASL 2.0" : "Elastic License" out = dir.convert(FPM::Package::RPM) out.license = license out.attributes[:rpm_use_file_permissions] = true out.attributes[:rpm_user] = "root" out.attributes[:rpm_group] = "root" out.attributes[:rpm_os] = "linux" out.attributes[:rpm_digest] = "sha256" out.config_files << "/etc/logstash/startup.options" out.config_files << "/etc/logstash/jvm.options" out.config_files << "/etc/logstash/log4j2.properties" out.config_files << "/etc/logstash/logstash.yml" out.config_files << "/etc/logstash/logstash-sample.conf" out.config_files << "/etc/logstash/pipelines.yml" out.config_files << "/lib/systemd/system/logstash.service" out.config_files << "/etc/default/logstash" out.replaces << "logstash < 7.10.0" when "debian", "ubuntu" require "fpm/package/deb" license = oss ? "ASL-2.0" : "Elastic-License" out = dir.convert(FPM::Package::Deb) out.license = license out.attributes[:deb_user] = "root" out.attributes[:deb_group] = "root" out.attributes[:deb_suggests] = ["java11-runtime-headless"] unless bundle_jdk out.config_files << "/etc/logstash/startup.options" out.config_files << "/etc/logstash/jvm.options" out.config_files << "/etc/logstash/log4j2.properties" out.config_files << "/etc/logstash/logstash.yml" out.config_files << "/etc/logstash/logstash-sample.conf" out.config_files << "/etc/logstash/pipelines.yml" out.config_files << "/lib/systemd/system/logstash.service" out.config_files << "/etc/default/logstash" out.conflicts << "logstash (<< 7.10.0)" out.replaces << "logstash (<< 7.10.0)" end # Packaging install/removal scripts ["before", "after"].each do |stage| ["install", "remove"].each do |action| script = "#{stage}-#{action}" # like, "before-install" script_sym = script.gsub("-", "_").to_sym script_path = File.join(File.dirname(__FILE__), "..", "pkg", platform, "#{script}.sh") next unless File.exist?(script_path) out.scripts[script_sym] = File.read(script_path) end end # TODO(sissel): Invoke Pleaserun to generate the init scripts/whatever out.name = oss ? "logstash-oss" : "logstash" out.architecture = bundle_jdk ? map_architecture_for_package_type(platform, jdk_arch) : "all" out.version = "#{LOGSTASH_VERSION}#{PACKAGE_SUFFIX}".gsub(/[.-]([[:alpha:]])/, '~\1') # TODO(sissel): Include the git commit hash? out.iteration = "1" # what revision? out.url = "https://www.elastic.co/logstash" out.description = "An extensible logging pipeline" out.vendor = "Elastic" # Because we made a mistake in naming the RC version numbers, both rpm and deb view # "1.5.0.rc1" higher than "1.5.0". Setting the epoch to 1 ensures that we get a kind # of clean slate as to how we compare package versions. The default epoch is 0, and # epoch is sorted first, so a version 1:1.5.0 will have greater priority # than 1.5.0.rc4 out.epoch = 1 # We don't specify a dependency on Java because: # - On Red Hat, Oracle and Red Hat both label their java packages in # incompatible ways. Further, there is no way to guarantee a qualified # version is available to install. # - On Debian and Ubuntu, there is no Oracle package and specifying a # correct version of OpenJDK is impossible because there is no guarantee that # is impossible for the same reasons as the Red Hat section above. # References: # - https://github.com/elastic/logstash/issues/6275 # - http://www.elasticsearch.org/blog/java-1-7u55-safe-use-elasticsearch-lucene/ # - deb: https://github.com/elasticsearch/logstash/pull/1008 # - rpm: https://github.com/elasticsearch/logstash/pull/1290 # - rpm: https://github.com/elasticsearch/logstash/issues/1673 # - rpm: https://logstash.jira.com/browse/LOGSTASH-1020 out.attributes[:force?] = true # overwrite the rpm/deb/etc being created begin path = File.join(basedir, "build", out.to_s(package_filename)) x = out.output(path) puts "Completed: #{path}" ensure out.cleanup end end # def package def map_architecture_for_package_type(platform, jdk_arch) if jdk_arch == 'x86_64' case platform when "debian", "ubuntu" return "amd64" else return "x86_64" end elsif jdk_arch == 'arm64' case platform when "debian", "ubuntu" return "arm64" else return "aarch64" end else raise "CPU architecture not recognized: #{jdk_arch}" end end def build_docker(flavor) env = { "ARTIFACTS_DIR" => ::File.join(Dir.pwd, "build"), "RELEASE" => ENV["RELEASE"], "VERSION_QUALIFIER" => VERSION_QUALIFIER, "BUILD_DATE" => BUILD_DATE } Dir.chdir("docker") do |dir| safe_system(env, "make build-from-local-#{flavor}-artifacts") end end def build_dockerfile(flavor) env = { "ARTIFACTS_DIR" => ::File.join(Dir.pwd, "build"), "RELEASE" => ENV["RELEASE"], "VERSION_QUALIFIER" => VERSION_QUALIFIER, "BUILD_DATE" => BUILD_DATE } Dir.chdir("docker") do |dir| safe_system(env, "make public-dockerfiles_#{flavor}") puts "Dockerfiles created in #{env['ARTIFACTS_DIR']}" end end end