Skip to content

Conversation

chrysn
Copy link
Member

@chrysn chrysn commented Apr 2, 2021

I'm not yet sure this is all the right way to do things, but a) hope that you can tell me, and b) ask the CI to build this (for with my current uplink this all would take ages)

@chrysn
Copy link
Member Author

chrysn commented Apr 3, 2021

I'm approaching the end of my ideas of how to make this build; the Compiling cargo v0.44.1 ran even into a 30' timeout. Maybe that's really too short as I had to put the travis_wait command around all of the docker build, trying once with a 45' timeout and gonna stop wasting build time if even that doesn't work out.

@chrysn
Copy link
Member Author

chrysn commented Apr 6, 2021

This really is a timeout issue; I now have a machine where I can run this without timeouts, and it does terminate (albeit with an error I'm just tracking further).

On the more general side, are we OK with increasing the build time by as much as this (don't have numbers, but this might double the build times), with hacks to extend the timeout? (Single Cargo crate compilation is simply nothing too verbose, and the travis_wait doesn't quite cut it; a du-based custom watcher (like "have a background process that prints directory sizes every five minutes; as long as it's still going that will increase") could do, but will we stay on travis anyway? I don't know much about that tool as I'm using GitLab for my projects, but the builds show a deprecation / migration warning.)

@chrysn
Copy link
Member Author

chrysn commented Apr 6, 2021

Hm, seems I had the wrong travis log open; the current version builds locally, and the latest build before this push (https://travis-ci.org/github/RIOT-OS/riotdocker/builds/765744396) indicates the timeout extension does work.

So if things go green here, the main question to remain is whether we want to have the increased build time and image size; I think the benefits of running Rust on RIOT in CI are worth it, but I'm obviously biased ;-)

@chrysn
Copy link
Member Author

chrysn commented Apr 6, 2021

… and rebased with the time-saving do-not-merge commit removed because now the builds run through the Docker image creation, and all steps in there are required to make the later hello-world build tests run through.

@kaspar030
Copy link
Contributor

So if things go green here, the main question to remain is whether we want to have the increased build time and image size; I think the benefits of running Rust on RIOT in CI are worth it, but I'm obviously biased ;-)

I might be similarly biased, but having Rust is definitely worth a lot. I think we can cover up the increased image size ("giant" will still be "giant" afterwards), but, can we mitigate the build time by building c2rust externally?

c2rust should end up being a single binary, with some runtime dependencies (libllvm, ...). If we carve out c2rusts building into it's own Docker container, we can rebuild that only if c2rust changes, and then re-use the artifact for the build of riotdocker.
Maybe move that into another repository?

@chrysn
Copy link
Member Author

chrysn commented Apr 6, 2021

I've had immunant/c2rust#326 open for some time on that topic. Options seem to be:

  • Have a Docker build from the same image (we're on bionic) that can be merged in
  • Have generally usable Linux binaries produced by c2rust that can just be wgot and installed by placing them into the container.

I have a personal preference for the latter, and am exploring that road; I'd welcome anyone familiar with Docker workings and customs to explore the other road.

@chrysn
Copy link
Member Author

chrysn commented Apr 6, 2021

Hm, they do already provide a docker image; that route may actually be easier even without good familiartiy with Docker. Playing around...

@chrysn
Copy link
Member Author

chrysn commented Apr 7, 2021

Next iteration: Turns out the image provided by immunant only contains everything required for building and testing c2rust and not c2rust itself. However, that makes it rather straightforward to create one where it's built too, and (until my two pending PRs there are merged) we need a customized build anyway.

The current setup uses one intermediate image (also built in here by Travis) based on the immunant image that just builds "our" c2rust; that image is added as a dependency of the riotbuild image and the single c2rust binary is copied over. It ran through locally, so if anything runs afoul I may need to introduce travis_waits again…

@chrysn
Copy link
Member Author

chrysn commented Apr 7, 2021

With the latest fixes, this can now be now tested comprehensively by running, inside the produced riotdocker (at least with what I'm producing locally):

# git clone https://github.com/chrysn-pull-requests/RIOT.git -b rust-application
# cd RIOT/examples/rust-hello-world/
# make all term

(I assume it doesn't make much sense to include a test in the code at this stage where RIOT-OS/RIOT#16274 is not merged yet; testing the fundamentals manually, then testing that PR based on Rust support in riotdocker, and at some point later maybe adding the rust-hello-world example to the make tests.)


With the Travis Docker images, I'm still in trouble: There's a travis run for building the c2rust-built docker image now, and riotdocker depends on that, but somehow fails to pull it in unlike the static-test-tools one built just the same way a line above. I tried with 49c3326 but that wasn't it -- any clues?

@kaspar030
Copy link
Contributor

With the Travis Docker images, I'm still in trouble: There's a travis run for building the c2rust-built docker image now, and riotdocker depends on that, but somehow fails to pull it in unlike the static-test-tools one built just the same way a line above. I tried with 49c3326 but that wasn't it -- any clues?

could it be that because of the --pull in docker build --pull -t riotdocker riotbuildthe riotbuild run always tries to pull from docker hub, and this just works for the other images because there's a version there (pushed earlier)? This would mean the current workflow is broken. @aabadie do you have an idea?

I think the --pull should not be used for riotbuild, but the base images.

@chrysn
Copy link
Member Author

chrysn commented Apr 8, 2021

That --pull may even have entered the system inadvertedly when some Rotzbua committed unrelated changes in ea042a7, trying without...

[edit: The --pull was discussed just not mentioned in the commit message; https://github.com//pull/81 sounds like it made sense at the time; possibly the right course of action is really to just remove the --pull for the PR evaluation, then upload an initial riot/c2rust image to dockerhub and then drop the --pull-removing commit before merging].

@chrysn chrysn changed the base branch from master to trying April 8, 2021 19:24
@chrysn chrysn changed the base branch from trying to master April 8, 2021 19:24
@chrysn chrysn changed the base branch from master to trying April 8, 2021 19:26
@chrysn chrysn changed the base branch from trying to master April 8, 2021 19:26
@chrysn
Copy link
Member Author

chrysn commented Apr 8, 2021

All running fine through the changed parts up to the point when the global timeout reaps the job. What can we do about that? Build our c2rust in a separate repo? Or just build and upload one (it's a 2-liner Dockerfile) out of CI and publish that?

@kaspar030
Copy link
Contributor

bors try

bors bot added a commit that referenced this pull request Apr 9, 2021
@kaspar030
Copy link
Contributor

bors ping

@bors
Copy link
Contributor

bors bot commented Apr 9, 2021

pong

@bors
Copy link
Contributor

bors bot commented Apr 9, 2021

try

Build failed:

@chrysn
Copy link
Member Author

chrysn commented Apr 9, 2021

Hm, bors runs into the same timeout. It's about 20' for the C2Rust compilation step, and in total this exceeds the 50' limit.

Splitting it up in different repos would be the obvious option, but that'll mean that changes in C2Rust build repo won't be CI-tested with the rest until they're merged and published. Then again, the risk is from breaking changes down at C2Rust anyway, and they don't CI with us (how should they with every downstream), so meh. I'm preparing such a step by publishing what's now in c2rust-built as chrysn/c2rust-built in preparation of the same image being tagged riot/c2rust-built.

Generally speaking, how do we publish riotdocker images? Is there an automatism from it being merged, or does someone locally build and publish them at regular intervals?

@chrysn
Copy link
Member Author

chrysn commented Apr 9, 2021

Runs through now. May I rebase?

@chrysn
Copy link
Member Author

chrysn commented Aug 25, 2021

I've taken the liberty to rebase this, given that #148 made this unmergable on its own. Some of the travis workarounds could vanish with that.

I'm a tad confused as to where the information about what to build actually went, hoping to get a bit of clarity from looking at the CI output.

[edit: found it in .github/workflows/build.yml, will adapt...]

@chrysn
Copy link
Member Author

chrysn commented Aug 25, 2021

I don't know much about the github workflows involved here, and have taken the recipes from the other docker containers in something between cargo-culting and guessing-what's-needed -- relying on reviewers to judge whether what's in there makes sense.

Having the container rebuilt on every CI run seems extraneous, can we somehow make it so that "Build c2rust" is only ever executed when c2rust/Dockerfile changes? (As that clones from a git branch, if it helps, I can make that clone a named revision, to ensure that the built container is as much a function of the Dockerfile as possible, and thus use Docker's memoization).

@chrysn chrysn force-pushed the with-rust branch 2 times, most recently from 038efaf to 2125143 Compare August 26, 2021 12:44
@chrysn
Copy link
Member Author

chrysn commented Aug 26, 2021

As-good-as-it-gets for now: The cyclic dependency which riotbuild complained about is done (turned out I don't need a FROM to COPY --from), but an actual circular dependency came up when it turned out buildx (how many layers deep has all that docker stuff become?) can't parse arguments in --from.

Quoting from the comment:

+# The local prefix should be ${DOCKER_REGISTRY}, but variables are not supported
+# in this position by buildx, leading to errors like this:
+#
+# Error: buildx failed with: error: failed to solve: failed to solve with
+# frontend dockerfile.v0: failed to create LLB definition: failed to parse
+# stage name "${DOCKER_REGISTRY}/c2rust-built": invalid reference format:
+# repository name must be lowercase
+#
+# Until github supports this, the hardcoded "local" works well enough for the
+# tests, and needs to be replaced manually with "riot" when going live. Once
+# replaced and published, the ill-effect downstream users will experience is
+# that if they change their c2rust build, they'll have to adjust this line.
+# (For others, c2rust will be built but not used here).
+COPY --from=local/c2rust-built /usr/bin/c2rust

I think that's OK for now, can't fix the whole docker world (and especially the nonfree github infrastructure, not sinking time there).

This builds fine now. For it to build in deployment, I'll have to switch over from local to riot -- can do that right before going live. Once that is changed and has run with publishing once, it can stay like this even for local builds: These will then build c2rust but use the published one. Shouldn't be too bad unless one is changing something in c2rust and relying on the change at the same time.

Please review.

@chrysn
Copy link
Member Author

chrysn commented Aug 26, 2021

To recap, open question:

  • (How) can we skip the c2rust build to only happen if actually triggered, eg. by a change to the respective Dockerfile?
  • Any better ideas on the --from hardcoded "riot/c2rust-built" string? (If we only build c2rust sporadically, which is probably a good idea, then it'll need to stay hardcoded anyway, b/c when it's not built it can't be fetched from local).

@chrysn
Copy link
Member Author

chrysn commented Aug 29, 2021

bors try

(to see whether I can wield this magic too)

bors bot added a commit that referenced this pull request Aug 29, 2021
@bors
Copy link
Contributor

bors bot commented Aug 29, 2021

try

Build failed:

@chrysn
Copy link
Member Author

chrysn commented Aug 29, 2021

OK, that failed in the expected mode; we'll need to publish a riot/c2rust-built once either manually, or just change that before merging to s/local/c2rust/, and then bors can do the final tests and merge after they pass.

@kaspar030
Copy link
Contributor

To recap, open question:

Can't help with those. I agree that we hopefully won't rebuild c2rust too often.

Overall this PR looks good. One thing that bugs me though: can we pin the nightly version somehow?
I know riotdocker is not really reproducible, but installing rust/nightly will result in different rust versions daily.

@chrysn
Copy link
Member Author

chrysn commented Aug 31, 2021 via email

Comment on lines 299 to 315

# These depend on llvm-7-dev to be installed

# The local prefix should be ${DOCKER_REGISTRY}, but variables are not supported
# in this position by buildx, leading to errors like this:
#
# Error: buildx failed with: error: failed to solve: failed to solve with
# frontend dockerfile.v0: failed to create LLB definition: failed to parse
# stage name "${DOCKER_REGISTRY}/c2rust-built": invalid reference format:
# repository name must be lowercase
#
# Until github supports this, the hardcoded "local" works well enough for the
# tests, and needs to be replaced manually with "riot" when going live. Once
# replaced and published, the ill-effect downstream users will experience is
# that if they change their c2rust build, they'll have to adjust this line.
# (For others, c2rust will be built but not used here).
COPY --from=local/c2rust-built /usr/bin/c2rust /usr/bin/c2rust-refactor /usr/bin/c2rust-transpile /usr/bin/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using multistage COPY, FROM etc... you just need to redeclare the ARG see https://github.com/fjmolinas/riotdocker/blob/master/flashers/edbg.Dockerfile as an example

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll give it a try with the next CI test run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try it locally first otherwise!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buildx is not in Debian yet, and I'm very careful about third party debs, but I'm running all tests I can without it here, and with the reference script and the ARG it's hopefully just one more run.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, even with the repeated ARG I get the same circular dependency error; any clues?

(Then again, going for a different workflow probably sidesteps the issue -- so maybe it's best to let this be and go for the other workflow right away).

@fjmolinas
Copy link
Contributor

@chrysn how about adding a distinct workflow for c2rust, and the use on workflow_run combined with action-workflow-run-wait@v1 so that the riotbuild action test is triggered after that build as well. And you can add:

    paths:
      - 'c2rust-built//**'

I played around with it a bit here https://github.com/fjmolinas/riotdocker/blob/master/.github/workflows/flashers_build.yml.

chrysn added a commit to chrysn-pull-requests/riotdocker that referenced this pull request Aug 31, 2021
* nightly: RIOT-OS#141 (comment)
* as default: to reduce duplication, and because otherwise the RIOT
  builds would need mechanism to find which toolchain was prepared for
  them
* profile: As per IRC discussion, keeps size down & we don't need tools
  for building std or advanced debugging in here
chrysn added a commit to chrysn-pull-requests/riotdocker that referenced this pull request Aug 31, 2021
As suggested on RIOT-OS#141 (comment)

The difference between this and earlier attempts is the value-less `ARG
DOCKER_REGISTRY` above the FROM.
@chrysn
Copy link
Member Author

chrysn commented Aug 31, 2021

Converting this to a separate workflow, there's one thing I don't see how to do: How would I get the information about whether the c2rust workflow was run into the riotbuild/Dockerfile?

If the c2rust workflow was run, I'd need to set up the copy from as ${DOCKER_REGISTRY}/c2rust-built:latest (do I need to get any files around for that, or are they all in the runner's local environment?) -- but if the c2rust workflow was not run, it'd need to copy from the latest riot/c2rust-built.

@chrysn
Copy link
Member Author

chrysn commented Sep 1, 2021

Frustrated with the github worker setup, let's take this a step at a time -- with c2rust-built from a third party source (me). Let's focus on #152 first -- that's basically this but stripped down to treating c2rust-built as a third party image.

Once we're done with that (I'd guess it's pretty ready), we can resume work here to explore how to build a riot/c2rust-built on this infrastructure.

bors bot added a commit that referenced this pull request Sep 1, 2021
152: riotbuild: Install Rust (minimal edition) r=kaspar030 a=chrysn

The c2rust program (required in addition to Rust itself) is installed
for what is for most intents and purposes a third party container, but
happens to have its sources shipped along the other containers.

---

This is a minimal version competing with #141 -- we can still get c2rust to fully integrate over time, but right now there's a third party (happens to be me) who publishes a suitable base container, which is not much more or less transparently managed than any other base container (especially immunant/c2rust which it itself is based on), and hey by the way even the Dockerfile for that container is shipped here (but more for informational purposes, not because CI would access it).

Co-authored-by: chrysn <chrysn@fsfe.org>
@chrysn chrysn mentioned this pull request Nov 11, 2021
@chrysn
Copy link
Member Author

chrysn commented Nov 11, 2021

Given that the split solution of #152 Kind Of Works, I'm closing this for now; next steps are updating the c2rust build process anyway (#153) which simplifies how that (manually built / managed by me but still having its sources here) process works.

What remains (remained?) valuable from this PR is the machinery of building c2rust in here too; I don't see that happen right now (also for lack of pressure). As the branch in this PR is hard to read (needs diffing to #152 as that was squashed), I'm force-pushing a latest state here based on #152 that loses history but in return is understandable in terms of what is missing compared to there.

@chrysn chrysn closed this Nov 11, 2021
bors bot added a commit that referenced this pull request Nov 11, 2021
161: Rust updates r=kaspar030 a=chrysn

* Add what is needed to experiment with AVR (not fully supported for Rust-on-RIOT, but way easier to test being in the docker build as I haven't had AVR toolchains installed around for a long time, though they probably still can be installed easily)
* Update Rust nightly (that's a semi-regular thing since we decided to pin the version in #141 (comment) which also went into #152)

Co-authored-by: chrysn <chrysn@fsfe.org>
chrysn added a commit to chrysn-pull-requests/riotdocker that referenced this pull request Nov 17, 2021
This drops a workaround that was necessary during evaluation of RIOT-OS#153 in
favor of a more long-term usable distinction between experimentation and
stable delivery, which is necessary until RIOT-OS#141 is done properly and
c2rust is built in one go with the rest of this.
bors bot added a commit that referenced this pull request Nov 17, 2021
162: riotbuild: Drop :focal tag in favor of a more stable one r=kaspar030 a=chrysn

This drops a workaround that was necessary during evaluation of #153 in
favor of a more long-term usable distinction between experimentation and
stable delivery, which is necessary until #141 is done properly and
c2rust is built in one go with the rest of this.

---

Cleanup change with no expected actual impact. (Tags diverge because `latest` = `for-riot` was rebuilt after #153 was merged, but any differences should be just because building is not byte-by-byte reproducible.)

Co-authored-by: chrysn <chrysn@fsfe.org>
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.

3 participants