Related to #7288
The installutils.set_directive() reads the file, changes a line and writes the full file to disk again. That's a rather slow and tedious approach in case of 20, 25 installutils.set_directive() in a row, e.g. ipaserver/install/cainstance.py. We should turn the code into a proper context manager that reads and writes the file only one time. The code is also missing a chmod and should use atomic sync of file and directory inode.
installutils.set_directive()
ipaserver/install/cainstance.py
chmod
Here is the basic interface. I leave the rest to the implementer.
SENTINEL = object() class DirectiveSetter(object): def __init__(self, filename, quotes=True, separator=''): self.filename = filename self.quotes = quotes self.separator = separator self.lines = None self.stat = None def __enter__(self): with open(self.filename) as f: self.stat = os.fstat(f.fileno()) self.lines = list(f) def __exit__(self, exc_type, exc_val, exc_tb): if exc_type is None: # write to temporary file in same directory as self.filename # os.fchmod(...) # os.fchown(...) # flush_sync(...) # os.rename() def set(self, directive, value, quotes=SENTINEL, separator=SENTINEL): if quotes is SENTINEL: quotes = self.quotes if separator is SENTINEL: separator = self.separator set_directive_lines(...)
with DirectiveSetter(paths.CA_CS_CFG_PATH, quotes=False, separator='=') as d: d.set('ca.publish.enable', 'true') d.set('ca.publish.ldappublish.enable', 'false') ...
or
with DirectiveSetter(filename) as ds: ds.setitems([ ('key1', 'value1'), ('key2', 'value2'), ... ('key99', 'value99'), ])
Implemented as part of PR https://github.com/freeipa/freeipa/pull/1379
Metadata Update from @cheimes: - Issue assigned to cheimes
master:
ipa-4-6:
ipa-4-5:
Metadata Update from @pvoborni: - Issue close_status updated to: fixed - Issue set to the milestone: FreeIPA 4.5.5 - Issue status updated to: Closed (was: Open)
Login to comment on this ticket.