You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

98 lines
3.2 KiB

4 years ago
require "bento/common"
require "bento/buildmetadata"
require "bento/providermetadata"
require "bento/packerexec"
class BuildRunner
include Common
include PackerExec
attr_reader :template_files, :config, :dry_run, :debug, :only, :except, :mirror, :headed, :single,
:override_version, :build_timestamp, :cpus, :mem
def initialize(opts)
@template_files = opts.template_files
@config = opts.config ||= false
@dry_run = opts.dry_run
@debug = opts.debug
@only = opts.only ||= "parallels-iso,virtualbox-iso,vmware-iso"
@except = opts.except
@mirror = opts.mirror
@headed = opts.headed ||= false
@single = opts.single ||= false
@override_version = opts.override_version
@build_timestamp = Time.now.gmtime.strftime("%Y%m%d%H%M%S")
@cpus = opts.cpus
@mem = opts.mem
end
def start
templates = config ? build_list : template_files
banner("Starting build for templates:")
templates.each { |t| puts "- #{t}" }
time = Benchmark.measure do
templates.each { |template| build(template) }
end
banner("Build finished in #{duration(time.real)}.")
end
private
def build(file)
bento_dir = Dir.pwd
dir = File.dirname(file)
template = File.basename(file)
Dir.chdir dir
for_packer_run_with(template) do |md_file, _var_file|
cmd = packer_build_cmd(template, md_file.path)
banner("[#{template}] Building: '#{cmd.join(" ")}'")
time = Benchmark.measure do
system(*cmd) || raise("[#{template}] Error building, exited #{$CHILD_STATUS}")
end
write_final_metadata(template, time.real.ceil)
banner("[#{template}] Finished building in #{duration(time.real)}.")
end
Dir.chdir(bento_dir)
end
def packer_build_cmd(template, var_file)
vars = "#{template}.variables.json"
cmd = %W{packer build -force -var-file=#{var_file} #{template}.json}
cmd.insert(2, "-var-file=#{vars}") if File.exist?(vars)
cmd.insert(2, "-only=#{only}")
cmd.insert(2, "-except=#{except}") if except
# Build the command line in the correct order and without spaces as future input for the splat operator.
cmd.insert(2, "cpus=#{cpus}") if cpus
cmd.insert(2, "-var") if cpus
cmd.insert(2, "memory=#{mem}") if mem
cmd.insert(2, "-var") if mem
cmd.insert(2, "mirror=#{mirror}") if mirror
cmd.insert(2, "-var") if mirror
cmd.insert(2, "headless=true") unless headed
cmd.insert(2, "-var") unless headed
cmd.insert(2, "-parallel=false") if single
cmd.insert(2, "-debug") if debug
cmd.insert(0, "echo") if dry_run
cmd
end
def write_final_metadata(template, buildtime)
md = BuildMetadata.new(template, build_timestamp, override_version).read
path = File.join("../../builds")
filename = File.join(path, "#{md[:box_basename]}.metadata.json")
md[:providers] = ProviderMetadata.new(path, md[:box_basename]).read
md[:providers].each do |p|
p[:build_time] = buildtime
p[:build_cpus] = cpus unless cpus.nil?
p[:build_mem] = mem unless mem.nil?
end
if dry_run
banner("(Dry run) Metadata file contents would be something similar to:")
puts JSON.pretty_generate(md)
else
File.open(filename, "wb") { |file| file.write(JSON.pretty_generate(md)) }
end
end
end