Jinja模板中or逻辑运算符在cloud-init中失效的问题咨询
解决cloud-init Jinja模板中or逻辑运算符的使用问题
问题根源
你之前写的{% if distro == 'centos' or 'redhat' %}这类语句存在逻辑语法错误,Jinja会将其解析为(distro == 'centos') or 'redhat'。由于非空字符串在布尔判断中会被视为True,这个表达式的结果永远为True,但在你的代码上下文里,要么前面的if/elif分支先匹配了其他条件,要么逻辑混乱导致预期结果不生效。而单独写if distro == 'redhat'能生效,是因为这是完整的正确比较表达式。
正确写法
写法1:完整逻辑比较
保留or运算符,但每个分支都要写出完整的变量比较:
## template: jinja #cloud-config {% set u1 = 'myuser' %} {% set u1pass = 'strong-passwd' %} {% set u1key = 'key1' %} {% set u2 = 'example' %} {% set u2pass = 'passwd2' %} {% set u2key = 'key2' %} ............. {% if distro == 'centos' or distro == 'rocky' or distro == 'redhat' %} {% set group = 'wheel' %} {% elif distro == 'ubuntu' or distro == 'debian' %} {% set group = 'sudo' %} {%- endif %} distro: {{distro}} user1: {{u1}} user2: {{u2}} group: {{group}} ## Add users - name: {{ u1 }} groups: {{ group }} lock_passwd: false passwd: {{ u1pass }} ssh_authorized_keys: - {{ u1key }} shell: /bin/bash - name: {{ u2 }} groups: {{ group }} lock_passwd: false passwd: {{ u2pass }} ssh_authorized_keys: - {{ u2key }} shell: /bin/bash
写法2:使用in运算符简化(推荐)
把同组的发行版放到列表中,用in判断变量是否在列表内,代码更简洁易维护:
## template: jinja #cloud-config {% set u1 = 'myuser' %} {% set u1pass = 'strong-passwd' %} {% set u1key = 'key1' %} {% set u2 = 'example' %} {% set u2pass = 'passwd2' %} {% set u2key = 'key2' %} ............. {% if distro in ['centos', 'rocky', 'redhat'] %} {% set group = 'wheel' %} {% elif distro in ['ubuntu', 'debian'] %} {% set group = 'sudo' %} {%- endif %} distro: {{distro}} user1: {{u1}} user2: {{u2}} group: {{group}} ## Add users - name: {{ u1 }} groups: {{ group }} lock_passwd: false passwd: {{ u1pass }} ssh_authorized_keys: - {{ u1key }} shell: /bin/bash - name: {{ u2 }} groups: {{ group }} lock_passwd: false passwd: {{ u2pass }} ssh_authorized_keys: - {{ u2key }} shell: /bin/bash
疑问解答
不需要为每个元数据值单独编写if语句,用上述两种写法都能实现多值判断,既简化代码又保证逻辑正确。当传入distro: redhat时,模板会匹配到wheel组,符合你的预期结果。
内容的提问来源于stack exchange,提问作者dj423
相关产品推荐
相关产品推荐

