write_files: Added option to append the file with given content

If the option is set to true, the code will append the file with given content.

Cloud-config example:
write_files:
  -
    content: "append"
    path: 'C:\\path.txt'
    append: true

Fixes: https://github.com/cloudbase/cloudbase-init/issues/25

Change-Id: Ifd3d21842042dd34f7fde38a992e7fd74c1a595d
This commit is contained in:
Madalin 2019-12-02 16:16:20 +02:00
parent 6e9f0f0286
commit f09dc6431a
2 changed files with 56 additions and 1 deletions

View File

@ -132,6 +132,7 @@ class WriteFilesPlugin(base.BaseCloudConfigPlugin):
permissions: The octal permissions set that should be given for
this file.
encoding: An optional encoding specification for the file.
append: An optional flag to append the content
The only required keys in this dictionary are `path` and `content`.
"""
@ -146,7 +147,12 @@ class WriteFilesPlugin(base.BaseCloudConfigPlugin):
content = _process_content(item['content'],
item.get('encoding'))
permissions = _convert_permissions(item.get('permissions'))
_write_file(path, content, permissions)
open_mode = "wb"
if item.get('append', False):
open_mode = "ab"
_write_file(path, content, permissions, open_mode)
def process(self, data):
"""Process the given data received from the cloud-config userdata.

View File

@ -266,3 +266,52 @@ class WriteFilesPluginTests(unittest.TestCase):
expected = "Can't process the type of data %r" % type(1)
self.assertEqual(expected, str(cm.exception))
def test_process_item_fail(self):
fake_data = {}
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
'userdataplugins.cloudconfigplugins.'
'write_files') as snatcher:
write_files.WriteFilesPlugin()._process_item(fake_data)
self.assertEqual(['Missing required keys from file information {}'],
snatcher.output)
@mock.patch('cloudbaseinit.plugins.common.userdataplugins.'
'cloudconfigplugins.write_files._process_content')
@mock.patch('cloudbaseinit.plugins.common.userdataplugins.'
'cloudconfigplugins.write_files._write_file')
@mock.patch('os.path.abspath')
def _test_process_item(self, fake_data,
mock_os_path,
mock_write_file,
mock_process_content):
fake_path = mock.MagicMock()
mock_os_path.return_value = fake_path
fake_content = mock.MagicMock()
mock_process_content.return_value = fake_content
with testutils.LogSnatcher('cloudbaseinit.plugins.common.'
'userdataplugins.cloudconfigplugins.'
'write_files') as snatcher:
write_files.WriteFilesPlugin()._process_item(fake_data)
self.assertEqual(['Fail to process permissions None, assuming 420'],
snatcher.output)
open_mode = 'wb'
if fake_data.get('append', False) is True:
open_mode = 'ab'
mock_write_file.assert_called_with(fake_path, fake_content, 420,
open_mode)
def test_process_item_write(self):
self._test_process_item(
{'path': 'fake_path', 'content': 'fake_content', 'append': False})
def test_process_item_append(self):
self._test_process_item(
{'path': 'fake_path', 'content': 'fake_content', 'append': True})