From e60c643b5f46d9365dc67e6022c904f10c261b45 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 18 Nov 2020 10:57:38 -0500 Subject: [PATCH] Make configutil.write_config atomic and also make it take a FilePath --- src/allmydata/test/test_configutil.py | 7 +++++-- src/allmydata/util/configutil.py | 17 +++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/allmydata/test/test_configutil.py b/src/allmydata/test/test_configutil.py index 9e792dc87..19e5b303d 100644 --- a/src/allmydata/test/test_configutil.py +++ b/src/allmydata/test/test_configutil.py @@ -15,6 +15,9 @@ if PY2: import os.path +from twisted.python.filepath import ( + FilePath, +) from twisted.trial import unittest from allmydata.util import configutil @@ -55,7 +58,7 @@ enabled = false # test that set_config can mutate an existing option configutil.set_config(config, "node", "nickname", "Alice!") - configutil.write_config(tahoe_cfg, config) + configutil.write_config(FilePath(tahoe_cfg), config) config = configutil.get_config(tahoe_cfg) self.failUnlessEqual(config.get("node", "nickname"), "Alice!") @@ -63,7 +66,7 @@ enabled = false # test that set_config can set a new option descriptor = "Twas brillig, and the slithy toves Did gyre and gimble in the wabe" configutil.set_config(config, "node", "descriptor", descriptor) - configutil.write_config(tahoe_cfg, config) + configutil.write_config(FilePath(tahoe_cfg), config) config = configutil.get_config(tahoe_cfg) self.failUnlessEqual(config.get("node", "descriptor"), descriptor) diff --git a/src/allmydata/util/configutil.py b/src/allmydata/util/configutil.py index 4bee7d043..d905a8e00 100644 --- a/src/allmydata/util/configutil.py +++ b/src/allmydata/util/configutil.py @@ -59,8 +59,21 @@ def set_config(config, section, option, value): assert config.get(section, option) == value def write_config(tahoe_cfg, config): - with open(tahoe_cfg, "w") as f: - config.write(f) + """ + Write a configuration to a file. + + :param FilePath tahoe_cfg: The path to which to write the config. + + :param ConfigParser config: The configuration to write. + + :return: ``None`` + """ + tmp = tahoe_cfg.temporarySibling() + # FilePath.open can only open files in binary mode which does not work + # with ConfigParser.write. + with open(tmp.path, "wt") as fp: + config.write(fp) + tmp.moveTo(tahoe_cfg) def validate_config(fname, cfg, valid_config): """