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.
97 lines
3.2 KiB
97 lines
3.2 KiB
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
|
|
|