Commit 71714516 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

Add more parameters to utils.WriteFile

- Make closing file optional: Required by ganeti-watcher to keep
  file open after writing it. Changes return value of utils.WriteFile
  if "close" parameter evaluates to True.
- Pre- and post-write functions: Can be used to lock files. This
  will be used by ganeti-watcher to lock the temporary file before
  renaming.

Reviewed-by: iustinp
parent 67fe61c4
......@@ -959,8 +959,9 @@ def NewUUID():
def WriteFile(file_name, fn=None, data=None,
mode=None, uid=-1, gid=-1,
atime=None, mtime=None,
check_abspath=True, dry_run=False, backup=False):
atime=None, mtime=None, close=True,
check_abspath=True, dry_run=False, backup=False,
prewrite=None, postwrite=None):
"""(Over)write a file atomically.
The file_name and either fn (a function taking one argument, the
......@@ -974,6 +975,22 @@ def WriteFile(file_name, fn=None, data=None,
exception, an existing target file should be unmodified and the
temporary file should be removed.
Args:
file_name: New filename
fn: Content writing function, called with file descriptor as parameter
data: Content as string
mode: File mode
uid: Owner
gid: Group
atime: Access time
mtime: Modification time
close: Whether to close file after writing it
prewrite: Function object called before writing content
postwrite: Function object called after writing content
Returns:
None if "close" parameter evaluates to True, otherwise file descriptor.
"""
if check_abspath and not os.path.isabs(file_name):
raise errors.ProgrammerError("Path passed to WriteFile is not"
......@@ -998,19 +1015,29 @@ def WriteFile(file_name, fn=None, data=None,
os.chown(new_name, uid, gid)
if mode:
os.chmod(new_name, mode)
if callable(prewrite):
prewrite(fd)
if data is not None:
os.write(fd, data)
else:
fn(fd)
if callable(postwrite):
postwrite(fd)
os.fsync(fd)
if atime is not None and mtime is not None:
os.utime(new_name, (atime, mtime))
if not dry_run:
os.rename(new_name, file_name)
finally:
os.close(fd)
if close:
os.close(fd)
result = None
else:
result = fd
RemoveFile(new_name)
return result
def all(seq, pred=bool):
"Returns True if pred(x) is True for every element in the iterable"
......
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