Class: Highlander::Compiler::LambdaResolver

Inherits:
Object
  • Object
show all
Defined in:
lib/highlander.compiler.rb

Instance Method Summary collapse

Constructor Details

#initialize(component, lambda_key, workdir, confirm_code_execution = true) ⇒ LambdaResolver

Returns a new instance of LambdaResolver.



192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/highlander.compiler.rb', line 192

def initialize(component, lambda_key, workdir, confirm_code_execution = true)
  @component = component
  @lambda_config = @component.config[lambda_key]
  @component_dir = @component.component_dir
  @workdir = workdir
  @metadata = {
      'path' => {},
      'sha256' => {},
      'version' => {}
  }
  @confirm_code_execution = confirm_code_execution
end

Instance Method Details

#generateSourceArchives ⇒ Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# File 'lib/highlander.compiler.rb', line 205

def generateSourceArchives

  # Clear previous packages
  FileUtils.rmtree "#{@workdir}/output/lambdas"

  archive_paths = []

  # Cached downloads map
  cached_downloads = {}
  @lambda_config['functions'].each do |name, lambda_config|
    # create folder
    out_folder = "#{@workdir}/out/lambdas/"
    timestamp = Time.now.utc.to_i.to_s
    file_name = "#{name}.#{@component.name}.#{@component.version}.#{timestamp}.zip"
    @metadata['path'][name] = file_name
    full_destination_path = "#{out_folder}#{file_name}"
    archive_paths << full_destination_path
    FileUtils.mkdir_p out_folder
    # clear destination if already there
    FileUtils.remove full_destination_path if File.exist? full_destination_path

    # download file if code remote archive
    puts "Packaging AWS Lambda function #{name}...\n"
    if lambda_config['code'].include? 'http'
      md5 = Digest::MD5.new
      md5.update lambda_config['code']
      hash = md5.hexdigest
      cached_location = "#{@workdir}/.cache/lambdas/#{hash}"
      if cached_downloads.key? lambda_config['code']
        puts "Using already downloaded archive #{lambda_config['code']}"
        FileUtils.copy(cached_downloads[lambda_config['code']], full_destination_path)
      elsif File.file? cached_location
        puts "Using cached download - '#{cached_location}'"
        FileUtils.copy(cached_location, "#{out_folder}/src.zip")
      else
        puts "Downloading file #{lambda_config['code']} ..."
        download = open(lambda_config['code'])
        IO.copy_stream(download, "#{out_folder}/src.zip")
        FileUtils.mkdir_p('.cache/lambdas')
        FileUtils.copy("#{out_folder}/src.zip", cached_location)
        puts "Download complete, caching in #{cached_location}"
        cached_downloads[lambda_config['code']] = cached_location
      end
    else
      # zip local code
      zip_options = ''
      full_path = "#{@component_dir}/lambdas/#{lambda_config['code']}"

      # lambda source can be either path to file or directory within that file
      # optionally, lambda source code
      lambda_source_dir = File.dirname(full_path)
      lambda_source_file = File.basename(full_path)
      lambda_source_file = '.' if Pathname.new(full_path).directory?
      lambda_source_dir = full_path if Pathname.new(full_path).directory?

      # executing package command can generate files. We DO NOT want this file in source directory,
      # but rather in intermediate directory
      tmp_source_dir = "#{@workdir}/out/lambdas/tmp/#{name}"
      FileUtils.mkpath(File.dirname(tmp_source_dir))
      FileUtils.copy_entry(lambda_source_dir, tmp_source_dir)
      lambda_source_dir = tmp_source_dir

      # Lambda function source code allows pre-processing (e.g. install code dependencies)
      unless lambda_config['package_cmd'].nil?
        puts "Following code will be executed to generate lambda function #{name}:\n\n#{lambda_config['package_cmd']}\n\n"

        if @confirm_code_execution
          exit -7 unless HighLine.agree('Proceed (y/n)?')
        end

        package_cmd = "cd #{lambda_source_dir} && #{lambda_config['package_cmd']}"
        puts 'Processing package command...'
        package_result = system(package_cmd)
        unless package_result
          puts "Error packaging lambda function, following command failed\n\n#{package_cmd}\n\n"
          exit -4
        end
      end
      File.delete full_destination_path if File.exist? full_destination_path
      zip_generator = Highlander::Util::ZipFileGenerator.new(lambda_source_dir, full_destination_path)
      zip_generator.write

    end

    sha256 = Digest::SHA256.file full_destination_path
    sha256 = sha256.base64digest
    puts "Created zip package #{full_destination_path} for lambda #{name} with digest #{sha256}"
    @metadata['sha256'][name] = sha256
    @metadata['version'][name] = timestamp
  end

  return archive_paths
end

#mergeComponentConfig ⇒ Object



299
300
301
# File 'lib/highlander.compiler.rb', line 299

def mergeComponentConfig
  @component.config['lambda_metadata'] = @metadata
end