I tried following the instructions for the reproducible build at the link below, using restic-0.8.2.tar.gz https://github.com/restic/builder
I’ve not been able to match the checksums in the official release.
I also notice that if I run the command twice docker run --rm --volume $PWD:/home/build restic/builder build.sh restic-0.8.2.tar.gz
I get a different set of checksums in the output folder from one run to the next.
Can anyone reproduce and confirm this? I’m wondering whether I might have set something up incorrectly.
I’ve just discovered that Go 1.10 changed something and the compiler argument I’m using in build.go to remove the temporary directory from the binary does not work any more. Hm. The binaries will contain the temporary directory several times, which will change with every run:
I just reran this with the new release 0.8.3. My docker image ID is ‘5590a1ad68f3’. I’m not very familiar with using docker. Should that ID exactly match yours?
When I said the checksums differ, I mean that the docker run... command appears to complete successfully, and creates a new directory (with a timestamp name) with a bunch of .bz2 output files. The checksums of those files don’t match the ones downloadable from https://github.com/restic/restic/releases/download/v0.8.3/SHA256SUMS
Also, when I re-run the same command, I again get a different set of checksums in the new directory. That suggests to me that perhaps the timestamp is getting embedded in the builds (so they would never be reproducible). But my lack of familiarity with docker may mean I am mistaken.
The program build.go will create a new GOPATH (e.g. in /tmp/restic-build-630783517) in a temporary directory, and then passes -gcflags -trimpath=/tmp/restic-build-630783517 to the compiler to make it strip the directory prefix and only record relative files in the resulting binary.
In the post above I showed the strings that I found in the binary, which still contains the temp dir.
Since the temp dir is different every time, the binaries will be different.
That makes sense. I’m afraid I don’t know how to fix that.
Just to avoid ambiguity, a small suggestion: maybe in future it would be worth adding a line to the release page specifying which commit from the builder repo should be used to reproduce the build. (I know it would normally be possible to figure out from the timestamps).
Reproducing the build requires a newer build.go, but then you can reproduce the official binaries as follows:
Run a new instance of the builder container:
$ docker run --rm -ti --volume $PWD:/home/build restic/builder
Within the container:
$ wget https://github.com/restic/restic/releases/download/v0.8.3/restic-0.8.3.tar.gz
[...]
$ tar xfz restic-0.8.3.tar.gz
$ cd restic-0.8.3
$ rm build.go
$ wget https://raw.githubusercontent.com/restic/restic/master/build.go
[...]
$ go run build.go --tempdir /tmp/restic-build-413028034 --goos linux --goarch amd64 -o restic_0.8.3_linux_amd64
$ bzip2 restic_0.8.3_linux_amd64
$ wget https://github.com/restic/restic/releases/download/v0.8.3/SHA256SUMS
[...]
$ sha256sum -c SHA256SUMS
[...]
restic_0.8.3_linux_amd64.bz2: OK
[...]
You could also patch build.sh to pass exactly this temp dir to build.go, to get the other files. Please note that the tempdir is different for each OS and architecture build of restic.
I’ve fixed build.go so that it correctly generates easily reproducible binaries for the next release. For 0.8.3, we’ll keep it this way. I’ll add a note to the release notes.