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