`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.