diff --git a/.bazelrc b/.bazelrc index c5bf90531edf..3446d4d56116 100644 --- a/.bazelrc +++ b/.bazelrc @@ -71,10 +71,6 @@ build:rbe-26 --platforms=//bazel/platforms:erlang_linux_26_platform # no-op config so that --config=local does not error build:local --color=auto -# having bzlmod enabled seems to interfere with docker toolchain resolution, -# so we set this flag -build --@io_bazel_rules_docker//transitions:enable=false - # Try importing a user specific .bazelrc # You can create your own by copying and editing the template-user.bazelrc template: # cp template-user.bazelrc user.bazelrc diff --git a/.github/workflows/oci.yaml b/.github/workflows/oci.yaml index 486f63871a62..769034844e58 100644 --- a/.github/workflows/oci.yaml +++ b/.github/workflows/oci.yaml @@ -6,46 +6,31 @@ on: - '.github/workflows/secondary-umbrella.yaml' workflow_dispatch: env: - GENERIC_UNIX_ARCHIVE: ${{ github.workspace }}/bazel-bin/package-generic-unix.tar.xz - RABBITMQ_VERSION: ${{ github.event.pull_request.head.sha || github.sha }} VERSION: ${{ github.event.pull_request.head.sha || github.sha }} concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: - - # This job will build one docker image per supported Erlang major version. - # Each image will have two tags (one containing the Git commit SHA, one containing the branch name). - # - # For example, for Git commit SHA '111aaa' and branch name 'main' and maximum supported Erlang major version '26', - # the following tags will be pushed to Dockerhub: - # - # * 111aaa-otp-min (image OTP 25) - # * main-otp-min (image OTP 25) - # * 111aaa-otp-max (image OTP 26) - # * main-otp-max (image OTP 26) - build-publish-dev-bazel: - runs-on: ubuntu-20.04 - strategy: - fail-fast: false - matrix: - include: - - image_tag_suffix: otp-min-bazel - otp_version_id: 25_0 - - image_tag_suffix: otp-max-bazel - otp_version_id: 25_3 + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - - name: Mount Bazel Cache - uses: actions/cache@v4.0.2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Configure Erlang + uses: erlef/setup-beam@v1 with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- + otp-version: 26.2 + elixir-version: 1.15 + + - name: Expose GitHub Runtime + uses: crazy-max/ghaction-github-runtime@v3 - name: Configure Bazel run: | @@ -57,35 +42,27 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PRIVATE - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= - build:buildbuddy --remote_download_toplevel + build --experimental_ui_max_stdouterr_bytes=4194304 + build --action_env EXTRA_BUILDX_OPTS="--cache-from=type=gha --cache-to=type=gha" EOF - - name: Configure otp for the OCI image + - name: Build amd64 run: | - sudo npm install --global --silent @bazel/buildozer - - buildozer 'set tars ["@otp_src_${{ matrix.otp_version_id }}//file"]' \ - //packaging/docker-image:otp_source + bazelisk build //packaging/docker-image:rabbitmq-amd64 \ + --config=buildbuddy - - name: Build + - name: Build arm64 run: | - bazelisk build //packaging/docker-image:rabbitmq \ - --config=rbe-${{ matrix.otp_version_id }} + bazelisk build //packaging/docker-image:rabbitmq-arm64 \ + --config=buildbuddy - name: Test run: | OCI_TESTS=$(bazel cquery 'tests(//packaging/docker-image/...)' | awk '{ print $1 }') bazelisk test ${OCI_TESTS} \ - --config=rbe-${{ matrix.otp_version_id }} - - - name: Load - run: | - bazelisk run //packaging/docker-image:rabbitmq \ - --config=rbe-${{ matrix.otp_version_id }} + --config=buildbuddy - name: Check for Push Credentials id: authorized @@ -96,6 +73,11 @@ jobs: echo "PUSH=false" >> $GITHUB_OUTPUT fi + - name: Assemble Multi-Arch + run: | + bazelisk build //packaging/docker-image:rabbitmq \ + --config=buildbuddy + - name: Login to DockerHub if: steps.authorized.outputs.PUSH == 'true' uses: docker/login-action@v3 @@ -106,16 +88,16 @@ jobs: - name: Tag and Push if: steps.authorized.outputs.PUSH == 'true' run: | - TAG_1="${{ github.event.pull_request.head.sha || github.sha }}-${{ matrix.image_tag_suffix }}" - TAG_2="${GITHUB_REF##*/}-${{ matrix.image_tag_suffix }}" + TAG_1="${{ env.VERSION }}" - docker tag bazel/packaging/docker-image:rabbitmq \ - pivotalrabbitmq/rabbitmq:${TAG_1} - docker tag bazel/packaging/docker-image:rabbitmq \ - pivotalrabbitmq/rabbitmq:${TAG_2} + REF_NAME="${{ github.ref_name }}" + TAG_2="${REF_NAME//\//-}" - docker push pivotalrabbitmq/rabbitmq:${TAG_1} - docker push pivotalrabbitmq/rabbitmq:${TAG_2} + set -x + bazelisk run //packaging/docker-image:push \ + --config=buildbuddy -- \ + --tag ${TAG_1} \ + --tag ${TAG_2} summary-oci: needs: diff --git a/.github/workflows/rabbitmq_peer_discovery_aws.yaml b/.github/workflows/rabbitmq_peer_discovery_aws.yaml index 61f7e0c31bdf..acbcdbfd646c 100644 --- a/.github/workflows/rabbitmq_peer_discovery_aws.yaml +++ b/.github/workflows/rabbitmq_peer_discovery_aws.yaml @@ -7,9 +7,8 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - include: - - image_tag_suffix: otp-max-bazel - otp_version_id: 25_3 + otp_version_id: + - 25_3 timeout-minutes: 45 steps: - name: CHECKOUT REPOSITORY @@ -18,16 +17,9 @@ jobs: uses: lewagon/wait-on-check-action@v1.3.4 with: ref: ${{ github.ref }} - check-name: build-publish-dev-bazel (${{ matrix.image_tag_suffix }}, ${{ matrix.otp_version_id }}) + check-name: build-publish-dev-bazel repo-token: ${{ secrets.GITHUB_TOKEN }} wait-interval: 30 # seconds - - name: MOUNT BAZEL CACHE - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - name: CONFIGURE BAZEL run: | cat << EOF >> user.bazelrc @@ -35,9 +27,7 @@ jobs: build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PRIVATE - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= EOF #! - name: Setup tmate session #! uses: mxschmitt/action-tmate@v3 @@ -53,6 +43,6 @@ jobs: --build_tests_only \ --test_env AWS_ACCESS_KEY_ID=${{ secrets.CONCOURSE_AWS_ACCESS_KEY_ID }} \ --test_env AWS_SECRET_ACCESS_KEY=${{ secrets.CONCOURSE_AWS_SECRET_ACCESS_KEY }} \ - --test_env RABBITMQ_IMAGE="pivotalrabbitmq/rabbitmq:${{ github.sha }}-otp-max-bazel" \ + --test_env RABBITMQ_IMAGE="pivotalrabbitmq/rabbitmq:${{ github.sha }}" \ --test_env AWS_ECS_CLUSTER_NAME="rabbitmq-peer-discovery-aws-actions-${branch_or_tag//[._]/-}" \ --verbose_failures diff --git a/.github/workflows/test-authnz.yaml b/.github/workflows/test-authnz.yaml index 15d28890774b..23b17c23725c 100644 --- a/.github/workflows/test-authnz.yaml +++ b/.github/workflows/test-authnz.yaml @@ -50,18 +50,8 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - - name: Mount Bazel Cache - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - - name: Configure Bazel run: | - ERLANG_HOME="$(dirname $(dirname $(which erl)))" - ELIXIR_HOME="$(dirname $(dirname $(which iex)))" if [ -n "${{ secrets.BUILDBUDDY_API_KEY }}" ]; then cat << EOF >> user.bazelrc build:buildbuddy --remote_header=x-buildbuddy-api-key=${{ secrets.BUILDBUDDY_API_KEY }} @@ -70,20 +60,12 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PRIVATE - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= - - build:buildbuddy --remote_download_toplevel - - build --@rules_erlang//:erlang_version=${{ matrix.erlang_version }} - build --@rules_erlang//:erlang_home=${ERLANG_HOME} - build --//:elixir_home=${ELIXIR_HOME} EOF - name: Build & Load RabbitMQ OCI run: | - bazelisk run packaging/docker-image:rabbitmq \ + bazelisk run packaging/docker-image:rabbitmq-amd64 \ --config=buildbuddy - name: Configure Docker Network @@ -97,7 +79,7 @@ jobs: - name: Run Suites run: | - RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq ${SELENIUM_DIR}/run-suites.sh full-suite-authnz + RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq-amd64 ${SELENIUM_DIR}/run-suites.sh full-suite-authnz-messaging - name: Upload Test Artifacts if: always() diff --git a/.github/workflows/test-erlang-git.yaml b/.github/workflows/test-erlang-git.yaml index 4404861be196..b8480d27786b 100644 --- a/.github/workflows/test-erlang-git.yaml +++ b/.github/workflows/test-erlang-git.yaml @@ -11,13 +11,6 @@ jobs: steps: - name: CHECKOUT REPOSITORY uses: actions/checkout@v4 - - name: MOUNT BAZEL CACHE - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - name: CONFIGURE BAZEL run: | if [ -n "${{ secrets.BUILDBUDDY_API_KEY }}" ]; then @@ -28,9 +21,7 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PUBLIC - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= build:rbe --platforms=//bazel/platforms:erlang_git_master_platform build:rbe --extra_execution_platforms=//bazel/platforms:erlang_git_master_platform diff --git a/.github/workflows/test-mixed-versions.yaml b/.github/workflows/test-mixed-versions.yaml index 07b5cdf87845..bac953e89439 100644 --- a/.github/workflows/test-mixed-versions.yaml +++ b/.github/workflows/test-mixed-versions.yaml @@ -69,14 +69,6 @@ jobs: with: ref: v${{ steps.check.outputs.version }} path: secondary-umbrella - - name: MOUNT BAZEL CACHE - if: env.exists != 'true' - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: repo-cache-secondary-umbrella-${{ hashFiles('primary-umbrella/MODULE.bazel','primary-umbrella/WORKSPACE','primary-umbrella/bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - repo-cache-secondary-umbrella- - name: BUILD SECONDARY UMBRELLA ARCHIVE if: env.exists != 'true' working-directory: secondary-umbrella @@ -90,9 +82,7 @@ jobs: build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PRIVATE build:buildbuddy --remote_instance_name=buildbuddy-io/buildbuddy/ci-secondary-umbrella - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= build:buildbuddy --remote_download_toplevel EOF @@ -134,13 +124,6 @@ jobs: steps: - name: CHECKOUT REPOSITORY uses: actions/checkout@v4 - - name: MOUNT BAZEL CACHE - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - name: CONFIGURE BAZEL run: | if [ -n "${{ secrets.BUILDBUDDY_API_KEY }}" ]; then @@ -151,9 +134,7 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PUBLIC - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= EOF #! - name: Setup tmate session #! uses: mxschmitt/action-tmate@v3 diff --git a/.github/workflows/test-selenium.yaml b/.github/workflows/test-selenium.yaml index faa4476f2000..493797d190fa 100644 --- a/.github/workflows/test-selenium.yaml +++ b/.github/workflows/test-selenium.yaml @@ -49,18 +49,8 @@ jobs: otp-version: ${{ matrix.erlang_version }} elixir-version: ${{ matrix.elixir_version }} - - name: Mount Bazel Cache - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - - name: Configure Bazel run: | - ERLANG_HOME="$(dirname $(dirname $(which erl)))" - ELIXIR_HOME="$(dirname $(dirname $(which iex)))" if [ -n "${{ secrets.BUILDBUDDY_API_KEY }}" ]; then cat << EOF >> user.bazelrc build:buildbuddy --remote_header=x-buildbuddy-api-key=${{ secrets.BUILDBUDDY_API_KEY }} @@ -69,20 +59,12 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PRIVATE - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= - - build:buildbuddy --remote_download_toplevel - - build --@rules_erlang//:erlang_version=${{ matrix.erlang_version }} - build --@rules_erlang//:erlang_home=${ERLANG_HOME} - build --//:elixir_home=${ELIXIR_HOME} EOF - name: Build & Load RabbitMQ OCI run: | - bazelisk run packaging/docker-image:rabbitmq \ + bazelisk run packaging/docker-image:rabbitmq-amd64 \ --config=buildbuddy - name: Configure Docker Network @@ -96,7 +78,7 @@ jobs: - name: Run Suites run: | - RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq ${SELENIUM_DIR}/run-suites.sh + RABBITMQ_DOCKER_IMAGE=bazel/packaging/docker-image:rabbitmq-amd64 ${SELENIUM_DIR}/run-suites.sh - name: Upload Test Artifacts if: always() diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index b99c47483c27..487470f4ba5f 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -40,13 +40,6 @@ jobs: steps: - name: CHECKOUT REPOSITORY uses: actions/checkout@v4 - - name: MOUNT BAZEL CACHE - uses: actions/cache@v4.0.2 - with: - path: "/home/runner/repo-cache/" - key: ${{ runner.os }}-repo-cache-${{ hashFiles('MODULE.bazel','WORKSPACE','bazel/bzlmod/secondary_umbrella.bzl') }} - restore-keys: | - ${{ runner.os }}-repo-cache- - name: CONFIGURE BAZEL run: | if [ -n "${{ secrets.BUILDBUDDY_API_KEY }}" ]; then @@ -57,9 +50,7 @@ jobs: cat << EOF >> user.bazelrc build:buildbuddy --build_metadata=ROLE=CI build:buildbuddy --build_metadata=VISIBILITY=PUBLIC - build:buildbuddy --repository_cache=/home/runner/repo-cache/ build:buildbuddy --color=yes - build:buildbuddy --disk_cache= EOF bazelisk info release diff --git a/BUILD.bazel b/BUILD.bazel index ff37ed991543..4fe2fcfe3eaa 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -235,12 +235,14 @@ erl_eval( name = "otp_version", outs = ["otp_version.txt"], expression = """{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), file:write_file(os:getenv("OUTS"), Version), halt().""", + visibility = ["//visibility:public"], ) iex_eval( name = "elixir_version", outs = ["elixir_version.txt"], expression = """File.write!(System.get_env("OUTS"), System.version()); System.halt()""", + visibility = ["//visibility:public"], ) filegroup( diff --git a/MODULE.bazel b/MODULE.bazel index 0d3e8d927793..a35e22e0bd35 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -23,6 +23,16 @@ bazel_dep( version = "0.0.9", ) +bazel_dep( + name = "rules_oci", + version = "1.7.4", +) + +bazel_dep( + name = "container_structure_test", + version = "1.16.0", +) + bazel_dep( name = "gazelle", version = "0.33.0", diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 000000000000..d1c670eb1a23 --- /dev/null +++ b/TODO.txt @@ -0,0 +1 @@ +* import defintions in minority diff --git a/WORKSPACE b/WORKSPACE index b511bf032919..16b9b4583d61 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -34,42 +34,6 @@ load("@rules_erlang//gazelle:deps.bzl", "gazelle_deps") gazelle_deps() -http_archive( - name = "io_bazel_rules_docker", - sha256 = "b1e80761a8a8243d03ebca8845e9cc1ba6c82ce7c5179ce2b295cd36f7e394bf", - urls = ["https://github.com/bazelbuild/rules_docker/releases/download/v0.25.0/rules_docker-v0.25.0.tar.gz"], -) - -load( - "@io_bazel_rules_docker//repositories:repositories.bzl", - container_repositories = "repositories", -) - -container_repositories() - -load("@io_bazel_rules_docker//repositories:deps.bzl", container_deps = "deps") - -container_deps() - -load( - "@io_bazel_rules_docker//container:container.bzl", - "container_pull", -) - -container_pull( - name = "ubuntu2004", - registry = "index.docker.io", - repository = "pivotalrabbitmq/ubuntu", - tag = "20.04", -) - -http_file( - name = "openssl-1.1.1g", - downloaded_file_path = "openssl-1.1.1g.tar.gz", - sha256 = "ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46", - urls = ["https://www.openssl.org/source/openssl-1.1.1g.tar.gz"], -) - http_file( name = "otp_src_24", downloaded_file_path = "OTP-24.3.4.6.tar.gz", diff --git a/erlang_ls.config b/erlang_ls.config index 31f041feaf6d..9a797e628a4d 100644 --- a/erlang_ls.config +++ b/erlang_ls.config @@ -6,8 +6,6 @@ deps_dirs: - "deps/*/apps/*" - "extra_deps/*" diagnostics: - disabled: - - bound_var_in_pattern enabled: - crossref - dialyzer @@ -26,9 +24,12 @@ lenses: - suggest-spec - function-references disabled: [] +providers: + enabled: + - signature-help # macros: # - name: DEFINED_WITH_VALUE # value: 42 -# code_reload: -# node: rabbit@localhost +code_reload: + node: rabbit@rabbit plt_path: .rabbitmq_server_release.plt diff --git a/packaging/docker-image/10-default-guest-user.conf b/packaging/docker-image/10-defaults.conf similarity index 78% rename from packaging/docker-image/10-default-guest-user.conf rename to packaging/docker-image/10-defaults.conf index 3d905739f34b..e221e4b78b36 100644 --- a/packaging/docker-image/10-default-guest-user.conf +++ b/packaging/docker-image/10-defaults.conf @@ -6,3 +6,7 @@ ## https://www.rabbitmq.com/access-control.html#loopback-users ## https://www.rabbitmq.com/production-checklist.html#users loopback_users.guest = false + +## Send all logs to stdout/TTY. Necessary to see logs when running via +## a container +log.console = true \ No newline at end of file diff --git a/packaging/docker-image/20-management_agent.disable_metrics_collector.conf b/packaging/docker-image/20-management_agent.disable_metrics_collector.conf new file mode 100644 index 000000000000..6eb7a86cbf8b --- /dev/null +++ b/packaging/docker-image/20-management_agent.disable_metrics_collector.conf @@ -0,0 +1,2 @@ +# Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) +management_agent.disable_metrics_collector = true diff --git a/packaging/docker-image/BUILD.bazel b/packaging/docker-image/BUILD.bazel index d456d6db4153..b6127d8d279c 100644 --- a/packaging/docker-image/BUILD.bazel +++ b/packaging/docker-image/BUILD.bazel @@ -1,302 +1,151 @@ +load("@bazel_skylib//rules:write_file.bzl", "write_file") +load("@container_structure_test//:defs.bzl", "container_structure_test") load( - "@io_bazel_rules_docker//container:container.bzl", - "container_image", - "container_layer", -) -load( - "@io_bazel_rules_docker//contrib:test.bzl", - "container_test", -) -load( - "@io_bazel_rules_docker//docker/util:run.bzl", - "container_run_and_commit_layer", -) -load( - "@io_bazel_rules_docker//docker/package_managers:download_pkgs.bzl", - "download_pkgs", -) -load( - "@io_bazel_rules_docker//docker/package_managers:install_pkgs.bzl", - "install_pkgs", + "@rules_oci//oci:defs.bzl", + "oci_image", + "oci_image_index", + "oci_push", + "oci_tarball", +) +load("//:rabbitmq.bzl", "APP_VERSION") + +filegroup( + name = "context-files", + srcs = [ + "10-defaults.conf", + "20-management_agent.disable_metrics_collector.conf", + "Dockerfile", + "docker-entrypoint.sh", + "//:package-generic-unix", + ], ) -BUILD_DEPS_PACKAGES = [ - "autoconf", - "ca-certificates", - "dpkg-dev", - "g++", - "gcc", - "libncurses5-dev", - "make", +_ARCHS = [ + "amd64", + "arm64", ] -REQUIRED_PACKAGES = [ - "gosu", - "ca-certificates", +_TAGS = [ + "docker", + "manual", + "no-sandbox", + "no-remote-exec", # buildbuddy runners do not have the emulator available ] -CONVENIENCE_PACKAGES = [ - "python3", - "dstat", - "sysstat", - "htop", - "nmon", - "tmux", - "neovim", +[ + genrule( + name = "docker-build-%s" % arch, + srcs = [ + ":context-files", + ], + outs = [ + "image-%s.tar" % arch, + ], + cmd = """set -euo pipefail + +CONTEXT="$$(mktemp -d)" + +cp $(locations :context-files) "$$CONTEXT" + +docker buildx \\ + build \\ + "$$CONTEXT" \\ + --platform linux/{arch} \\ + --build-arg RABBITMQ_VERSION="{rmq_version}" \\ + --output type=tar,dest=$(location image-{arch}.tar) $${{EXTRA_BUILDX_OPTS:-}} +""".format( + arch = arch, + rmq_version = APP_VERSION, + ), + tags = _TAGS, + ) + for arch in _ARCHS ] -FIRECRACKER_EXEC_PROPS = { - # https://www.buildbuddy.io/docs/rbe-microvms - "workload-isolation-type": "firecracker", - "EstimatedFreeDiskBytes": "16GB", - "init-dockerd": "true", - "recycle-runner": "true", - # Use the default buildbuddy RBE image - "container-image": "", -} - -download_pkgs( - name = "otp_pkgs", - exec_properties = FIRECRACKER_EXEC_PROPS, - image_tar = "@ubuntu2004//image", - packages = BUILD_DEPS_PACKAGES, - tags = ["manual"], -) - -download_pkgs( - name = "rabbitmq_pkgs", - exec_properties = FIRECRACKER_EXEC_PROPS, - image_tar = "@ubuntu2004//image", - packages = REQUIRED_PACKAGES + CONVENIENCE_PACKAGES, - tags = ["manual"], -) - -install_pkgs( - name = "otp_pkgs_image", - exec_properties = FIRECRACKER_EXEC_PROPS, - image_tar = "@ubuntu2004//image", - installables_tar = ":otp_pkgs.tar", - installation_cleanup_commands = "rm -rf /var/lib/apt/lists/*", - output_image_name = "otp_pkgs_image", - tags = ["manual"], -) - -install_pkgs( - name = "rabbitmq_pkgs_image", - exec_properties = FIRECRACKER_EXEC_PROPS, - image_tar = "@ubuntu2004//image", - installables_tar = ":rabbitmq_pkgs.tar", - installation_cleanup_commands = "rm -rf /var/lib/apt/lists/*", - output_image_name = "rabbitmq_pkgs_image", - tags = ["manual"], -) - -container_layer( - name = "openssl_source_layer", - directory = "/usr/local/src", - env = { - "OPENSSL_VERSION": "1.1.1g", - }, - files = [ - "build_install_openssh.sh", - ], - tags = ["manual"], - tars = [ - "@openssl-1.1.1g//file", - ], -) - -container_image( - name = "openssl_source", - base = ":otp_pkgs_image", - layers = [":openssl_source_layer"], - tags = ["manual"], -) - -container_run_and_commit_layer( - name = "openssl_layer", - commands = [ - "/usr/local/src/build_install_openssh.sh", - "rm /usr/local/src/build_install_openssh.sh", - ], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":openssl_source.tar", - tags = ["manual"], -) - -container_image( - name = "otp_source", - base = ":otp_pkgs_image", - directory = "/usr/local/src", - files = [ - "build_install_otp.sh", - ], - layers = [ - ":openssl_layer", - ], - tags = ["manual"], - tars = select({ - "@erlang_config//:erlang_24": ["@otp_src_24//file"], - "@erlang_config//:erlang_25_0": ["@otp_src_25_0//file"], - "@erlang_config//:erlang_25_1": ["@otp_src_25_1//file"], - "@erlang_config//:erlang_25_2": ["@otp_src_25_2//file"], - "@erlang_config//:erlang_25_3": ["@otp_src_25_3//file"], - "@erlang_config//:erlang_26": ["@otp_src_26//file"], - }), -) - -container_run_and_commit_layer( - name = "otp_layer", - commands = [ - "/usr/local/src/build_install_otp.sh", - "rm /usr/local/src/build_install_otp.sh", - ], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":otp_source.tar", - tags = ["manual"], -) - -container_layer( - name = "rabbitmq_tarball_layer", - directory = "/opt", - files = [ - "10-default-guest-user.conf", - "docker-entrypoint.sh", - "install_rabbitmq.sh", - ], - tags = ["manual"], - tars = [ - "//:package-generic-unix", - ], -) - -RABBITMQ_DATA_DIR = "/var/lib/rabbitmq" - -RABBITMQ_HOME = "/opt/rabbitmq" +write_file( + name = "cmd", + out = "cmd.txt", + # must match Dockerfile + content = ["rabbitmq-server"], +) + +write_file( + name = "entrypoint", + out = "entrypoint.txt", + # must match Dockerfile + content = ["docker-entrypoint.sh"], +) + +[ + oci_image( + name = "image-%s" % arch, + architecture = arch, + cmd = ":cmd", + entrypoint = ":entrypoint", + # must match Dockerfile + # docker inspect bazel/packaging/docker-image/docker-build:amd64 + # after + # bazel build //packaging/docker-image/docker-build:amd64 + # to check values + env = { + "PATH": "/opt/rabbitmq/sbin:/opt/erlang/bin:/opt/openssl/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", + "ERLANG_INSTALL_PATH_PREFIX": "/opt/erlang", + "OPENSSL_INSTALL_PATH_PREFIX": "/opt/openssl", + "RABBITMQ_DATA_DIR": "/var/lib/rabbitmq", + "RABBITMQ_VERSION": APP_VERSION, + "RABBITMQ_HOME": "/opt/rabbitmq", + "HOME": "/var/lib/rabbitmq", + "LANG": "C.UTF-8", + "LANGUAGE": "C.UTF-8", + "LC_ALL": "C.UTF-8", + }, + os = "linux", + tags = _TAGS, + tars = [":image-%s.tar" % arch], + ) + for arch in _ARCHS +] -container_image( - name = "rabbitmq_tarball", - base = ":rabbitmq_pkgs_image", - env = { - "RABBITMQ_DATA_DIR": RABBITMQ_DATA_DIR, - "RABBITMQ_HOME": RABBITMQ_HOME, - "RABBITMQ_LOGS": "-", - }, - layers = [ - ":otp_layer", - ":rabbitmq_tarball_layer", - ], - tags = ["manual"], -) +[ + oci_tarball( + name = "rabbitmq-%s" % arch, + image = ":image-%s" % arch, + repo_tags = ["bazel/packaging/docker-image:rabbitmq-%s" % arch], + tags = _TAGS, + ) + for arch in _ARCHS +] -container_run_and_commit_layer( - name = "rabbitmq_layer", - commands = [ - "/opt/install_rabbitmq.sh", - "rm /opt/install_rabbitmq.sh", +oci_image_index( + name = "image", + images = [ + ":image-%s" % arch + for arch in _ARCHS ], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":rabbitmq_tarball.tar", - tags = ["manual"], + tags = _TAGS, ) -C_UTF8 = "C.UTF-8" - -container_image( +oci_tarball( name = "rabbitmq", - base = ":rabbitmq_pkgs_image", - cmd = ["rabbitmq-server"], - entrypoint = ["docker-entrypoint.sh"], - env = { - "RABBITMQ_DATA_DIR": RABBITMQ_DATA_DIR, - "RABBITMQ_HOME": RABBITMQ_HOME, - "RABBITMQ_LOGS": "-", - "HOME": RABBITMQ_DATA_DIR, - "PATH": "%s/sbin:$$PATH" % RABBITMQ_HOME, - "LANG": C_UTF8, - "LANGUAGE": C_UTF8, - "LC_ALL": C_UTF8, - }, - layers = [ - ":otp_layer", - ":rabbitmq_layer", - ], - ports = [ - "4369/tcp", # epmd - "5671/tcp", # amqp-tls - "5672/tcp", # amqp - "25672/tcp", # erlang - "15671/tcp", # management-tls - "15672/tcp", # management - "15691/tcp", # prometheus-tls - "15692/tcp", # prometheus - "5551/tcp", # stream-tls - "5552/tcp", # stream - "8883/tcp", # mqtt-tls - "1883/tcp", # mqtt - "15676/tcp", # web-mqtt-tls - "15675/tcp", # web-mqtt - "61614/tcp", # stomp-tls - "61613/tcp", # stomp - "15673/tcp", # web-stomp-tls - "15674/tcp", # web-stomp - "15670/tcp", # examples - ], - tags = ["manual"], - volumes = [ - RABBITMQ_DATA_DIR, - ], -) - -# Wrapper targets for the tarred images are required in order to be able to run -# commandTests in container_test targets. - -container_image( - name = "openssl_install_wrapper", - base = ":otp_source", - tags = ["manual"], -) - -container_image( - name = "otp_install_wrapper", - base = ":rabbitmq_pkgs_image", - layers = [ - ":otp_layer", - ], - tags = ["manual"], -) - -# Tests - -container_test( - name = "openssl_test", - configs = ["//packaging/docker-image/test_configs:openssl_ubuntu.yaml"], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":openssl_install_wrapper", - tags = [ - "docker", - "manual", - ], -) - -container_test( - name = "otp_test", - configs = ["//packaging/docker-image/test_configs:otp_ubuntu.yaml"], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":otp_install_wrapper", - tags = [ - "docker", - "manual", - ], -) + format = "oci", + image = ":image", + repo_tags = ["bazel/packaging/docker-image:rabbitmq"], + tags = _TAGS, +) + +[ + container_structure_test( + name = "rabbitmq_test_%s" % arch, + configs = ["//packaging/docker-image/test_configs:rabbitmq_ubuntu.yaml"], + image = ":image-%s" % arch, + tags = _TAGS, + ) + for arch in _ARCHS +] -container_test( - name = "rabbitmq_test", - configs = ["//packaging/docker-image/test_configs:rabbitmq_ubuntu.yaml"], - exec_properties = FIRECRACKER_EXEC_PROPS, - image = ":rabbitmq", - tags = [ - "docker", - "manual", - ], +oci_push( + name = "push", + image = ":image", + repository = "index.docker.io/pivotalrabbitmq/rabbitmq", + tags = _TAGS, ) diff --git a/packaging/docker-image/Dockerfile b/packaging/docker-image/Dockerfile index ced2a49e760f..7571087fc773 100644 --- a/packaging/docker-image/Dockerfile +++ b/packaging/docker-image/Dockerfile @@ -1,77 +1,68 @@ -# The official Canonical Ubuntu Bionic image is ideal from a security perspective, +# +# NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" +# +# PLEASE DO NOT EDIT IT DIRECTLY. +# + +# The official Canonical Ubuntu Focal image is ideal from a security perspective, # especially for the enterprises that we, the RabbitMQ team, have to deal with -ARG BASE=ubuntu -FROM ${BASE}:20.04 + +FROM ubuntu:22.04 as build-base + +ARG BUILDKIT_SBOM_SCAN_STAGE=true RUN set -eux; \ - apt-get update; \ - apt-get install -y --no-install-recommends \ -# grab gosu for easy step-down from root - gosu \ - ; \ - rm -rf /var/lib/apt/lists/*; \ -# verify that the "gosu" binary works - gosu nobody true + apt-get update; \ + apt-get install -y --no-install-recommends \ + build-essential \ + ca-certificates \ + gnupg \ + libncurses5-dev \ + wget + +FROM build-base as openssl-builder + +ARG BUILDKIT_SBOM_SCAN_STAGE=true -# PGP key servers are too flaky for us to verify during every CI triggered build -# https://github.com/docker-library/official-images/issues/4252 -ARG SKIP_PGP_VERIFY=false # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally -ARG PGP_KEYSERVER=ha.pool.sks-keyservers.net +ARG PGP_KEYSERVER=keyserver.ubuntu.com # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, -# run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:3.7 --build-arg PGP_KEYSERVER=pgpkeys.eu 3.7/ubuntu +# run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:3.13 --build-arg PGP_KEYSERVER=pgpkeys.eu 3.13/ubuntu # For context, see https://github.com/docker-library/official-images/issues/4252 -# Using the latest OpenSSL LTS release, with support until September 2023 - https://www.openssl.org/source/ -ENV OPENSSL_VERSION 1.1.1g -ENV OPENSSL_SOURCE_SHA256="ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46" -# https://www.openssl.org/community/omc.html -ENV OPENSSL_PGP_KEY_IDS="0x8657ABB260F056B1E5190839D9C4D26D0E604491 0x5B2545DAB21995F4088CEFAA36CEE4DEB00CFE33 0xED230BEC4D4F2518B9D7DF41F0DB4D21C1D35231 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D" +ENV OPENSSL_VERSION 3.1.5 +ENV OPENSSL_SOURCE_SHA256="6ae015467dabf0469b139ada93319327be24b98251ffaeceda0221848dc09262" +# https://www.openssl.org/community/otc.html +# https://www.openssl.org/source/ +ENV OPENSSL_PGP_KEY_IDS="0x8657ABB260F056B1E5190839D9C4D26D0E604491 0xB7C1C14360F353A36862E4D5231C84CDDCC69C45 0xC1F33DD8CE1D4CC613AF14DA9195C48241FBF7DD 0x95A9908DDFA16830BE9FB9003D30A3A9FF1360DC 0x7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C 0xA21FAB74B0088AA361152586B8EF1A6BA9DA2D5C 0xE5E52560DD91C556DDBDA5D02064C53641C25E5D 0xEFC0A467D613CB83C7ED6D30D894E2CE8B3D79F5" -# Use the latest stable Erlang/OTP release - make find-latest-otp - https://github.com/erlang/otp/tags -ARG OTP_VERSION -ENV OTP_VERSION ${OTP_VERSION} +ENV OTP_VERSION 26.2.2 # TODO add PGP checking when the feature will be added to Erlang/OTP's build system -# http://erlang.org/pipermail/erlang-questions/2019-January/097067.html -ARG OTP_SHA256 -ENV OTP_SOURCE_SHA256=${OTP_SHA256} -ARG SKIP_OTP_VERIFY=false +# https://erlang.org/pipermail/erlang-questions/2019-January/097067.html +ENV OTP_SOURCE_SHA256="d537ff4ac5d8c1cb507aedaf7198fc1f155ea8aa65a8d83edb35c2802763cc28" + +# install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages +ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang +ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl # Install dependencies required to build Erlang/OTP from source # https://erlang.org/doc/installation_guide/INSTALL.html -# autoconf: Required to configure Erlang/OTP before compiling # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP # gnupg: Required to verify OpenSSL artefacts # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli RUN set -eux; \ - \ - savedAptMark="$(apt-mark showmanual)"; \ - apt-get update; \ - apt-get install --yes --no-install-recommends \ - autoconf \ - ca-certificates \ - dpkg-dev \ - gcc \ - g++ \ - gnupg \ - libncurses5-dev \ - make \ - wget \ - ; \ - rm -rf /var/lib/apt/lists/*; \ - \ OPENSSL_SOURCE_URL="https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz"; \ OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ - OPENSSL_CONFIG_DIR=/usr/local/etc/ssl; \ + OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ \ # Required by the crypto & ssl Erlang/OTP applications wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ export GNUPGHOME="$(mktemp -d)"; \ for key in $OPENSSL_PGP_KEY_IDS; do \ - gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key" || true; \ + gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ done; \ - test "$SKIP_PGP_VERIFY" == "true" || gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ + gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ gpgconf --kill all; \ rm -rf "$GNUPGHOME"; \ echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum --check --strict -; \ @@ -80,35 +71,61 @@ RUN set -eux; \ \ # Configure OpenSSL for compilation cd "$OPENSSL_PATH"; \ +# without specifying "--libdir", Erlang will fail during "crypto:supports()" looking for a "pthread_atfork" function that doesn't exist (but only on arm32v7/armhf??) # OpenSSL's "config" script uses a lot of "uname"-based target detection... - MACHINE="$(dpkg-architecture --query DEB_BUILD_GNU_CPU)" \ + dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ +# https://deb.debian.org/debian/dists/unstable/main/ + case "$dpkgArch" in \ +# https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) + amd64) opensslMachine='linux-x86_64' ;; \ + arm64) opensslMachine='linux-aarch64' ;; \ +# https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 +# https://wiki.debian.org/ArchitectureSpecificsMemo#Architecture_baselines +# https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html + armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ + i386) opensslMachine='linux-x86' ;; \ + ppc64el) opensslMachine='linux-ppc64le' ;; \ + riscv64) opensslMachine='linux64-riscv64' ;; \ + s390x) opensslMachine='linux64-s390x' ;; \ + *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ + esac; \ + MACHINE="$opensslMachine" \ RELEASE="4.x.y-z" \ SYSTEM='Linux' \ BUILD='???' \ - ./config \ + ./Configure \ + "$opensslMachine" \ + enable-fips \ + --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ --openssldir="$OPENSSL_CONFIG_DIR" \ -# add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure /usr/local/lib is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) - -Wl,-rpath=/usr/local/lib \ + --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ +# add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) + -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ + ${opensslExtraConfig:-} \ ; \ # Compile, install OpenSSL, verify that the command-line works & development headers are present make -j "$(getconf _NPROCESSORS_ONLN)"; \ - make install_sw install_ssldirs; \ - cd ..; \ - rm -rf "$OPENSSL_PATH"*; \ + make install_sw install_ssldirs install_fips; \ ldconfig; \ # use Debian's CA certificates rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ - ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR"; \ + ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" + # smoke test - openssl version; \ - \ - OTP_SOURCE_URL="https://github.com/erlang/otp/archive/OTP-$OTP_VERSION.tar.gz"; \ +RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version + +FROM openssl-builder as erlang-builder + +ARG BUILDKIT_SBOM_SCAN_STAGE=true + +RUN set -eux; \ + OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ \ # Download, verify & extract OTP_SOURCE mkdir -p "$OTP_PATH"; \ wget --progress dot:giga --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ - test "$SKIP_OTP_VERIFY" = "true" || echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ + echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ \ # Configure Erlang/OTP for compilation, disable unused features & applications @@ -116,28 +133,32 @@ RUN set -eux; \ # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation cd "$OTP_PATH"; \ export ERL_TOP="$OTP_PATH"; \ - ./otp_build autoconf; \ CFLAGS="$(dpkg-buildflags --get CFLAGS)"; export CFLAGS; \ -# add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure /usr/local/lib is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) - export CFLAGS="$CFLAGS -Wl,-rpath=/usr/local/lib"; \ +# add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$OPENSSL_INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) + export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ +# JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 + jitFlag=; \ + case "$dpkgArch" in \ + amd64 | arm64) jitFlag='--enable-jit' ;; \ + esac; \ ./configure \ + --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ --host="$hostArch" \ --build="$buildArch" \ - --disable-dynamic-ssl-lib \ --disable-hipe \ --disable-sctp \ --disable-silent-rules \ - --enable-jit \ + --enable-builtin-zlib \ --enable-clock-gettime \ --enable-hybrid-heap \ --enable-kernel-poll \ - --enable-shared-zlib \ --enable-smp-support \ --enable-threads \ --with-microstate-accounting=extra \ + --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ --without-common_test \ --without-debugger \ --without-dialyzer \ @@ -156,80 +177,110 @@ RUN set -eux; \ --without-ssh \ --without-tftp \ --without-wx \ + $jitFlag \ ; \ + \ # Compile & install Erlang/OTP make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ make install; \ - cd ..; \ - rm -rf \ - "$OTP_PATH"* \ - /usr/local/lib/erlang/lib/*/examples \ - /usr/local/lib/erlang/lib/*/src \ - ; \ \ -# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies - apt-mark auto '.*' > /dev/null; \ - [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \ - find /usr/local -type f -executable -exec ldd '{}' ';' \ - | awk '/=>/ { print $(NF-1) }' \ - | sort -u \ - | xargs -r dpkg-query --search \ - | cut -d: -f1 \ - | sort -u \ - | xargs -r apt-mark manual \ - ; \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ +# Remove unnecessary files + find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ + find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ + find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + + +# Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly +ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH +RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' +RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' + +FROM ubuntu:22.04 + +# OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again +ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang +ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl +COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX +RUN echo '{"spdxVersion":"SPDX-2.3","SPDXID":"SPDXRef-DOCUMENT","name":"erlang-sbom","packages":[{"name":"erlang","versionInfo":"26.2.2","SPDXID":"SPDXRef-Package--erlang","externalRefs":[{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:generic/erlang@26.2.2?os_name=ubuntu&os_version=22.04"}],"licenseDeclared":"Apache-2.0"}]}' > $ERLANG_INSTALL_PATH_PREFIX/erlang.spdx.json + +COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX +RUN echo '{"spdxVersion":"SPDX-2.3","SPDXID":"SPDXRef-DOCUMENT","name":"openssl-sbom","packages":[{"name":"openssl","versionInfo":"3.1.5","SPDXID":"SPDXRef-Package--openssl","externalRefs":[{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:generic/openssl@3.1.5?os_name=ubuntu&os_version=22.04"}],"licenseDeclared":"Apache-2.0"}]}' > $OPENSSL_INSTALL_PATH_PREFIX/openssl.spdx.json + +ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH + +ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq + +RUN set -eux; \ +# Configure OpenSSL to use system certs + ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ \ -# Check that OpenSSL still works after purging build dependencies +# Check that OpenSSL still works after copying from previous builder + ldconfig; \ + sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ + -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ + sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ + [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ openssl version; \ + openssl version -d; \ + \ # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly - erl -noshell -eval 'io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' - -ENV RABBITMQ_DATA_DIR=/var/lib/rabbitmq + erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ + \ # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM -RUN set -eux; \ groupadd --gid 999 --system rabbitmq; \ useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq; \ mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ - chmod 777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ + chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie -# https://www.rabbitmq.com/signatures.html#importing-gpg -# ENV RABBITMQ_PGP_KEY_ID="0x0A9AF2115F4687BD29803A206B73A36E6026DFCA" -ENV RABBITMQ_HOME=/opt/rabbitmq +# Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) +ARG RABBITMQ_VERSION=4.0.0 +ENV RABBITMQ_VERSION=${RABBITMQ_VERSION} +ENV RABBITMQ_HOME /opt/rabbitmq + +# Add RabbitMQ to PATH +ENV PATH $RABBITMQ_HOME/sbin:$PATH -# Add RabbitMQ to PATH, send all logs to TTY -ENV PATH=$RABBITMQ_HOME/sbin:$PATH \ - RABBITMQ_LOGS=- +COPY package-generic-unix.tar.xz /usr/local/src/rabbitmq-$RABBITMQ_VERSION.tar.xz +# Install RabbitMQ RUN set -eux; \ - \ - savedAptMark="$(apt-mark showmanual)"; \ + export DEBIAN_FRONTEND=noninteractive; \ apt-get update; \ apt-get install --yes --no-install-recommends \ ca-certificates \ +# grab gosu for easy step-down from root + gosu \ +# Bring in tzdata so users could set the timezones through the environment + tzdata \ + ; \ +# verify that the "gosu" binary works + gosu nobody true; \ + \ + savedAptMark="$(apt-mark showmanual)"; \ + apt-get install --yes --no-install-recommends \ gnupg \ wget \ xz-utils \ ; \ rm -rf /var/lib/apt/lists/*; \ \ - apt-mark auto '.*' > /dev/null; \ - apt-mark manual $savedAptMark; \ - apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false - -# Install RabbitMQ -ARG RABBITMQ_BUILD -COPY ${RABBITMQ_BUILD} $RABBITMQ_HOME - -RUN set -eux; \ + RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ + RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ + \ + mkdir -p "$RABBITMQ_HOME"; \ + tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ + rm -rf "$RABBITMQ_PATH"*; \ # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ \ + apt-mark auto '.*' > /dev/null; \ + apt-mark manual $savedAptMark; \ + apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ + \ # verify assumption of no stale cookies [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user @@ -238,7 +289,12 @@ RUN set -eux; \ gosu rabbitmq rabbitmqctl list_ciphers; \ gosu rabbitmq rabbitmq-plugins list; \ # no stale cookies - rm "$RABBITMQ_DATA_DIR/.erlang.cookie" + rm "$RABBITMQ_DATA_DIR/.erlang.cookie"; \ + \ + echo '{"spdxVersion":"SPDX-2.3","SPDXID":"SPDXRef-DOCUMENT","name":"rabbitmq-sbom","packages":[{"name":"rabbitmq","versionInfo":"3.13.0","SPDXID":"SPDXRef-Package--rabbitmq","externalRefs":[{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:generic/rabbitmq@3.13.0?os_name=ubuntu&os_version=22.04"}],"licenseDeclared":"MPL-2.0 AND Apache-2.0"}]}' > $RABBITMQ_HOME/rabbitmq.spdx.json + +# Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) +RUN gosu rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus # Added for backwards compatibility - users can simply COPY custom plugins to /plugins RUN ln -sf /opt/rabbitmq/plugins /plugins @@ -253,62 +309,26 @@ VOLUME $RABBITMQ_DATA_DIR # https://docs.docker.com/samples/library/ubuntu/#locales ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 -COPY --chown=rabbitmq:rabbitmq 10-default-guest-user.conf /etc/rabbitmq/conf.d/ +COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ COPY docker-entrypoint.sh /usr/local/bin/ ENTRYPOINT ["docker-entrypoint.sh"] -# EPMD AMQP-TLS AMQP ERLANG -EXPOSE 4369 5671 5672 25672 +EXPOSE 4369 5671 5672 15691 15692 25672 CMD ["rabbitmq-server"] -# rabbitmq_management -RUN rabbitmq-plugins enable --offline rabbitmq_management && \ - rabbitmq-plugins is_enabled rabbitmq_management --offline -# extract "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z.ez" plugin zipfile + +RUN set eux; \ + rabbitmq-plugins enable --offline rabbitmq_management; \ +# make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) + rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ +# grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder # see https://github.com/docker-library/rabbitmq/issues/207 -# RabbitMQ 3.9 onwards uses uncompressed plugins by default, in which case extraction is -# unnecesary -RUN set -eux; \ - if [ -s /plugins/rabbitmq_management-*.ez ]; then \ - erl -noinput -eval ' \ - { ok, AdminBin } = zip:foldl(fun(FileInArchive, GetInfo, GetBin, Acc) -> \ - case Acc of \ - "" -> \ - case lists:suffix("/rabbitmqadmin", FileInArchive) of \ - true -> GetBin(); \ - false -> Acc \ - end; \ - _ -> Acc \ - end \ - end, "", init:get_plain_arguments()), \ - io:format("~s", [ AdminBin ]), \ - init:stop(). \ - ' -- /plugins/rabbitmq_management-*.ez > /usr/local/bin/rabbitmqadmin; \ - else \ - cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ - fi; \ + cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ [ -s /usr/local/bin/rabbitmqadmin ]; \ chmod +x /usr/local/bin/rabbitmqadmin; \ - apt-get update; apt-get install -y --no-install-recommends python3 dstat sysstat htop nmon tmux neovim; rm -rf /var/lib/apt/lists/*; \ + apt-get update; \ + apt-get install -y --no-install-recommends python3; \ + rm -rf /var/lib/apt/lists/*; \ rabbitmqadmin --version -# MANAGEMENT-TLS MANAGEMENT -EXPOSE 15671 15672 - -RUN rabbitmq-plugins enable --offline rabbitmq_prometheus && \ - rabbitmq-plugins is_enabled rabbitmq_prometheus --offline -# PROMETHEUS-TLS PROMETHEUS -EXPOSE 15691 15692 - -RUN rabbitmq-plugins enable --all -# STREAM-TLS STREAM -EXPOSE 5551 5552 -# MQTT-TLS MQTT -EXPOSE 8883 1883 -# WEB-MQTT-TLS WEB-MQTT -EXPOSE 15676 15675 -# STOMP-TLS STOMP -EXPOSE 61614 61613 -# WEB-STOMP-TLS WEB-STOMP -EXPOSE 15673 15674 -# EXAMPLES -EXPOSE 15670 + +EXPOSE 15671 15672 \ No newline at end of file diff --git a/packaging/docker-image/docker-entrypoint.sh b/packaging/docker-image/docker-entrypoint.sh index 722dc1e235a7..4f8eba34b1f1 100755 --- a/packaging/docker-image/docker-entrypoint.sh +++ b/packaging/docker-image/docker-entrypoint.sh @@ -11,11 +11,8 @@ if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then fi deprecatedEnvVars=( - RABBITMQ_DEFAULT_PASS RABBITMQ_DEFAULT_PASS_FILE - RABBITMQ_DEFAULT_USER RABBITMQ_DEFAULT_USER_FILE - RABBITMQ_DEFAULT_VHOST RABBITMQ_MANAGEMENT_SSL_CACERTFILE RABBITMQ_MANAGEMENT_SSL_CERTFILE RABBITMQ_MANAGEMENT_SSL_DEPTH diff --git a/packaging/docker-image/install_rabbitmq.sh b/packaging/docker-image/install_rabbitmq.sh deleted file mode 100644 index 29ba8c59534f..000000000000 --- a/packaging/docker-image/install_rabbitmq.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env bash - -set -euxo pipefail - -mv /opt/rabbitmq_server-* $RABBITMQ_HOME - -groupadd --gid 999 --system rabbitmq -useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq -mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq -chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq -chmod 777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq -ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie - -export PATH="$RABBITMQ_HOME/sbin:$PATH" - -# Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty -grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults" -sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults" -grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults" -chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME" - -# verify assumption of no stale cookies -[ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ] -# Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user -# If they all succeed, it's safe to assume that things have been set up correctly -gosu rabbitmq rabbitmqctl help -gosu rabbitmq rabbitmqctl list_ciphers -gosu rabbitmq rabbitmq-plugins list -# no stale cookies -rm "$RABBITMQ_DATA_DIR/.erlang.cookie" - -# Added for backwards compatibility - users can simply COPY custom plugins to /plugins -ln -sf /opt/rabbitmq/plugins /plugins - -# move default config and docker entrypoint into place -mv /opt/10-default-guest-user.conf /etc/rabbitmq/conf.d/ -chown rabbitmq:rabbitmq /etc/rabbitmq/conf.d/10-default-guest-user.conf -mv /opt/docker-entrypoint.sh /usr/local/bin - -# rabbitmq_management -rabbitmq-plugins enable --offline rabbitmq_management && \ - rabbitmq-plugins is_enabled rabbitmq_management --offline -# extract "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z.ez" plugin zipfile -# see https://github.com/docker-library/rabbitmq/issues/207 -# RabbitMQ 3.9 onwards uses uncompressed plugins by default, in which case extraction is -# unnecesary -cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin -[ -s /usr/local/bin/rabbitmqadmin ] -chmod +x /usr/local/bin/rabbitmqadmin -rabbitmqadmin --version - -# rabbitmq_prometheus -rabbitmq-plugins enable --offline rabbitmq_prometheus && \ - rabbitmq-plugins is_enabled rabbitmq_prometheus --offline diff --git a/packaging/docker-image/test_configs/otp_ubuntu.yaml b/packaging/docker-image/test_configs/otp_ubuntu.yaml deleted file mode 100644 index a96dbe90f26b..000000000000 --- a/packaging/docker-image/test_configs/otp_ubuntu.yaml +++ /dev/null @@ -1,10 +0,0 @@ -schemaVersion: 2.0.0 - -commandTests: - - name: "otp version" - command: "erl" - args: - - -noshell - - -eval - - '{ok, Version} = file:read_file(filename:join([code:root_dir(), "releases", erlang:system_info(otp_release), "OTP_VERSION"])), io:fwrite(Version), halt().' - expectedOutput: ["2\\d\\.\\d+"] diff --git a/packaging/docker-image/test_configs/rabbitmq_ubuntu.yaml b/packaging/docker-image/test_configs/rabbitmq_ubuntu.yaml index 598283ba7eb1..6890754a3ae1 100644 --- a/packaging/docker-image/test_configs/rabbitmq_ubuntu.yaml +++ b/packaging/docker-image/test_configs/rabbitmq_ubuntu.yaml @@ -2,6 +2,7 @@ schemaVersion: 2.0.0 commandTests: - name: "rabbitmq-plugins" + setup: [["docker-entrypoint.sh"]] command: "rabbitmq-plugins" args: ["list"] expectedOutput: ["\\[E \\] rabbitmq_management"]