Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproducible build #2

Closed
Pesa opened this issue Nov 27, 2019 · 3 comments
Closed

Reproducible build #2

Pesa opened this issue Nov 27, 2019 · 3 comments

Comments

@Pesa
Copy link
Member

Pesa commented Nov 27, 2019

We should make the build process reproducible.

The first problem I've noticed is that app/version/make-version.sh embeds a timestamp in the generated version.go. We should get rid of the timestamp. There may be other sources of non-reproducibility in the build system.

yoursunny added a commit to yoursunny/ndn-dpdk that referenced this issue Dec 19, 2019
@yoursunny
Copy link
Member

Reproducible build is now available for make cmds target, under the following conditions:

  • same version of Ubuntu and apt packages
  • same version/patches of DPDK and SPDK with same configuration
  • same version of Go dependencies: this can be achieved by running make goget at the same time, or copying $GOPATH/src folder
  • same commit of ndn-dpdk codebase, with no "dirty" files
  • same compiler and release mode choices when invoking make cmds

@yoursunny
Copy link
Member

yoursunny commented May 18, 2020

A recent test on commit bdb3761 indicates that the builds are still unreproducible, even on the same machine.

I used the following sequence of commands:

  1. npm install
  2. make
  3. find build -type f | xargs openssl sha256 | sort >1.txt
  4. make clean
  5. make
  6. find build -type f | xargs openssl sha256 | sort >2.txt
  7. diff 1.txt 2.txt

If the builds were reproducible, the last command should have empty output.
Instead, it reports that build/bin/ndnfw-dpdk has a different digest.

To diagnose this issue, I decompiled both programs with objdump -D build/bin/ndnfw-dpdk: https://pastebin.com/Ux0GPqZD
The assembly has difference in the following sections:

  • .note.go.buildid and .note.gnu.build-id: some instructions are different; the symbol per_lcore_gPccDebugString (a global variable) appears, but a large offset like 0x400321 suggests that it may be unrelated
  • ndn-dpdk/strategy/strategy_elf.fastrouteO (and all other strategy ELF objects): one instruction movabs $0xed654aafd,%rcx has a different number in it

buildid is stored in a Go package or binary, and it's supposed to "accurately record a content hash of the file". Therefore, I believe the difference in buildid sections is caused by the difference in strategy sections.

Strategy ELF objects, as produced by clang-8, are the same. Therefore, go-bindata is likely the troublemaker here. I'll see what adjustment can be made to resolve this issue.

@yoursunny yoursunny reopened this May 18, 2020
yoursunny added a commit to yoursunny/ndn-dpdk that referenced this issue Jun 24, 2020
go-bindata by default inserts metadata of binary assets,
which includes file modification time. Setting -nometadata
turns off the metadata, and makes NDN-DPDK builds reproducible.

refs usnistgov#2
@yoursunny
Copy link
Member

Fixed in a0172a0.

It turns out that go-bindata is including metadata for the binary assets, which contains file modification time. Since the strategy ELF objects are freshly compiled, their modification times will differ.
Setting go-bindata -nometadata flag solves this problem.

Due to recent changes in build procedure, find build -type f | xargs openssl sha256 | sort would capture the digest of meson and ninja logs.
Ignoring the difference on these log files, the binary files compiled in two different virtual machines are identical.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants