-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Define example manifest files and add --watch
flag
#1105
Conversation
examples/aggregator/example.toml
Outdated
name = "aggregator" | ||
|
||
[modules.module] | ||
lang = "Rust" |
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.
You probably don't need both the lang and cargo_manifest? If it has a cargo_manifest it should be clear it's cargo :)
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.
In pure Rust this would be an enum with different fields, and everything would be type safe. In principle, that could be done for TOML too, but the parser does not seem to like those kind of enums :/ toml-rs/toml-rs#390
examples/aggregator/example.toml
Outdated
[clients.cpp] | ||
lang = "Cpp" | ||
additional_args = ["--bucket=test", "--data=1:10,2:20,3:30"] |
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.
Same here - if you have a clients.cpp maybe you don't need to specify the lang?
f5b2352
to
3f7797b
Compare
--watch
flag
3f7797b
to
cda22e5
Compare
"--cert_chain=../../../../../../../../examples/certs/local/local.pem", | ||
"--private_key=../../../../../../../../examples/certs/local/local.key", |
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 know it's a minor thing, but the ../../../../../../../../
paths honestly confuse me so much. But I guess with us moving away from bazel that's a seperate thing. :)
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.
Yeah, that's orthogonal to this change, please ignore for now :)
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.
Feel free to ignore this since it's not actionable, but purely to satisfy my curiosity,:
This basically navigates us out of the bazel runner directory and back into the working directory to load the certs, right? Had we considered instead copying the certs in into the bazel runner dir with a build rule?
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, bazel artifacts are nested deep inside the guts of bazel cache.
I don't think it's possible to just copy additional stuff in the cache folder, but I haven't looked into it closely.
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've seen some examples do it, but yeah don't know what's best practice. Relying on the cache path seems a bit like using internals, not APIs, but thankfully I'm told we're moving away from bazel anyway. :)
}), | ||
}, | ||
], | ||
} | ||
} | ||
|
||
fn run_client(name: &str, client: &Client) -> Step { | ||
match &client.target { | ||
Target::Cargo { .. } => todo!(), |
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.
TIL that Rust had a literal todo
macro. 😅
vec![ | ||
"run".to_string(), | ||
"--".to_string(), | ||
format!("//examples/{}/client:client", example.name), | ||
"--ca_cert=../../../../../../../../examples/certs/local/ca.pem" | ||
.to_string(), | ||
] | ||
steps: example | ||
.clients | ||
.iter() | ||
.chain(example.additional_client_flags.iter()), | ||
), | ||
.map(|(name, client)| run_client(name, &client)) | ||
.collect(), |
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 nice, it seems like this PR is unofficially adding support for running multiple clients
#[derive(serde::Deserialize, Debug)] | ||
#[serde(deny_unknown_fields)] | ||
enum Target { | ||
Bazel { bazel_target: String }, | ||
Cargo { cargo_manifest: String }, | ||
} |
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.
What I like about the manifest is that it specifies everything needed to run an example in one place, as opposed if-conditions in our various build scripts. :)
With that approach, it has occurred to me that maybe it would make sense to keep the target logic outside of the runner and instead in each manifest.
Eg instead of specifying a target, and the runner having instructions on how to build with that target, could the manifest simply list a command that should be run, leaving the details of the build system up to it?
Lemme know if that makes sense. :)
Also curious to hear @rbehjati thoughts, since this somewhat relates to our conversation in the Oak Channel.
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.
Eg instead of specifying a target, and the runner having instructions on how to build with that target, could the manifest simply list a command that should be run, leaving the details of the build system up to it?
then we end up in the same copy paste collage that we already have in our scripts. the point of these manifests is to factor out as much common logic as possible.
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.
To me the main advantage isn't to get rid of redundancy (which seems more common in our formatting scripts anyway), but rather to avoid the various if [[ "${EXAMPLE}" == 'foo' ]];
conditionals in our shell scripts, putting all the logic for an example in one place.
Then in order to contribute an example, one needs to merely understand the manifest, not have a mental model of all of our build scripts.
I think if we can also eliminate the some redundancy, that's a bonus. My fear with being too aggressive in abstracting-common logic is that we'll eventually have similar conditionals in the rust runner to account for special & one-of cases, which would defeat the advantage outlined above.
It's not that I strongly feel about needing to go the other way here, but I do think it's worth keeping in mind. :)
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.
Sorry for the delay. I like what you are proposing @juliettepretot. Whenever there is a discussion of reuse, it reminds me of this hilarious talk.
I am also a bit worried about lines like this (although I think this line can easily be removed, and be added to each manifest):
Line 408 in 2709157
"--ca_cert=../../../../../../../../examples/certs/local/ca.pem".to_string(), |
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.
Thanks for sharing, that was a fun talk. :)
Re the line you mentioned, that's unrelated to the manifest. The same line exists in our bash script, and thankfully it will be phased out as we switch away from bazel.
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 think --ca_cert=...
could be added to the additional_args
list for each example, to make the manifests self-contained.
It is not an issue now, especially since we are going to remove bazel. But I think in general it is better to keep the manifests self-contained. I am also thinking of these manifest files as a form of documentation and a reference for how to run the examples. Similar to what you wrote :)
Then in order to contribute an example, one needs to merely understand the manifest, not have a mental model of all of our build scripts.
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.
LGTM :)
a693332
to
06436a1
Compare
06436a1
to
34c5d87
Compare
@@ -14,6 +14,7 @@ allow = [ | |||
"Apache-2.0", | |||
"Apache-2.0 WITH LLVM-exception", | |||
"BSD-2-Clause", | |||
"CC0-1.0", |
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.
FYI @conradgrobler I added this to the list of allowed licenses, as per go/thirdpartylicenses#unencumbered .
Reproducibility Index:
Reproducibility Index diff: |
Each example has a manifest file that determines how to build and run the oak application and related clients.
The new
--watch
flag allows runner to keep running in the background and re-run tests or any commands when any file in the repository changes.Example video: https://screencast.googleplex.com/cast/NDYzNjQyNTc2Mjg5NzkyMHwyY2VlYjM0Zi04Mw (Google internal only)
Checklist
construction.