-
Notifications
You must be signed in to change notification settings - Fork 51
Upgrade to tonic 0.8.x #506
Upgrade to tonic 0.8.x #506
Conversation
I have been trying to get the build to succeed for the last three days. No luck :-( I have narrowed the problem down to the usage of git related features of the vergen crate that is used in the So, I wonder
@argerus @SebastianSchildt any thoughts? |
I think we want to move away from this as it's not the first time it's been causing issues. It's probably better to extract / produce version information externally from the (cargo) build and making it available as e.g. environment variables or a generated file.
I don't think it's necessary as the build wasn't using Alpine until recently. But I suppose there where reasons for introducing it, @SebastianSchildt? |
I don't have a solution right now (but I do see some exploration started in #510 , but I have background and history :) databroker tries to print its version, or whether that is not available it's githash, and also an indicator whether this is a dirty build or not. This is not only useful (you know exactly what is required), but actually also a requirement for software supply chain mgmt (i.e. all our other components should learn this as well). The "normal" way to do this in rust is vergen: It basically runs the necessary git queries, put results in environment vars, which then can be incorporated into code. The problem you found: vergen (or rather some RUST git dependency) has this weird issue with MUSL "in some conditions". Why we build in alpine? Well, if i remember correctly there was another weird error for jemalloc (when it was still mandatory) when trying to link that on a glibc system cross-compiling for MUSL. In any case - C libray aside - a lot of buildx is used, where with one Dockerfile you can build any target you which, where docker, when set up correctly distributes the workload to a computer with the correct platform (for example when you build in this repo, arm builds are spun out to an AWS graviton instance). Maybe, as they guy who did quite a bit of the initial CI/container setup in KUKSA, I also need to admit I am not considering cross-compiling an easy solution, that even if it seems works sometimes fails in interesting ways. But I can also admit, the scars on my souls responsible for that, came form a time, long before Rust was even born :) Other related things: Why not cross-rs (https://github.com/cross-rs/cross) ? That actually has been discussed (with no definite conclusion) Traditionally (from the C++ only days) we build everything in kuksa from scratch in docker. Two advantages: Reproducibility goes up (not dependent on build system), and runners (if you provision them yourselves) are easier: They only need docker, not needed to maintain any build infrastructure on them, or the danger of previous builds poisoning your environment. Now at least in case of cross-rs, which uses docker internally, depends on some rust installation and cross cargo package on the build host (if you don't do stunts like "docker in docker", which is ugly in it's own ways). In any case, it can be concluded the current solution is not perfect anyway, and as @argerus has pointed out in the past, at least for some Rust crates we already needed to destroy our clean "one simple Dockerfile for buildx" pattern, with platform specific hacks, not unlike the ones that also happen with things like cross-rs behind the scenes. Anyway, I will take a look whether this can be fixed here "quickly", and apart from that let's explore in #510 if there is a better way. |
Also defined several dependencies shared by multiple packages as workspace dependencies so that their versions can be managed in a single place. Signed-off-by: Kai Hudalla <kai.hudalla@bosch.io>
Ok, it looks I finally got it running. I have now simply replaced the rust:1.65-alpine base image with the images that I had tried out in #510 and this seems to do the trick :-) |
@@ -32,6 +32,10 @@ jobs: | |||
runs-on: ubuntu-latest | |||
|
|||
steps: | |||
- name: Install Protoc | |||
uses: arduino/setup-protoc@v1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just apt install
it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would, of course, also work but then you have no control over the version being installed (which may or may not be relevant). If you'd rather have the OS package being used, I will be happy to change it ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point as well.
Preferably though, we want it to work with any protoc version (which by the way probably means we should rethink the current use of optional
in the kuksa.val.v1
.proto files).
I would say if it just works replacing it with apt install
at this point in time, I'd go with that.
Cargo.toml
Outdated
[workspace.dependencies] | ||
clap = { version = "3.1.10", default-features = false, features = [ | ||
"std", | ||
"env", | ||
] } | ||
databroker-proto = { path = "kuksa_databroker/databroker-proto" } | ||
prost = "0.11" | ||
prost-types = "0.11" | ||
tokio = { version = "1.17.0", features = [ | ||
"macros", | ||
"rt-multi-thread", | ||
"time", | ||
"signal", | ||
] } | ||
tokio-stream = { version = "0.1.8", features = ["sync", "net"] } | ||
tonic = "0.8" | ||
tonic-build = "0.8" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good initiative with workspace dependencies!
However, I think it would be better to use it only for specifying a shared version, i.e. (tokio = { version = "1.17.0" }
), and not features. Features are additive anyway, and it's easier to keep track of which crate needs which feature if it's added for each crate instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and one more thing. Since features are additive, in order for the workspace.dependencies not to inadvertently enable all the default features (see default-features ignored), default-features = false
should also be retained in the workspace dependencies.
So at least for clap in this case (and maybe for all?)
clap = { version = "3.1.10", default-features = false }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't that also be the decision (responsibility) of the different packages? In the end they will need to know if they need/want the default features or not, or won't they?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes exactly. So in order to give them the ability to make that decision, the workspace dependencies need to have default-features = false
.
Otherwise, default-features will be enabled for every member regardless of what they specify themself.
RUN rm -rf ../thirdparty | ||
RUN python3 createbom.py ../databroker-cli | ||
|
||
WORKDIR /build/kuksa_databroker/databroker-cli | ||
|
||
ENV RUSTFLAGS='-C link-arg=-s' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RUSTFLAGS='-C link-arg=-s'
We want to strip the resulting binaries. But support for this has actually been added to cargo now, so it can be added to the top level Cargo.toml
instead of specifying these flags manually, i.e.
[profile.release]
strip = true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I finally understand what the -s
linker arg means ;-)
Personally, I vastly prefer to make cross compilation work instead of depending on buildx to somehow compile it on the actual target (requiring availability of specific hardware or relying on emulation as I understand it). Not least based on the insane compilation times I've seen for kuksa-val-server which as I understand it, is caused by this... I did by the way not see any jemalloc issue when using cargo cross, so I would assume that this was related to how the cross compilation was set up. cargo cross provides those already set up environments. This solution seems to be another way to do that.
Looks like a step in the right direction to me :) |
I see the image doubled in size, ist this, becasue strip is missing, or is tonic so mich larger nwo?
|
kuksa_databroker/Dockerfile
Outdated
FROM rust:1.65-alpine as base | ||
RUN apk add git musl-dev python3 protoc ncurses-terminfo-base make | ||
RUN rustup component add rustfmt | ||
FROM messense/rust-musl-cross:x86_64-musl AS builder-amd64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FROM messense/rust-musl-cross:x86_64-musl AS builder-amd64 | |
FROM ghcr.io/rust-cross/rust-musl-cross:x86_64-musl AS builder-amd64 |
since we're running on github, it would presumably be better to use the GHCR registry (rust-musl-cross prebuild images)
Signed-off-by: Kai Hudalla <kai.hudalla@bosch.io>
@SebastianSchildt I have added the |
Signed-off-by: Kai Hudalla <kai.hudalla@bosch.io>
@SebastianSchildt looks like the artifacts are now even smaller ... |
Signed-off-by: Kai Hudalla <kai.hudalla@bosch.io>
FMPOV we're good to go now. If you agree, I can squash the commits and you could then merge ... |
Unfortunately, when I tried building locally, it fails.
It's because I'm running ubuntu 20.04 which has an older protoc. I suppose we could merge it anyway, but 20.04 is pretty common, it would be good to have a solution that works with this as well.. The best solution is probably to stop using |
yes, I ran into that same problem on my machine (Ubuntu 20.04) as well. I solved this by using the protobuf snap instead of the protobuf-compiler DEB package. The snap provides protoc 3.14.0 which understands the optional modifier ....
I think so too :-) |
It builds even on mac OS . Luckily my default protoc version sees to fit :) . I think the vergen magic is broken in CI builds, unless I mixed up builds. The docker image gives
The locally build one is better and gives
(which maybe also points to the fact, we should always print git hash, that way I'd be more sure about the container) I think it seems due to wrong checkout (shallow) in the checkout action. There is also a longstanding bug/PR open GH side actions/checkout#579 . We did have a workaround the prevents from fetching the whole history, and I though we used this already... I will check, anyway, it seems currently it is not introduced by this change, so, we'd also not need to fix it in this one. I will look into it When I tried building locally and needed to update my rust to latest stable (because I did not have a version supporting workspace_inheritance).
So I am not sure the warning I got is related to the changes here but compiling yields:
Running that gives a looong output, but I think most messages are the same issue, here is the beginning
I think it is not an immediate problem, but if we introduced it here - or can solve it by bumping a dependency, now maybe is the time to do it? |
@SebastianSchildt I will take a look at the nom dependency and what we can do about it ... |
With rustc --version
rustc 1.67.0 (fc594f156 2023-01-24) I do not see any of this output. |
I have Rust 1.68, that seems to be the newest stable, we should not fiddle with "transitive" depenedencies. The ideas was rather if nom comes via terminfo whether there is newer terminfo version, that also updated the dependency accordingly (I understand from your comment, that is not the case?). So in that case I think we do not need to repair it (rather, we might want to open an issue upstream) |
No, there isn't.
I agree |
For me it is fine, but I only give it a short test run. If @argerus agrees (aka "approves") this is fine structure-wise in the Cargo files I'd merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather have the build work on Ubuntu 20.04 as well, either by:
- Downloading protoc and using that as part of the
build.rs
if the installed protoc is to old, or - Remove the use of
optional
inkuksa.val.v1
But I think it would be ok to merge this now and have another PR fix this later.
Also defined several dependencies shared by multiple packages as workspace dependencies so that their versions can be managed in a single place.