commit:     ef123a214708c85f9802f2a649b93137fd2ee3be
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sat Dec 17 05:12:46 2022 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Wed Dec 21 01:28:02 2022 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=ef123a21

config: Add 'volatile' configuration option

This introduces a 'volatile' configuration option for repos.conf.

* If a repository is marked as volatile (volatile=true), then Portage
  will assume the repository may be changed at any time, and that
  it may contain e.g. local changes.

  Portage will not perform optimizations based on assuming its integrity.

  It will also not perform destructive operations if it is a git repository
  (it will not prioritise being able to continue to sync).

* If a repository is marked as non-volatile (volatile=false), then Portage
  will assume that only Portage changes the repository and that it will not
  be modified otherwise.

  Portage will perform optimizations based on assuming this, like not
  needing to verify the metadata cache for ebuilds & eclasses.

  Portage will prioritise the repository continuing to work and may
  e.g. 'git reset --hard' or 'git clean -fdx' in order to keep git repositories
  working for sync purposes. (If you do not like this, please set 
'volatile=true').

Bug: https://bugs.gentoo.org/528394
Bug: https://bugs.gentoo.org/887025
See: https://github.com/gentoo/portage/pull/801
See: https://github.com/gentoo/portage/pull/931
See: https://github.com/gentoo/portage/pull/939
See: https://github.com/gentoo/portage/pull/960
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/repository/config.py | 40 +++++++++++++++++++++++++++++++++++++++-
 man/portage.5                    |  8 ++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/lib/portage/repository/config.py b/lib/portage/repository/config.py
index 1dc88668c..97feb6632 100644
--- a/lib/portage/repository/config.py
+++ b/lib/portage/repository/config.py
@@ -160,6 +160,7 @@ class RepoConfig:
         "thin_manifest",
         "update_changelog",
         "user_location",
+        "volatile",
         "_eapis_banned",
         "_eapis_deprecated",
         "_masters_orig",
@@ -330,10 +331,36 @@ class RepoConfig:
                     self.name = name
                 if portage._sync_mode:
                     missing = False
-
         elif name == "DEFAULT":
             missing = False
 
+        volatile = repo_opts.get("volatile")
+        # If volatile is explicitly set, go with it.
+        if volatile is not None:
+            self.volatile = volatile in ("true", "yes")
+        else:
+            # If it's unset, we default to no (i.e. the repository is not 
volatile),
+            # but with a heuristic for when a repository is not likely to be 
suitable
+            # (likely to contain custom user changes).
+
+            # If the repository doesn't exist, we can't check its ownership,
+            # so err on the safe side.
+            if missing or not self.location:
+                self.volatile = True
+            # On Prefix, you can't rely on the ownership as a proxy for user
+            # owned because the user typically owns everything.
+            # But we can't access if we're on Prefix here, so use whether
+            # we're under /var/db/repos instead.
+            elif not self.location.startswith("/var/db/repos"):
+                self.volatile = True
+            # If the owner of the repository isn't root or Portage, it's
+            # an indication the user may expect to be able to safely make
+            # changes in the directory, so default to volatile.
+            elif Path(self.location).user not in ("root", "portage"):
+                self.volatile = True
+            else:
+                self.volatile = False
+
         self.eapi = None
         self.missing_repo_name = missing
         # sign_commit is disabled by default, since it requires Git >=1.7.9,
@@ -581,6 +608,8 @@ class RepoConfig:
             repo_msg.append(
                 indent + "eclass-overrides: " + " ".join(self.eclass_overrides)
             )
+        if self.volatile is not None:
+            repo_msg.append(indent + "volatile: " + str(self.volatile))
         for o, v in self.module_specific_options.items():
             if v is not None:
                 repo_msg.append(indent + o + ": " + v)
@@ -690,8 +719,16 @@ class RepoConfigLoader:
                             "sync_umask",
                             "sync_uri",
                             "sync_user",
+                            "volatile",
                         ):
                             v = getattr(repos_conf_opts, k, None)
+
+                            # If PORTDIR_OVERLAY is set, we have to require 
volatile,
+                            # because it'll break changes e.g. with ebuild(1) 
or
+                            # development in a local repository with the same 
repo_name.
+                            if k == "volatile" and portdir_overlay:
+                                v = True
+
                             if v is not None:
                                 setattr(repo, k, v)
 
@@ -1216,6 +1253,7 @@ class RepoConfigLoader:
             "sync_allow_hardlinks",
             "sync_openpgp_key_refresh",
             "sync_rcu",
+            "volatile",
         )
         str_or_int_keys = (
             "auto_sync",

diff --git a/man/portage.5 b/man/portage.5
index ba556aeba..c5100940b 100644
--- a/man/portage.5
+++ b/man/portage.5
@@ -1259,6 +1259,14 @@ Keep snapshots in \fBDISTDIR\fR (do not delete). 
Defaults to no, false.
 Require the detached tarball signature to contain a good OpenPGP
 signature. This uses the OpenPGP key(ring) specified by the
 sync\-openpgp\-key\-path setting. Defaults to no, false.
+.B volatile
+Specifies whether a repository is volatile.  Volatile repositories
+are assumed to contain changes made outside of Portage.  This prohibits
+optimizations from occurring by assuming the integrity of the repository
+and its caches may be violated.  Disabling this option allows local changes to
+be made to the repository for e.g. development safely.  For git-synced
+repositories, Portage will not perform destructive operations.
+.TP
 
 .RE
 

Reply via email to