2
# -*- coding: utf-8 -*-
4
# (c) 2012, Stephen Fromm <sfromm@gmail.com>
6
# This file is part of Ansible
8
# Ansible is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# Ansible is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
29
short_description: Assembles a configuration file from fragments
31
- Assembles a configuration file from fragments. Often a particular
32
program will take a single configuration file and does not support a
33
C(conf.d) style structure where it is easy to build up the configuration
34
from multiple sources. M(assemble) will take a directory of files that have
35
already been transferred to the system, and concatenate them together to
36
produce a destination file. Files are assembled in string sorting order.
37
Puppet calls this idea I(fragments).
42
- An already existing directory full of source files.
48
- A file to create using the concatenation of all of the source files.
53
- Create a backup file (if C(yes)), including the timestamp information so
54
you can get the original file back if you somehow clobbered it
57
choices: [ "yes", "no" ]
61
- all arguments accepted by the M(file) module also work here
64
- code: "assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf"
65
description: "Example from Ansible Playbooks"
69
# ===========================================
72
def assemble_from_fragments(path):
73
''' assemble a file from a directory of fragments '''
75
for f in sorted(os.listdir(path)):
76
fragment = "%s/%s" % (path, f)
77
if os.path.isfile(fragment):
78
assembled.append(file(fragment).read())
79
return "".join(assembled)
81
def write_temp_file(data):
82
fd, path = tempfile.mkstemp()
87
# ==============================================================
92
module = AnsibleModule(
93
# not checking because of daisy chain to file module
95
src = dict(required=True),
96
dest = dict(required=True),
97
backup=dict(default=False, type='bool'),
99
add_file_common_args=True
105
src = os.path.expanduser(module.params['src'])
106
dest = os.path.expanduser(module.params['dest'])
107
backup = module.params['backup']
109
if not os.path.exists(src):
110
module.fail_json(msg="Source (%s) does not exist" % src)
112
if not os.path.isdir(src):
113
module.fail_json(msg="Source (%s) is not a directory" % src)
115
path = write_temp_file(assemble_from_fragments(src))
116
pathmd5 = module.md5(path)
118
if os.path.exists(dest):
119
destmd5 = module.md5(dest)
121
if pathmd5 != destmd5:
122
if backup and destmd5 is not None:
123
module.backup_local(dest)
124
shutil.copy(path, dest)
127
file_args = module.load_file_common_arguments(module.params)
128
changed = module.set_file_attributes_if_different(file_args, changed)
130
module.exit_json(src=src, dest=dest, md5sum=destmd5,
131
changed=changed, msg="OK")
133
# this is magic, see lib/ansible/module_common.py
134
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>