class Builderator::Tasks::Packer
Wrap Packer
commands
Public Class Methods
exit_on_failure?()
click to toggle source
# File lib/builderator/tasks/packer.rb, line 17 def self.exit_on_failure? true end
Public Instance Methods
build(profile = :default, *args)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 32 def build(profile = :default, *args) invoke :configure, [profile], options run_with_input "#{Interface.packer.command} build #{options['debug'] ? '-debug -on-error=abort' : ''} - #{args.join('')}", Interface.packer.render end
configure(profile = :default)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 24 def configure(profile = :default) Config.profile.use(profile) invoke Tasks::Version, :current, [], options puts Interface.packer.render if options['debug'] end
copy(profile)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 38 def copy(profile) invoke :configure, [profile], options images.each do |image_name, (image, build)| parameters = { :source_region => Config.aws.region, :source_image_id => image.image_id, :name => image_name, :description => image.description } build.ami_regions.each do |region| say_status :copy, "image #{image_name} (#{image.image_id}) from #{Config.aws.region} to #{region}" copy_image(region, parameters) end end invoke :wait, [profile], options invoke :tag, [profile], options invoke :share, [profile], options end
remote_tag(profile)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 124 def remote_tag(profile) invoke :configure, [profile], options allowed_cred_keys = %w(access_key_id secret_access_key session_token) images.each do |image_name, (image, build)| ami_regions = build.ami_regions ami_regions << Config.aws.region ami_regions.uniq! ami_regions.each do |region| sts_client = Aws::STS::Client.new(region: region) if build.tagging_role.nil? say_status :complete, 'No remote tagging to be performed as no IAM role is defined' return end regional_image = find_image(region, image_name) build.ami_users.each do |account| role_arn = "arn:aws:iam::#{account}:role/#{build.tagging_role}" begin response = sts_client.assume_role( :role_arn => role_arn, :role_session_name => "tag-new-ami") raise "Could not assume role [#{role_arn}]. Perhaps it does not exist?" unless response.successful? rescue => e say_status :skip, "Got error when trying to assume role: #{e.message} - continuing." next end creds_hash = response.credentials.to_h.keep_if { |k,v| allowed_cred_keys.include?(k.to_s) } say_status :remote_tag, "Tag AMI #{image_name} (#{regional_image.image_id}) in #{region} (#{account})" Util.ec2(region, creds_hash) .create_tags(:dry_run => false, :resources => [regional_image.image_id], :tags => image.tags) end end end say_status :complete, 'Remote tagging complete' end
tag(profile)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 61 def tag(profile) invoke :configure, [profile], options images.each do |image_name, (image, build)| ## Add some additional tags about the regional source image.tags << { :key => 'source_region', :value => Config.aws.region } image.tags << { :key => 'source_ami', :value => image.image_id } build.ami_regions.each do |region| regional_image = find_image(region, image_name) say_status :tag, "AMI #{image_name} (#{regional_image.image_id}) in #{region}" Util.ec2(region).create_tags(:resources => [regional_image.image_id], :tags => image.tags) end end end
wait(profile)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 85 def wait(profile) invoke :configure, [profile], options waiting = true images.each do |image_name, (image, build)| say_status :wait, "for #{image.image_id} (#{image_name}) to be available in #{build.ami_regions.join(', ')}", :yellow end while waiting waiting = false images.each do |image_name, (image, build)| build.ami_regions.each do |region| regional_image = find_image(region, image_name) ## It takes a few seconds for the new AMI to show up in the `describe_images` response-set state = regional_image.nil? ? 'unknown' : regional_image.state image_id = regional_image.nil? ? 'unknown' : regional_image.image_id waiting = (state != 'available') || waiting status_color = case state when 'pending', 'unknown' then :yellow when 'available' then :green else :red end say_status :image, "#{image_id} (#{image.name}) is #{state} in #{region}", status_color end end ## If waiting == false, loop immediately to break sleep(20) if waiting end say_status :complete, 'All copied images are available' end
Private Instance Methods
copy_image(region, params)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 211 def copy_image(region, params) Retryable.retryable(:sleep => lambda { |n| 4**n }, :tries => 4, :on => [Aws::EC2::Errors::ServiceError]) do |retries, _| say_status :error, 'Error copying image', :red if retries > 0 Util.ec2(region).copy_image(params) end end
find_image(region, image_name)
click to toggle source
# File lib/builderator/tasks/packer.rb, line 218 def find_image(region, image_name) filters = [{ :name => 'name', :values => [image_name] }] image = nil Retryable.retryable(:sleep => lambda { |n| 4**n }, :tries => 4, :on => [Aws::EC2::Errors::ServiceError]) do |retries, _| say_status :error, 'Error finding image', :red if retries > 0 image = Util.ec2(region).describe_images(:filters => filters).images.first end image end
images()
click to toggle source
Find details for generated images in current region
# File lib/builderator/tasks/packer.rb, line 201 def images Retryable.retryable(:sleep => lambda { |n| 4**n }, :tries => 4, :on => [NoMethodError]) do |retries, _| @images ||= Config.profile.current.packer.build.each_with_object({}) do |(_, build), memo| memo[build.ami_name] = [Control::Data.lookup(:image, :name => build.ami_name).first, build] end @images.length # Will throw NoMethodError if no images found; triggers retry end @images end