From 5c0a32d528fe7f39c5a45831fab4bf07a80ce9ca Mon Sep 17 00:00:00 2001 From: Ryan Moran Date: Tue, 14 Feb 2023 15:55:01 -0800 Subject: [PATCH] Rewrites buildpack entrypoints to install Ruby before executing - the bin/{compile,detect,finalize,release} executables have been wrapped in a small shim that makes sure a Ruby interpreter is available on the PATH before exec-ing the existing buildpack entrypoints - works both online and offline - currently pinned to the latest Ruby 3.1.x version available in the Ruby Buildpack repository --- bin/compile | 28 +------- bin/detect | 36 +--------- bin/finalize | 30 +-------- bin/release | 30 +-------- bin/ruby-run | 50 ++++++++++++++ bin/run | 109 +++++++++++++++++++++++++++++++ config/ruby.yml | 19 ++++++ rakelib/dependency_cache_task.rb | 2 +- 8 files changed, 183 insertions(+), 121 deletions(-) mode change 100755 => 120000 bin/compile mode change 100755 => 120000 bin/detect mode change 100755 => 120000 bin/finalize mode change 100755 => 120000 bin/release create mode 100755 bin/ruby-run create mode 100755 bin/run create mode 100644 config/ruby.yml diff --git a/bin/compile b/bin/compile deleted file mode 100755 index bf6d6650e8..0000000000 --- a/bin/compile +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed 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. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) diff --git a/bin/compile b/bin/compile new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/compile @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/detect b/bin/detect deleted file mode 100755 index c0552f2f3b..0000000000 --- a/bin/detect +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed 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. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', - &:detect).compact - -if components.empty? - abort -else - str = components.join(' ') - puts str.length > 255 ? str.slice(0..251) + '...' : str -end diff --git a/bin/detect b/bin/detect new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/detect @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/finalize b/bin/finalize deleted file mode 100755 index b1d3b95e03..0000000000 --- a/bin/finalize +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed 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. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] -deps_dir = ARGV[2] -index = ARGV[3] - -JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) diff --git a/bin/finalize b/bin/finalize new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/finalize @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/release b/bin/release deleted file mode 100755 index 0882a48d99..0000000000 --- a/bin/release +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -# Cloud Foundry Java Buildpack -# Copyright 2013-2020 the original author or authors. -# -# Licensed 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. - -$stdout.sync = true -$stderr.sync = true -$LOAD_PATH.unshift File.expand_path('../lib', __dir__) - -require 'java_buildpack/buildpack' - -app_dir = ARGV[0] - -output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) - -puts output diff --git a/bin/release b/bin/release new file mode 120000 index 0000000000..84db910f22 --- /dev/null +++ b/bin/release @@ -0,0 +1 @@ +./run \ No newline at end of file diff --git a/bin/ruby-run b/bin/ruby-run new file mode 100755 index 0000000000..598cb27d6a --- /dev/null +++ b/bin/ruby-run @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed 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. + +$stdout.sync = true +$stderr.sync = true +$LOAD_PATH.unshift File.expand_path('../lib', __dir__) +require 'java_buildpack/buildpack' + +case ARGV[0] + when "compile" + app_dir = ARGV[1] + JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Compile failed with exception %s', &:compile) + + when "detect" + app_dir = ARGV[1] + components = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Detect failed with exception %s', + &:detect).compact + if components.empty? + abort + else + str = components.join(' ') + puts str.length > 255 ? str.slice(0..251) + '...' : str + end + + when "finalize" + app_dir = ARGV[1] + deps_dir = ARGV[3] + index = ARGV[4] + JavaBuildpack::Buildpack.with_buildpack(app_dir, deps_dir, index, 'Finalize failed with exception %s', &:compile) + + when "release" + app_dir = ARGV[1] + output = JavaBuildpack::Buildpack.with_buildpack(app_dir, nil, nil, 'Release failed with exception %s', &:release) + puts output +end diff --git a/bin/run b/bin/run new file mode 100755 index 0000000000..c4bd677b81 --- /dev/null +++ b/bin/run @@ -0,0 +1,109 @@ +#!/usr/bin/env bash + +set -e +set -u +set -o pipefail + +BUILDPACK_DIR="$(cd "$(dirname "${0}")/.." && pwd)" +readonly BUILDPACK_DIR + +RUBY_DIR="/tmp/ruby" +readonly RUBY_DIR + +function util::config::lookup() { + sed '/^#/d' < "${BUILDPACK_DIR}/config/ruby.yml" +} + +function util::cache::present() { + if [[ -e "${BUILDPACK_DIR}/resources/cache" ]]; then + return 0 + else + return 1 + fi +} + +function util::index::lookup() { + local repository_root + repository_root="$(grep "repository_root" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + + local uri + uri="${repository_root}/index.yml" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::semver::parse() { + local version major minor patch + version="$(grep "version" <<< "$(util::config::lookup)" | cut -d' ' -f2)" + major="$(cut -d'.' -f1 <<< "${version}")" + minor="$(cut -d'.' -f2 <<< "${version}")" + patch="$(cut -d'.' -f3 <<< "${version}")" + + printf "%s" "${major/+/*}\\.${minor/+/*}\\.${patch/+/*}" +} + +function util::ruby::stream() { + local uri + uri="${1}" + + if util::cache::present; then + local sha + sha="$(printf "%s" "${uri}" | shasum -a 256 | cut -d' ' -f1)" + cat "${BUILDPACK_DIR}/resources/cache/${sha}.cached" + else + curl -ssL "${uri}" + fi +} + +function util::install() { + local index semver + index="$(util::index::lookup)" + semver="$(util::semver::parse)" + + local uri + uri="$(grep "${semver}" <<< "${index}" | head -n 1 | awk '{print $2}')" + + util::ruby::stream "${uri}" | tar xz -C "${RUBY_DIR}" +} + +function util::print::error() { + local message red reset + message="${1}" + red="\033[0;31m" + reset="\033[0;39m" + + echo -e "${red}${message}${reset}" >&2 + exit 1 +} + +function util::environment::setup() { + export PATH="${RUBY_DIR}/bin:${PATH:-}" + export LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export LD_LIBRARY_PATH="${RUBY_DIR}/lib:${LIBRARY_PATH:-}" + export CPATH="${RUBY_DIR}/include:${CPATH:-}" +} + +function main() { + local phase + phase="$(basename "${0}")" + + if [[ "${CF_STACK}" == "cflinuxfs4" ]]; then + if [[ ! -e "${RUBY_DIR}" ]]; then + mkdir -p "${RUBY_DIR}" + + util::install + fi + + util::environment::setup + fi + + exec "${BUILDPACK_DIR}/bin/ruby-run" "${phase}" "${@-}" +} + +main "${@:-}" diff --git a/config/ruby.yml b/config/ruby.yml new file mode 100644 index 0000000000..bb36ccf0e2 --- /dev/null +++ b/config/ruby.yml @@ -0,0 +1,19 @@ +# Cloud Foundry Java Buildpack +# Copyright 2013-2020 the original author or authors. +# +# Licensed 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. + +# Configuration for Ruby +--- +version: 3.1.+ +repository_root: https://raw.githubusercontent.com/cloudfoundry/ruby-buildpack/develop/java-index diff --git a/rakelib/dependency_cache_task.rb b/rakelib/dependency_cache_task.rb index 01a1512a47..3e07630160 100644 --- a/rakelib/dependency_cache_task.rb +++ b/rakelib/dependency_cache_task.rb @@ -119,7 +119,7 @@ def component_ids offline_cache = offline_cache.split(',') (conf << offline_cache).flatten!.uniq! end - conf + conf << "ruby" end def component_configuration(component_id)