Commit 5fcec261 authored by Kirill Smelkov's avatar Kirill Smelkov

X wcfs: Run fusermount and friends with /bin:/usr/bin always on path

For example runUnitTest in ERP5 runs test program with $PATH set without those
directores. This leads to failures like

      File "/srv/slapgrid/slappart16/srv/testnode/djk/soft/950bed0366ff018b829e9bbb7dc3326f/parts/wendelin.core/wcfs/__init__.py", line 533, in _is_mountpoint
        mounted = (0 == subprocess.call(["mountpoint", "-q", path]))
      File "/srv/slapgrid/slappart16/srv/testnode/djk/shared/python2.7/a8bdae732e550b385eb04a06ed09d383/lib/python2.7/subprocess.py", line 172, in call
        return Popen(*popenargs, **kwargs).wait()
      File "/srv/slapgrid/slappart16/srv/testnode/djk/shared/python2.7/a8bdae732e550b385eb04a06ed09d383/lib/python2.7/subprocess.py", line 394, in __init__
        errread, errwrite)
      File "/srv/slapgrid/slappart16/srv/testnode/djk/shared/python2.7/a8bdae732e550b385eb04a06ed09d383/lib/python2.7/subprocess.py", line 1047, in _execute_child
        raise child_exception
    OSError: [Errno 2] No such file or directory

where those system programs are not found.
parent 5bfa8cf8
...@@ -489,9 +489,8 @@ def _mkdir_p(path, mode=0o777): # -> created(bool) ...@@ -489,9 +489,8 @@ def _mkdir_p(path, mode=0o777): # -> created(bool)
# _fuse_unmount calls `fusermount -u` + logs details if unmount failed. # _fuse_unmount calls `fusermount -u` + logs details if unmount failed.
@func @func
def _fuse_unmount(mntpt): def _fuse_unmount(mntpt):
try: ret = _sysproccall(["fusermount", "-u", mntpt], close_fds=True)
subprocess.check_call(["fusermount", "-u", mntpt], close_fds=True) if ret != 0:
except subprocess.CalledProcessError:
# unmount failed, usually due to "device is busy". # unmount failed, usually due to "device is busy".
# Log which files are still opened and reraise # Log which files are still opened and reraise
def _(): def _():
...@@ -503,8 +502,8 @@ def _fuse_unmount(mntpt): ...@@ -503,8 +502,8 @@ def _fuse_unmount(mntpt):
# if there are other uncleaned wcfs mountpoints. # if there are other uncleaned wcfs mountpoints.
# (lsof stats all filesystems on startup) # (lsof stats all filesystems on startup)
# XXX -> better use `fuser -m <mntpt>` (it says it will limit search to files only under mntpt) ? # XXX -> better use `fuser -m <mntpt>` (it says it will limit search to files only under mntpt) ?
lsof = subprocess.Popen(["lsof", "-w", "+D", mntpt], lsof = _sysproc(["lsof", "-w", "+D", mntpt],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = lsof.communicate() out, _ = lsof.communicate()
log.warn(out) log.warn(out)
if lsof.returncode: if lsof.returncode:
...@@ -530,10 +529,33 @@ def _is_mountpoint(path): # -> bool ...@@ -530,10 +529,33 @@ def _is_mountpoint(path): # -> bool
if not S_ISDIR(_.st_mode): if not S_ISDIR(_.st_mode):
return False return False
mounted = (0 == subprocess.call(["mountpoint", "-q", path])) mounted = (0 == _sysproccall(["mountpoint", "-q", path]))
return mounted return mounted
# _sysproc creates subprocess.Popen for "system" command.
#
# System commands are those that reside either in /bin or /usr/bin and which
# should be found even if $PATH does no contain those directories. For example
# runUnitTest in ERP5 sets $PATH without /bin, and this way executing
# fusermount via subprocess.Popen instead of _sysproc would fail.
def _sysproc(argv, **kw): # -> subprocess.Popen
env = kw.get('env', None)
if env is None:
env = os.environ
env = env.copy()
path = env.get('PATH', '')
if path:
path += ':'
path += '/bin:/usr/bin'
env['PATH'] = path
return subprocess.Popen(argv, env=env, **kw)
# _sysproccall is to _sysproc like subprocess.call is to subprocess.Popen.
def _sysproccall(argv, **kw): # -> retcode
return _sysproc(argv, **kw).wait()
# _procwait waits for a process (subprocess.Popen) to terminate. # _procwait waits for a process (subprocess.Popen) to terminate.
def _procwait(ctx, proc): def _procwait(ctx, proc):
_waitfor(ctx, lambda: proc.poll() is not None) _waitfor(ctx, lambda: proc.poll() is not None)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment