bottle: make bottle checksums reproducible.

I've set all the variable data to versions that are dependent on the
latest source file date and various modification dates also to the
latest source file date. With this if you rerun `brew bottle`
multiple times in a row you will see the same checksum even if you have
`brew reinstall`ed (as long as upstream does not hardcode e.g. the
build date).

I debugged this with diffoscope and worked on this as part of the
Athens 2015 reproducible builds workshop:
https://reproducible-builds.org/events/athens2015/

Closes Homebrew/homebrew#46587.

Signed-off-by: Mike McQuaid <mike@mikemcquaid.com>
This commit is contained in:
Mike McQuaid 2015-12-15 14:21:27 +00:00
parent e5ba31fcdc
commit 214c865167
2 changed files with 28 additions and 1 deletions

View File

@ -174,6 +174,9 @@ module Homebrew
filename = Bottle::Filename.create(f, bottle_tag, bottle_revision)
bottle_path = Pathname.pwd/filename
tar_filename = filename.to_s.sub(/.gz$/, "")
tar_path = Pathname.pwd/tar_filename
prefix = HOMEBREW_PREFIX.to_s
cellar = HOMEBREW_CELLAR.to_s
@ -183,7 +186,13 @@ module Homebrew
relocatable = false
skip_relocation = false
formula_source_time = f.stable.stage do
Pathname.pwd.to_enum(:find).map(&:mtime).max
end
keg.lock do
original_tab = nil
begin
keg.relocate_install_names prefix, Keg::PREFIX_PLACEHOLDER,
cellar, Keg::CELLAR_PLACEHOLDER
@ -192,10 +201,25 @@ module Homebrew
keg.delete_pyc_files!
tab = Tab.for_keg(keg)
original_tab = tab.dup
empty_tab = Tab.empty
tab["poured_from_bottle"] = empty_tab["poured_from_bottle"]
tab["HEAD"] = empty_tab["HEAD"]
tab["time"] = empty_tab["time"]
tab.write
keg.find {|k| File.utime(File.atime(k), formula_source_time, k) }
cd cellar do
safe_system "tar", "cf", tar_path, "#{f.name}/#{f.pkg_version}"
File.utime(File.atime(tar_path), formula_source_time, tar_path)
relocatable_tar_path = "#{f}-bottle.tar"
mv tar_path, relocatable_tar_path
# Use gzip, faster to compress than bzip2, faster to uncompress than bzip2
# or an uncompressed tarball (and more bandwidth friendly).
safe_system "tar", "czf", bottle_path, "#{f.name}/#{f.pkg_version}"
safe_system "gzip", "-f", relocatable_tar_path
mv "#{relocatable_tar_path}.gz", bottle_path
end
if bottle_path.size > 1*1024*1024
@ -222,6 +246,7 @@ module Homebrew
raise
ensure
ignore_interrupts do
original_tab.write
keg.relocate_install_names Keg::PREFIX_PLACEHOLDER, prefix,
Keg::CELLAR_PLACEHOLDER, cellar
end

View File

@ -741,6 +741,8 @@ class FormulaInstaller
tab.tap = formula.tap
tab.poured_from_bottle = true
tab.time = Time.now.to_i
tab.head = Homebrew.git_head
tab.write
end