Your application is now running on a container in Amazon ECS.
' > top; /bin/date > date ; echo 'Last updated on {{ansible_date_time.iso8601}}
+ +- name: remove HTML as well as surrounding markers + blockinfile: + dest: /var/www/html/index.html + marker: "" + content: "" + +- name: Add mappings to /etc/hosts + blockinfile: + dest: /etc/hosts + block: | + {{item.ip}} {{item.name}} + marker: "# {mark} ANSIBLE MANAGED BLOCK {{item.name}}" + with_items: + - { name: host1, ip: 10.10.1.10 } + - { name: host2, ip: 10.10.1.11 } + - { name: host3, ip: 10.10.1.12 } +""" + +import re +import os +import tempfile +from ansible.module_utils.six import b +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_bytes + +def write_changes(module, contents, dest): + + tmpfd, tmpfile = tempfile.mkstemp() + f = os.fdopen(tmpfd, 'wb') + f.write(contents) + f.close() + + validate = module.params.get('validate', None) + valid = not validate + if validate: + if "%s" not in validate: + module.fail_json(msg="validate must contain %%s: %s" % (validate)) + (rc, out, err) = module.run_command(validate % tmpfile) + valid = rc == 0 + if rc != 0: + module.fail_json(msg='failed to validate: ' + 'rc:%s error:%s' % (rc, err)) + if valid: + module.atomic_move(tmpfile, dest, unsafe_writes=module.params['unsafe_writes']) + + +def check_file_attrs(module, changed, message): + + file_args = module.load_file_common_arguments(module.params) + if module.set_file_attributes_if_different(file_args, False): + + if changed: + message += " and " + changed = True + message += "ownership, perms or SE linux context changed" + + return message, changed + + +def main(): + module = AnsibleModule( + argument_spec=dict( + dest=dict(required=True, aliases=['name', 'destfile'], type='path'), + state=dict(default='present', choices=['absent', 'present']), + marker=dict(default='# {mark} ANSIBLE MANAGED BLOCK', type='str'), + block=dict(default='', type='str', aliases=['content']), + insertafter=dict(default=None), + insertbefore=dict(default=None), + create=dict(default=False, type='bool'), + backup=dict(default=False, type='bool'), + validate=dict(default=None, type='str'), + ), + mutually_exclusive=[['insertbefore', 'insertafter']], + add_file_common_args=True, + supports_check_mode=True + ) + + params = module.params + dest = params['dest'] + if module.boolean(params.get('follow', None)): + dest = os.path.realpath(dest) + + if os.path.isdir(dest): + module.fail_json(rc=256, + msg='Destination %s is a directory !' % dest) + + path_exists = os.path.exists(dest) + if not path_exists: + if not module.boolean(params['create']): + module.fail_json(rc=257, + msg='Destination %s does not exist !' % dest) + original = None + lines = [] + else: + f = open(dest, 'rb') + original = f.read() + f.close() + lines = original.splitlines() + + insertbefore = params['insertbefore'] + insertafter = params['insertafter'] + block = to_bytes(params['block']) + marker = to_bytes(params['marker']) + present = params['state'] == 'present' + + if not present and not path_exists: + module.exit_json(changed=False, msg="File not present") + + if insertbefore is None and insertafter is None: + insertafter = 'EOF' + + if insertafter not in (None, 'EOF'): + insertre = re.compile(insertafter) + elif insertbefore not in (None, 'BOF'): + insertre = re.compile(insertbefore) + else: + insertre = None + + marker0 = re.sub(b(r'{mark}'), b('BEGIN'), marker) + marker1 = re.sub(b(r'{mark}'), b('END'), marker) + if present and block: + # Escape seqeuences like '\n' need to be handled in Ansible 1.x + if module.ansible_version.startswith('1.'): + block = re.sub('', block, '') + blocklines = [marker0] + block.splitlines() + [marker1] + else: + blocklines = [] + + n0 = n1 = None + for i, line in enumerate(lines): + if line == marker0: + n0 = i + if line == marker1: + n1 = i + + if None in (n0, n1): + n0 = None + if insertre is not None: + for i, line in enumerate(lines): + if insertre.search(line): + n0 = i + if n0 is None: + n0 = len(lines) + elif insertafter is not None: + n0 += 1 + elif insertbefore is not None: + n0 = 0 # insertbefore=BOF + else: + n0 = len(lines) # insertafter=EOF + elif n0 < n1: + lines[n0:n1+1] = [] + else: + lines[n1:n0+1] = [] + n0 = n1 + + lines[n0:n0] = blocklines + + if lines: + result = b('\n').join(lines) + if original is None or original.endswith(b('\n')): + result += b('\n') + else: + result = '' + if original == result: + msg = '' + changed = False + elif original is None: + msg = 'File created' + changed = True + elif not blocklines: + msg = 'Block removed' + changed = True + else: + msg = 'Block inserted' + changed = True + + if changed and not module.check_mode: + if module.boolean(params['backup']) and path_exists: + module.backup_local(dest) + write_changes(module, result, dest) + + if module.check_mode and not path_exists: + module.exit_json(changed=changed, msg=msg) + + msg, changed = check_file_attrs(module, changed, msg) + module.exit_json(changed=changed, msg=msg) + + +if __name__ == '__main__': + main() diff --git a/files/patch.py b/files/patch.py index 576333c38f8..c5aecf4e0d4 100644 --- a/files/patch.py +++ b/files/patch.py @@ -19,6 +19,10 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see