Petr Horáček has uploaded a new change for review.
Change subject: utils: atomic write ......................................................................
utils: atomic write
Atomic writes are needed for safe file editation. This function will be used in following network patch 'acquire external interfaces'.
Change-Id: Icbb5a2d3ac439a334db2c9075376f219c356762c Bug-Url: https://bugzilla.redhat.com/1195208 Signed-off-by: Petr Horáček phoracek@redhat.com --- M lib/vdsm/utils.py M tests/utilsTests.py 2 files changed, 73 insertions(+), 3 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/82/61482/1
diff --git a/lib/vdsm/utils.py b/lib/vdsm/utils.py index 0beac90..10888bb 100644 --- a/lib/vdsm/utils.py +++ b/lib/vdsm/utils.py @@ -834,8 +834,7 @@ suffix, e.g. dummy_ilXaYiSn7. The name is bound to IFNAMSIZ of 16-1 chars. """ suffix_len = max_length - len(prefix) - suffix = ''.join(random.choice(string.ascii_letters + string.digits) - for _ in range(suffix_len)) + suffix = _random_alnum_string(suffix_len) return prefix + suffix
@@ -929,3 +928,43 @@ elif len(keys) == 0: return dict return rget(dict.get(keys[0]), keys[1:], default) + + +@contextmanager +def atomic_write(path, flag): + """Atomically write into a file. + + Usage: + + with atomic_write('foo.txt', 'w') as f: + f.write('shrubery') + # there are no changes on foo.txt yet + # now it is changed + + Temporary copy of the original is created in the same folder == same file + system. + """ + tmp_path = _generate_tmp_path(path) + if os.path.exists(path): + shutil.copyfile(path, tmp_path) + try: + with open(tmp_path, flag) as f: + yield f + except: + raise + else: + shutil.copyfile(tmp_path, path) + finally: + os.remove(tmp_path) + + +def _generate_tmp_path(path): + id = _random_alnum_string(8) + tmp_path = '{}.{}.tmp'.format(path, id) + return tmp_path + + +def _random_alnum_string(length): + return ''.join( + random.choice(string.ascii_letters + string.digits) + for _ in range(length)) diff --git a/tests/utilsTests.py b/tests/utilsTests.py index 975cb0b..1fc4f95 100644 --- a/tests/utilsTests.py +++ b/tests/utilsTests.py @@ -47,7 +47,7 @@ from monkeypatch import MonkeyPatch, MonkeyPatchScope from vmTestsData import VM_STATUS_DUMP from monkeypatch import Patch -from testlib import forked, online_cpus +from testlib import forked, online_cpus, namedTemporaryDir from testlib import permutations, expandPermutations from testlib import VdsmTestCase as TestCaseBase from testValidation import brokentest @@ -1059,3 +1059,34 @@ proc.start() self._noIntrWatchFd(myPipe, isEpoll=False, mask=select.POLLIN) proc.join() + + +class AtomicWriteTest(TestCaseBase): + + def test_create_a_new_file(self): + TEST_TEXT = 'shrubery' + + with namedTemporaryDir() as tmp_dir: + test_file_path = os.path.join(tmp_dir, 'foo.txt') + with utils.atomic_write(test_file_path, 'w') as f: + f.write(TEST_TEXT) + self.assertFalse(os.path.exists(test_file_path)) + self._assert_file_contains(test_file_path, TEST_TEXT) + + def test_edit_file(self): + TEST_TEXT_1 = 'foo' + TEST_TEXT_2 = 'bar' + + with namedTemporaryDir() as tmp_dir: + test_file_path = os.path.join(tmp_dir, 'foo.txt') + with open(test_file_path, 'w') as f: + f.write(TEST_TEXT_1) + with utils.atomic_write(test_file_path, 'w') as f: + f.write(TEST_TEXT_2) + self._assert_file_contains(test_file_path, TEST_TEXT_1) + self._assert_file_contains(test_file_path, TEST_TEXT_2) + + def _assert_file_contains(self, path, expected_content): + with open(path) as f: + content = f.read() + self.assertEqual(content, expected_content)
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 1:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 2:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 3:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 4:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 5:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 6:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 6: Verified+1
Passed utilsTests.py and network/*_test.py.
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 7:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Edward Haas has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 7: Code-Review-1
(3 comments)
https://gerrit.ovirt.org/#/c/61482/7/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 827: """ Line 828: return os.times()[4] Line 829: Line 830: Line 831: def random_iface_name(prefix='', max_length=15): Suggestion: Rename this to something generic, like random_name.
Then call it instead of _random_alnum... We do not need the _random_alnum... it give no readability or reuse now.
The docstring needs to change as well.
I guess you will need a separate patch for this... sorry. Line 832: """ Line 833: Create a network device name with the supplied prefix and a pseudo-random Line 834: suffix, e.g. dummy_ilXaYiSn7. The name is bound to IFNAMSIZ of 16-1 chars. Line 835: """
https://gerrit.ovirt.org/#/c/61482/7/tests/utilsTests.py File tests/utilsTests.py:
PS7, Line 1070: original_text='foo', new_text='bar' It will be nicer if you can arrange them as in the func definition.
Line 1068: Line 1069: def test_edit_file(self): Line 1070: self._test_atomic_write(original_text='foo', new_text='bar') Line 1071: Line 1072: def _test_atomic_write(self, new_text, original_text=None): Too much logic exists here with regard to original_text existing or not.
It may be nicer and clearer to do the actions in the test. Line 1073: with namedTemporaryDir() as tmp_dir: Line 1074: test_file_path = os.path.join(tmp_dir, 'foo.txt') Line 1075: if original_text is not None: Line 1076: with open(test_file_path, 'w') as f:
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Edward Haas has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8: Code-Review+1
Petr Horáček has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8: Verified+1
(3 comments)
Passed utilsTests.py and network/*_test.py.
https://gerrit.ovirt.org/#/c/61482/7/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 827: """ Line 828: return os.times()[4] Line 829: Line 830: Line 831: def random_name(prefix='', max_length=15):
Suggestion: Rename this to something generic, like random_name.
Done Line 832: """ Line 833: Create a random name with the supplied prefix and a pseudo-random suffix, Line 834: e.g. dummy_ilXaYiSn7. Network devices' names are bound to IFNAMSIZ of 16-1 Line 835: chars.
https://gerrit.ovirt.org/#/c/61482/7/tests/utilsTests.py File tests/utilsTests.py:
PS7, Line 1070: ite(test_file_path, 'w') as f:
It will be nicer if you can arrange them as in the func definition.
helper was dropped
Line 1068: with namedTemporaryDir() as tmp_dir: Line 1069: test_file_path = os.path.join(tmp_dir, 'foo.txt') Line 1070: with utils.atomic_write(test_file_path, 'w') as f: Line 1071: f.write(TEXT) Line 1072: self.assertFalse(os.path.exists(test_file_path))
Too much logic exists here with regard to original_text existing or not.
Done Line 1073: self._assert_file_contains(test_file_path, TEXT) Line 1074: # temporary file was removed Line 1075: self.assertEqual(len(os.listdir(tmp_dir)), 1) Line 1076:
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8: Code-Review-1
(5 comments)
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_write(path, flag): call it - atomic_file_write_context. and if its only write, remove the flag param Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Line 942: f.write('shrubery') Line 943: # there are no changes on foo.txt yet Line 944: # now it is changed Line 945: """ Line 946: tmp_path = _generate_tmp_file_path(path) path is a file name and not a path, at least if I follow the usage comment Line 947: if os.path.exists(path): Line 948: shutil.copyfile(path, tmp_path) Line 949: try: Line 950: with open(tmp_path, flag) as f:
Line 946: tmp_path = _generate_tmp_file_path(path) Line 947: if os.path.exists(path): Line 948: shutil.copyfile(path, tmp_path) Line 949: try: Line 950: with open(tmp_path, flag) as f: you should use the full path I guess, or call it filename. its confusing Line 951: yield f Line 952: except: Line 953: raise Line 954: else:
Line 953: raise Line 954: else: Line 955: shutil.copyfile(tmp_path, path) Line 956: finally: Line 957: os.remove(tmp_path) use rmFile, or handle exceptions Line 958: Line 959: Line 960: def _generate_tmp_file_path(file_path):
Line 957: os.remove(tmp_path) Line 958: Line 959: Line 960: def _generate_tmp_file_path(file_path): Line 961: return '{}.{}.tmp'.format(file_path, random_name()) you don't need this helper, it got no use - do it directly in the function
Edward Haas has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_write(path, flag):
call it - atomic_file_write_context. and if its only write, remove the flag
Without the '_context' please, I prefer the type name not to be specified, the 'with' should be enough in the usage. Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_write(path, flag):
Without the '_context' please, I prefer the type name not to be specified,
this implies about the usage imo Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Edward Haas has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_write(path, flag):
this implies about the usage imo
As I see it, it's like asking to specify the type name in the variable (or the returned value type of a func). The func is marked as a contextmanager, that is enough imo.
Leaving it to you guys to solve this out, I won't fight over it. Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Dan Kenigsberg has posted comments on this change.
Change subject: utils: atomic write ......................................................................
Patch Set 8:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 956: finally: Line 957: os.remove(tmp_path) Line 958: Line 959: Line 960: def _generate_tmp_file_path(file_path): tempfile.NamedTemporaryFile(dir=os.path.dirname(file_path))
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 9:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 9: Code-Review-1
(3 comments)
https://gerrit.ovirt.org/#/c/61482/9/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(file, flag): file is a saved word.. better to use file_name.
I think 'w' should be the default flag for file_write... or even hardcoded flag.. why do you need to accept here different flags at all? Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(file, flag): Line 937: """Atomically write into a file. I don't know why in rget above the doc string is in that format, but please break the line after the """ prefix as in the rest of the comments """ docs """ Line 938: Line 939: Usage: Line 940: Line 941: with atomic_write('foo.txt', 'w') as f:
Line 942: f.write('shrubery') Line 943: # there are no changes on foo.txt yet Line 944: # now it is changed Line 945: """ Line 946: _, tmp_file = tempfile.mkstemp(dir=os.path.dirname(os.path.abspath(file)), you can't ignore the fd. you need to close it Line 947: prefix=os.path.basename(file), Line 948: suffix='.tmp') Line 949: try: Line 950: if os.path.exists(file):
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 10:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Dan Kenigsberg has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 9:
(3 comments)
https://gerrit.ovirt.org/#/c/61482/9/lib/vdsm/utils.py File lib/vdsm/utils.py:
PS9, Line 936: file this is a builtin type, better use "filename"
PS9, Line 942: b bb
PS9, Line 957: copyfile copyfile is NOT atomic. you must use os.rename() which is promised by POSIX to either success or fail, never to partially write something on destination.
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 11:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 11: Verified+1
(12 comments)
Passed utilsTests.py
https://gerrit.ovirt.org/#/c/61482/8/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag):
call it - atomic_file_write_context. and if its only write, remove the flag
Write methods are available in 'w', 'a' and '+' flags. We should keep the flag argument. Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag):
As I see it, it's like asking to specify the type name in the variable (or
I think it is obvious from its usage. Plus none of our context manager functions has _context in it. Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Line 942: f.write('shrubbery') Line 943: # there are no changes on foo.txt yet Line 944: # now it is changed Line 945: """ Line 946: fd, tmp_filename = tempfile.mkstemp(
path is a file name and not a path, at least if I follow the usage comment
Done Line 947: dir=os.path.dirname(os.path.abspath(filename)), Line 948: prefix=os.path.basename(filename) + '.', Line 949: suffix='.tmp') Line 950: os.close(fd)
Line 946: fd, tmp_filename = tempfile.mkstemp( Line 947: dir=os.path.dirname(os.path.abspath(filename)), Line 948: prefix=os.path.basename(filename) + '.', Line 949: suffix='.tmp') Line 950: os.close(fd)
you should use the full path I guess, or call it filename. its confusing
I renamed it to 'file'. Python 3 uses the same for open() https://docs.python.org/3.5/library/functions.html#open Line 951: try: Line 952: if os.path.exists(filename): Line 953: shutil.copyfile(filename, tmp_filename) Line 954: with open(tmp_filename, flag) as f:
Line 953: shutil.copyfile(filename, tmp_filename) Line 954: with open(tmp_filename, flag) as f: Line 955: yield f Line 956: except: Line 957: rmFile(tmp_filename)
use rmFile, or handle exceptions
Done Line 958: raise Line 959: else:
Line 956: except: Line 957: rmFile(tmp_filename) Line 958: raise Line 959: else: Line 960: os.rename(tmp_filename, filename)
tempfile.NamedTemporaryFile(dir=os.path.dirname(file_path))
Done
Line 957: rmFile(tmp_filename) Line 958: raise Line 959: else: Line 960: os.rename(tmp_filename, filename) Line 961
you don't need this helper, it got no use - do it directly in the function
Done
https://gerrit.ovirt.org/#/c/61482/9/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 932: return rget(dict.get(keys[0]), keys[1:], default) Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag):
file is a saved word.. better to use file_name.
In the following patch I use 'r+' to read and edit file inside one with block.
Changed to filename. Line 937: """Atomically write into a file. Line 938: Line 939: Usage: Line 940:
Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag): Line 937: """Atomically write into a file.
I don't know why in rget above the doc string is in that format, but please
I'm following https://www.python.org/dev/peps/pep-0257/#multi-line-docstrings Line 938: Line 939: Usage: Line 940: Line 941: with atomic_write('foo.txt', 'w') as f:
PS9, Line 942: b
bb
Thanks!
Line 942: f.write('shrubbery') Line 943: # there are no changes on foo.txt yet Line 944: # now it is changed Line 945: """ Line 946: fd, tmp_filename = tempfile.mkstemp(
you can't ignore the fd. you need to close it
Done Line 947: dir=os.path.dirname(os.path.abspath(filename)), Line 948: prefix=os.path.basename(filename) + '.', Line 949: suffix='.tmp') Line 950: os.close(fd)
PS9, Line 957: tmp_file
copyfile is NOT atomic. you must use os.rename() which is promised by POSIX
Done
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 11:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/9/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag): Line 937: """Atomically write into a file.
I'm following https://www.python.org/dev/peps/pep-0257/#multi-line-docstrin
ok. please follow the file standards here Line 938: Line 939: Usage: Line 940: Line 941: with atomic_write('foo.txt', 'w') as f:
Martin Polednik has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 11:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/11/lib/vdsm/utils.py File lib/vdsm/utils.py:
PS11, Line 956: except: Too generic.
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 12:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 12:
(2 comments)
https://gerrit.ovirt.org/#/c/61482/9/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 933: Line 934: Line 935: @contextmanager Line 936: def atomic_file_write(filename, flag): Line 937: """
ok. please follow the file standards here
Done Line 938: Atomically write into a file. Line 939: Line 940: Usage: Line 941:
https://gerrit.ovirt.org/#/c/61482/11/lib/vdsm/utils.py File lib/vdsm/utils.py:
PS11, Line 956:
Too generic.
Done
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 12: Verified+1
Passed utilsTests.py
Edward Haas has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 12: Code-Review+1
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 12:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/12/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 953: if os.path.exists(filename): Line 954: shutil.copyfile(filename, tmp_filename) Line 955: with open(tmp_filename, flag) as f: Line 956: yield f Line 957: except Exception: still too generic. isn't IOException enough here? Line 958: rmFile(tmp_filename) Line 959: raise Line 960: else:
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 13:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 13: Verified+1
(1 comment)
Passed utilsTests.py
https://gerrit.ovirt.org/#/c/61482/12/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 953: if os.path.exists(filename): Line 954: shutil.copyfile(filename, tmp_filename) Line 955: with open(tmp_filename, flag) as f: Line 956: yield f Line 957: except IOError:
still too generic. isn't IOException enough here?
Changed to IOError. Line 958: rmFile(tmp_filename) Line 959: raise Line 960: else:
Edward Haas has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 13: Code-Review-1
(1 comment)
https://gerrit.ovirt.org/#/c/61482/12/lib/vdsm/utils.py File lib/vdsm/utils.py:
Line 953: if os.path.exists(filename): Line 954: shutil.copyfile(filename, tmp_filename) Line 955: with open(tmp_filename, flag) as f: Line 956: yield f Line 957: except IOError:
Changed to IOError.
But it needs to be generic... If a failure occurs, the file needs to be removed regardless of the error type. If no failure occurs, the file is moved to apply the change atomically. Line 958: rmFile(tmp_filename) Line 959: raise Line 960: else:
Edward Haas has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 13:
(1 comment)
https://gerrit.ovirt.org/#/c/61482/13/tests/utilsTests.py File tests/utilsTests.py:
Line 1060: self._noIntrWatchFd(myPipe, isEpoll=False, mask=select.POLLIN) Line 1061: proc.join() Line 1062: Line 1063: Line 1064: class AtomicFileWriteTest(TestCaseBase): Please add a test with an exception and check that the temp file is cleaned. Line 1065: Line 1066: def test_create_a_new_file(self): Line 1067: TEXT = 'foo' Line 1068: with namedTemporaryDir() as tmp_dir:
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 14:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 14: Verified+1
(1 comment)
Passed utilsTests.py
https://gerrit.ovirt.org/#/c/61482/13/tests/utilsTests.py File tests/utilsTests.py:
Line 1060: fcntl.fcntl(hisPipe, fcntl.F_SETFL, os.O_NONBLOCK) Line 1061: fcntl.fcntl(myPipe, fcntl.F_SETFL, os.O_NONBLOCK) Line 1062: proc = Process(target=_raiseEAGAIN, args=(hisPipe,)) Line 1063: proc.start() Line 1064: self._noIntrWatchFd(myPipe, isEpoll=False, mask=select.POLLIN)
Please add a test with an exception and check that the temp file is cleaned
Done Line 1065: proc.join() Line 1066: Line 1067: Line 1068: class AtomicFileWriteTest(TestCaseBase):
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 14: -Verified
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 15:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 15: Verified+1
Passed utilsTests.py
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 16:
* #1195208::Update tracker: OK * Check Bug-Url::OK * Check Public Bug::#1195208::OK, public bug * Check Product::#1195208::OK, Correct classification oVirt * Check TM::SKIP, not in a monitored branch (ovirt-3.6 ovirt-4.0) * Check merged to previous::IGNORE, Not in stable branch (['ovirt-3.6', 'ovirt-4.0'])
Petr Horáček has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 16: Verified+1
Passed utilsTests.py
Edward Haas has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 16: Code-Review+1
Yaniv Bronhaim has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 16: Code-Review+1
Dan Kenigsberg has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 16: Code-Review+2
raising score
Dan Kenigsberg has submitted this change and it was merged.
Change subject: utils: atomic file write ......................................................................
utils: atomic file write
Atomic writes are needed for safe file editation. This function will be used in following network patch 'acquire interfaces'.
Change-Id: Icbb5a2d3ac439a334db2c9075376f219c356762c Bug-Url: https://bugzilla.redhat.com/1195208 Signed-off-by: Petr Horáček phoracek@redhat.com Reviewed-on: https://gerrit.ovirt.org/61482 Continuous-Integration: Jenkins CI Reviewed-by: Edward Haas edwardh@redhat.com Reviewed-by: Yaniv Bronhaim ybronhei@redhat.com Reviewed-by: Dan Kenigsberg danken@redhat.com --- M lib/vdsm/utils.py M tests/utilsTests.py 2 files changed, 80 insertions(+), 1 deletion(-)
Approvals: Yaniv Bronhaim: Looks good to me, but someone else must approve Jenkins CI: Passed CI tests Petr Horáček: Verified Dan Kenigsberg: Looks good to me, approved Edward Haas: Looks good to me, but someone else must approve
gerrit-hooks has posted comments on this change.
Change subject: utils: atomic file write ......................................................................
Patch Set 17:
* #1195208::Update tracker: OK * Set MODIFIED::bug 1195208::::#1195208::::FAILED, illegal change from ON_QA
vdsm-patches@lists.fedorahosted.org