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

Supporting pure build toolchains #732

Open
psionic-k opened this issue Mar 1, 2024 · 8 comments
Open

Supporting pure build toolchains #732

psionic-k opened this issue Mar 1, 2024 · 8 comments
Labels
disposition:close The tagged item can probably be closed

Comments

@psionic-k
Copy link

Writing this relatively late for me, so expect inaccuracies.

In order to ensure reproducibility and avoid unidentified supply chain surface area, Nix and Guix etc seek to build from within a sandbox.

To accomplish this, the network access for dependencies happens separately from any build and cargo is directed to the location of these pre-fetched dependencies and made to succeed somewhat painstakingly.

Since providing and using the dependencies for a Rust build output are pretty tightly related, it makes sense to output the wasm and then hand it to trunk to complete the steps of running bindgen and bundling.

Have you seen any of this done or considered it yet?

@ctron
Copy link
Collaborator

ctron commented Mar 1, 2024

Nope. However, IIRC trunk has a nixos package, and an --offline switch. Wouldn't that work?

@psionic-k
Copy link
Author

Indeed I used the nix package to run trunk, and I will that package as a build dependency to build an application.

For context, Nix builds are only done for deployment. The goal is to complete every build step in a sandbox using only upstream outputs or resources that can be content hashed. Cargo --offline is part of the picture, but we also need to purely provide the resources that enable --offline to succeed. Basically, where does the target directory or a bunch of -L flags come from?

Cargo is one piece. Broadly, any steps that might try to access the network will need some treatment. I don't really use SASS etc, so maybe you can help me out at identifying other potential sources of network access used by trunk build. The usual way of handling these is to purify dependency fetching and then do anything that can be done in a sandbox as normally as possible.

To make the cargo step pure, as far as Trunk is concerned, I only need to specify the path where Trunk can find my cargo outputs and proceed with bindgen and so on. I will complete the cargo build independently before handing off to Trunk. This probably means I just use an option to delegate part of the cargo pipeline.

In case you are curious about the delegation, purifying cargo builds to succeed in a sandbox can be broken into three steps:

  1. All dependency fetching is converted to pure, reproducible specifications, basically something that has a content hash
  2. Builds are done within a sandbox that can only access inputs from 1 and outputs are recorded in a pure store
  3. Any downstream Rust builds are configured to use the pure inputs from 2.

All of the Nix tools for building a Rust binary use variations of steps 1-3 and varying degrees of composition of steps (step 3).

@ctron
Copy link
Collaborator

ctron commented Mar 4, 2024

I don't know about nix, so I can't help much there.

But to my understanding, you would need to pull in all inputs (tools and source) through some trusted mechanism. May the by nix or just trusting your local source. So I guess, like a container, you would need to assemble some build environment with nix, which has all the tools required pre-populated. And then run trunk with --offline, to other use the local tools, or fail if they are missing.

After that, just provide that environment your own sources, as well as the vendored ones. cargo should take care of the rest.

So I think this should already be possible.

@psionic-k
Copy link
Author

Ping me if anyone looks for Nix support. I have a pretty good idea of the scope of the work needed. It's minor surgery.

However, I decided to go full stack for now. Since I have in independent API server, I may go back to Trunk. I was just interested in getting SSR for at least the client-independent rendering to do fine with SEO and low / no javascript.

@Nub
Copy link

Nub commented May 16, 2024

Ping me if anyone looks for Nix support. I have a pretty good idea of the scope of the work needed. It's minor surgery.

However, I decided to go full stack for now. Since I have in independent API server, I may go back to Trunk. I was just interested in getting SSR for at least the client-independent rendering to do fine with SEO and low / no javascript.

I would love to hear if you identified a fix, I am currently struggling with deploying and app in nix via trunk due to the runtime deps it wants to download, and it fails to even search your path if you provide them in a sane manner.

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
2024-05-16T01:39:21.511820Z  INFO fetching cargo artifacts
2024-05-16T01:39:21.596186Z  INFO processing WASM for frontend
2024-05-16T01:39:21.621080Z ERROR ❌ error
error from HTML pipeline

Caused by:
    0: error from asset pipeline
    1: couldn't find application wasm-bindgen
Error: error from HTML pipeline

Caused by:
    0: error from asset pipeline
    1: couldn't find application wasm-bindgen

[merops@nixos:~/src/themis/frontend]$ wasm-bindgen
Invalid arguments.

Usage:
    wasm-bindgen [options] <input>
    wasm-bindgen -h | --help
    wasm-bindgen -V | --version

@Nub
Copy link

Nub commented May 16, 2024

And to make things worse if you let it download bins they don't run as expected

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
2024-05-16T01:44:32.924352Z  INFO fetching cargo artifacts
2024-05-16T01:44:33.007139Z  INFO processing WASM for frontend
2024-05-16T01:44:33.030969Z  INFO downloading wasm-bindgen version="0.2.92"
2024-05-16T01:44:34.215630Z  INFO installing wasm-bindgen
2024-05-16T01:44:34.302538Z  INFO calling wasm-bindgen for frontend
Could not start dynamically linked executable: /home/merops/.cache/trunk/wasm-bindgen-0.2.92/wasm-bindgen
NixOS cannot run dynamically linked executables intended for generic
linux environments out of the box. For more information, see:
https://nix.dev/permalink/stub-ld
2024-05-16T01:44:34.304254Z ERROR ❌ error
error from HTML pipeline

Caused by:
    0: error from asset pipeline
    1: wasm-bindgen call returned a bad status
Error: error from HTML pipeline

Caused by:
    0: error from asset pipeline
    1: wasm-bindgen call returned a bad status

@ctron
Copy link
Collaborator

ctron commented May 16, 2024

Looks like there's a hint:

For more information, see:
https://nix.dev/permalink/stub-ld

One aspect of trunk is to manage the required CLIs for you. If you opt-out of this, you need to take care of this yourself. And if you want to use it, trunk can only do this for environments for which the dependencies/tools support it.

It looks like wasm-bindgen released a binary which doesn't run on nixos. I wouldn't see this as an issue of trunk though.

Judging from the error message, it looks like you're running an older version of trunk. Could you run trunk --version and paste the output? If it's anything before 0.19.x, I would recommend to upgrade, as there have been many improvements to the management of tools.

@ctron
Copy link
Collaborator

ctron commented May 24, 2024

I am not sure what needs to be done here. It feels more like a discussion. So maybe this should be transformed into one.

@ctron ctron added the disposition:close The tagged item can probably be closed label May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition:close The tagged item can probably be closed
Projects
None yet
Development

No branches or pull requests

3 participants