~sdn-charmers/charms/trusty/neutron-contrail/dpdk

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/core/templating.py

  • Committer: Robert Ayres
  • Date: 2016-10-10 20:55:32 UTC
  • Revision ID: robert.ayres@canonical.com-20161010205532-zes2f1g9e34e7arf
Sync charm helpers

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright 2014-2015 Canonical Limited.
2
2
#
3
 
# This file is part of charm-helpers.
4
 
#
5
 
# charm-helpers is free software: you can redistribute it and/or modify
6
 
# it under the terms of the GNU Lesser General Public License version 3 as
7
 
# published by the Free Software Foundation.
8
 
#
9
 
# charm-helpers is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU Lesser General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU Lesser General Public License
15
 
# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 
3
# Licensed under the Apache License, Version 2.0 (the "License");
 
4
# you may not use this file except in compliance with the License.
 
5
# You may obtain a copy of the License at
 
6
#
 
7
#  http://www.apache.org/licenses/LICENSE-2.0
 
8
#
 
9
# Unless required by applicable law or agreed to in writing, software
 
10
# distributed under the License is distributed on an "AS IS" BASIS,
 
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
12
# See the License for the specific language governing permissions and
 
13
# limitations under the License.
16
14
 
17
15
import os
 
16
import sys
18
17
 
19
18
from charmhelpers.core import host
20
19
from charmhelpers.core import hookenv
21
20
 
22
21
 
23
22
def render(source, target, context, owner='root', group='root',
24
 
           perms=0o444, templates_dir=None, encoding='UTF-8'):
 
23
           perms=0o444, templates_dir=None, encoding='UTF-8', template_loader=None):
25
24
    """
26
25
    Render a template.
27
26
 
28
27
    The `source` path, if not absolute, is relative to the `templates_dir`.
29
28
 
30
 
    The `target` path should be absolute.
 
29
    The `target` path should be absolute.  It can also be `None`, in which
 
30
    case no file will be written.
31
31
 
32
32
    The context should be a dict containing the values to be replaced in the
33
33
    template.
36
36
 
37
37
    If omitted, `templates_dir` defaults to the `templates` folder in the charm.
38
38
 
39
 
    Note: Using this requires python-jinja2; if it is not installed, calling
40
 
    this will attempt to use charmhelpers.fetch.apt_install to install it.
 
39
    The rendered template will be written to the file as well as being returned
 
40
    as a string.
 
41
 
 
42
    Note: Using this requires python-jinja2 or python3-jinja2; if it is not
 
43
    installed, calling this will attempt to use charmhelpers.fetch.apt_install
 
44
    to install it.
41
45
    """
42
46
    try:
43
47
        from jinja2 import FileSystemLoader, Environment, exceptions
49
53
                        'charmhelpers.fetch to install it',
50
54
                        level=hookenv.ERROR)
51
55
            raise
52
 
        apt_install('python-jinja2', fatal=True)
 
56
        if sys.version_info.major == 2:
 
57
            apt_install('python-jinja2', fatal=True)
 
58
        else:
 
59
            apt_install('python3-jinja2', fatal=True)
53
60
        from jinja2 import FileSystemLoader, Environment, exceptions
54
61
 
55
 
    if templates_dir is None:
56
 
        templates_dir = os.path.join(hookenv.charm_dir(), 'templates')
57
 
    loader = Environment(loader=FileSystemLoader(templates_dir))
 
62
    if template_loader:
 
63
        template_env = Environment(loader=template_loader)
 
64
    else:
 
65
        if templates_dir is None:
 
66
            templates_dir = os.path.join(hookenv.charm_dir(), 'templates')
 
67
        template_env = Environment(loader=FileSystemLoader(templates_dir))
58
68
    try:
59
69
        source = source
60
 
        template = loader.get_template(source)
 
70
        template = template_env.get_template(source)
61
71
    except exceptions.TemplateNotFound as e:
62
72
        hookenv.log('Could not load template %s from %s.' %
63
73
                    (source, templates_dir),
64
74
                    level=hookenv.ERROR)
65
75
        raise e
66
76
    content = template.render(context)
67
 
    host.mkdir(os.path.dirname(target), owner, group, perms=0o755)
68
 
    host.write_file(target, content.encode(encoding), owner, group, perms)
 
77
    if target is not None:
 
78
        target_dir = os.path.dirname(target)
 
79
        if not os.path.exists(target_dir):
 
80
            # This is a terrible default directory permission, as the file
 
81
            # or its siblings will often contain secrets.
 
82
            host.mkdir(os.path.dirname(target), owner, group, perms=0o755)
 
83
        host.write_file(target, content.encode(encoding), owner, group, perms)
 
84
    return content