cross-rs / cross

“Zero setup” cross compilation and “cross testing” of Rust crates
Apache License 2.0
6.49k stars 365 forks source link

Forge command not found even when proving it is available #1358

Closed 0xfourzerofour closed 10 months ago

0xfourzerofour commented 10 months ago
[build]
pre-build = [
    "apt-get -y install apt-transport-https ca-certificates",
    "curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -",
    "echo 'deb https://dl.yarnpkg.com/debian/ stable main' | tee /etc/apt/sources.list.d/yarn.list",
    "apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config protobuf-compiler nodejs yarn",
    "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal",
    ". /root/.cargo/env",
    "cargo install --git https://github.com/foundry-rs/foundry --profile local --locked forge",
    ". /root/.cargo/env",
    "forge --help"
]

I have the following pre-build script and able to see the output of forge --help.

Once my application gets to the step where there is a build.rs that uses forge, the cross build fails with forge not installed

fn generate_abis() -> Result<(), Box<dyn error::Error>> {
    run_command(
        Command::new("forge")
            .arg("build")
            .arg("--root")
            .arg("./contracts"),
        "https://getfoundry.sh/",
        "generate ABIs",
    )
}

Any help solving this would be greatly appreciated

Emilgardis commented 10 months ago

pre-build runs as use root, the actuall cargo invocation in the container is ran as a normal user. The issue is probably that the forge binary is not in path, nor is it visible.

Fix it by putting the binary in another directory, like /usr/local/bin (and make sure to also chmod it to be readable by all users)

0xfourzerofour commented 10 months ago

ah nice yeh I will give that a go thank you!

Emilgardis commented 10 months ago

also, I'd like to voice my dislike for this solution :3 better solution would be a pre-compiled forge binary that you simply download

0xfourzerofour commented 10 months ago

@Emilgardis yeh I would like to do that but the GLIBC issues do not allow it on the default ubuntu container in cross-rs

Emilgardis commented 10 months ago

I think this should work

# Cross.toml
[build]
dockerfile = "Dockerfile.forge"
# Dockerfile.forge
ARG CROSS_BASE_IMAGE

FROM ghcr.io/foundry-rs/foundry:latest as foundry

FROM $CROSS_BASE_IMAGE
COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge

:edited: to be more correct

0xfourzerofour commented 10 months ago

ooo that would be much cleaner if I could get it to work

I am getting the following error when I add that to my cross.toml

#2 [internal] load build definition from Dockerfile.forge
#2 transferring dockerfile: 221B done
#2 DONE 0.0s
Dockerfile.forge:6
--------------------
   4 |     
   5 |     ARG CROSS_BASE_IMAGE
   6 | >>> FROM $CROSS_BASE_IMAGE
   7 |     COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge
--------------------
ERROR: failed to solve: base name ($CROSS_BASE_IMAGE) should not be blank
Error: 
   0: could not run container
   1: when building custom image
   2: when building dockerfile
   3: `docker buildx build --progress auto --label 'org.cross-rs.for-cross-target=aarch64-unknown-linux-gnu' --label 'org.cross-rs.runs-with=x86_64-unknown-linux-gnu' --label 'org.cross-rs.workspace_root=/home/runner/work/rundler/rundler' --tag localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe --build-arg 'CROSS_DEB_ARCH=arm64' --build-arg 'CROSS_BASE_IMAGE=ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main' --file Dockerfile.forge --output 'type=docker' /home/runner/work/rundler/rundler` failed with exit status: 1
Emilgardis commented 10 months ago

interesting, it's clearly passing the build arg --build-arg 'CROSS_BASE_IMAGE=ghcr.io/cross-rs/aarch64-unknown-linux-gnu:main' so it should work fine

Emilgardis commented 10 months ago

can you try FROM ${CROSS_BASE_IMAGE} maybe?

Emilgardis commented 10 months ago

ooohh! Sorry, I forgot how dockerfiles work...

ARGs for FROM need to be specified upfront...

ARG CROSS_BASE_IMAGE
# Dockerfile.forge
FROM ghcr.io/foundry-rs/foundry:latest as foundry

FROM $CROSS_BASE_IMAGE
COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge
0xfourzerofour commented 10 months ago

ok I got further with that update however I get a weird error

#7 extracting sha256:211eac2d596e7b81f6f8a379c1ca93b747ce4e063388cd28949156bc7fcaed85 done
#7 DONE 19.9s

#8 [stage-1 2/2] COPY --from=foundry /usr/local/bin/forge /usr/local/bin/forge
#8 DONE 2.6s

#9 exporting to docker image format
#9 exporting layers
#9 exporting layers 1.6s done
#9 exporting manifest sha256:bca5fec824b98b01fa68cfad86ccd65f555afdf842d0346d8fdb847bf20ff0bf done
#9 exporting config sha256:b78c04d8d3442c2835f11a5ad6a6e5c449c6427a064a435141acc9b48ffec4ac done
#9 sending tarball
#9 ...

#10 importing to docker
#10 DONE 25.2s

#9 exporting to docker image format
#9 sending tarball 33.7s done
#9 DONE 35.4s
#0 building with "cross-builder" instance using docker-container driver

#1 [internal] load build definition from Dockerfile.aarch64-unknown-linux-gnu-custom
#1 transferring dockerfile: [271](https://github.com/alchemyplatform/rundler/actions/runs/6671060091/job/18132202267#step:8:272)B done
#1 DONE 0.0s

#2 [internal] load metadata for localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe
#2 ERROR: failed to do request: Head "http://localhost/v2/cross-rs/cross-custom-rundler/manifests/aarch64-unknown-linux-gnu-c9fbe": dial tcp 127.0.0.1:80: connect: connection refused
------
 > [internal] load metadata for localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe:
------
Dockerfile.aarch64-unknown-linux-gnu-custom:2
--------------------
   1 |     
   2 | >>>                 FROM localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe
   3 |                     ARG CROSS_DEB_ARCH=
   4 |                     ARG CROSS_CMD
--------------------
ERROR: failed to solve: localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe: failed to do request: Head "http://localhost/v2/cross-rs/cross-custom-rundler/manifests/aarch64-unknown-linux-gnu-c9fbe": dial tcp 127.0.0.1:80: connect: connection refused
Error: 
   0: could not run container
   1: when building custom image
   2: when pre-building
   3: `docker buildx build --progress auto --label 'org.cross-rs.for-cross-target=aarch64-unknown-linux-gnu' --label 'org.cross-rs.runs-with=x86_64-unknown-linux-gnu' --label 'org.cross-rs.workspace_root=/home/runner/work/rundler/rundler' --tag localhost/cross-rs/cross-custom-rundler:aarch64-unknown-linux-gnu-c9fbe-pre-build --build-arg 'CROSS_CMD=apt-get -y install apt-transport-https ca-certificates
      curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
      echo '\''deb https://dl.yarnpkg.com/debian/ stable main'\'' | tee /etc/apt/sources.list.d/yarn.list
      apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config protobuf-compiler nodejs yarn' --build-arg 'CROSS_DEB_ARCH=arm64' --file /home/runner/work/rundler/rundler/target/aarch64-unknown-linux-gnu/Dockerfile.aarch64-unknown-linux-gnu-custom --output 'type=docker' /home/runner/work/rundler/rundler` failed with exit status: 1

looks like a strange local host error

Emilgardis commented 10 months ago

ugh, will have to investigate that, I think I know the cause.

for now, just remove any commands in pre-build and use RUN apt-get update && apt-get install my-dependency in Dockerfile.forge if you need to install something

0xfourzerofour commented 10 months ago

yeh no worries I think I can do that. Will let you know how it goes. Thanks for the help!

0xfourzerofour commented 10 months ago

Adding build dependencies to the forge docker container worked until it ran into a permissions issue

Resolving deltas: 100% (129/129), done. Failed to install solc 0.8.22: Permission denied (os error 13) Error: Permission denied (os error 13)

Error: "Failed to generate ABIs." warning: build failed, waiting for other jobs to finish... make[1]: [Makefile:39: build-aarch64-unknown-linux-gnu] Error 101 make[1]: Leaving directory '/home/runner/work/rundler/rundler' make: [Makefile:44: docker-build-latest] Error 2 Error: Process completed with exit code 2.

When I run it locally using sudo it works but my github action does not like when I use sudo due to the cargo install and the PATH

Emilgardis commented 10 months ago

i'm not sure I understand? That doesn't seem related to cross.

0xfourzerofour commented 10 months ago

Yeh its not specific to cross I think, just a permissions error in the docker custom container

0xfourzerofour commented 10 months ago
error: failed to run custom build command for `rundler-types v0.1.0-beta (/home/runner/work/rundler/rundler/crates/types)`

Caused by:
  process didn't exit successfully: `/target/release/build/rundler-types-ed3a290aef67a0d1/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=contracts/lib
  cargo:rerun-if-changed=contracts/src
  cargo:rerun-if-changed=contracts/foundry.toml

  --- stderr
  fatal: detected dubious ownership in repository at '/home/runner/work/rundler/rundler'
  To add an exception for this directory, call:

    git config --global --add safe.directory /home/runner/work/rundler/rundler

  Error: "Failed to update submodules."

Have you seen this happen in the contianers if the repo needs to import submodules?

Emilgardis commented 10 months ago

Why is the build script fetching submodules? Seems to me like you should checkout fully (because this looks like GH CI)

- uses: actions/checkout@v4
  with:
    submodules: true

anyway, this git error seems to be new: https://github.blog/2022-04-18-highlights-from-git-2-36/#stricter-repository-ownership-checks

we should be passing -u $UID:$GID so we should be fine, https://github.com/cross-rs/cross/blob/44011c8854cb2eaac83b173cc323220ccdff18ea/src/docker/shared.rs#L1109

Emilgardis commented 10 months ago

This seems related, don't know how to fix

https://github.com/actions/checkout/issues/766

0xfourzerofour commented 10 months ago

We pull in git submodules to be used for code generation using forge, but this looks like it will be a new error going forward so I will just remove the git submodule stuff from build.rs and I think it should be fine

0xfourzerofour commented 10 months ago

thank you!