commit:     206efe5f6341bce99a5e9994a0458c304513b2c3
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 20 12:38:59 2014 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Nov 24 07:38:51 2014 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=206efe5f

emerge: check for writable PKGDIR (490732)

If there are packages to be merged and "buildpkg" or "buildsyspkg" is
enabled, then bail out early if PKGDIR is not writable (in order to
avoid a fatal EROFS error which would otherwise occur later on).
Behavior remains unchanged for --pretend, --fetchonly and
--fetch-all-uri. For --ask, it will bail out just after the last
relevant --ask prompt.

X-Gentoo-Bug: 490732
X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=490732
Acked-by: Alexander Berntsen <bernalex <AT> gentoo.org>

---
 pym/_emerge/actions.py       | 28 ++++++++++++++++++++++++++--
 pym/portage/dbapi/bintree.py | 12 ++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py
index 6f7dfe0..dec5b04 100644
--- a/pym/_emerge/actions.py
+++ b/pym/_emerge/actions.py
@@ -428,7 +428,18 @@ def action_build(settings, trees, mtimedb,
                        # least show warnings about missed updates and such.
                        mydepgraph.display_problems()
 
-               if not Scheduler._opts_no_self_update.intersection(myopts):
+
+               need_write_vardb = not Scheduler. \
+                       _opts_no_self_update.intersection(myopts)
+
+               need_write_bindb = not any(x in myopts for x in
+                       ("--fetchonly", "--fetch-all-uri", "--pretend")) and \
+                       (any("buildpkg" in trees[eroot]["root_config"].
+                               settings.features for eroot in trees) or
+                       any("buildsyspkg" in trees[eroot]["root_config"].
+                               settings.features for eroot in trees))
+
+               if need_write_bindb or need_write_vardb:
 
                        eroots = set()
                        for x in mydepgraph.altlist():
@@ -436,13 +447,26 @@ def action_build(settings, trees, mtimedb,
                                        eroots.add(x.root)
 
                        for eroot in eroots:
-                               if not trees[eroot]["vartree"].dbapi.writable:
+                               if need_write_vardb and \
+                                       not 
trees[eroot]["vartree"].dbapi.writable:
                                        writemsg_level("!!! %s\n" %
                                                _("Read-only file system: %s") %
                                                
trees[eroot]["vartree"].dbapi._dbroot,
                                                level=logging.ERROR, 
noiselevel=-1)
                                        return 1
 
+                               if need_write_bindb and \
+                                       ("buildpkg" in 
trees[eroot]["root_config"].
+                                       settings.features or
+                                       "buildsyspkg" in 
trees[eroot]["root_config"].
+                                       settings.features) and \
+                                       not 
trees[eroot]["bintree"].dbapi.writable:
+                                       writemsg_level("!!! %s\n" %
+                                               _("Read-only file system: %s") %
+                                               trees[eroot]["bintree"].pkgdir,
+                                               level=logging.ERROR, 
noiselevel=-1)
+                                       return 1
+
                if ("--resume" in myopts):
                        favorites=mtimedb["resume"]["favorites"]
 

diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py
index a5d7ac9..b56c8c1 100644
--- a/pym/portage/dbapi/bintree.py
+++ b/pym/portage/dbapi/bintree.py
@@ -18,6 +18,7 @@ portage.proxy.lazyimport.lazyimport(globals(),
        'portage.util:atomic_ofstream,ensure_dirs,normalize_path,' + \
                'writemsg,writemsg_stdout',
        'portage.util.listdir:listdir',
+       'portage.util.path:first_existing',
        'portage.util._urlopen:urlopen@_urlopen',
        'portage.versions:best,catpkgsplit,catsplit,_pkg_str',
 )
@@ -85,6 +86,17 @@ class bindbapi(fakedbapi):
                self._aux_cache_slot_dict = 
slot_dict_class(self._aux_cache_keys)
                self._aux_cache = {}
 
+       @property
+       def writable(self):
+               """
+               Check if PKGDIR is writable, or permissions are sufficient
+               to create it if it does not exist yet.
+               @rtype: bool
+               @return: True if PKGDIR is writable or can be created,
+                       False otherwise
+               """
+               return os.access(first_existing(self.bintree.pkgdir), os.W_OK)
+
        def match(self, *pargs, **kwargs):
                if self.bintree and not self.bintree.populated:
                        self.bintree.populate()

Reply via email to