This is an automated email from the ASF dual-hosted git repository. juergbi pushed a commit to branch jbilleter/http-cache in repository https://gitbox.apache.org/repos/asf/buildstream.git
commit c1f1af0b9190259ffe0befb545c2c3d6d23c5fc9 Author: Jürg Billeter <[email protected]> AuthorDate: Fri Aug 7 15:26:02 2026 +0200 _remotespec.py: Add `protocol` option for HTTP REST support --- src/buildstream/_assetcache.py | 3 +++ src/buildstream/_remotespec.py | 29 +++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/buildstream/_assetcache.py b/src/buildstream/_assetcache.py index 9406b9cf9..f2f8aa1e8 100644 --- a/src/buildstream/_assetcache.py +++ b/src/buildstream/_assetcache.py @@ -56,6 +56,9 @@ class AssetRemote(BaseRemote): # RemoteError: If the upstream has a problem # def _check(self): + if self.spec.protocol != "grpc": + raise RemoteError("Index servers are supported only with the 'grpc' protocol") + request = remote_asset_pb2.FetchBlobRequest() if self.instance_name: request.instance_name = self.instance_name diff --git a/src/buildstream/_remotespec.py b/src/buildstream/_remotespec.py index f0ffd4d3e..375968ff6 100644 --- a/src/buildstream/_remotespec.py +++ b/src/buildstream/_remotespec.py @@ -65,6 +65,7 @@ class RemoteSpec: url: str, *, push: bool = False, + protocol: Optional[str] = None, server_cert: Optional[str] = None, client_key: Optional[str] = None, client_cert: Optional[str] = None, @@ -75,6 +76,8 @@ class RemoteSpec: spec_node: Optional[MappingNode] = None, ) -> None: + provenance = "{}: ".format(spec_node.get_provenance()) if spec_node else "" + # # Public members # @@ -88,6 +91,19 @@ class RemoteSpec: # The url of the remote, this may contain a port number self.url: str = url + # The protocol to use + self.protocol: str = protocol or "grpc" + if self.protocol not in ["grpc", "http"]: + raise RemoteError(f"{provenance}Value for 'protocol' must be 'grpc' or 'http', got: {self.protocol}") + + if self.protocol == "http": + if self.remote_type != RemoteType.STORAGE: + raise RemoteError( + f"{provenance}Value for remote 'type' must be '{RemoteType.STORAGE}' for HTTP remotes" + ) + if self.push: + raise RemoteError(f"{provenance}Push is not supported for HTTP remotes") + # The name of the grpc service to talk to at this remote url self.instance_name: Optional[str] = instance_name @@ -127,6 +143,7 @@ class RemoteSpec: self.remote_type, self.push, self.url, + self.protocol, self.instance_name, self.server_cert_file, self.client_key_file, @@ -141,7 +158,7 @@ class RemoteSpec: ) def __str__(self) -> str: - string = self.url + "\n" + string = f"{self.url} ({self.protocol})\n" string += "push: {} type: {} instance: {}\n".format(self.push, self.remote_type, self.instance_name) if self._spec_node: provenance = str(self._spec_node.get_provenance()) @@ -210,6 +227,7 @@ class RemoteSpec: # def to_localcas_remote(self, remote): remote.url = self.url + remote.protocol = self.protocol if self.instance_name: remote.instance_name = self.instance_name if self.server_cert: @@ -264,7 +282,7 @@ class RemoteSpec: push: bool = False remote_type: str = RemoteType.ENDPOINT - valid_keys: List[str] = ["url", "instance-name", "auth", "connection-config"] + valid_keys: List[str] = ["url", "protocol", "instance-name", "auth", "connection-config"] if not remote_execution: remote_type = cast(str, spec_node.get_enum("type", RemoteType, default=RemoteType.ALL)) valid_keys += ["type"] @@ -283,6 +301,8 @@ class RemoteSpec: provenance = spec_node.get_node("url").get_provenance() raise LoadError("{}: empty artifact cache URL".format(provenance), LoadErrorReason.INVALID_DATA) + protocol = spec_node.get_str("protocol", default="grpc") + instance_name = spec_node.get_str("instance-name", default=None) auth_node = spec_node.get_mapping("auth", None) @@ -296,6 +316,7 @@ class RemoteSpec: return cls( remote_type, url, + protocol=protocol, push=push, server_cert=server_cert, client_key=client_key, @@ -327,6 +348,7 @@ class RemoteSpec: @classmethod def new_from_string(cls, string: str, purpose: int = RemoteSpecPurpose.ALL) -> "RemoteSpec": url: Optional[str] = None + protocol: Optional[str] = None instance_name: Optional[str] = None remote_type: str = RemoteType.ALL push: bool = True @@ -353,6 +375,8 @@ class RemoteSpec: if key == "url": url = val + elif key == "protocol": + protocol = val elif key == "instance-name": instance_name = val elif key == "type": @@ -396,6 +420,7 @@ class RemoteSpec: return cls( remote_type, url, + protocol=protocol, push=push, server_cert=server_cert, client_key=client_key,
