xous-core icon indicating copy to clipboard operation
xous-core copied to clipboard

Using GNU Guix for reproducibility.

Open jeandudey opened this issue 1 year ago • 4 comments

An alternative solution to #57.

Only a proof of concept, may or may not be merged :), only to showcase the possibility of using GNU Guix to perform reproducible builds of Xous.

The main advantage of GNU Guix is that everything is built from source, even the C, and Rust compilers, from a small binary seed and a working Linux system. Packages are defined using DSL made with Guile Scheme.

Also, packages are built in an isolated environment that can't be tampered with, without network access, or access to any other part of the filesystem, so build script can run without modifications. The build stage is separate from the download stage, and the download must match the hash of the file in the source declaration.

Most of the packages in GNU Guix are checked to remove bundled code, so that's another plus, as those hidden dependencies can also be audited separately and tampering of code is more hard.

For Rust packages are always reproducible as the strings present inside of the binary will be paths to the GNU Guix store, and these should be the same for each user if the packages are reproducible.

In this PR as of now the following packages can be built using GNU Guix.

  • svd2repl.
  • svd2utra.
  • utralib.
  • wycheproof-import.
  • precursorupdater. To showcase the usage of other languages.

To install Guix, see:

https://guix.gnu.org/manual/en/html_node/Installation.html

⚠️ Using home-manager on foreign (non-Guix) distributions can cause some problems, so, my advice is to not use it unless when the user uses GNU Guix as a distribution. It is not needed for building the code present here.

To build the packages defined, just:

guix time-machine --channels=channels.scm -- build -f guix.scm

Should give the following output at the end:

/gnu/store/3jnlzb119jmcbsng96gky074ajc7y6xb-precursorupdater-0.1.3
/gnu/store/lir3wnx9w1prcvhw4skjdksj97wjnqij-rust-svd2repl-0.1.0
/gnu/store/47ns4w3qklyjjnxqwq03kvilykjzchj0-rust-svd2utra-0.1.17
/gnu/store/f6j8ypn0c74fhm89vlx1dd5y8ija5b21-rust-utralib-0.1.20
/gnu/store/ji8h3f4nl638l7zl83ckqzvchdr7mgh3-wycheproof-import-0.1.0

To use any of these tools in a shell:

guix time-machine --channels=channels.scm -- shell -f guix.scm

And the packages should be available in the PATH. For example, it should be possible to run precursorupdater or svd2utra.

The guix time-machine command is to use a pinned version of GNU Guix as versions can differ when doing a guix pull thus, resulting in different build hashes (or derivations).

If you consider using Guix as an option, package definitions for the Xous rust target could be made, for the kernel, for services, etc. progressively, without needing to do it all at once.

As a side, note, had to update serde-with to make it easier to package wycheproof-import.

jeandudey avatar Jun 27 '23 15:06 jeandudey

This is pretty cool! reproduceable builds are important.

I have some horrifyingly noob questions to ask about guix, I had to Google it to see what it was.

We use Jenkins for ci, do you think guix would integrate seamlessly with Jenkins (given that it is Java and would need a jre, I worry a project like guix might be explicitly anti Java) and do you have a sense for how hard it is to run a public server on guix that is also secure? Basically does it come with safe defaults for noobs or does it tend to have lots of services and ports running by default, and updates are hard so that it runs a higher risk of being broken by remote exploit?

bunnie avatar Jun 27 '23 18:06 bunnie

do you think guix would integrate seamlessly with Jenkins (given that it is Java and would need a jre, I worry a project like guix might be explicitly anti Java)

One can still install software (albeit a bit hacky to do so) and get it running on Guix that is not built on Guix, a recent OpenJDK package is provided and could run Jenkins. That if using Guix as a distribution.

Guix can still be installed on other distributions and only would have a daemon running and won't listen to external connections unless configured to do so, only a unix domain socket is created for the machine it is running on. (the daemon can listen to external connections so other devices can connect to that one to offload builds, but is unencrypted and should be used with WireGuard or the likes).

Also, if planning to use GNU Guix as a distribution they do provide a service type for Cuirass which is a CI for Guix channels:

https://guix.gnu.org/manual/en/html_node/Continuous-Integration.html

It would only require a separate repository which holds the package definitions, an example channel would be:

https://gitlab.com/nonguix/nonguix/

Basically does it come with safe defaults for noobs or does it tend to have lots of services and ports running by default, and updates are hard so that it runs a higher risk of being broken by remote exploit?

As a distribution the system is described using the DSL and only comes with the bare minimum services needed to run the operating system. Everything else can be added on top. For example:

https://guix.gnu.org/manual/en/html_node/Using-the-Configuration-System.html

Even the base services can be changed if necessary.

jeandudey avatar Jun 27 '23 20:06 jeandudey

hm, it looks like the latest rust version native to guix is 1.67.1. do you happen to know where I can find any information on the guix project's general commitment to Rust and what expectations I may have for how long it takes for them to follow the Rust release train?

some release lag is fine but I am a little worried about grumblings I have heard about forks to crablang and license fights, and I don't want to hop on a train that takes the project into an essential dependency that doesn't track the mainline reliably.

that being said, maybe there is a point where we stop tracking latest Rust, and this concern becomes a non issue, but for now we are still tracking the release train.

bunnie avatar Jun 28 '23 23:06 bunnie

hm, it looks like the latest rust version native to guix is 1.67.1. do you happen to know where I can find any information on the guix project's general commitment to Rust and what expectations I may have for how long it takes for them to follow the Rust release train?

It isn't updated frequently because it would trigger a rebuild of a lot of packages in CI and make substitutes (cached binaries of compilations) unavailable for a while, right now it would rebuild:

guix refresh --list-dependent rust
Building the following 5252 packages would ensure 7853 dependent packages are rebuilt:

So they let Rust release a few versions first, to avoid frequent rebuilds.

They do provide up to rust-1.68 (not user-installable, but available for package definitions), without rustfmt, and new versions can be added, but for building the distribution packages they do use 1.67, and only 1.67 is fully tested. So, in theory, one could send patches to add 1.69 to compile 1.70, and we could use 1.70 in Rust packages by adding a #:rust rust-1.70 argument.

jeandudey avatar Jun 29 '23 09:06 jeandudey