我有一个用于使用debmirror
构建本地存储库的宏。
以下是代码片段:
{%- set gnupghome = kwargs.pop('gnupghome', '/root/.gnupg') %}
{%- set env = { 'GNUPGHOME': gnupghome } %}
keyring_import:
cmd:
- run
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
{%- set keyid = kwargs.pop('keyid') %}
{%- set keyserver = kwargs.pop('keyserver') %}
- name: 'gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --keyserver {{ keyserver }} --recv-keys {{ keyid }}'
{%- elif 'key_url' in kwargs %}
{%- set key_url = kwargs.pop('key_url') %}
- name: 'wget -q -O- "{{ key_url }}" | gpg --no-default-keyring --keyring {{ gnupghome }}/trustedkeys.gpg --import'
{%- endif %}
- require:
- pkg: wget
- pkg: gnupg
在endif
关键字,我想使用else
来引发异常,例如:
key_url或keyserver和keyid都需要。
有可能吗?
答案 0 :(得分:11)
这可以在扩展中处理。来自https://github.com/duelafn/python-jinja2-apci
# FROM: https://github.com/duelafn/python-jinja2-apci/blob/master/jinja2_apci/error.py
from jinja2 import nodes
from jinja2.ext import Extension
from jinja2.exceptions import TemplateRuntimeError
class RaiseExtension(Extension):
# This is our keyword(s):
tags = set(['raise'])
# See also: jinja2.parser.parse_include()
def parse(self, parser):
# the first token is the token that started the tag. In our case we
# only listen to "raise" so this will be a name token with
# "raise" as value. We get the line number so that we can give
# that line number to the nodes we insert.
lineno = next(parser.stream).lineno
# Extract the message from the template
message_node = parser.parse_expression()
return nodes.CallBlock(
self.call_method('_raise', [message_node], lineno=lineno),
[], [], [], lineno=lineno
)
def _raise(self, msg, caller):
raise TemplateRuntimeError(msg)
将扩展程序传递给您的环境:jinja2.Environment(... extensions=[RaiseExtension])
然后在模板中使用它:
{%- if 'keyid' in kwargs and 'keyserver' in kwargs %}
...
{%- else %}
{% raise "Either key_url or both keyserver and keyid required." %}
{% endif %}
答案 1 :(得分:10)
Dean Serenevy的回答很优雅。这是一个较短的解决方案,它为jinja的环境增添了一个全球性。
def raise_helper(msg):
raise Exception(msg)
env = jinja2.Environment(...
env.globals['raise'] = raise_helper
然后在你的模板中:
{{ raise("uh oh...") }}
答案 2 :(得分:9)
超快速解决方法,只要您不介意提出ZeroDivisionError
:
在您想要引发异常的任何地方插入{{ 0/0 }}
。
答案 3 :(得分:7)
插入{{ "My error explained here"/0 }}
表达式。 e.g。
{% if not required_parameter %}
{{ "required_parameter must be defined."/0 }}
{% endif %}
(建立在zsero的0/0回答上)
答案 4 :(得分:3)
如果这是通过Ansible完成的,则Ansible将mandatory过滤器添加到Jinja,可用于执行以下操作:
{{ ('OK text' if condition_ok) | mandatory('Text of error message') }}
给出故障:
fatal: [hostname]: FAILED! => {"msg": "Text of error message"}
(用所需的支票代替condition_ok
; 'OK text'
可以只是''
。)
答案 5 :(得分:1)
我还想从 jinja2 模板中抛出带有错误消息的异常,但没有任何外部依赖项(全局/扩展)。我最终得到了这个宏:
{% macro abort(error) %}
{{ None['[ERROR] ' ~ error][0] }}
{% endmacro %}
使用:
{{ abort("Either key_url or both keyserver and keyid required.") }}
给出了此异常的堆栈跟踪:
jinja2.exceptions.UndefinedError: 'None' has no attribute '[ERROR] Either key_url or both keyserver and keyid required.'
答案 6 :(得分:0)
打印给定值的另一个快速技巧:
func rotateLeft(d int32, arr []int32) []int32 {
for ; d > 0 ; d-- {
left := arr[0]
arr = arr[1:]
arr = append(arr, left)
}
return arr
}
结果:
{% include 'error: ' ~ value_to_print %}