Merge ~j.w.baxter/cloud-init:append_files into cloud-init:master

Proposed by James Baxter
Status: Merged
Approved by: Scott Moser
Approved revision: 21e0df9fa41564265bbbd2c5d6c8ece8889725d7
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~j.w.baxter/cloud-init:append_files
Merge into: cloud-init:master
Diff against target: 48 lines (+18/-1)
2 files modified
cloudinit/config/cc_write_files.py (+6/-1)
tests/unittests/test_handler/test_handler_write_files.py (+12/-0)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Scott Moser Approve
Ryan Harper Approve
Review via email: mp+359975@code.launchpad.net

Commit message

write_files: add support for appending to files.

Add 'append: true' to write_files entries to append 'content' to file
specified by 'path' key. This modifies the file open mode to append.

Description of the change

Adds the ability to append to files

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

James,

Thanks for the patch here. I've an inline comment/suggestion to the code. Could you also add a unittest here:

tests/unittests/test_handler/test_handler_write_files.py

review: Needs Fixing
~j.w.baxter/cloud-init:append_files updated
21e0df9... by James Baxter

config: simplify write_files append and add unit test

Revision history for this message
James Baxter (j.w.baxter) wrote :

Thanks, have made the suggested changes!

Revision history for this message
Ryan Harper (raharper) wrote :

One more suggestion for the unittest. Thanks for adding that.

Revision history for this message
James Baxter (j.w.baxter) wrote :

Hmmmm, so I tried to make those changes, but I get a file permission issue due to an attempted chown to the default owner (root). Maybe this is why 'test_simple' uses patchUtils?

ERROR: tests.unittests.test_handler.test_handler_write_files.TestWriteFiles.test_append
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/james/projects/cloud-init/tests/unittests/test_handler/test_handler_write_files.py", line 63, in test_append
    [{"content": added, "path": filename, "append": "true"}])
  File "/home/james/projects/cloud-init/cloudinit/config/cc_write_files.py", line 122, in write_files
    util.chownbyname(path, u, g)
  File "/home/james/projects/cloud-init/cloudinit/util.py", line 1424, in chownbyname
    chownbyid(fname, uid, gid)
  File "/home/james/projects/cloud-init/cloudinit/util.py", line 1411, in chownbyid
    os.chown(fname, uid, gid)
PermissionError: [Errno 1] Operation not permitted: '/tmp/ci-TestWriteFiles.rozoygw8/append.file'
-------------------- >> begin captured logging << --------------------
cloudinit.util: DEBUG: Writing to /tmp/ci-TestWriteFiles.rozoygw8/append.file - wb: [644] 6 bytes
cloudinit.util: DEBUG: Writing to /tmp/ci-TestWriteFiles.rozoygw8/append.file - ab: [644] 6 bytes
cloudinit.util: DEBUG: Changing the ownership of /tmp/ci-TestWriteFiles.rozoygw8/append.file to 0:0
--------------------- >> end captured logging << ---------------------

Revision history for this message
Ryan Harper (raharper) wrote :

I'm sorry, I made you run in circles. The patchUtils() mocks the calls to cloudinit.util() which helps prevent it attempting to run operations like chmod/chown etc, it also "re-roots" /tmp so it's fine to put a /tmp/XXXX.

Sorry for the trouble.

Revision history for this message
Ryan Harper (raharper) :
review: Approve
Revision history for this message
Scott Moser (smoser) wrote :

I think this is fine.
The only thing I wold say is that 'append: <boolean>' is less
future-safe than 'mode: append' (where 'mode' would default to
'truncate' to retain backwards compatible behavior).

The benefit of 'mode' (or whatever word we want to use there) is
that then ou could later extend that to support "write only if exists"
or something like that.

So i think the other would be more future safe but I think this is fine.

review: Approve
Revision history for this message
Server Team CI bot (server-team-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/config/cc_write_files.py b/cloudinit/config/cc_write_files.py
2index 31d1db6..0b6546e 100644
3--- a/cloudinit/config/cc_write_files.py
4+++ b/cloudinit/config/cc_write_files.py
5@@ -49,6 +49,10 @@ binary gzip data can be specified and will be decoded before being written.
6 ...
7 path: /bin/arch
8 permissions: '0555'
9+ - content: |
10+ 15 * * * * root ship_logs
11+ path: /etc/crontab
12+ append: true
13 """
14
15 import base64
16@@ -113,7 +117,8 @@ def write_files(name, files):
17 contents = extract_contents(f_info.get('content', ''), extractions)
18 (u, g) = util.extract_usergroup(f_info.get('owner', DEFAULT_OWNER))
19 perms = decode_perms(f_info.get('permissions'), DEFAULT_PERMS)
20- util.write_file(path, contents, mode=perms)
21+ omode = 'ab' if util.get_cfg_option_bool(f_info, 'append') else 'wb'
22+ util.write_file(path, contents, omode=omode, mode=perms)
23 util.chownbyname(path, u, g)
24
25
26diff --git a/tests/unittests/test_handler/test_handler_write_files.py b/tests/unittests/test_handler/test_handler_write_files.py
27index 7fa8fd2..bc8756c 100644
28--- a/tests/unittests/test_handler/test_handler_write_files.py
29+++ b/tests/unittests/test_handler/test_handler_write_files.py
30@@ -52,6 +52,18 @@ class TestWriteFiles(FilesystemMockingTestCase):
31 "test_simple", [{"content": expected, "path": filename}])
32 self.assertEqual(util.load_file(filename), expected)
33
34+ def test_append(self):
35+ self.patchUtils(self.tmp)
36+ existing = "hello "
37+ added = "world\n"
38+ expected = existing + added
39+ filename = "/tmp/append.file"
40+ util.write_file(filename, existing)
41+ write_files(
42+ "test_append",
43+ [{"content": added, "path": filename, "append": "true"}])
44+ self.assertEqual(util.load_file(filename), expected)
45+
46 def test_yaml_binary(self):
47 self.patchUtils(self.tmp)
48 data = util.load_yaml(YAML_TEXT)

Subscribers

People subscribed via source and target branches