diff --git a/.buildkite-bazelrc b/.buildkite-bazelrc index 240afe826..3a824554f 100644 --- a/.buildkite-bazelrc +++ b/.buildkite-bazelrc @@ -12,7 +12,8 @@ #build:remote-cache --disk_cache= build:remote-cache --remote_download_toplevel build:remote-cache --remote_cache=grpc://bazel-remote-cache:9092 -build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092 +# Does not work with rules_oci. See https://github.com/bazel-contrib/rules_oci/issues/292 +#build:remote-cache --experimental_remote_downloader=grpc://bazel-remote-cache:9092 build:remote-cache --remote_local_fallback build:remote-cache --experimental_remote_cache_async build:remote-cache --experimental_remote_merkle_tree_cache diff --git a/WORKSPACE b/WORKSPACE index d49d3a6dc..86304506b 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -50,8 +50,6 @@ load("@prysm//tools/cross-toolchain:prysm_toolchains.bzl", "configure_prysm_tool configure_prysm_toolchains() -load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") - http_archive( name = "bazel_skylib", sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c", @@ -87,6 +85,24 @@ http_archive( urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.25.0/rules_docker-v0.25.0.tar.gz"], ) +http_archive( + name = "rules_oci", + sha256 = "c71c25ed333a4909d2dd77e0b16c39e9912525a98c7fa85144282be8d04ef54c", + strip_prefix = "rules_oci-1.3.4", + url = "https://github.com/bazel-contrib/rules_oci/releases/download/v1.3.4/rules_oci-v1.3.4.tar.gz", +) + +load("@rules_oci//oci:dependencies.bzl", "rules_oci_dependencies") + +rules_oci_dependencies() + +load("@rules_oci//oci:repositories.bzl", "LATEST_CRANE_VERSION", "oci_register_toolchains") + +oci_register_toolchains( + name = "oci", + crane_version = LATEST_CRANE_VERSION, +) + http_archive( name = "io_bazel_rules_go", patch_args = ["-p1"], @@ -167,6 +183,24 @@ container_pull( repository = "pinglamb/alpine-glibc", ) +load("@rules_oci//oci:pull.bzl", "oci_pull") + +# A multi-arch base image +oci_pull( + name = "linux_debian11_multiarch_base", # Debian bullseye + digest = "sha256:9b8e0854865dcaf49470b4ec305df45957020fbcf17b71eeb50ffd3bc5bf885d", # 2023-05-17 + image = "gcr.io/distroless/cc-debian11", + platforms = [ + "linux/amd64", + "linux/arm64", + ], + reproducible = True, +) + +load("@prysm//tools:image_deps.bzl", "prysm_image_deps") + +prysm_image_deps() + load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") go_rules_dependencies() @@ -337,9 +371,6 @@ http_archive( ], ) -# Group the sources of the library so that CMake rule have access to it -all_content = """filegroup(name = "all", srcs = glob(["**"]), visibility = ["//visibility:public"])""" - # External dependencies load("//:deps.bzl", "prysm_deps") diff --git a/cmd/beacon-chain/BUILD.bazel b/cmd/beacon-chain/BUILD.bazel index 640a2bfae..aa973fdf4 100644 --- a/cmd/beacon-chain/BUILD.bazel +++ b/cmd/beacon-chain/BUILD.bazel @@ -4,6 +4,7 @@ load("@io_bazel_rules_docker//go:image.bzl", "go_image") load("@io_bazel_rules_docker//container:container.bzl", "container_bundle", "container_image") load("//tools:go_image.bzl", "go_image_debug") load("@io_bazel_rules_docker//contrib:push-all.bzl", "docker_push") +load("//tools:prysm_image.bzl", "prysm_image_upload") go_library( name = "go_default_library", @@ -126,3 +127,14 @@ go_test( "@com_github_urfave_cli_v2//:go_default_library", ], ) + +prysm_image_upload( + name = "push_oci_image", + binary = ":beacon-chain", + entrypoint = ["/beacon-chain"], + repository = "gcr.io/prylabs-dev/prysm/beacon-chain", + symlinks = { + # Backwards compatiability for images that depended on the old filepath. + "/app/cmd/beacon-chain/beacon-chain": "/beacon-chain", + }, +) diff --git a/cmd/prysmctl/BUILD.bazel b/cmd/prysmctl/BUILD.bazel index c8c839ea3..f84ecc09b 100644 --- a/cmd/prysmctl/BUILD.bazel +++ b/cmd/prysmctl/BUILD.bazel @@ -4,6 +4,7 @@ load("@io_bazel_rules_docker//go:image.bzl", "go_image") load("@io_bazel_rules_docker//container:container.bzl", "container_bundle", "container_image") load("//tools:go_image.bzl", "go_image_debug") load("@io_bazel_rules_docker//contrib:push-all.bzl", "docker_push") +load("//tools:prysm_image.bzl", "prysm_image_upload") go_library( name = "go_default_library", @@ -88,3 +89,14 @@ go_binary( gotags = ["noMainnetGenesis"], visibility = ["//visibility:public"], ) + +prysm_image_upload( + name = "push_oci_image", + binary = ":prysmctl", + entrypoint = ["/prysmctl"], + repository = "gcr.io/prylabs-dev/prysm/prysmctl", + symlinks = { + # Backwards compatiability for images that depended on the old filepath. + "/app/cmd/prysmctl/prysmctl": "/prysmctl", + }, +) diff --git a/cmd/validator/BUILD.bazel b/cmd/validator/BUILD.bazel index 4643c5cbd..2e7b9b382 100644 --- a/cmd/validator/BUILD.bazel +++ b/cmd/validator/BUILD.bazel @@ -4,6 +4,7 @@ load("@io_bazel_rules_docker//go:image.bzl", "go_image") load("@io_bazel_rules_docker//container:container.bzl", "container_bundle", "container_image") load("//tools:go_image.bzl", "go_image_debug") load("@io_bazel_rules_docker//contrib:push-all.bzl", "docker_push") +load("//tools:prysm_image.bzl", "prysm_image_upload") go_library( name = "go_default_library", @@ -121,3 +122,14 @@ go_test( "@com_github_urfave_cli_v2//:go_default_library", ], ) + +prysm_image_upload( + name = "push_oci_image", + binary = ":validator", + entrypoint = ["/validator"], + repository = "gcr.io/prylabs-dev/prysm/validator", + symlinks = { + # Backwards compatiability for images that depended on the old filepath. + "/app/cmd/validator/validator": "/validator", + }, +) diff --git a/hack/build_and_upload_docker.sh b/hack/build_and_upload_docker.sh new file mode 100755 index 000000000..c80e82fe7 --- /dev/null +++ b/hack/build_and_upload_docker.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +# ----------------------------------------------------------------------------- +# This script builds and uploads the docker images to the registries. +# +# This script is intended to be a workaround until the rules_oci project supports +# targets with multiple repositories like rules_docker does. See: https://github.com/bazel-contrib/rules_oci/issues/248 +# ----------------------------------------------------------------------------- + +# Validate that the tag argument exists. +if [ "$1" = "" ] +then + echo "Usage: $0 " + exit +fi +TAG=$1 + +# Sanity check that all targets can build before running them. +bazel build --config=release \ + //cmd/beacon-chain:push_oci_image \ + //cmd/validator:push_oci_image \ + //cmd/prysmctl:push_oci_image + +# Push the images to the registry. +### Beacon chain +bazel run --config=release \ + //cmd/beacon-chain:push_oci_image -- --tag=$TAG + +### Beacon chain (blst portable image) +bazel run --config=release --define=blst_modern=false \ + //cmd/beacon-chain:push_oci_image -- --tag=$TAG-portable + +### Validator +bazel run --config=release \ + //cmd/validator:push_oci_image -- --tag=$TAG + +### Prysmctl +bazel run --config=release \ + //cmd/prysmctl:push_oci_image -- --tag=$TAG diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index 47c9215ee..d33500812 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -40,6 +40,7 @@ pkg_tar( mode = "0o644", package_dir = "etc", tags = ["manual"], + visibility = ["//visibility:public"], ) CC_DEFAULT_BASE = select({ @@ -99,3 +100,28 @@ container_image( user = "root", visibility = ["//visibility:public"], ) + +# Create a bash tar layer for docker images. This allows docker images to have access to the "bash" +# command and improves debugging abilities on the image. +genrule( + name = "bash_tar", + srcs = select({ + "@platforms//cpu:x86_64": ["@bash_amd64//file"], + "@platforms//cpu:arm64": ["@bash_arm64//file"], + }), + outs = ["bash.tar"], + cmd = "ar x $< && xz -d data.tar.xz -c >> $@", + visibility = ["//visibility:public"], +) + +# libtinfo6 is required for terminal activity and contains terminfo library. +genrule( + name = "libtinfo6_tar", + srcs = select({ + "@platforms//cpu:x86_64": ["@libtinfo6_amd64//file"], + "@platforms//cpu:arm64": ["@libtinfo6_arm64//file"], + }), + outs = ["libtinfo6.tar"], + cmd = "ar x $< && xz -d data.tar.xz -c >> $@", + visibility = ["//visibility:public"], +) diff --git a/tools/image_deps.bzl b/tools/image_deps.bzl new file mode 100644 index 000000000..bdc415792 --- /dev/null +++ b/tools/image_deps.bzl @@ -0,0 +1,48 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file") + +def prysm_image_deps(): + http_file( + name = "bash_amd64", + sha256 = "f702ef058e762d7208a9c83f6f6bbf02645533bfd615c54e8cdcce842cd57377", + urls = [ + "http://ftp.us.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_amd64.deb", + "http://http.us.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_amd64.deb", + "http://ftp.uk.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_amd64.deb", + "http://ftp.au.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_amd64.deb", + ], + ) + + http_file( + name = "bash_arm64", + sha256 = "d7c7af5d86f43a885069408a89788f67f248e8124c682bb73936f33874e0611b", + urls = [ + "http://ftp.us.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_arm64.deb", + "http://http.us.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_arm64.deb", + "http://ftp.uk.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_arm64.deb", + "http://ftp.au.debian.org/debian/pool/main/b/bash/bash_5.1-2+deb11u1_arm64.deb", + ], + ) + + http_file( + name = "libtinfo6_amd64", + sha256 = "92ac8a8c12f02a6fe08c47f33ea6fb313e1b9480484e26eab34e2058ea59fdb4", + urls = [ + "http://ftp.us.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_amd64.deb", + "http://http.us.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_amd64.deb", + "http://ftp.uk.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_amd64.deb", + "http://ftp.au.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_amd64.deb", + ], + ) + + http_file( + name = "libtinfo6_arm64", + sha256 = "8282a785437b305bca7758aba19252bd81b5d0d2a54b709af97e682516f1cf4e", + urls = [ + "http://ftp.us.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_arm64.deb", + "http://http.us.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_arm64.deb", + "http://ftp.uk.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_arm64.deb", + "http://ftp.au.debian.org/debian/pool/main/n/ncurses/libtinfo6_6.2+20201114-2+deb11u1_arm64.deb", + ], + ) + + diff --git a/tools/multi_arch.bzl b/tools/multi_arch.bzl new file mode 100644 index 000000000..8c811b182 --- /dev/null +++ b/tools/multi_arch.bzl @@ -0,0 +1,30 @@ +"a rule transitioning an oci_image to multiple platforms" + +def _multiarch_transition(settings, attr): + return [ + {"//command_line_option:platforms": str(platform)} + for platform in attr.platforms + ] + +multiarch_transition = transition( + implementation = _multiarch_transition, + inputs = [], + outputs = ["//command_line_option:platforms"], +) + +# multiarch_transition impl returns a DefaultInfo provider with the image deps as declared outputs to +# build. +def _impl(ctx): + return DefaultInfo(files = depset(ctx.files.image)) + +# The multi_arch rule builds the image for multiple platforms defined in the platforms attribute. +multi_arch = rule( + implementation = _impl, + attrs = { + "image": attr.label(cfg = multiarch_transition), + "platforms": attr.label_list(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) diff --git a/tools/prysm_image.bzl b/tools/prysm_image.bzl new file mode 100644 index 000000000..55dcbc752 --- /dev/null +++ b/tools/prysm_image.bzl @@ -0,0 +1,50 @@ +load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index", "oci_push") +load("@rules_pkg//:pkg.bzl", "pkg_tar") +load("//tools:multi_arch.bzl", "multi_arch") + +def prysm_image_upload( + name, + binary, + entrypoint, + symlinks, + repository): + + pkg_tar( + name = "binary_tar", + srcs = [binary], + symlinks=symlinks, + ) + + oci_image( + name = "oci_image", + base = "@linux_debian11_multiarch_base", + entrypoint = entrypoint, + tars = [ + "//tools:passwd_tar", + "//tools:libtinfo6_tar", + "//tools:bash_tar", + ":binary_tar", + ], + ) + + multi_arch( + name = "oci_multiarch", + image = ":oci_image", + platforms = [ + "@io_bazel_rules_go//go/toolchain:linux_amd64_cgo", + "@io_bazel_rules_go//go/toolchain:linux_arm64_cgo", + ], + ) + + oci_image_index( + name = "oci_image_index", + images = [ + ":oci_multiarch", + ], + ) + + oci_push( + name = name, + image = ":oci_image_index", + repository = repository, + ) \ No newline at end of file