Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit df972db

Browse files
author
Erik Johnson
authored
Merge pull request #42930 from CorvinM/issue36942
Jinja line statements and comments
2 parents 97863f3 + c67db52 commit df972db

File tree

9 files changed

+271
-26
lines changed

9 files changed

+271
-26
lines changed

conf/master

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -569,18 +569,35 @@
569569
# The renderer to use on the minions to render the state data
570570
#renderer: yaml_jinja
571571

572-
# The Jinja renderer can strip extra carriage returns and whitespace
573-
# See http://jinja.pocoo.org/docs/api/#high-level-api
574-
#
575-
# If this is set to True the first newline after a Jinja block is removed
576-
# (block, not variable tag!). Defaults to False, corresponds to the Jinja
577-
# environment init variable "trim_blocks".
578-
#jinja_trim_blocks: False
579-
#
580-
# If this is set to True leading spaces and tabs are stripped from the start
581-
# of a line to a block. Defaults to False, corresponds to the Jinja
582-
# environment init variable "lstrip_blocks".
583-
#jinja_lstrip_blocks: False
572+
# Default Jinja environment options for all templates except sls templates
573+
#jinja_env:
574+
# block_start_string: '{%'
575+
# block_end_string: '%}'
576+
# variable_start_string: '{{'
577+
# variable_end_string: '}}'
578+
# comment_start_string: '{#'
579+
# comment_end_string: '#}'
580+
# line_statement_prefix:
581+
# line_comment_prefix:
582+
# trim_blocks: False
583+
# lstrip_blocks: False
584+
# newline_sequence: '\n'
585+
# keep_trailing_newline: False
586+
587+
# Jinja environment options for sls templates
588+
#jinja_sls_env:
589+
# block_start_string: '{%'
590+
# block_end_string: '%}'
591+
# variable_start_string: '{{'
592+
# variable_end_string: '}}'
593+
# comment_start_string: '{#'
594+
# comment_end_string: '#}'
595+
# line_statement_prefix:
596+
# line_comment_prefix:
597+
# trim_blocks: False
598+
# lstrip_blocks: False
599+
# newline_sequence: '\n'
600+
# keep_trailing_newline: False
584601

585602
# The failhard option tells the minions to stop immediately after the first
586603
# failure detected in the state execution, defaults to False

conf/suse/master

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -540,18 +540,35 @@ syndic_user: salt
540540
# The renderer to use on the minions to render the state data
541541
#renderer: yaml_jinja
542542

543-
# The Jinja renderer can strip extra carriage returns and whitespace
544-
# See http://jinja.pocoo.org/docs/api/#high-level-api
545-
#
546-
# If this is set to True the first newline after a Jinja block is removed
547-
# (block, not variable tag!). Defaults to False, corresponds to the Jinja
548-
# environment init variable "trim_blocks".
549-
#jinja_trim_blocks: False
550-
#
551-
# If this is set to True leading spaces and tabs are stripped from the start
552-
# of a line to a block. Defaults to False, corresponds to the Jinja
553-
# environment init variable "lstrip_blocks".
554-
#jinja_lstrip_blocks: False
543+
# Default Jinja environment options for all templates except sls templates
544+
#jinja_env:
545+
# block_start_string: '{%'
546+
# block_end_string: '%}'
547+
# variable_start_string: '{{'
548+
# variable_end_string: '}}'
549+
# comment_start_string: '{#'
550+
# comment_end_string: '#}'
551+
# line_statement_prefix:
552+
# line_comment_prefix:
553+
# trim_blocks: False
554+
# lstrip_blocks: False
555+
# newline_sequence: '\n'
556+
# keep_trailing_newline: False
557+
558+
# Jinja environment options for sls templates
559+
#jinja_sls_env:
560+
# block_start_string: '{%'
561+
# block_end_string: '%}'
562+
# variable_start_string: '{{'
563+
# variable_end_string: '}}'
564+
# comment_start_string: '{#'
565+
# comment_end_string: '#}'
566+
# line_statement_prefix:
567+
# line_comment_prefix:
568+
# trim_blocks: False
569+
# lstrip_blocks: False
570+
# newline_sequence: '\n'
571+
# keep_trailing_newline: False
555572

556573
# The failhard option tells the minions to stop immediately after the first
557574
# failure detected in the state execution, defaults to False

doc/ref/configuration/master.rst

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1979,11 +1979,120 @@ the cloud profile or master config file, no templating will be performed.
19791979
19801980
userdata_template: jinja
19811981
1982+
.. conf_master:: jinja_env
1983+
1984+
``jinja_env``
1985+
-------------
1986+
1987+
.. versionadded:: Oxygen
1988+
1989+
Default: ``{}``
1990+
1991+
jinja_env overrides the default Jinja environment options for
1992+
**all templates except sls templates**.
1993+
To set the options for sls templates use :conf_master:`jinja_sls_env`.
1994+
1995+
.. note::
1996+
1997+
The `Jinja2 Environment documentation <http://jinja.pocoo.org/docs/api/#jinja2.Environment>`_ is the official source for the default values.
1998+
Not all the options listed in the jinja documentation can be overridden using :conf_master:`jinja_env` or :conf_master:`jinja_sls_env`.
1999+
2000+
The default options are:
2001+
2002+
.. code-block:: yaml
2003+
2004+
jinja_env:
2005+
block_start_string: '{%'
2006+
block_end_string: '%}'
2007+
variable_start_string: '{{'
2008+
variable_end_string: '}}'
2009+
comment_start_string: '{#'
2010+
comment_end_string: '#}'
2011+
line_statement_prefix:
2012+
line_comment_prefix:
2013+
trim_blocks: False
2014+
lstrip_blocks: False
2015+
newline_sequence: '\n'
2016+
keep_trailing_newline: False
2017+
2018+
.. conf_master:: jinja_sls_env
2019+
2020+
``jinja_sls_env``
2021+
-----------------
2022+
2023+
.. versionadded:: Oxygen
2024+
2025+
Default: ``{}``
2026+
2027+
jinja_sls_env sets the Jinja environment options for **sls templates**.
2028+
The defaults and accepted options are exactly the same as they are
2029+
for :conf_master:`jinja_env`.
2030+
2031+
The default options are:
2032+
2033+
.. code-block:: yaml
2034+
2035+
jinja_sls_env:
2036+
block_start_string: '{%'
2037+
block_end_string: '%}'
2038+
variable_start_string: '{{'
2039+
variable_end_string: '}}'
2040+
comment_start_string: '{#'
2041+
comment_end_string: '#}'
2042+
line_statement_prefix:
2043+
line_comment_prefix:
2044+
trim_blocks: False
2045+
lstrip_blocks: False
2046+
newline_sequence: '\n'
2047+
keep_trailing_newline: False
2048+
2049+
Example using line statements and line comments to increase ease of use:
2050+
2051+
If your configuration options are
2052+
2053+
.. code-block:: yaml
2054+
jinja_sls_env:
2055+
line_statement_prefix: '%'
2056+
line_comment_prefix: '##'
2057+
2058+
With these options jinja will interpret anything after a ``%`` at the start of a line (ignoreing whitespace)
2059+
as a jinja statement and will interpret anything after a ``##`` as a comment.
2060+
2061+
This allows the following more convenient syntax to be used:
2062+
2063+
.. code-block:: yaml
2064+
2065+
## (this comment will not stay once rendered)
2066+
# (this comment remains in the rendered template)
2067+
## ensure all the formula services are running
2068+
% for service in formula_services:
2069+
enable_service_{{ serivce }}:
2070+
service.running:
2071+
name: {{ service }}
2072+
% endfor
2073+
2074+
The following less convenient but equivalent syntax would have to
2075+
be used if you had not set the line_statement and line_comment options:
2076+
2077+
.. code-block:: yaml
2078+
2079+
{# (this comment will not stay once rendered) #}
2080+
# (this comment remains in the rendered template)
2081+
{# ensure all the formula services are running #}
2082+
{% for service in formula_services %}
2083+
enable_service_{{ service }}:
2084+
service.running:
2085+
name: {{ service }}
2086+
{% endfor %}
2087+
19822088
.. conf_master:: jinja_trim_blocks
19832089

19842090
``jinja_trim_blocks``
19852091
---------------------
19862092

2093+
.. deprecated:: Oxygen
2094+
Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env`
2095+
19872096
.. versionadded:: 2014.1.0
19882097

19892098
Default: ``False``
@@ -2001,6 +2110,9 @@ to the Jinja environment init variable ``trim_blocks``.
20012110
``jinja_lstrip_blocks``
20022111
-----------------------
20032112

2113+
.. deprecated:: Oxygen
2114+
Replaced by :conf_master:`jinja_env` and :conf_master:`jinja_sls_env`
2115+
20042116
.. versionadded:: 2014.1.0
20052117

20062118
Default: ``False``

salt/config/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,12 @@ def _gather_buffer_space():
890890
# check in with their lists of expected minions before giving up
891891
'syndic_wait': int,
892892

893+
# Override Jinja environment option defaults for all templates except sls templates
894+
'jinja_env': dict,
895+
896+
# Set Jinja environment options for sls templates
897+
'jinja_sls_env': dict,
898+
893899
# If this is set to True leading spaces and tabs are stripped from the start
894900
# of a line to a block.
895901
'jinja_lstrip_blocks': bool,
@@ -1642,6 +1648,8 @@ def _gather_buffer_space():
16421648
'winrepo_passphrase': '',
16431649
'winrepo_refspecs': _DFLT_REFSPECS,
16441650
'syndic_wait': 5,
1651+
'jinja_env': {},
1652+
'jinja_sls_env': {},
16451653
'jinja_lstrip_blocks': False,
16461654
'jinja_trim_blocks': False,
16471655
'tcp_keepalive': True,

salt/daemons/masterapi.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,8 @@ def _master_opts(self, load):
470470
mopts['state_auto_order'] = self.opts['state_auto_order']
471471
mopts['state_events'] = self.opts['state_events']
472472
mopts['state_aggregate'] = self.opts['state_aggregate']
473+
mopts['jinja_env'] = self.opts['jinja_env']
474+
mopts['jinja_sls_env'] = self.opts['jinja_sls_env']
473475
mopts['jinja_lstrip_blocks'] = self.opts['jinja_lstrip_blocks']
474476
mopts['jinja_trim_blocks'] = self.opts['jinja_trim_blocks']
475477
return mopts

salt/master.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,8 @@ def _master_opts(self, load):
11501150
mopts[u'state_auto_order'] = self.opts[u'state_auto_order']
11511151
mopts[u'state_events'] = self.opts[u'state_events']
11521152
mopts[u'state_aggregate'] = self.opts[u'state_aggregate']
1153+
mopts[u'jinja_env'] = self.opts[u'jinja_env']
1154+
mopts[u'jinja_sls_env'] = self.opts[u'jinja_sls_env']
11531155
mopts[u'jinja_lstrip_blocks'] = self.opts[u'jinja_lstrip_blocks']
11541156
mopts[u'jinja_trim_blocks'] = self.opts[u'jinja_trim_blocks']
11551157
return mopts

salt/state.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2838,6 +2838,8 @@ def __gen_opts(self, opts):
28382838
opts[u'default_top'] = mopts.get(u'default_top', opts.get(u'default_top'))
28392839
opts[u'state_events'] = mopts.get(u'state_events')
28402840
opts[u'state_aggregate'] = mopts.get(u'state_aggregate', opts.get(u'state_aggregate', False))
2841+
opts[u'jinja_env'] = mopts.get(u'jinja_env', {})
2842+
opts[u'jinja_sls_env'] = mopts.get(u'jinja_sls_env', {})
28412843
opts[u'jinja_lstrip_blocks'] = mopts.get(u'jinja_lstrip_blocks', False)
28422844
opts[u'jinja_trim_blocks'] = mopts.get(u'jinja_trim_blocks', False)
28432845
return opts

salt/utils/templates.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,16 +355,40 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None):
355355
env_args['extensions'].append('jinja2.ext.loopcontrols')
356356
env_args['extensions'].append(salt.utils.jinja.SerializerExtension)
357357

358+
opt_jinja_env = opts.get('jinja_env', {})
359+
opt_jinja_sls_env = opts.get('jinja_sls_env', {})
360+
361+
opt_jinja_env = opt_jinja_env if isinstance(opt_jinja_env, dict) else {}
362+
opt_jinja_sls_env = opt_jinja_sls_env if isinstance(opt_jinja_sls_env, dict) else {}
363+
358364
# Pass through trim_blocks and lstrip_blocks Jinja parameters
359365
# trim_blocks removes newlines around Jinja blocks
360366
# lstrip_blocks strips tabs and spaces from the beginning of
361367
# line to the start of a block.
362368
if opts.get('jinja_trim_blocks', False):
363369
log.debug('Jinja2 trim_blocks is enabled')
364-
env_args['trim_blocks'] = True
370+
log.warning('jinja_trim_blocks is deprecated and will be removed in a future release, please use jinja_env and/or jinja_sls_env instead')
371+
opt_jinja_env['trim_blocks'] = True
372+
opt_jinja_sls_env['trim_blocks'] = True
365373
if opts.get('jinja_lstrip_blocks', False):
366374
log.debug('Jinja2 lstrip_blocks is enabled')
367-
env_args['lstrip_blocks'] = True
375+
log.warning('jinja_lstrip_blocks is deprecated and will be removed in a future release, please use jinja_env and/or jinja_sls_env instead')
376+
opt_jinja_env['lstrip_blocks'] = True
377+
opt_jinja_sls_env['lstrip_blocks'] = True
378+
379+
def opt_jinja_env_helper(opts, optname):
380+
for k, v in six.iteritems(opts):
381+
k = k.lower()
382+
if hasattr(jinja2.defaults, k.upper()):
383+
log.debug('Jinja2 environment {0} was set to {1} by {2}'.format(k, v, optname))
384+
env_args[k] = v
385+
else:
386+
log.warning('Jinja2 environment {0} is not recognized'.format(k))
387+
388+
if 'sls' in context and context['sls'] != '':
389+
opt_jinja_env_helper(opt_jinja_sls_env, 'jinja_sls_env')
390+
else:
391+
opt_jinja_env_helper(opt_jinja_env, 'jinja_env')
368392

369393
if opts.get('allow_undefined', False):
370394
jinja_env = jinja2.Environment(**env_args)

tests/unit/templates/test_jinja.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,67 @@ def test_render_with_undefined_variable_unicode(self):
481481
)
482482

483483

484+
class TestJinjaDefaultOptions(TestCase):
485+
486+
def __init__(self, *args, **kws):
487+
TestCase.__init__(self, *args, **kws)
488+
self.local_opts = {
489+
'cachedir': TEMPLATES_DIR,
490+
'file_client': 'local',
491+
'file_ignore_regex': None,
492+
'file_ignore_glob': None,
493+
'file_roots': {
494+
'test': [os.path.join(TEMPLATES_DIR, 'files', 'test')]
495+
},
496+
'pillar_roots': {
497+
'test': [os.path.join(TEMPLATES_DIR, 'files', 'test')]
498+
},
499+
'fileserver_backend': ['roots'],
500+
'hash_type': 'md5',
501+
'extension_modules': os.path.join(
502+
os.path.dirname(os.path.abspath(__file__)),
503+
'extmods'),
504+
'jinja_env': {
505+
'line_comment_prefix': '##',
506+
'line_statement_prefix': '%',
507+
},
508+
}
509+
self.local_salt = {
510+
'myvar': 'zero',
511+
'mylist': [0, 1, 2, 3],
512+
}
513+
514+
def test_comment_prefix(self):
515+
516+
template = """
517+
%- set myvar = 'one'
518+
## ignored comment 1
519+
{{- myvar -}}
520+
{%- set myvar = 'two' %} ## ignored comment 2
521+
{{- myvar }} ## ignored comment 3
522+
%- if myvar == 'two':
523+
%- set myvar = 'three'
524+
%- endif
525+
{{- myvar -}}
526+
"""
527+
rendered = render_jinja_tmpl(template,
528+
dict(opts=self.local_opts, saltenv='test', salt=self.local_salt))
529+
self.assertEqual(rendered, u'onetwothree')
530+
531+
def test_statement_prefix(self):
532+
533+
template = """
534+
{%- set mylist = ['1', '2', '3'] %}
535+
%- set mylist = ['one', 'two', 'three']
536+
%- for item in mylist:
537+
{{- item }}
538+
%- endfor
539+
"""
540+
rendered = render_jinja_tmpl(template,
541+
dict(opts=self.local_opts, saltenv='test', salt=self.local_salt))
542+
self.assertEqual(rendered, u'onetwothree')
543+
544+
484545
class TestCustomExtensions(TestCase):
485546

486547
def __init__(self, *args, **kws):

0 commit comments

Comments
 (0)