~canonical-ci-engineering/ubuntu-ci-services-itself/ansible

« back to all changes in this revision

Viewing changes to library/assemble

  • Committer: Package Import Robot
  • Author(s): Michael Vogt, Harlan Lieberman-Berg, Michael Vogt
  • Date: 2013-11-01 09:40:59 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20131101094059-6w580ocxzqyqzuu3
Tags: 1.3.4+dfsg-1
[ Harlan Lieberman-Berg ]
* New upstream release (Closes: #717777).
  Fixes CVE-2013-2233 (Closes: #714822).
  Fixes CVE-2013-4259 (Closes: #721766).
* Drop fix-ansible-cfg patch.
* Change docsite generation to not expect docs as part of a wordpress install.
* Add trivial patch to fix lintian error with rpm-key script.
* Add patch header information to fix-html-makefile.

[ Michael Vogt ]
* add myself to uploader
* build/ship the module manpages for ansible in the ansible package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
# -*- coding: utf-8 -*-
3
 
 
4
 
# (c) 2012, Stephen Fromm <sfromm@gmail.com>
5
 
#
6
 
# This file is part of Ansible
7
 
#
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.
12
 
#
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.
17
 
#
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/>.
20
 
 
21
 
import os
22
 
import os.path
23
 
import shutil
24
 
import tempfile
25
 
 
26
 
DOCUMENTATION = '''
27
 
---
28
 
module: assemble
29
 
short_description: Assembles a configuration file from fragments
30
 
description:
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).
38
 
version_added: "0.5"
39
 
options:
40
 
  src:
41
 
    description:
42
 
      - An already existing directory full of source files.
43
 
    required: true
44
 
    default: null
45
 
    aliases: []
46
 
  dest:
47
 
    description:
48
 
      - A file to create using the concatenation of all of the source files.
49
 
    required: true
50
 
    default: null
51
 
  backup:
52
 
    description:
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
55
 
        incorrectly.
56
 
    required: false
57
 
    choices: [ "yes", "no" ]
58
 
    default: "no"
59
 
  others:
60
 
    description:
61
 
      - all arguments accepted by the M(file) module also work here
62
 
    required: false
63
 
examples:
64
 
   - code: "assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf"
65
 
     description: "Example from Ansible Playbooks"
66
 
author: Stephen Fromm
67
 
'''
68
 
 
69
 
# ===========================================
70
 
# Support methods
71
 
 
72
 
def assemble_from_fragments(path):
73
 
    ''' assemble a file from a directory of fragments '''
74
 
    assembled = []
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)
80
 
 
81
 
def write_temp_file(data):
82
 
    fd, path = tempfile.mkstemp()
83
 
    os.write(fd, data)
84
 
    os.close(fd)
85
 
    return path
86
 
 
87
 
# ==============================================================
88
 
# main
89
 
 
90
 
def main():
91
 
 
92
 
    module = AnsibleModule(
93
 
        # not checking because of daisy chain to file module
94
 
        argument_spec = dict(
95
 
            src = dict(required=True),
96
 
            dest = dict(required=True),
97
 
            backup=dict(default=False, type='bool'),
98
 
        ),
99
 
        add_file_common_args=True
100
 
    )
101
 
 
102
 
    changed=False
103
 
    pathmd5 = None
104
 
    destmd5 = None
105
 
    src = os.path.expanduser(module.params['src'])
106
 
    dest = os.path.expanduser(module.params['dest'])
107
 
    backup = module.params['backup']
108
 
 
109
 
    if not os.path.exists(src):
110
 
        module.fail_json(msg="Source (%s) does not exist" % src)
111
 
 
112
 
    if not os.path.isdir(src):
113
 
        module.fail_json(msg="Source (%s) is not a directory" % src)
114
 
 
115
 
    path = write_temp_file(assemble_from_fragments(src))
116
 
    pathmd5 = module.md5(path)
117
 
 
118
 
    if os.path.exists(dest):
119
 
        destmd5 = module.md5(dest)
120
 
 
121
 
    if pathmd5 != destmd5:
122
 
        if backup and destmd5 is not None:
123
 
            module.backup_local(dest)
124
 
        shutil.copy(path, dest)
125
 
        changed = True
126
 
 
127
 
    file_args = module.load_file_common_arguments(module.params)
128
 
    changed = module.set_file_attributes_if_different(file_args, changed)
129
 
    # Mission complete
130
 
    module.exit_json(src=src, dest=dest, md5sum=destmd5,
131
 
        changed=changed, msg="OK")
132
 
 
133
 
# this is magic, see lib/ansible/module_common.py
134
 
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
135
 
 
136
 
main()