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

Using GNU Guix for reproducibility. #393

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

jeandudey
Copy link
Contributor

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.

Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
These are auto-generated files and should not be included in the
repository.

Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Use the latest released version mainly because the 1.x version uses a
yanked crate.

Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
Signed-off-by: Jean-Pierre De Jesus DIAZ <[email protected]>
@bunnie
Copy link
Member

bunnie commented Jun 27, 2023

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?

@jeandudey
Copy link
Contributor Author

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.

@bunnie
Copy link
Member

bunnie commented Jun 28, 2023

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.

@jeandudey
Copy link
Contributor Author

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.

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

Successfully merging this pull request may close these issues.

2 participants