Revision b81b3c96 lib/utils/io.py

b/lib/utils/io.py
28 28
import tempfile
29 29
import errno
30 30
import time
31
import stat
31 32

  
32 33
from ganeti import errors
33 34
from ganeti import constants
......
331 332
    raise
332 333

  
333 334

  
335
def EnforcePermission(path, mode, uid=-1, gid=-1, must_exist=True,
336
                      _chmod_fn=os.chmod, _chown_fn=os.chown, _stat_fn=os.stat):
337
  """Enforces that given path has given permissions.
338

  
339
  @param path: The path to the file
340
  @param mode: The mode of the file
341
  @param uid: The uid of the owner of this file
342
  @param gid: The gid of the owner of this file
343
  @param must_exist: Specifies if non-existance of path will be an error
344
  @param _chmod_fn: chmod function to use (unittest only)
345
  @param _chown_fn: chown function to use (unittest only)
346

  
347
  """
348
  logging.debug("Checking %s", path)
349
  try:
350
    st = _stat_fn(path)
351

  
352
    fmode = stat.S_IMODE(st[stat.ST_MODE])
353
    if fmode != mode:
354
      logging.debug("Changing mode of %s from %#o to %#o", path, fmode, mode)
355
      _chmod_fn(path, mode)
356

  
357
    if max(uid, gid) > -1:
358
      fuid = st[stat.ST_UID]
359
      fgid = st[stat.ST_GID]
360
      if fuid != uid or fgid != gid:
361
        logging.debug("Changing owner of %s from UID %s/GID %s to"
362
                      " UID %s/GID %s", path, fuid, fgid, uid, gid)
363
        _chown_fn(path, uid, gid)
364
  except EnvironmentError, err:
365
    if err.errno == errno.ENOENT:
366
      if must_exist:
367
        raise errors.GenericError("Path %s should exist, but does not" % path)
368
    else:
369
      raise errors.GenericError("Error while changing permissions on %s: %s" %
370
                                (path, err))
371

  
372

  
373
def MakeDirWithPerm(path, mode, uid, gid, _lstat_fn=os.lstat,
374
                    _mkdir_fn=os.mkdir, _perm_fn=EnforcePermission):
375
  """Enforces that given path is a dir and has given mode, uid and gid set.
376

  
377
  @param path: The path to the file
378
  @param mode: The mode of the file
379
  @param uid: The uid of the owner of this file
380
  @param gid: The gid of the owner of this file
381
  @param _lstat_fn: Stat function to use (unittest only)
382
  @param _mkdir_fn: mkdir function to use (unittest only)
383
  @param _perm_fn: permission setter function to use (unittest only)
384

  
385
  """
386
  logging.debug("Checking directory %s", path)
387
  try:
388
    # We don't want to follow symlinks
389
    st = _lstat_fn(path)
390
  except EnvironmentError, err:
391
    if err.errno != errno.ENOENT:
392
      raise errors.GenericError("stat(2) on %s failed: %s" % (path, err))
393
    _mkdir_fn(path)
394
  else:
395
    if not stat.S_ISDIR(st[stat.ST_MODE]):
396
      raise errors.GenericError(("Path %s is expected to be a directory, but "
397
                                 "isn't") % path)
398

  
399
  _perm_fn(path, mode, uid=uid, gid=gid)
400

  
401

  
334 402
def Makedirs(path, mode=0750):
335 403
  """Super-mkdir; create a leaf directory and all intermediate ones.
336 404

  

Also available in: Unified diff