Skip to content

Commit

Permalink
(PE-36345) Add ruby/openssl to bolt-server main
Browse files Browse the repository at this point in the history
Includes a ruby and openssl build inside the bolt-server main package.
This change paves the way for us to enable legacy chiphers in
bolt-server's openssl to ensure ntlm (and by extension the WinRM
transport) can still function.
  • Loading branch information
mcdonaldseanp committed Jul 11, 2023
1 parent 46c127e commit 329c23d
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 2 deletions.
7 changes: 7 additions & 0 deletions configs/components/rubygem-gettext-setup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
version = settings[:rubygem_gettext_setup_version] || '1.1.0'
pkg.version version

ruby_version ||= settings[:ruby_version]
builtin_ruby ||= settings[:builtin_ruby]

if builtin_ruby
pkg.build_requires "ruby-#{ruby_version}"
end

case version
when '1.1.0'
pkg.sha256sum '2ad4fa99575d869f18056941d98dc9cb2a656abc7b991f360fbd3e32d28fd4ec'
Expand Down
19 changes: 18 additions & 1 deletion configs/components/runtime-pe-bolt-server.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# This component exists to install project-wide build dependencies for pe-bolt-server projects
component "runtime-pe-bolt-server" do |pkg, settings, platform|
pkg.build_requires "libffi"
pkg.build_requires "libyaml"

# PROJECT_SHORTNAME is used in the runtime script to determine the
# libdir where we put all the linked lib files. For bolt-server there's
# a whole path it needs to follow instead of just a name like 'installer'
# or 'bolt'.
pkg.environment "PROJECT_SHORTNAME", "server/apps/bolt-server"
pkg.add_source "file://resources/files/runtime/runtime.sh"

# PE Bolt Server depends on puppet-agent - it uses the agent's ruby installation to build gems.
# Add the enterprise repo for this project's PE version so that puppet-agent can be installed as a build dependency:
if platform.name =~ /ubuntu-18\.04/
Expand All @@ -19,4 +29,11 @@
end

pkg.build_requires('puppet-agent')
end
if platform.name =~ /el-[567]|redhatfips-7|sles-(:?11|12)|ubuntu-18.04-amd64/
libbase = platform.architecture =~ /64/ ? 'lib64' : 'lib'
libdir = "/opt/pl-build-tools/#{libbase}"
pkg.install do
"bash runtime.sh #{libdir}"
end
end
end
233 changes: 233 additions & 0 deletions configs/projects/_shared-pe-bolt-server_with_ruby.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
# This "project" is a common basis for all pe-bolt-server branches. It should
# not be built on its own. Instead, other project files should load it with
# instance_eval. See configs/projects/pe-bolt-server-runtime-<branchname>.rb
# for branch-specific details.
unless defined?(proj)
warn("'#{File.basename(__FILE__)}' is a set of basic configuration values" \
" shared by all pe-bolt-server projects; It cannot be built as a" \
" standalone project.")
warn("Please choose one of the other pe-bolt-server projects instead.")
exit(1)
end

pe_version = settings[:pe_version]
unless pe_version && !pe_version.empty?
warn("You must set the `pe_version` setting in your pe-bolt-server project" \
" file before instance_eval'ing '#{File.basename(__FILE__)}'. This should" \
" be an x.y version like '2019.1' or similar.")
exit(1)
end

proj.description('The PE Bolt runtime contains third-party components needed for PE Bolt server packaging')
proj.license('See components')
proj.vendor('Puppet, Inc. <info@puppet.com>')
proj.homepage('https://puppet.com')
proj.identifier('com.puppetlabs')
proj.version_from_git
proj.generate_archives(true)
proj.generate_packages(false)

proj.setting(:artifactory_url, "https://artifactory.delivery.puppetlabs.net/artifactory")
proj.setting(:buildsources_url, "#{proj.artifactory_url}/generic/buildsources")

# This setting can be used sparingly in component configurations to conditionally include dependencies:
proj.setting(:runtime_project, 'pe-bolt-server')

# Ruby + OpenSSL included with bolt-server
# --------------------------------------------
#
# Starting with pe-bolt-server packages installed next to Puppet 8
# pe-bolt-server now vendors its own ruby and openssl installation.
#
# FOR FUTURE REFERENCE:
#
# Somehow only one gem needed updates in the whole gamut of gems installed for
# bolt to get the build order right, so in case we add a gem in the future or
# the house of cards that is the build order falls down: Ruby needs to build
# first before all the gems (duh) but you have to tell vanagon about that or the
# gems may attempt to build first.
#
# If that happens (the gem tries to build first) add the following to the gem's
# component file:
#
# ruby_version ||= settings[:ruby_version]
# builtin_ruby ||= settings[:builtin_ruby]
# if builtin_ruby
# pkg.build_requires "ruby-#{ruby_version}"
# end
#
# and the component will successfully build after ruby
proj.setting(:builtin_ruby, true)

# Set desired versions for gem components that offer multiple versions:
# TODO: Can runtime projects use these updated versions?
proj.setting(:rubygem_deep_merge_version, '1.2.2')
proj.setting(:rubygem_net_ssh_version, '7.0.1')

# (pe-bolt-server does not run on Windows, so only the *nix path is here)
proj.setting(:prefix, '/opt/puppetlabs/server/apps/bolt-server')
proj.setting(:bindir, File.join(proj.prefix, 'bin'))
proj.setting(:libdir, File.join(proj.prefix, 'lib'))
proj.setting(:includedir, File.join(proj.prefix, "include"))

# proj.ruby_dir needs to be set by the individual versions of pe-bolt-server-runtime. Bolt-Server versions running
# alongside puppet 8 and later use their own ruby instead of the agent's.
proj.setting(:ruby_dir, proj.prefix)
proj.setting(:ruby_bindir, File.join(proj.ruby_dir, 'bin'))
proj.setting(:host_ruby, File.join(proj.ruby_bindir, 'ruby'))
proj.setting(:host_gem, File.join(proj.ruby_bindir, 'gem'))
proj.setting(:gem_build, "#{proj.host_gem} build")

# We build bolt server with the ruby installed in the puppet-agent dep. For ruby 2.7 we need to use a --no-document flag
# for gem installs instead of --no-ri --no-rdoc. This setting allows us to use this while we support both ruby 2.5 and 2.7
# Once we are no longer using ruby 2.5 we can update.
if proj.no_doc
proj.setting(:gem_install, "#{proj.host_gem} install --no-document --local --bindir=#{proj.bindir}")
else
proj.setting(:gem_install, "#{proj.host_gem} install --no-rdoc --no-ri --local --bindir=#{proj.bindir}")
end


proj.setting(:datadir, File.join(proj.prefix, "share"))
proj.setting(:mandir, File.join(proj.datadir, "man"))

ruby_base_version = proj.ruby_version.gsub(/(\d+)\.(\d+)\.(\d+)/, '\1.\2.0')
proj.setting(:gem_home, File.join(proj.libdir, 'ruby', 'gems', ruby_base_version))

# Define default CFLAGS and LDFLAGS for most platforms, and then
# tweak or adjust them as needed.
proj.setting(:cppflags, "-I#{proj.includedir} -I/opt/pl-build-tools/include")
proj.setting(:cflags, "#{proj.cppflags}")
proj.setting(:ldflags, "-L#{proj.libdir} -L/opt/pl-build-tools/lib -Wl,-rpath=#{proj.libdir}")

# Platform specific overrides or settings, which may override the defaults

# Harden Linux ELF binaries by compiling with PIE (Position Independent Executables) support,
# stack canary and full RELRO.
# We only do this on platforms that use their default OS toolchain since pl-gcc versions
# are too old to support these flags.
if platform.name =~ /sles-15|el-8|debian-10/ || platform.is_fedora?
proj.setting(:cppflags, "-I#{proj.includedir} -D_FORTIFY_SOURCE=2")
proj.setting(:cflags, '-fstack-protector-strong -fno-plt -O2')
proj.setting(:ldflags, "-L#{proj.libdir} -Wl,-rpath=#{proj.libdir},-z,relro,-z,now")
end

# Required to build ruby
proj.component 'libffi'
proj.component 'libyaml'

# Actually include the openssl/ruby components. Must be done after loading
# the shared bolt-server file
proj.component "openssl-#{proj.openssl_version}"
proj.component "ruby-#{proj.ruby_version}"

# What to build?
# --------------

# This component installs the puppet-agent build dependency:
proj.component('runtime-pe-bolt-server')

# R10k dependencies
proj.component('rubygem-gettext-setup')

# Puppet dependencies
proj.component 'rubygem-deep_merge'
proj.component 'rubygem-text'
proj.component 'rubygem-locale'
proj.component 'rubygem-gettext'
proj.component 'rubygem-fast_gettext'
proj.component 'rubygem-semantic_puppet'

# hiera-eyaml and its dependencies
proj.component('rubygem-highline')
proj.component('rubygem-optimist')
proj.component('rubygem-hiera-eyaml')

# faraday and its dependencies
proj.component('rubygem-faraday')
proj.component('rubygem-faraday-em_http')
proj.component('rubygem-faraday-em_synchrony')
proj.component('rubygem-faraday-excon')
proj.component('rubygem-faraday-httpclient')
proj.component('rubygem-faraday-multipart')
proj.component('rubygem-faraday-net_http')
proj.component('rubygem-faraday-net_http_persistent')
proj.component('rubygem-faraday-patron')
proj.component('rubygem-faraday-rack')
proj.component('rubygem-faraday-retry')
proj.component('rubygem-faraday_middleware')
proj.component('rubygem-ruby2_keywords')

# Core dependencies
proj.component('rubygem-addressable')
proj.component('rubygem-aws-eventstream')
proj.component('rubygem-aws-partitions')
proj.component('rubygem-aws-sdk-core')
proj.component('rubygem-aws-sdk-ec2')
proj.component('rubygem-aws-sigv4')
proj.component('rubygem-bcrypt_pbkdf')
proj.component('rubygem-bindata')
proj.component('rubygem-builder')
proj.component('rubygem-CFPropertyList')
proj.component('rubygem-colored2')
proj.component('rubygem-concurrent-ruby')
proj.component('rubygem-connection_pool')
proj.component('rubygem-cri')
proj.component('rubygem-ed25519')
proj.component('rubygem-erubi')
proj.component('rubygem-facter')
proj.component('rubygem-ffi')
proj.component('rubygem-gssapi')
proj.component('rubygem-gyoku')
proj.component('rubygem-hiera')
proj.component('rubygem-hocon')
proj.component('rubygem-httpclient')
proj.component('rubygem-jmespath')
proj.component('rubygem-jwt')
proj.component('rubygem-little-plugger')
proj.component('rubygem-log4r')
proj.component('rubygem-logging')
proj.component('rubygem-minitar')
proj.component('rubygem-molinillo')
proj.component('rubygem-multi_json')
proj.component('rubygem-multipart-post')
proj.component('rubygem-net-http-persistent')
proj.component('rubygem-net-scp')
proj.component('rubygem-net-ssh')
proj.component('rubygem-net-ssh-krb')
proj.component('rubygem-nori')
proj.component('rubygem-orchestrator_client')
proj.component('rubygem-public_suffix')
proj.component('rubygem-paint')
proj.component('rubygem-puppet')
proj.component('rubygem-puppet_forge')
proj.component('rubygem-puppet-resource_api')
proj.component('rubygem-puppet-strings')
proj.component('rubygem-puppetfile-resolver')
proj.component('rubygem-r10k')
proj.component('rubygem-rgen')
proj.component('rubygem-rubyntlm')
proj.component('rubygem-ruby_smb')
proj.component('rubygem-rubyzip')
proj.component('rubygem-scanf')
proj.component('rubygem-terminal-table')
proj.component('rubygem-thor')
proj.component('rubygem-unicode-display_width')
proj.component('rubygem-webrick')
proj.component('rubygem-yard')

# Core Windows dependencies
proj.component('rubygem-windows_error')
proj.component('rubygem-winrm')
proj.component('rubygem-winrm-fs')

# Export the settings for the current project and platform as yaml during builds
proj.publish_yaml_settings

if platform.name =~ /^el-(8)-.*/
# Disable build-id generation since it's currently generating conflicts
# with system libgcc and libstdc++
proj.package_override("# Disable build-id generation to avoid conflicts\n%global _build_id_links none")
end

proj.directory(proj.prefix)
6 changes: 5 additions & 1 deletion configs/projects/pe-bolt-server-runtime-main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
# Once we are no longer using ruby 2.5 we can update.
proj.setting(:no_doc, true)

instance_eval File.read(File.join(File.dirname(__FILE__), '_shared-pe-bolt-server.rb'))
proj.setting(:ruby_version, '3.2.2')
proj.setting(:openssl_version, '3.0')

instance_eval File.read(File.join(File.dirname(__FILE__), '_shared-pe-bolt-server_with_ruby.rb'))

# TODO: Work around PE-36078 by using forked non-optimal solution
proj.component('rubygem-rubyntlm-fork')
proj.component 'rubygem-prime'
Expand Down

0 comments on commit 329c23d

Please sign in to comment.