Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions buck2/golang/.buckconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[cells]
root = .
prelude = prelude
toolchains = toolchains
none = none

[cell_aliases]
config = prelude
fbcode = none
fbsource = none
buck = none

[external_cells]
prelude = bundled

[parser]
target_platform_detector_spec = target:root//...->prelude//platforms:default

[buck2]
digest_algorithms = SHA256

[buck2_re_client]
engine_address = <CLUSTER_NAME>.cluster.engflow.com
action_cache_address = <CLUSTER_NAME>.cluster.engflow.com
cas_address = <CLUSTER_NAME>.cluster.engflow.com
http_headers = x-engflow-auth-method:jwt-v0,x-engflow-auth-token:LONG_JWT_STRING

[build]
execution_platforms = root//platforms:remote_platform

[project]
ignore = .git
Empty file added buck2/golang/.buckroot
Empty file.
1 change: 1 addition & 0 deletions buck2/golang/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/buck-out
52 changes: 52 additions & 0 deletions buck2/golang/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# EngFlow RE + Buck2 Go example

This example demonstrates use of EngFlow RE for a simple Go lang project built with [Buck2](https://github.com/facebook/buck2) using the prelude.

It is based on three existing samples in the Buck2 upstream repo and the EngFlow samples repo:

* Simple go project with prelude - https://github.com/facebook/buck2/tree/main/examples/with_prelude/go
* Buck2 remote execution integration with EngFlow - https://github.com/facebook/buck2/tree/main/examples/remote_execution/engflow
* EngFlow go example - https://github.com/EngFlow/example/tree/main/go

### Example structure

In the `platforms` cell we specify:
* 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`.
* The action keys `root//platforms:remote_execution_action_keys`, which provides a default `BuildModeInfo` that is needed for RE of tests to function properly.
* 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 `go` preinstalled. This is because, unlike Bazel go rules, Buck2 go rules do not include a hermetic go binary.

In the `toolchains` cell we specify:

* The remote go toolchain `root//toolchains:remote_go_toolchain` and remote go bootstrap toolchain `root//toolchains:remote_go_bootstrap_toolchain`, which are compatible with the remote execution environment. These toolchains are configured for `go_arch` set to `amd64` and `go_os` set to `linux`.
* 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.

The `main` cell and `library` cell:

* Contains an copied version of https://github.com/facebook/buck2/tree/main/examples/with_prelude/go that works with Buck2 and RE as configured in this sample project.

To test this cell with RE run (after setting up `.buckconfig` as indicated below):

```
buck2 test //go/greeting:greeting_test
```

You can also build the `main` for this sample by running:

```
buck2 build //go:hello
```

### Relevant configs in `.buckconfig`

The EngFlow endpoint and certificate should be configured as the
following:

```ini
[buck2_re_client]
engine_address = <CLUSTER_NAME>.cluster.engflow.com
action_cache_address = <CLUSTER_NAME>.cluster.engflow.com
cas_address = <CLUSTER_NAME>.cluster.engflow.com
http_headers = x-engflow-auth-method:jwt-v0,x-engflow-auth-token:LONG_JWT_STRING
```

To obtain the value of `LONG_JWT_STRING`, log into https://<CLUSTER_NAME>.cluster.engflow.com/gettingstarted and use the value of `x-engflow-auth-token` in section `Method 2: JWT`.
21 changes: 21 additions & 0 deletions buck2/golang/go/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2022 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

go_binary(
name = "hello",
srcs = ["main.go"],
deps = [
"//go/greeting:greeting",
],
)
25 changes: 25 additions & 0 deletions buck2/golang/go/greeting/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright 2022 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

go_library(
name = "greeting",
srcs = glob(["*.go"]),
visibility = ["PUBLIC"],
)

go_test(
name = "greeting_test",
srcs = glob(["*.go"]),
remote_execution_action_key_providers = "//platforms:remote_execution_action_keys",
)
7 changes: 7 additions & 0 deletions buck2/golang/go/greeting/greeting.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

package greeting

// Greeting returns a greeting message
func Greeting() string {
return "Hello, world!"
}
9 changes: 9 additions & 0 deletions buck2/golang/go/greeting/greeting_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package greeting

import "testing"

func TestHello(t *testing.T) {
if Greeting() != "Hello, world!" {
t.Errorf("Greeting() = %v, want \"Hello, world!\"", Greeting())
}
}
11 changes: 11 additions & 0 deletions buck2/golang/go/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"fmt"

"go/greeting"
)

func main() {
fmt.Println(greeting.Greeting())
}
30 changes: 30 additions & 0 deletions buck2/golang/platforms/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright 2022 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load(":defs.bzl", "platforms")
load(":defs.bzl", "action_keys")

# This platform configures details of remote execution.
platforms(
name = "remote_platform",
)

# This action_key provides a default BuildModeInfo that is needed for RE of tests to function properly.
# The values in `cell` and `mode` can be used, in practice, to create cache silos. Any values can be given to these attributes.
action_keys(
name = "remote_execution_action_keys",
cell = "standard",
mode = "standard",
visibility = ["PUBLIC"],
)
68 changes: 68 additions & 0 deletions buck2/golang/platforms/defs.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright 2022 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# 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
# The main difference is we enable passing CPU and OS constraints and we use the sample EngFlow RE image.
load("@prelude//:build_mode.bzl", "BuildModeInfo")

def _platforms(ctx):
constraints = dict()
configuration = ConfigurationInfo(
constraints = constraints,
values = {},
)

# A bookworm image with go pre-installed.
# Unlike Bazel go_toolchain, Buck2 go_toolchain does not include a hermetic go binary.
image = "docker://public.ecr.aws/docker/library/golang:1.23.3-bookworm@sha256:3f3b9daa3de608f3e869cd2ff8baf21555cf0fca9fd34251b8f340f9b7c30ec5"
name = ctx.label.raw_target()
platform = ExecutionPlatformInfo(
label = ctx.label.raw_target(),
configuration = configuration,
executor_config = CommandExecutorConfig(
local_enabled = False,
remote_enabled = True,
use_limited_hybrid = False,
remote_execution_properties = {
"container-image": image,
},
remote_execution_use_case = "buck2-default",
# TODO: Use output_paths
remote_output_paths = "strict",
),
)

return [
DefaultInfo(),
ExecutionPlatformRegistrationInfo(platforms = [platform]),
]

def _action_keys(ctx):
return [
DefaultInfo(),
BuildModeInfo(cell = ctx.attrs.cell, mode = ctx.attrs.mode),
]

platforms = rule(
attrs = {},
impl = _platforms
)

action_keys = rule(
attrs = {
"cell": attrs.string(),
"mode": attrs.string(),
},
impl = _action_keys
)
65 changes: 65 additions & 0 deletions buck2/golang/toolchains/BUCK
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@

# Copyright 2022 EngFlow Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load("defs.bzl", "remote_go_toolchain", "remote_go_bootstrap_toolchain")
load("@prelude//toolchains:cxx.bzl", "cxx_tools_info_toolchain")
load("@prelude//toolchains:python.bzl", "system_python_bootstrap_toolchain")
load("@prelude//toolchains:remote_test_execution.bzl", "remote_test_execution_toolchain")
load("@prelude//tests:test_toolchain.bzl", "noop_test_toolchain")

# Python toolchain used in scripts that bootstrap other aspects of the Buck2 prelude.
system_python_bootstrap_toolchain(
name = "python_bootstrap",
visibility = ["PUBLIC"],
)

remote_go_bootstrap_toolchain(
name = "go_bootstrap",
visibility = ["PUBLIC"],
)

# c++ toolchain required implicitly for py targets.
cxx_tools_info_toolchain(
name = "cxx",
visibility = ["PUBLIC"],
)

remote_go_toolchain(
name = "go",
visibility = ["PUBLIC"],
)

# Default toolchain for remote execution of tests.
# Note it defines a profile with a capability that defines the `container-image` that matches the one defined in //platforms:remote_platform.
# Capabilities are passed to the RE service to find workers that match them as Platform options.
remote_test_execution_toolchain(
name = "remote_test_execution",
visibility = ["PUBLIC"],
default_profile = "cxx_re_toolchain",
profiles = {
"cxx_re_toolchain": {
"use_case": "cxx-testing",
"capabilities": {
"container-image" : "docker://gcr.io/bazel-public/ubuntu2004-java11@sha256:69a78f121230c6d5cbfe2f4af8ce65481aa3f2acaaaf8e899df335f1ac1b35b5",
},
}
},
)

# In some cases the execution of test can fail looking for this `noop_test_toolchain`.
noop_test_toolchain(
name = "test",
visibility = ["PUBLIC"],
)
Loading
Loading