This is an automated email from the ASF dual-hosted git repository.

juergbi pushed a commit to branch juerg/cache-config
in repository https://gitbox.apache.org/repos/asf/buildstream.git

commit f213f10aff87d72ccdd1b3bfc7f77c621794f253
Author: Jürg Billeter <[email protected]>
AuthorDate: Fri Aug 30 07:48:33 2024 +0200

    Add `reserved-disk-space` config option to the `cache` section
    
    BuildStream has been relying on buildbox-casd's default for this, which
    is currently set at 2 GB. This adds a config option and sets the default
    to 5% of the size of the filesystem as it doesn't seem reasonable to
    fill up the filesystem more than 95% by default.
---
 doc/source/using_config.rst                | 14 +++++++++++++-
 src/buildstream/_cas/casdprocessmanager.py | 17 ++++++++++++++++-
 src/buildstream/_context.py                | 23 ++++++++++++++++++++++-
 src/buildstream/data/userconfig.yaml       |  3 +++
 4 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/doc/source/using_config.rst b/doc/source/using_config.rst
index 065dfef76..59211c2cd 100644
--- a/doc/source/using_config.rst
+++ b/doc/source/using_config.rst
@@ -124,9 +124,12 @@ toplevel of your configuration file, like so:
    #
    cache:
 
-     # Allow using as much free space as possible
+     # Use as much space as possible
      quota: infinity
 
+     # Keep 5% of disk space available
+     reserved-disk-space: 5%
+
      # Avoid pulling large amounts of data we don't need locally
      pull-buildtrees: False
 
@@ -184,6 +187,15 @@ Attributes
     Percentage values are taken to represent a percentage of the partition
     size on the filesystem where the cache has been configured.
 
+* ``reserved-disk-space``
+
+  This controls how much disk space should remain available. If the amount
+  of available disk space falls below the specified value, unused cache
+  objects will be pruned even if the configured quota has not been exceeded.
+
+  ``reserved-disk-space`` can be specified in the same way as ``quota``, with
+  the exception of the special ``infinity`` value. The default is ``5%``.
+
 * ``pull-buildtrees``
 
   Whether to pull *build trees* when downloading remote artifacts.
diff --git a/src/buildstream/_cas/casdprocessmanager.py 
b/src/buildstream/_cas/casdprocessmanager.py
index 0d5cd6a8d..3b5775409 100644
--- a/src/buildstream/_cas/casdprocessmanager.py
+++ b/src/buildstream/_cas/casdprocessmanager.py
@@ -58,12 +58,24 @@ _REQUIRED_CASD_MICRO = 58
 #     log_dir (str): The directory for the logs
 #     log_level (LogLevel): Log level to give to buildbox-casd for logging
 #     cache_quota (int): User configured cache quota
+#     reserved (int): User configured reserved disk space
 #     remote_cache_spec (RemoteSpec): Optional remote cache server
 #     protect_session_blobs (bool): Disable expiry for blobs used in the 
current session
 #     messenger (Messenger): The messenger to report warnings through the UI
 #
 class CASDProcessManager:
-    def __init__(self, path, log_dir, log_level, cache_quota, 
remote_cache_spec, protect_session_blobs, messenger):
+    def __init__(
+        self,
+        path,
+        log_dir,
+        log_level,
+        cache_quota,
+        remote_cache_spec,
+        protect_session_blobs,
+        messenger,
+        *,
+        reserved=None
+    ):
         os.makedirs(path, exist_ok=True)
 
         self._log_dir = log_dir
@@ -82,6 +94,9 @@ class CASDProcessManager:
             casd_args.append("--quota-high={}".format(int(cache_quota)))
             casd_args.append("--quota-low={}".format(int(cache_quota / 2)))
 
+        if reserved is not None:
+            casd_args.append("--reserved={}".format(int(reserved)))
+
         if protect_session_blobs:
             casd_args.append("--protect-session-blobs")
 
diff --git a/src/buildstream/_context.py b/src/buildstream/_context.py
index 31b2df85f..db6887b25 100644
--- a/src/buildstream/_context.py
+++ b/src/buildstream/_context.py
@@ -185,6 +185,9 @@ class Context:
         # User specified cache quota, used for display messages
         self.config_cache_quota_string: Optional[str] = None
 
+        # Reserved disk space for local cache in bytes
+        self.config_cache_reserved: Optional[int] = None
+
         # Remote cache server
         self.remote_cache_spec: Optional[RemoteSpec] = None
 
@@ -362,7 +365,7 @@ class Context:
         # We need to find the first existing directory in the path of our
         # casdir - the casdir may not have been created yet.
         cache = defaults.get_mapping("cache")
-        cache.validate_keys(["quota", "storage-service", "pull-buildtrees", 
"cache-buildtrees"])
+        cache.validate_keys(["quota", "reserved-disk-space", 
"storage-service", "pull-buildtrees", "cache-buildtrees"])
 
         cas_volume = self.casdir
         while not os.path.exists(cas_volume):
@@ -378,6 +381,23 @@ class Context:
                 LoadErrorReason.INVALID_DATA,
             ) from e
 
+        cache_reserved_string = cache.get_str("reserved-disk-space")
+        try:
+            self.config_cache_reserved = 
utils._parse_size(cache_reserved_string, cas_volume)
+            if self.config_cache_reserved is None:
+                provenance = 
cache.get_scalar("reserved-disk-space").get_provenance()
+                raise LoadError(
+                    "{}: Please specify the value in bytes or as a % of full 
disk space.\n"
+                    "\nValid values are, for example: 2G 
5%\n".format(provenance),
+                    LoadErrorReason.INVALID_DATA,
+                )
+        except utils.UtilError as e:
+            raise LoadError(
+                "{}\nPlease specify the value in bytes or as a % of full disk 
space.\n"
+                "\nValid values are, for example: 2G 5%\n".format(str(e)),
+                LoadErrorReason.INVALID_DATA,
+            ) from e
+
         remote_cache = cache.get_mapping("storage-service", default=None)
         if remote_cache:
             self.remote_cache_spec = RemoteSpec.new_from_node(remote_cache)
@@ -701,6 +721,7 @@ class Context:
                 self.remote_cache_spec,
                 protect_session_blobs=True,
                 messenger=self.messenger,
+                reserved=self.config_cache_reserved,
             )
         return self._casd
 
diff --git a/src/buildstream/data/userconfig.yaml 
b/src/buildstream/data/userconfig.yaml
index 7a5b98ad6..3cd2b0df4 100644
--- a/src/buildstream/data/userconfig.yaml
+++ b/src/buildstream/data/userconfig.yaml
@@ -38,6 +38,9 @@ cache:
   # Use as much space as possible
   quota: infinity
 
+  # Keep 5% of disk space available
+  reserved-disk-space: 5%
+
   # Whether to pull build trees when downloading element artifacts
   pull-buildtrees: False
 

Reply via email to