Class: Lono::AppFile::Build::LambdaLayer::RubyPackager
- Inherits:
-
Object
- Object
- Lono::AppFile::Build::LambdaLayer::RubyPackager
- Defined in:
- lib/lono/app_file/build/lambda_layer/ruby_packager.rb
Overview
Based on jets
Constant Summary collapse
- @@rsync_installed =
false
Instance Method Summary collapse
- #build ⇒ Object
- #build_area ⇒ Object
-
#bundle_install ⇒ Object
Installs gems on the current target system: both compiled and non-compiled.
- #cache_area ⇒ Object
- #check_rsync_installed! ⇒ Object
-
#consolidate_gems_to_opt ⇒ Object
Also restructure the folder from: vendor/gems/ruby/2.5.0 To: ruby/gems/2.5.0.
- #copy_back_gemfile_lock ⇒ Object
- #gemfile_exist? ⇒ Boolean
-
#initialize(blueprint, registry_item) ⇒ RubyPackager
constructor
A new instance of RubyPackager.
- #opt_area ⇒ Object
- #output_area ⇒ Object
-
#package ⇒ Object
We consolidate all gems to opt.
-
#remove_bundled_with(gemfile_lock) ⇒ Object
Remove the BUNDLED WITH line since we don’t control the bundler gem version on AWS Lambda And this can cause issues with require ‘bundler/setup’.
- #rsync(src, dest) ⇒ Object
- #rsync_and_link(src, dest) ⇒ Object
- #ruby_folder ⇒ Object
- #setup_bundle_config(dir) ⇒ Object
- #sh(command) ⇒ Object
Constructor Details
#initialize(blueprint, registry_item) ⇒ RubyPackager
Returns a new instance of RubyPackager.
6 7 8 9 10 11 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 6 def initialize(blueprint, registry_item) @blueprint, @registry_item = blueprint, registry_item @registry_name = @registry_item.name.sub(/\/$/,'') @app_root = "#{Lono.blueprint_root}/app/files/#{@registry_name}" end |
Instance Method Details
#build ⇒ Object
13 14 15 16 17 18 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 13 def build return unless gemfile_exist? bundle_install package end |
#build_area ⇒ Object
144 145 146 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 144 def build_area "#{Lono.config.output_path}/#{@blueprint}/lambda_layers/#{@registry_name}" end |
#bundle_install ⇒ Object
Installs gems on the current target system: both compiled and non-compiled. If user is on a macosx machine, macosx gems will be installed. If user is on a linux machine, linux gems will be installed.
Copies Gemfile* to /tmp/jets/demo/cache folder and installs gems with bundle install from there.
We take the time to copy Gemfile and bundle into a separate directory because it gets left around to act as a ‘cache’. So, when the builds the project gets built again not all the gems from get installed from the beginning.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 70 def bundle_install puts "Bundling: running bundle install in cache area: #{cache_area}." rsync(output_area, cache_area) # Uncomment out to always remove the cache/vendor/gems to debug # FileUtils.rm_rf("#{cache_area}/vendor/gems") # Remove .bundle folder so .bundle/config doesnt affect how gems are packages # Not using BUNDLE_IGNORE_CONFIG=1 to allow home ~/.bundle/config to affect bundling though. # This is useful if you have private gems sources that require authentication. Example: # # bundle config gems.myprivatesource.com user:pass # FileUtils.rm_rf("#{cache_area}/.bundle") require "bundler" # dynamically require bundler so user can use any bundler setup_bundle_config(cache_area) Bundler.with_unbundled_env do sh "cd #{cache_area} && env bundle install" end remove_bundled_with("#{cache_area}/Gemfile.lock") # Copy the Gemfile.lock back to the project in case it was updated. # For example we add the jets-rails to the Gemfile. copy_back_gemfile_lock puts 'Bundle install success.' end |
#cache_area ⇒ Object
148 149 150 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 148 def cache_area "#{build_area}/cache" end |
#check_rsync_installed! ⇒ Object
183 184 185 186 187 188 189 190 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 183 def check_rsync_installed! return if @@rsync_installed # only check once if system "type rsync > /dev/null 2>&1" @@rsync_installed = true else raise "ERROR: Rsync is required. Rsync does not seem to be installed.".color(:red) end end |
#consolidate_gems_to_opt ⇒ Object
Also restructure the folder from:
vendor/gems/ruby/2.5.0
To:
ruby/gems/2.5.0
For Lambda Layer structure
33 34 35 36 37 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 33 def consolidate_gems_to_opt src = "#{cache_area}/vendor/gems/ruby/#{ruby_folder}" dest = "#{opt_area}/ruby/gems/#{ruby_folder}" rsync_and_link(src, dest) end |
#copy_back_gemfile_lock ⇒ Object
123 124 125 126 127 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 123 def copy_back_gemfile_lock src = "#{cache_area}/Gemfile.lock" dest = "#{@app_root}/Gemfile.lock" FileUtils.cp(src, dest) end |
#gemfile_exist? ⇒ Boolean
156 157 158 159 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 156 def gemfile_exist? gemfile_path = "#{@app_root}/Gemfile" File.exist?(gemfile_path) end |
#opt_area ⇒ Object
152 153 154 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 152 def opt_area "#{build_area}/opt" end |
#output_area ⇒ Object
140 141 142 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 140 def output_area "#{Lono.config.output_path}/#{@blueprint}/files/#{@registry_name}" end |
#package ⇒ Object
We consolidate all gems to opt
21 22 23 24 25 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 21 def package setup_bundle_config(output_area) # copy_cache_gems # TODO: might not need this cache consolidate_gems_to_opt end |
#remove_bundled_with(gemfile_lock) ⇒ Object
Remove the BUNDLED WITH line since we don’t control the bundler gem version on AWS Lambda And this can cause issues with require ‘bundler/setup’
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 103 def remove_bundled_with(gemfile_lock) lines = IO.readlines(gemfile_lock) # amount is the number of lines to remove new_lines, capture, count, amount = [], true, 0, 2 lines.each do |l| capture = false if l.include?('BUNDLED WITH') if capture new_lines << l end if capture == false count += 1 capture = count > amount # renable capture end end content = new_lines.join('') IO.write(gemfile_lock, content) end |
#rsync(src, dest) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 170 def rsync(src, dest) # Using FileUtils.cp_r doesnt work if there are special files like socket files in the src dir. # Instead of using this hack https://bugs.ruby-lang.org/issues/10104 # Using rsync to perform the copy. src.chop! if src.ends_with?('/') dest.chop! if dest.ends_with?('/') check_rsync_installed! # Ensures required trailing slashes FileUtils.mkdir_p(File.dirname(dest)) sh "rsync -a --links --no-specials --no-devices #{Shellwords.escape(src)}/ #{Shellwords.escape(dest)}/" end |
#rsync_and_link(src, dest) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 39 def rsync_and_link(src, dest) FileUtils.mkdir_p(dest) rsync(src, dest) # create symlink in output path not the cache path symlink_dest = "#{output_area}/vendor/gems/ruby/#{ruby_folder}" puts "symlink_dest #{symlink_dest}" FileUtils.rm_rf(symlink_dest) # blow away original 2.5.0 folder # Create symlink that will point to the gems in the Lambda Layer: # stage/opt/ruby/gems/2.5.0 -> /opt/ruby/gems/2.5.0 FileUtils.mkdir_p(File.dirname(symlink_dest)) FileUtils.ln_sf("/opt/ruby/gems/#{ruby_folder}", symlink_dest) end |
#ruby_folder ⇒ Object
54 55 56 57 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 54 def ruby_folder major, minor, _ = RUBY_VERSION.split('.') [major, minor, '0'].join('.') # 2.5.1 => 2.5.0 end |
#setup_bundle_config(dir) ⇒ Object
129 130 131 132 133 134 135 136 137 138 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 129 def setup_bundle_config(dir) text ="---\nBUNDLE_PATH: \"vendor/gems\"\nBUNDLE_WITHOUT: \"development:test\"\n" bundle_config = "#{dir}/.bundle/config" FileUtils.mkdir_p(File.dirname(bundle_config)) IO.write(bundle_config, text) end |
#sh(command) ⇒ Object
161 162 163 164 165 166 167 168 |
# File 'lib/lono/app_file/build/lambda_layer/ruby_packager.rb', line 161 def sh(command) puts "=> #{command}" out = `#{command}` puts out if ENV['LONO_DEBUG_LAMBDA_LAYER'] success = $?.success? raise("ERROR: running command #{command}").color(:red) unless success success end |