gitian-builder/bin/gbuild

161 lines
4.0 KiB
Plaintext
Raw Normal View History

2011-01-30 21:12:02 +00:00
#!/usr/bin/ruby
require 'optparse'
require 'yaml'
require 'fileutils'
require 'pathname'
@options = {}
def system!(cmd)
system(cmd) or raise "failed to run #{cmd}"
end
def sanitize(str, where)
raise "unsanitary string in #{where}" if (str =~ /[^\w.-]/)
str
end
def info(str)
puts str unless @options[:quiet]
end
OptionParser.new do |opts|
opts.banner = "Usage: build [options] <build-description>.yml"
opts.on("-i", "--skip-image", "reuse current target image") do |v|
@options[:skip_image] = v
end
opts.on("-q", "--quiet", "be quiet") do |v|
@options[:skip_image] = v
end
end.parse!
base_dir = Pathname.new(__FILE__).expand_path.dirname.parent
libexec_dir = base_dir + 'libexec'
ENV['PATH'] = libexec_dir.to_s + ":" + ENV['PATH']
ENV['GITIAN_BASE'] = base_dir.to_s
build_desc_file = ARGV.shift or raise "must supply YAML build description file"
in_sums = []
build_desc = YAML.load_file(build_desc_file)
package_name = build_desc["name"] or raise "must supply name"
package_name = sanitize(package_name, "package name")
desc_sum = `sha256sum #{build_desc_file}`
desc_sum = desc_sum.sub(build_desc_file, "#{package_name}-desc.yml")
in_sums << desc_sum
reference_datetime = build_desc["reference_datetime"] or raise "must supply reference_datetime"
build_dir = 'build'
result_dir = 'result'
FileUtils.rm_rf(build_dir)
FileUtils.mkdir(build_dir)
FileUtils.mkdir_p(result_dir)
info "Stopping target if it is up"
system "stop-target"
sleep 1
unless @options[:skip_image]
info "Making a new image copy"
system! "cp base.qcow2 target.qcow2"
end
info "Starting target"
system! "start-target &"
$stdout.write "Checking if target is up"
(1..10).each do
system "on-target true 2> /dev/null" and break
sleep 2
$stdout.write '.'
end
info ''
system! "on-target true"
info "Preparing build environment"
system! "on-target bash < target-bin/init-build.sh"
build_desc["files"].each do |filename|
filename = sanitize(filename, "files section")
2011-01-30 23:31:33 +00:00
system! "cd inputs && copy-to-target #{filename} build/"
in_sums << `cd inputs && sha256sum #{filename}`
2011-01-30 21:12:02 +00:00
end
2011-01-30 23:31:33 +00:00
info "Installing additional packages (log in var/install.log)"
system! "on-target -u root apt-get -y install #{build_desc["packages"].join(" ")} > var/install.log 2>&1"
info "Grabbing package manifest"
system! "on-target -u root bash < target-bin/grab-packages.sh > var/base.manifest"
2011-01-30 21:12:02 +00:00
info "Creating build script (var/build-script)"
File.open("var/build-script", "w") do |script|
script.puts "#!/bin/bash"
script.puts "set -e"
script.puts "export OUTDIR=$HOME/out"
script.puts "MAKEOPTS=(-j2)"
(ref_date, ref_time) = reference_datetime.split
script.puts "REFERENCE_DATETIME='#{reference_datetime}'"
script.puts "REFERENCE_DATE='#{ref_date}'"
script.puts "REFERENCE_TIME='#{ref_time}'"
script.puts
build_desc["remotes"].each do |remote|
script.puts "git clone -q #{remote["url"]} build/#{remote["dir"]}"
2011-01-30 23:31:33 +00:00
script.puts "(cd build/#{remote["dir"]} && git checkout -q #{remote["commit"]})"
2011-01-30 21:12:02 +00:00
end
script.puts "cd build"
script.puts build_desc["script"]
end
info "Running build script (log in var/build.log)"
system! "on-target bash < var/build-script > var/build.log 2>&1"
info "Grabbing results"
system! "copy-from-target out #{build_dir}"
out_dir = File.join(build_dir, "out")
out_sums = {}
info "Generating report"
Dir.new(out_dir).each do |file|
next if file.start_with?(".")
file = sanitize(file, out_dir)
2011-01-30 23:31:33 +00:00
out_sums[file] = `cd #{out_dir} && sha256sum #{file}`
2011-01-30 21:12:02 +00:00
raise "failed to sum #{file}" unless $? == 0
puts out_sums[file] unless @options[:quiet]
end
out_manifest = out_sums.keys.sort.map { |key| out_sums[key] }.join('')
base_manifest = File.read('var/base.manifest')
in_manifest = in_sums.join('')
# Use Omap to keep result deterministic
report = YAML::Omap[
'out_manifest', out_manifest,
'in_manifest', in_manifest,
'base_manifest', base_manifest,
]
result_file = "#{package_name}-res.yml"
File.open(File.join(result_dir, result_file), "w") do |io|
io.write report.to_yaml
end
2011-01-30 23:31:33 +00:00
system!("cd #{result_dir} && sha256sum #{result_file}") unless @options[:quiet]
2011-01-30 21:12:02 +00:00
info "Done."