paketo-community / rustup

A Cloud Native Buildpack that provides Rustup and installs a Rust toolchain

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`rustup` with musl failing to read `rustc` version

Ch4s3r opened this issue · comments

Buildback fails to add a proper version of the rust toolchain.
Command used for building:

pack build image_name \
-b docker.io/paketocommunity/rust \
-B paketobuildpacks/builder:full \
-e BP_RUST_TOOLCHAIN=nightly  \
-e BP_RUST_PROFILE=complete \
-e BP_RUSTUP_INIT_LIBC=musl \
--clear-cache

Note: full and complete where only used for testing.

With musl the error is:

nightly-x86_64-unknown-linux-musl installed - (error reading rustc version)

Building without musl works fine and results in this line instead of the error above:

nightly-x86_64-unknown-linux-gnu installed - rustc 1.60.0-nightly (5d8767cb2 2022-02-12)

Error log:

full: Pulling from paketobuildpacks/builder
Digest: sha256:35a5e9ce46ef2405f7f740c9c35dba732ba05e99549c0d101d8d59f84b023009
Status: Image is up to date for paketobuildpacks/builder:full
full-cnb: Pulling from paketobuildpacks/run
Digest: sha256:8610aaf374a88b9d251d7ad0f463a4ea9bf159df9bccc08289f8e39de92afaaf
Status: Image is up to date for paketobuildpacks/run:full-cnb
latest: Pulling from paketocommunity/rust
Digest: sha256:bddf1870ab670a7fe650a463d6c7b41588254066fbdb04f20ca061fce69fada6
Status: Image is up to date for paketocommunity/rust:latest
===> ANALYZING
===> DETECTING
3 of 4 buildpacks participating
paketo-community/rustup    1.1.2
paketo-community/rust-dist 1.4.1
paketo-community/cargo     0.2.1
===> BUILDING

Paketo Rustup Buildpack 1.1.2
  https://github.com/paketo-community/rustup
  Rustup (musl libc) 1.24.3: Contributing to layer
    Downloading from https://static.rust-lang.org/rustup/archive/1.24.3/x86_64-unknown-linux-musl/rustup-init
    Verifying checksum
    Copying to /layers/paketo-community_rustup/rustup-musl/bin
  Cargo: Contributing to layer
  Rustup: Contributing to layer
    Installing Rustup
  Rust: Contributing to layer
    Installing Rust
      info: syncing channel updates for 'nightly-x86_64-unknown-linux-musl'
      info: latest update on 2022-02-13, rust version 1.60.0-nightly (5d8767cb2 2022-02-12)
      info: downloading component 'cargo'
      info: downloading component 'clippy'
      info: downloading component 'rust-docs'
      info: downloading component 'rust-std'
      info: downloading component 'rustc'
      info: downloading component 'rustfmt'
      info: installing component 'cargo'
      info: installing component 'clippy'
      info: installing component 'rust-docs'
      info: installing component 'rust-std'
      info: installing component 'rustc'
      info: installing component 'rustfmt'
      
        nightly-x86_64-unknown-linux-musl installed - (error reading rustc version)
      
      info: default toolchain set to 'nightly-x86_64-unknown-linux-musl'
      info: checking for self-updates
Warning: the following SBoM files will be ignored for buildpack api version < 0.7 [/layers/paketo-community_rustup/rustup-musl.sbom.syft.json]

Rust Distribution Buildpack 1.4.1
  https://github.com/paketo-community/rust-dist

Rust Cargo Build Pack 0.2.1
  https://github.com/paketo-community/cargo
  Build Configuration:
    $BP_CARGO_EXCLUDE_FOLDERS    static, templates, public, html  folders that should not be deleted and should persist to the generated image
    $BP_CARGO_INSTALL_ARGS                                        additional arguments to pass to Cargo install
    $BP_CARGO_WORKSPACE_MEMBERS                                   the subset of workspace members for Cargo to install
unable to create cargo layer contributor
unable to determine cargo version
error executing 'cargo version':
 Combined Output: error: command failed: 'cargo': No such file or directory (os error 2)
: 
exit status 1
ERROR: failed to build: exit status 1
ERROR: failed to build: executing lifecycle: failed with status code: 51

Combined Output: error: command failed: 'cargo': No such file or directory (os error 2)

Is coming from the buildpack. It's saying that cargo isn't installed. I think that's a reaction to what happens with rustup.

 info: installing component 'cargo'
 info: installing component 'clippy'
 info: installing component 'rust-docs'
 info: installing component 'rust-std'
 info: installing component 'rustc'
 info: installing component 'rustfmt'
 
   nightly-x86_64-unknown-linux-musl installed - (error reading rustc version)
 
 info: default toolchain set to 'nightly-x86_64-unknown-linux-musl'
 info: checking for self-updates

This is output from rustup. The buildpack is just calling rustup. You can see in the output something weird is happening when it installs rustc. Also, while it downloads cargo there is no lineinfo: installing component 'cargo', which I think is why the buildpacks end up failing. Cause cargo doesn't get installed.

FYI, I pulled a Ubuntu container, ran Rustup manually, and had similar issues.

What are you trying to do using this combination? The base images that are used with Paketo Buildpacks and pack build are x86_64 gnu libc based. The buildpack allows you to install different targets, but you shouldn't really need to do that unless you're customizing the stack and using different base images, which is an advanced use case.

For what it's worth, most standard builds will not require the complete profile. It shouldn't hurt anything but it is probably installing way more than is necessary. It's up to you though. If you have a use case that requires it, then by all means go ahead. Just pointing this out as it could save you some build time/network bandwidth if you don't specifically need it.

My goal is to use the tiny builder with a musl application, but that always fails, because the cargo buildpack cannot find the cargo binary and it probably fails because rustup has a problem installing rustc. Was using the full builder only to make sure it is working. Also there is a line saying info: installing component 'cargo' in the log above.

Ok, building for the tiny image has some gotchas. The primary one is that it's really a pain if you depend on any shared libraries, like OpenSSL. I did it a while back and it worked, at least for some small apps. Let me see if I can turn up my notes on what was necessary. I'll get back to you shortly.

With this command it works, but I wanted to get the image size down by using the tiny builder with the musl application

pack build image_name \
-b docker.io/paketocommunity/rust \
-B paketobuildpacks/builder:base \
-e BP_RUST_TOOLCHAIN=nightly  \
-e BP_RUST_PROFILE=default \
--clear-cache

And rustup always fails to correctly install when selecting musl.

OK, so if I run pack build rust -b paketo-community/rust -B paketobuildpacks/builder:tiny, the build will succeed. The buildpack installs Rust target stable-x86_64-unknown-linux-gnu. Cargo runs and compiles the app.

Then when you try to execute the image with docker run -it --init apps/rust, you get 👎

> docker run -it --init apps/rust
/workspace/bin/rust_hello_forever: error while loading shared libraries: libgcc_s.so.1: cannot open shared object file: No such file or directory

This particular library is not in the tiny stack, but my understanding is that Rust will create binaries that depend on it unless you use musl.


If you set -e BP_RUSTUP_INIT_LIBC=musl you are telling the buildpack to tell rustup to install a full version of Rust & its tools that are built against musl. That's is not what we want here because the base image is Ubuntu and it has libc. I'm not 100% sure why this fails. I thought a musl binary would run on Ubuntu, but for whatever reason the version of Rust and its tools that gets installed don't run. That why you see errors like failed: 'cargo': No such file or directory (os error 2) and (error reading rustc version) in the output.


What I believe we want is this: -e BP_CARGO_INSTALL_ARGS='--target x86_64-unknown-linux-musl'. This would install a glibc based Rust tool chain, but tell Cargo to build against the musl target. What unfortunately happens here is that the target isn't installed, so it fails.

I'm going to keep poking at this, but I think we'll need a new feature here to install additional targets like is being done here and here. I'll open an issue for that in a second.

Just tried to install musl locally with rustup install nightly-x86_64-unknown-linux-musl and it failed with the same error, but suggeting that instead we should call rustup target add x86_64-unknown-linux-musl.
So I guess this seems to be correct way to go with #44.

rustup install nightly-x86_64-unknown-linux-musl                                                                                                               INT ✘ 
error: DEPRECATED: future versions of rustup will require --force-non-host to install a non-host toolchain as the default.
warning: toolchain 'nightly-x86_64-unknown-linux-musl' may not be able to run on this system.
warning: If you meant to build software to target that platform, perhaps try `rustup target add x86_64-unknown-linux-musl` instead?
info: syncing channel updates for 'nightly-x86_64-unknown-linux-musl'
info: latest update on 2022-02-15, rust version 1.60.0-nightly (c5c610aad 2022-02-14)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
 34.9 MiB /  34.9 MiB (100 %)  30.5 MiB/s in  1s ETA:  0s
info: downloading component 'rustc'
 77.1 MiB /  77.1 MiB (100 %)  28.6 MiB/s in  2s ETA:  0s
info: downloading component 'rustfmt'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
 19.5 MiB /  19.5 MiB (100 %)   7.8 MiB/s in  2s ETA:  0s
info: installing component 'rust-std'
 34.9 MiB /  34.9 MiB (100 %)  11.0 MiB/s in  2s ETA:  0s
info: installing component 'rustc'
 77.1 MiB /  77.1 MiB (100 %)  14.7 MiB/s in  5s ETA:  0s
info: installing component 'rustfmt'

  nightly-x86_64-unknown-linux-musl installed - (error reading rustc version)

But it's still strange that it fails installing when musl is used.
So crosscompiling with the the the non-musl rustup installation to a musl binary should work, but may take longer than compiling directly with a musl rustup installation of the target.

Thanks for doing some validation on this as well. In addition to #44 I think what I can do is have the buildpack automatically detect if you're using the tiny stack and add in the additional target and build flags.

I'll still expose the env variable so that you a user can add more targets but this should make it so that builds for tiny just work out of the box.

#45 should resolve most of this. It will ensure that the right target for the Tiny stack is installed by default. You could specify a different target, but don't need to if you're just trying to build for the Tiny stack.

To build for now, set -e BP_CARGO_INSTALL_ARGS='--target x86_64-unknown-linux-musl'.

I've added paketo-community/cargo#145 which will make this just work out-of-the-box. It'll add that argument automatically for the Tiny stack.

Once #45 is merged, I'll cut a release and you'll be able to give this a try. I'll leave this open for feedback.

The paketo-community/rust release 0.7.0 has the changes to support building on Tiny. You do still need to add the BP_CARGO_INSTALL_ARGS as indicated in my previous comment. I'm hoping to get a PR in that will automate that on Tiny next week & I'll cut another release to include that support. At that point, building on Tiny should "just work".

The paketo-community/rust release 0.8.0 has the changes to support building on Tiny automatically.

The cargo buildpack will now automatically add BP_CARGO_INSTALL_ARGS to build against musl if the stack is set to Tiny.

I think that resolves everything we'd discussed on this issue. Thanks again for the awesome feedback & let me know if I forgot anything. Otherwise, I'll close out this issue shortly.