Revision c47eddb8

b/lib/utils/io.py
38 38
#: Path generating random UUID
39 39
_RANDOM_UUID_FILE = "/proc/sys/kernel/random/uuid"
40 40

  
41
# Possible values for keep_perms in WriteFile()
42
KP_NEVER = 0
43
KP_ALWAYS = 1
44
KP_IF_EXISTS = 2
45

  
46
KEEP_PERMS_VALUES = [
47
  KP_NEVER,
48
  KP_ALWAYS,
49
  KP_IF_EXISTS,
50
  ]
51

  
41 52

  
42 53
def ErrnoOrStr(err):
43 54
  """Format an EnvironmentError exception.
......
82 93
              mode=None, uid=-1, gid=-1,
83 94
              atime=None, mtime=None, close=True,
84 95
              dry_run=False, backup=False,
85
              prewrite=None, postwrite=None):
96
              prewrite=None, postwrite=None, keep_perms=KP_NEVER):
86 97
  """(Over)write a file atomically.
87 98

  
88 99
  The file_name and either fn (a function taking one argument, the
......
119 130
  @param prewrite: function to be called before writing content
120 131
  @type postwrite: callable
121 132
  @param postwrite: function to be called after writing content
133
  @type keep_perms: members of L{KEEP_PERMS_VALUES}
134
  @param keep_perms: if L{KP_NEVER} (default), owner, group, and mode are
135
      taken from the other parameters; if L{KP_ALWAYS}, owner, group, and
136
      mode are copied from the existing file; if L{KP_IF_EXISTS}, owner,
137
      group, and mode are taken from the file, and if the file doesn't
138
      exist, they are taken from the other parameters. It is an error to
139
      pass L{KP_ALWAYS} when the file doesn't exist or when C{uid}, C{gid},
140
      or C{mode} are set to non-default values.
122 141

  
123 142
  @rtype: None or int
124 143
  @return: None if the 'close' parameter evaluates to True,
......
138 157
    raise errors.ProgrammerError("Both atime and mtime must be either"
139 158
                                 " set or None")
140 159

  
160
  if not keep_perms in KEEP_PERMS_VALUES:
161
    raise errors.ProgrammerError("Invalid value for keep_perms: %s" %
162
                                 keep_perms)
163
  if keep_perms == KP_ALWAYS and (uid != -1 or gid != -1 or mode is not None):
164
    raise errors.ProgrammerError("When keep_perms==KP_ALWAYS, 'uid', 'gid',"
165
                                 " and 'mode' cannot be set")
166

  
141 167
  if backup and not dry_run and os.path.isfile(file_name):
142 168
    CreateBackup(file_name)
143 169

  
170
  if keep_perms == KP_ALWAYS or keep_perms == KP_IF_EXISTS:
171
    # os.stat() raises an exception if the file doesn't exist
172
    try:
173
      file_stat = os.stat(file_name)
174
      mode = stat.S_IMODE(file_stat.st_mode)
175
      uid = file_stat.st_uid
176
      gid = file_stat.st_gid
177
    except OSError:
178
      if keep_perms == KP_ALWAYS:
179
        raise
180
      # else: if keeep_perms == KP_IF_EXISTS it's ok if the file doesn't exist
181

  
144 182
  # Whether temporary file needs to be removed (e.g. if any error occurs)
145 183
  do_remove = True
146 184

  

Also available in: Unified diff