probonopd / go-appimage

Go implementation of AppImage tools
MIT License
710 stars 71 forks source link

Honor SOURCE_DATE_EPOCH #155

Open piegamesde opened 3 years ago

piegamesde commented 3 years ago

See https://reproducible-builds.org/docs/source-date-epoch/.

The application uses the -fstime option on mksquashfs. Its value is taken from now, which is inherently impure. When I have SOURCE_DATE_EPOCH set, mksquashfs fails with FATAL ERROR:SOURCE_DATE_EPOCH and command line options can't be used at the same time to set timestamp(s).

probonopd commented 3 years ago

We are relying on usable fstime to decide which AppImage is newer if we have 2 AppImages for the same applicatino.

Looks like SOURCE_DATE_EPOCH was invented for reproducible builds, where as a result you cannot tell anymore which one of 2 AppImages is the newer one?

https://reproducible-builds.org/docs/source-date-epoch/

piegamesde commented 3 years ago

SOURCE_DATE_EPOCH does not destroy the order relation of the appimages based on their fstime. Instead, it decouples it from the build process: Of two appimages, one is considered newer if its source is newer, regardless of when it was built. Two appimages built from the same source [with the same options] but at different times will be considered equal, which is actually what we want.

Regardless, this is opt-in, since most environments don't set SOURCE_DATE_EPOCH. In that case, taking the current time is fine.

probonopd commented 3 years ago

Looks like the code in question should go here:

https://github.com/probonopd/go-appimage/blob/6249fabe78b8725307ba2fbcdc548b56dc70937d/src/appimagetool/appimagetool.go#L500

If the environment variable SOURCE_DATE_EPOCH is set, then we would have to set FSTime to...?

piegamesde commented 3 years ago

I think the tooling only does all of this because it need to know the timestamp of the AppImage file for publishing or something. In my opinion, the best possible solution would be to let mksquashfs deal with all of this and then simply read the timestamp from the produced file.

If this is not possible, the alternative is to replace time.Now() with the value of SOURCE_DATE_EPOCH if that environment variable is set. In that case, the call to mksquashfs will not include the -fstime either, since the tool will get the value from SROUCE_DATE_EPOCH as well.

probonopd commented 3 years ago

The way I would like this to work is that if SOURCE_DATE_EPOCH is set, then we use its value for FSTime. This way it is guaranteed that the exact same value ends up in the squashfs file and is used in other places of the tool, such as for publishing.

The only thing I do not know is how to convert the value of SOURCE_DATE_EPOCH into something that Go can understand in place of time.Now().

PRs welcome.