Skip to content

Commit 67081ec

Browse files
authored
add buck2 RE rust example (#361)
- Adding Buck2 RE rust example - Adding example to CI run - Fixing a couple of typos in other READMEs - Fix minor issue with go toolchain with latest version of Buck2
1 parent aaaa3a4 commit 67081ec

File tree

13 files changed

+437
-0
lines changed

13 files changed

+437
-0
lines changed

buck2/rust/.buckconfig

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
[cells]
2+
root = .
3+
prelude = prelude
4+
toolchains = toolchains
5+
none = none
6+
7+
[cell_aliases]
8+
config = prelude
9+
fbcode = none
10+
fbsource = none
11+
buck = none
12+
13+
[external_cells]
14+
prelude = bundled
15+
16+
[parser]
17+
target_platform_detector_spec = target:root//...->root//platforms:remote_platform
18+
19+
[buck2]
20+
digest_algorithms = SHA256
21+
22+
[buck2_re_client]
23+
engine_address = <CLUSTER_NAME>.cluster.engflow.com
24+
action_cache_address = <CLUSTER_NAME>.cluster.engflow.com
25+
cas_address = <CLUSTER_NAME>.cluster.engflow.com
26+
http_headers = <AUTH_HTTP_HEADERS>
27+
28+
[build]
29+
execution_platforms = root//platforms:remote_platform
30+
31+
[project]
32+
ignore = .git

buck2/rust/.buckroot

Whitespace-only changes.

buck2/rust/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/buck-out

buck2/rust/BUCK

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2022 EngFlow Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
rust_library(
16+
name = "library",
17+
srcs = glob(
18+
["src/**/*.rs"],
19+
),
20+
)
21+
22+
rust_binary(
23+
name = "main",
24+
srcs = glob(
25+
["bin/**/*.rs"],
26+
),
27+
crate_root = "bin/main.rs",
28+
deps = [":library"],
29+
)
30+
31+
rust_test(
32+
name = "test",
33+
srcs = glob(
34+
["test/**/*.rs"],
35+
),
36+
deps = [":library"],
37+
# TODO: remove these once https://github.com/facebook/buck2/pull/826 gets merged.
38+
remote_execution_action_key_providers = select({
39+
"//platforms:engflow": "//platforms:remote_execution_action_keys",
40+
"DEFAULT": None,
41+
}),
42+
)

buck2/rust/README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# EngFlow RE + Buck2 Rust example
2+
3+
This example demonstrates use of EngFlow RE for a simple Rust project built with [Buck2](https://github.com/facebook/buck2) using the prelude.
4+
5+
It is based on two existing samples in the Buck2 upstream repo:
6+
7+
* Simple rust project with prelude - https://github.com/facebook/buck2/tree/main/examples/with_prelude/rust
8+
* Buck2 remote execution integration with EngFlow - https://github.com/facebook/buck2/tree/main/examples/remote_execution/engflow
9+
10+
### Example structure
11+
12+
In the `platforms` cell we specify:
13+
In the `platforms` cell we specify:
14+
* The platform used for remote execution in this project `root//platforms:remote_platform`, which includes the definition of the Docker image used for remote execution, and that defines constraints for targets to run in the remote execution environment. This platform provides an `ExecutionPlatformRegistrationInfo` a `ConfigurationInfo` and a `PlatformInfo` to be able to be used in the `.buckconfig`.
15+
* The action keys `root//platforms:remote_execution_action_keys`, which provides a default `BuildModeInfo` that is needed for RE of tests to function properly.
16+
* The platform `image` configured in `platforms/defs.bzl`, notably, uses a different image than other Buck2 samples in this repo. Specifically, it uses a public AWS image that has `rust` preinstalled. This is because Buck2 rust rules do not include a hermetic rust toolchain. We use a bookworm image with rust pre-installed. Image details can be found in https://gallery.ecr.aws/docker/library/rust. The Dockerfile can be found in https://github.com/rust-lang/docker-rust/blob/700c4f146427808cfb1e07a646e4afabbe99da4f/stable/bullseye/Dockerfile. If a different version of `rust` or other tools is needed you should create your own image and publish it to a repo that is accessible from the cluster.
17+
18+
In the `toolchains` cell we specify:
19+
20+
* The remote rust toolchain `root//toolchains:remote_rust_toolchain` which is compatible with the remote execution environment. This toolchain is configured with the `rustc_target_triple` to match the remote execution environment, and the `compiler`, `clippy_driver` and `rustdoc` attrs are set to point to the location of the `rustc` binary in the image used for remote execution.
21+
* The c++ toolchain `root//toolchains:cxx_tools_info_toolchain` that is compatible with the remote execution environment.
22+
* The clang tools, `root//toolchains:path_clang_tools`, which is used by the c++ toolchain, and specifies the tools installed in the Docker image.
23+
* The remote test execution toolchain, `root//toolchains:remote_test_execution_toolchain`. This toolchain defines platform options in the form of `capabilities`. Critically these include the `container-image`. This toolchain is identical to the one in the `buck2/cpp` sample in this repo.
24+
25+
The `src`, `bin` and `test` cells:
26+
27+
* Contain a copied version of https://github.com/facebook/buck2/tree/main/examples/with_prelude/rust that works with Buck2 and RE as configured in this sample project.
28+
29+
* Key changes for remote execution in the top level `BUCK` file include setting environment variables to select the pre-installed rust toolchain in the container and set a custom value for `HOME`. This custom value is needed as `rustp` attempts to create a directory in the `HOME` location and we prefer this happen inside the `buck-out/` directory to guarantee actions do not modify any content outside of their scratch directory.
30+
31+
To test the project with RE run (after setting up `.buckconfig` as indicated below):
32+
33+
```
34+
buck2 test --remote-only //:test
35+
```
36+
37+
You can also build the `main` for this sample by running:
38+
39+
```
40+
buck2 build --remote-only //:main
41+
```
42+
43+
Note the use of `--remote-only` to indicate remote execution should be used for the build / test command.
44+
45+
### Relevant configs in `.buckconfig`
46+
47+
The EngFlow endpoint and certificate should be configured as the
48+
following:
49+
50+
```ini
51+
[buck2_re_client]
52+
engine_address = <CLUSTER_NAME>.cluster.engflow.com
53+
action_cache_address = <CLUSTER_NAME>.cluster.engflow.com
54+
cas_address = <CLUSTER_NAME>.cluster.engflow.com
55+
http_headers = <AUTH_HTTP_HEADERS>
56+
```
57+
58+
To obtain the value of `<AUTH_HTTP_HEADERS>`, log into https://<CLUSTER_NAME>.cluster.engflow.com/gettingstarted and obtain the value of `x-engflow-auth-token` in section `Method 2: JWT`, take note of this value. Then set `AUTH_HTTP_HEADERS` with the value `x-engflow-auth-method:jwt-v0,x-engflow-auth-token:<JWT_TOKEN_FROM_GETTINGSTARTED_PAGE>.
59+
60+
Note for CI runs, the auth method used is [Github Tokens](https://docs.engflow.com/re/config/authentication.html#github-tokens).

buck2/rust/bin/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
library::print_hello();
3+
}

buck2/rust/platforms/BUCK

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Copyright 2022 EngFlow Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
load(":defs.bzl", "platforms")
16+
load(":defs.bzl", "action_keys")
17+
18+
constraint_setting(
19+
name = "re_provider"
20+
)
21+
22+
constraint_value(
23+
name = "engflow",
24+
constraint_setting = ":re_provider",
25+
)
26+
27+
# This platform configures details of remote execution.
28+
platforms(
29+
name = "remote_platform",
30+
cpu_configuration = "config//cpu:x86_64",
31+
os_configuration = "config//os:linux",
32+
re_provider = ":engflow",
33+
)
34+
35+
# This action_key provides a default BuildModeInfo that is needed for RE of tests to function properly.
36+
# The values in `cell` and `mode` can be used, in practice, to create cache silos. Any values can be given to these attributes.
37+
action_keys(
38+
name = "remote_execution_action_keys",
39+
cell = "standard",
40+
mode = "standard",
41+
visibility = ["PUBLIC"],
42+
)

buck2/rust/platforms/defs.bzl

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Copyright 2022 EngFlow Inc. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# This platform is essentially the same as the one provided in https://github.com/facebook/buck2/blob/804d62242214455d51787f7c8c96a1e12c75ec32/examples/remote_execution/engflow/platforms/defs.bzl
16+
# The main difference is we enable passing CPU and OS constraints and we use the sample EngFlow RE image.
17+
load("@prelude//:build_mode.bzl", "BuildModeInfo")
18+
19+
def _platforms(ctx):
20+
constraints = dict()
21+
constraints.update(ctx.attrs.cpu_configuration[ConfigurationInfo].constraints)
22+
constraints.update(ctx.attrs.os_configuration[ConfigurationInfo].constraints)
23+
constraints.update(ctx.attrs.re_provider[ConfigurationInfo].constraints)
24+
configuration = ConfigurationInfo(
25+
constraints = constraints,
26+
values = {},
27+
)
28+
29+
# A bookworm image with rust pre-installed. Image details can be found in https://gallery.ecr.aws/docker/library/rust.
30+
# Dockerfile can be found in https://github.com/rust-lang/docker-rust/blob/700c4f146427808cfb1e07a646e4afabbe99da4f/stable/bullseye/Dockerfile
31+
image = "docker://public.ecr.aws/docker/library/rust:1.83.0-bullseye@sha256:24118f76a7da011b22a25b8e9dbdbb549ed29c1eba635d6aa4a9c9f5ed545066"
32+
name = ctx.label.raw_target()
33+
platform = ExecutionPlatformInfo(
34+
label = ctx.label.raw_target(),
35+
configuration = configuration,
36+
executor_config = CommandExecutorConfig(
37+
local_enabled = False,
38+
remote_enabled = True,
39+
use_limited_hybrid = False,
40+
remote_execution_properties = {
41+
"container-image": image,
42+
},
43+
remote_execution_use_case = "buck2-default",
44+
# TODO: Use output_paths
45+
remote_output_paths = "strict",
46+
),
47+
)
48+
49+
return [
50+
DefaultInfo(),
51+
ExecutionPlatformRegistrationInfo(platforms = [platform]),
52+
configuration,
53+
PlatformInfo(label = str(name), configuration = configuration),
54+
]
55+
56+
def _action_keys(ctx):
57+
return [
58+
DefaultInfo(),
59+
BuildModeInfo(cell = ctx.attrs.cell, mode = ctx.attrs.mode),
60+
]
61+
62+
platforms = rule(
63+
attrs = {
64+
"cpu_configuration": attrs.dep(providers = [ConfigurationInfo]),
65+
"os_configuration": attrs.dep(providers = [ConfigurationInfo]),
66+
"re_provider": attrs.dep(providers = [ConfigurationInfo]),
67+
},
68+
impl = _platforms
69+
)
70+
71+
action_keys = rule(
72+
attrs = {
73+
"cell": attrs.string(),
74+
"mode": attrs.string(),
75+
},
76+
impl = _action_keys
77+
)

buck2/rust/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub fn print_hello() {
2+
println!("hello world from rust toolchain");
3+
}

buck2/rust/test/test.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#[test]
2+
fn test_it_doesnt_crash() {
3+
library::print_hello();
4+
}

0 commit comments

Comments
 (0)