class Linecook::AmiPacker
Constants
- BUILDER_CONFIG
- CHROOT_COMMANDS
- PACKER_PATH
- PACKER_VERSION
- POST_MOUNT_COMMANDS
- PRE_MOUNT_COMMANDS
- ROOT_DEVICE_MAP
- SOURCE_URL
Public Class Methods
new(config)
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 70 def initialize(config) system("#{packer_path} --version") @hvm = config[:hvm] || true @root_size = config[:root_size] || 10 @region = config[:region] || 'us-east-1' @copy_regions = config[:copy_regions] || [] @accounts = config[:account_ids] || [] @write_txt = Linecook.config[:packager] && Linecook.config[:packager][:ami] && Linecook.config[:packager][:ami][:update_txt] end
Public Instance Methods
package(image, directory)
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 80 def package(image, directory) @image = image kitchen_config = load_config(directory).send(:data).instance_variable_get(:@data) image_config = kitchen_config[:suites].find{ |x| x[:name] == image.name } if image_config && image_config[:packager] packager = image_config[:packager] || {} end conf_file = Tempfile.new("#{@image.id}-packer.json") config = generate_config(packager) conf_file.write(config) conf_file.close output = [] PTY.spawn("sudo #{PACKER_PATH} build -machine-readable #{conf_file.path}") do |stdout, _, _| begin stdout.each do |line| output << line if line =~ /artifact/ tokens = line.split(',') if tokens.length > 4 out = tokens[4].gsub('%!(PACKER_COMMA)', ',') time = DateTime.strptime(tokens[0], '%s').strftime('%c') puts "#{time} | #{out}" else puts "unexpected output format" puts tokens end end rescue Errno::EIO puts "Packer finshed executing" end end extract_amis_from_output(output) ensure conf_file.close conf_file.unlink end
Private Instance Methods
build_provisioner(chroot_commands)
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 150 def build_provisioner(chroot_commands) provisioner = [ { type: 'shell', inline: chroot_commands } ] end
extract_amis_from_output(output)
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 182 def extract_amis_from_output(output) amis = output.grep(/amazon-chroot,artifact,0,id/).first.chomp.split(',')[5].split('%!(PACKER_COMMA)') amis.each do |info_str| ami_info = info_str.split(':') ami_region = ami_info[0] ami_id = ami_info[1] puts "Built #{ami_id} for #{ami_region}" Linecook::Route53.upsert_record(@image.name, ami_id, ami_region) if @write_txt end end
generate_config(packager)
click to toggle source
TO DO: support for multiple accounts, multiple regions code to extract ami name(s) from output
amis = `grep "amazon-ebs,artifact,0,id" packer.log`.chomp.split(',')[5].split('%!(PACKER_COMMA)')
route53 TXT record integration
# File lib/linecook-gem/packager/packer.rb, line 124 def generate_config(packager) packager ||= {} config = { variables: { aws_access_key: Linecook.config[:aws][:access_key], aws_secret_key: Linecook.config[:aws][:secret_key], image_name: "linecook-#{@image.id}", source_image_path: @image.path }, builders: [ BUILDER_CONFIG.merge( ami_users: @accounts, ami_regions: @copy_regions, ami_virtualization_type: virt_type, root_volume_size: @root_size ).deep_merge(packager[:builder] || {}) ], provisioners: build_provisioner(CHROOT_COMMANDS) } unless config[:builders].first[:ami_block_device_mappings].find { |x| x[:device_name] == ROOT_DEVICE_MAP[:device_name] } config[:builders].first[:ami_block_device_mappings].prepend ROOT_DEVICE_MAP end JSON.pretty_generate(config) end
get_packer()
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 170 def get_packer puts "packer too old (<#{PACKER_VERSION}) or not present, getting latest packer" arch = 1.size == 8 ? 'amd64' : '386' FileUtils.rm_f(Dir[File.join(File.dirname(PACKER_PATH), "*")]) path = File.join(File.dirname(PACKER_PATH), 'packer.zip') url = File.join(SOURCE_URL, PACKER_VERSION, "packer_#{PACKER_VERSION}_linux_#{arch}.zip") download(url, path) unzip(path) PACKER_PATH end
packer_path()
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 159 def packer_path @path ||= begin found = File.exists?(PACKER_PATH) ? PACKER_PATH : find_executable('packer') path = if found version = `#{found} --version` Gem::Version.new(version) >= Gem::Version.new(PACKER_VERSION) ? found : nil end path ||= get_packer end end
virt_type()
click to toggle source
# File lib/linecook-gem/packager/packer.rb, line 193 def virt_type @hvm ? 'hvm' : 'paravirtual' end