From 0f939d66a9dd488e13377922cb3e6a8f9a5d3b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Mon, 21 Jul 2025 11:35:22 +0200 Subject: [PATCH 1/3] ci: Update images Update BuildBox to 1.3.24. --- .github/common.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/common.env b/.github/common.env index 4ffc90062..e2cb26257 100644 --- a/.github/common.env +++ b/.github/common.env @@ -1,6 +1,6 @@ # Shared common variables -CI_IMAGE_VERSION=master-1869708273 +CI_IMAGE_VERSION=master-1938898146 CI_TOXENV_MAIN=py39,py310,py311,py312,py313 CI_TOXENV_PLUGINS=py39-plugins,py310-plugins,py311-plugins,py312-plugins,py313-plugins CI_TOXENV_ALL="${CI_TOXENV_MAIN},${CI_TOXENV_PLUGINS}" From ed6522f36f4a193286c52882ab183442c58452f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Fri, 18 Jul 2025 14:18:46 +0200 Subject: [PATCH 2/3] sandbox: Add support for action cache updates via `remote-apis-socket` Action cache updates from sandboxed REAPI clients are disabled by default to protect action cache integrity. --- doc/source/format_declaring.rst | 10 ++++++++++ src/buildstream/sandbox/_config.py | 17 +++++++++++++---- src/buildstream/sandbox/_sandboxbuildboxrun.py | 2 ++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/doc/source/format_declaring.rst b/doc/source/format_declaring.rst index 7a1f71854..73820d78f 100644 --- a/doc/source/format_declaring.rst +++ b/doc/source/format_declaring.rst @@ -395,6 +395,7 @@ having implemented these options the same as buildstream. sandbox: remote-apis-socket: path: /run/reapi.sock + action-cache-enable-update: false Setting a path will add a UNIX socket to the sandbox that allows the use of `REAPI `_ clients such as @@ -407,6 +408,15 @@ This is supported with and without :ref:`remote execution ` section, +``push`` needs to be set to ``true`` to allow action cache updates to be pushed +to the server. + .. _format_dependencies: diff --git a/src/buildstream/sandbox/_config.py b/src/buildstream/sandbox/_config.py index 87e6b35fa..c25bf27d0 100644 --- a/src/buildstream/sandbox/_config.py +++ b/src/buildstream/sandbox/_config.py @@ -52,13 +52,15 @@ def __init__( build_arch: str, build_uid: Optional[int] = None, build_gid: Optional[int] = None, - remote_apis_socket_path: Optional[str] = None + remote_apis_socket_path: Optional[str] = None, + remote_apis_socket_action_cache_enable_update: bool = False ): self.build_os = build_os self.build_arch = build_arch self.build_uid = build_uid self.build_gid = build_gid self.remote_apis_socket_path = remote_apis_socket_path + self.remote_apis_socket_action_cache_enable_update = remote_apis_socket_action_cache_enable_update # to_dict(): # @@ -74,7 +76,7 @@ def __init__( # Returns: # A dictionary representation of this SandboxConfig # - def to_dict(self) -> Dict[str, Union[str, int]]: + def to_dict(self) -> Dict[str, Union[str, int, bool]]: # Assign mandatory portions of the sandbox configuration # @@ -82,7 +84,7 @@ def to_dict(self) -> Dict[str, Union[str, int]]: # the sandbox configuration, as that would result in # breaking cache key stability. # - sandbox_dict: Dict[str, Union[str, int]] = {"build-os": self.build_os, "build-arch": self.build_arch} + sandbox_dict: Dict[str, Union[str, int, bool]] = {"build-os": self.build_os, "build-arch": self.build_arch} # Assign optional portions of the sandbox configuration # @@ -97,6 +99,8 @@ def to_dict(self) -> Dict[str, Union[str, int]]: if self.remote_apis_socket_path is not None: sandbox_dict["remote-apis-socket-path"] = self.remote_apis_socket_path + if self.remote_apis_socket_action_cache_enable_update: + sandbox_dict["remote-apis-socket-action-cache-enable-update"] = True return sandbox_dict @@ -145,10 +149,14 @@ def new_from_node(cls, config: "MappingNode[Node]", *, platform: Optional[Platfo remote_apis_socket = config.get_mapping("remote-apis-socket", default=None) if remote_apis_socket: - remote_apis_socket.validate_keys(["path"]) + remote_apis_socket.validate_keys(["path", "action-cache-enable-update"]) remote_apis_socket_path = remote_apis_socket.get_str("path") + remote_apis_socket_action_cache_enable_update = remote_apis_socket.get_bool( + "action-cache-enable-update", default=False + ) else: remote_apis_socket_path = None + remote_apis_socket_action_cache_enable_update = False return cls( build_os=build_os, @@ -156,4 +164,5 @@ def new_from_node(cls, config: "MappingNode[Node]", *, platform: Optional[Platfo build_uid=build_uid, build_gid=build_gid, remote_apis_socket_path=remote_apis_socket_path, + remote_apis_socket_action_cache_enable_update=remote_apis_socket_action_cache_enable_update, ) diff --git a/src/buildstream/sandbox/_sandboxbuildboxrun.py b/src/buildstream/sandbox/_sandboxbuildboxrun.py index 99dadad4b..e188c1ac1 100644 --- a/src/buildstream/sandbox/_sandboxbuildboxrun.py +++ b/src/buildstream/sandbox/_sandboxbuildboxrun.py @@ -132,6 +132,8 @@ def _execute_action(self, action, flags): if self.re_remote: buildbox_command.append("--instance={}".format(self.re_remote.local_cas_instance_name)) + if config.remote_apis_socket_action_cache_enable_update: + buildbox_command.append("--nested-ac-enable-update") # Do not redirect stdout/stderr if "no-logs-capture" in self._capabilities: From 62129a52c1229a83c1a9b2f77c534886ab5e4148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Fri, 18 Jul 2025 14:47:02 +0200 Subject: [PATCH 3/3] tests/integration/sandbox.py: Add test for `action-cache-enable-update` --- .../sandbox/remote-apis-socket-ac-update.bst | 14 +++++++++++++ tests/integration/sandbox.py | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/integration/project/elements/sandbox/remote-apis-socket-ac-update.bst diff --git a/tests/integration/project/elements/sandbox/remote-apis-socket-ac-update.bst b/tests/integration/project/elements/sandbox/remote-apis-socket-ac-update.bst new file mode 100644 index 000000000..061d618e8 --- /dev/null +++ b/tests/integration/project/elements/sandbox/remote-apis-socket-ac-update.bst @@ -0,0 +1,14 @@ +kind: manual + +depends: + - filename: base.bst + type: build + +sandbox: + remote-apis-socket: + path: /tmp/reapi.sock + action-cache-enable-update: true + +config: + build-commands: + - test -S /tmp/reapi.sock diff --git a/tests/integration/sandbox.py b/tests/integration/sandbox.py index c23ce8a55..9ebc75c7b 100644 --- a/tests/integration/sandbox.py +++ b/tests/integration/sandbox.py @@ -83,6 +83,27 @@ def test_remote_apis_socket_with_action_cache(cli, tmpdir, datafiles): assert result.exit_code == 0 +# Test configuration with remote action cache for nested REAPI with updates enabled. +@pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox") +@pytest.mark.datafiles(DATA_DIR) +def test_remote_apis_socket_with_action_cache_update(cli, tmpdir, datafiles): + project = str(datafiles) + element_name = "sandbox/remote-apis-socket-ac-update.bst" + + with create_artifact_share(os.path.join(str(tmpdir), "remote")) as share: + cli.configure( + { + "remote-execution": { + "storage-service": {"url": share.repo}, + "action-cache-service": {"url": share.repo, "push": True}, + } + } + ) + + result = cli.run(project=project, args=["build", element_name]) + assert result.exit_code == 0 + + # Test configuration with cache storage-service and remote action cache for nested REAPI. @pytest.mark.skipif(not HAVE_SANDBOX, reason="Only available with a functioning sandbox") @pytest.mark.datafiles(DATA_DIR)