diff options
author | Robb Kidd <robb@thekidds.org> | 2019-10-01 17:21:09 -0400 |
---|---|---|
committer | Christopher A. Snapp <csnapp@chef.io> | 2020-07-13 10:19:45 -0600 |
commit | a555ea251f8f94df7093e87402187d3644aabdbe (patch) | |
tree | b0d11c7c96031edc1fe0ba5336aa8a63f0b68c44 /habitat | |
parent | 04eac6a86e51d71cdbfbe163ebb70a887c1c9ddb (diff) | |
download | chef-a555ea251f8f94df7093e87402187d3644aabdbe.tar.gz |
refactor Linux hab plan based on lessons from Windows plan
Lots of things changing in here. Let's take them in a possibly weird
order.
* do_prepare()
Move all the settng of build environment ..uh.. settings into the
prepare function. Notable things:
- GEM_HOME is set to a vendor directory under pkg_prefix so that all gem
installs (regardless of bundle install or gem install) will be
installed _there_. Expect to see all gems shipped with chef-client
under this directory.
- Multiple bundle config --local commands. These are executed in a
subshell after changing directory to the CACHE_PATH so that the
bundler configuration will be written out to a `.bundle/config` file
there. bundle commands will be run from this location later, so these
settings become effective for the duration of the build and obviate
the need for a _bundle helper function.
* pkg_bin_dirs=()
Add the `vendor/bin` directory (remember, vendor/ is where gems get
installed, so the binstubs created by the installation will appear here
in vendor/bin/) to the PATH of this package's runtime environment
because there are commands in there people sometimes want to run. They
won't be fast and they might end up with conflicts with gems installed
by the user or by downstream pacakges because they haven't been
appbundled.
* do_setup_environment()
These are environment variables we'll want set to these defaults at
runtime.
- GEM_PATH gets this package's gem installation directory pushed onto it
making the gems available at runtime regardless of whether bundle exec
is used.
- APPBUNDLER_ALLOW_RVM is a flag looked for by the binstubs generated by
appbundler. Setting this to "true" has nothing to do with RVM and
everything to do with asking the appbundled binstub to not wipe out
the carefully constructed `GEM_PATH` from this package and any
possible others that "publish" to the runtime environment that gems
are available within.
- SSL_CERT_FILE - trust the CA cert package from core, by default, but
downstream packages can override this if they like with something
custom.
* do_build()
Life is simpler in the build function now. Build environment is all
setup, so here we:
- bundle install to retrieve dependencies based on the Gemfile+.lock
- run the rake install for the project which builds and installs the
gems whose source are in this repo (chef, chef-bin, chef-config)
- for any gem installed via a git reference, we change to the source
directory and rake install it, too, to install it like any other gem
This results in a clean collection of all the required gems installed
like normal gems under "vendor/gems." With that directory on the
GEM_PATH, we don't need to care about whether the gems were installed by
path reference or via git.
* do_install()
OK. I fibbed about not needing to tell bundler anything else. For
install, we're going to generate the appbundled binstubs that lockdown
the versions of gems required by particular commands. appbundler uses
the project's Gemfile+lock to determine those version, so for the
install actions, we tell bundler via an environment variable that the
Gemfile to work with is over in CACHE_PATH. Then we iterate over the
names of gems we want appbundled binstubs for in this package. Those
will land in pkg_prefix/bin/.
Note: there's nothing to copy here during install because all the gem
install actions were targeting pkg_prefix/vendor so what we would copy
is here already.
* do_after()
Stuff to make the package smaller.
- We don't need the cached .gem artifacts.
- We don't need the cache of git repos retrieved by bundler (those gems
are installed at this point like any other gem.)
- We don't need to ship the gem API documentation. (I imagine we could
change our minds about this later.)
- We don't need the spec tests for all the gems ... except for our own
chef gem which, for Reasons, we keep the spec suite around for
post-build functional testing.
* pkg_deps()
Ruby comes with a version of bundler that works at the moment. We don't
have to risk conflicts between the version of Ruby this package depends
on and the version of Ruby core/bundler was built against.
Signed-off-by: Robb Kidd <robb@thekidds.org>
Signed-off-by: Christopher A. Snapp <csnapp@chef.io>
Diffstat (limited to 'habitat')
-rw-r--r-- | habitat/plan.sh | 137 |
1 files changed, 68 insertions, 69 deletions
diff --git a/habitat/plan.sh b/habitat/plan.sh index 6e113e8a95..967cdd334e 100644 --- a/habitat/plan.sh +++ b/habitat/plan.sh @@ -1,10 +1,13 @@ -pkg_name=chef-infra-client -pkg_origin=chef +_chef_client_ruby="core/ruby27" +pkg_name="chef-infra-client" +pkg_origin="chef" pkg_maintainer="The Chef Maintainers <humans@chef.io>" pkg_description="The Chef Infra Client" pkg_license=('Apache-2.0') -pkg_bin_dirs=(bin) -_chef_client_ruby="core/ruby27" +pkg_bin_dirs=( + bin + vendor/bin +) pkg_build_deps=( core/make core/gcc @@ -52,10 +55,34 @@ do_verify() { return 0 } +do_setup_environment() { + push_runtime_env GEM_PATH "${pkg_prefix}/vendor" + + set_runtime_env APPBUNDLER_ALLOW_RVM "true" # prevent appbundler from clearing out the carefully constructed runtime GEM_PATH + set_runtime_env SSL_CERT_FILE "$(pkg_path_for cacerts)/ssl/cert.pem" + set_runtime_env LANG "en_US.UTF-8" + set_runtime_env LC_CTYPE "en_US.UTF-8" +} + do_prepare() { - export OPENSSL_LIB_DIR=$(pkg_path_for openssl)/lib - export OPENSSL_INCLUDE_DIR=$(pkg_path_for openssl)/include - export SSL_CERT_FILE=$(pkg_path_for cacerts)/ssl/cert.pem + export GEM_HOME="${pkg_prefix}/vendor" + export OPENSSL_LIB_DIR="$(pkg_path_for openssl)/lib" + export OPENSSL_INCLUDE_DIR="$(pkg_path_for openssl)/include" + export SSL_CERT_FILE="$(pkg_path_for cacerts)/ssl/cert.pem" + export CPPFLAGS="${CPPFLAGS} ${CFLAGS}" + + ( cd "$CACHE_PATH" + bundle config --local build.nokogiri "--use-system-libraries \ + --with-zlib-dir=$(pkg_path_for zlib) \ + --with-xslt-dir=$(pkg_path_for libxslt) \ + --with-xml2-include=$(pkg_path_for libxml2)/include/libxml2 \ + --with-xml2-lib=$(pkg_path_for libxml2)/lib" + bundle config --local jobs "$(nproc)" + bundle config --local without server docgen maintenance pry travis integration ci chefstyle + bundle config --local shebang "$(pkg_path_for "$_chef_client_ruby")/bin/ruby" + bundle config --local retry 5 + bundle config --local silence_root_warning 1 + ) build_line "Setting link for /usr/bin/env to 'coreutils'" if [ ! -f /usr/bin/env ]; then @@ -64,58 +91,46 @@ do_prepare() { } do_build() { - local _libxml2_dir - local _libxslt_dir - local _zlib_dir - export CPPFLAGS - export GEM_HOME - export GEM_PATH - export NOKOGIRI_CONFIG - - _libxml2_dir=$(pkg_path_for libxml2) - _libxslt_dir=$(pkg_path_for libxslt) - _zlib_dir=$(pkg_path_for zlib) - - CPPFLAGS="${CPPFLAGS} ${CFLAGS}" - GEM_HOME=${pkg_prefix}/bundle - GEM_PATH=${GEM_HOME} - NOKOGIRI_CONFIG="--use-system-libraries \ - --with-zlib-dir=${_zlib_dir} \ - --with-xslt-dir=${_libxslt_dir} \ - --with-xml2-include=${_libxml2_dir}/include/libxml2 \ - --with-xml2-lib=${_libxml2_dir}/lib" - - build_line "Executing bundle install inside hab-cache path. ($CACHE_PATH/chef-config)" - ( cd "$CACHE_PATH/chef-config" || exit_with "unable to enter hab-cache directory" 1 - bundle config --local build.nokogiri "${NOKOGIRI_CONFIG}" - bundle config --local silence_root_warning 1 - _bundle_install "${pkg_prefix}/bundle" + ( cd "$CACHE_PATH" || exit_with "unable to enter hab-cache directory" 1 + build_line "Installing gem dependencies ..." + bundle install + build_line "Installing this project's gems ..." + bundle exec rake install + for gem in $GEM_HOME/bundler/gems/*; do + ( cd $gem + build_line "Installing gems from git repos properly ..." + rake install + ) + done ) - - build_line "Executing bundle install inside source path. ($SRC_PATH)" - _bundle_install "${pkg_prefix}/bundle" } do_install() { - build_line "Copying directories from source to pkg_prefix" - mkdir -p "${pkg_prefix}/chef" - for dir in bin chef-bin chef-config chef-utils lib chef.gemspec Gemfile Gemfile.lock; do - cp -rv "${SRC_PATH}/${dir}" "${pkg_prefix}/chef/" - done - - # If we generated them on install, bundler thinks our source is in $HAB_CACHE_SOURCE_PATH - build_line "Generating binstubs with the correct path" - ( cd "$pkg_prefix/chef" || exit_with "unable to enter pkg prefix directory" 1 - _bundle_install \ - "${pkg_prefix}/bundle" \ - --local \ - --quiet \ - --binstubs "${pkg_prefix}/bin" + ( cd "$pkg_prefix" || exit_with "unable to enter pkg prefix directory" 1 + export BUNDLE_GEMFILE="${CACHE_PATH}/Gemfile" + build_line "** fixing binstub shebangs" + fix_interpreter "${pkg_prefix}/vendor/bin/*" "$_chef_client_ruby" bin/ruby + export BUNDLE_GEMFILE="${CACHE_PATH}/Gemfile" + for gem in chef-bin chef inspec-core-bin ohai; do + build_line "** generating binstubs for $gem with precise version pins" + appbundler $CACHE_PATH $pkg_prefix/bin $gem + done ) +} - build_line "Fixing bin/ruby and bin/env interpreters" - fix_interpreter "${pkg_prefix}/bin/*" core/coreutils bin/env - fix_interpreter "${pkg_prefix}/bin/*" "$_chef_client_ruby" bin/ruby +do_after() { + build_line "Trimming the fat ..." + + # We don't need the cache of downloaded .gem files ... + rm -r "$pkg_prefix/vendor/cache" + # ... or bundler's cache of git-ref'd gems + rm -r "$pkg_prefix/vendor/bundler" + # We don't need the gem docs. + rm -r "$pkg_prefix/vendor/doc" + # We don't need to ship the test suites for every gem dependency, + # only Chef's for package verification. + find "$pkg_prefix/vendor/gems" -name spec -type d | grep -v "chef-${pkg_version}" \ + | while read spec_dir; do rm -r "$spec_dir"; done } do_end() { @@ -128,19 +143,3 @@ do_end() { do_strip() { return 0 } - -# Helper function to wrap up some repetitive bundle install flags -_bundle_install() { - local path - path="$1" - shift - - bundle install ${*:-} \ - --jobs "$(nproc)" \ - --without development:test:docgen \ - --path "$path" \ - --shebang="$(pkg_path_for "$_chef_client_ruby")/bin/ruby" \ - --no-clean \ - --retry 5 \ - --standalone -} |