Ansible: [PERINGATAN]: ketika pernyataan tidak boleh menyertakan pembatas template jinja2 seperti {{}} atau {%%}.

Dibuat pada 8 Mar 2017  ·  31Komentar  ·  Sumber: ansible/ansible

JENIS MASALAH

  • Laporan Bug
NAMA KOMPONEN
VERSI ANSIBLE
$ ansible --version
ansible 2.3.0 (devel a8910e78ca) last updated 2017/03/08 02:46:53 (GMT -500)
  config file =
  configured module search path = Default w/o overrides
  python version = 2.7.10 (default, Jul 30 2016, 19:40:32) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]
KONFIGURASI


Stock ansible.cfg

OS / LINGKUNGAN


MacOS host manajemen 10.12.3

RINGKASAN


Tugas yang telah saya gunakan selama lebih dari 7 bulan mulai memberikan peringatan.

LANGKAH UNTUK REPRODUKSI

- name: install powershell
  win_chocolatey:
    name: '{{ item }}'
    state: 'present'
    upgrade: True
  with_items:
    - "powershell"
  register: check_powershell5
  when: "{{ ansible_PSVersionTable.Major|int < 5 }}"
  tags: win_powershell
HASIL YANG DIHARAPKAN


Tugas akan berjalan tanpa peringatan

HASIL NYATA

TASK [win_powershell : install powershell] *************************************
 [WARNING]: when statements should not include jinja2 templating delimiters
such as {{ }} or {% %}. Found: {{ ansible_PSVersionTable.Major|int < 5 }}
affects_2.3 bug

Komentar yang paling membantu

Sejujurnya saya tidak mengerti bagaimana Anda bisa menulis pedoman yang berarti tanpa memicu pesan peringatan baru ini. Inti dari Ansible adalah bahwa berbagai hal dapat dimodularisasi menjadi peran. Jika Anda ingin menghentikan peringatan ini agar tidak dipicu, Anda tidak memiliki kesempatan kecuali Anda menulis buku pedoman datar dengan ekspresi jelek saat.

Contoh yang tampaknya tidak dapat diselesaikan:

default

auth_service       : none
auth_service_aws   : aws
auth_service_is_aws: '{{ (auth_service == auth_service_aws) | bool }}'

meta

dependencies:

  - { role: apollo/auth/aws, when: auth_service_is_aws }

melempar peringatan ....

Dan akhirnya (ini sangat sulit untuk diselesaikan!)

Peran Orang Tua - default

bootstrap_ping : true

Peran Induk - meta

dependencies:

  - { role: apollo/platform/ping, ping: '{{ bootstrap_ping }}' }

Peran Anak - tugas

- name: execute

  when: ping

  win_ping:

Saya benar-benar berharap saya menjadi bodoh dan kehilangan sesuatu yang sederhana atau perubahan ini akan dikembalikan di rilis berikutnya.

Semua 31 komentar

Ini diharapkan. Peringatan tersebut baru-baru ini ditambahkan ke rilis 2.3 dengan sengaja.

Seperti yang dinyatakan dalam peringatan, Anda tidak boleh menggunakan pembatas jinja2 dalam pernyataan when. Sebaliknya itu harus membaca:

when: ansible_PSVersionTable.Major|int < 5

Jika Anda memiliki pertanyaan lebih lanjut, silakan gunakan milis.

Bagaimana mengatasi peringatan ini jika ekspresi when disimpan dalam sebuah variabel (untuk alasan apapun, misalnya karena itu digunakan beberapa kali dalam permainan yang berbeda).

misal: mycondition: ansible_PSVersionTable.Major|int < 5 untuk digunakan sebagai when: mycondition .
-> Ini tidak berfungsi karena mycondition tidak dievaluasi / diperluas dan diperlakukan sebagai String.

Apa yang berhasil adalah dengan mendeklarasikan mycondition: "{{ ansible_PSVersionTable.Major|int < 5 }}" atau when: "{{ mycondition }}" tetapi keduanya akan menghasilkan PERINGATAN yang disebutkan di atas.

Ini berhasil untuk saya

  when: "(ansible_PSVersionTable.Major|int < 5) and ('Microsoft Windows 7' in ansible_distribution)"

dengan

$ ansible --version
ansible 2.4.0 (devel 53c52cf65f) last updated 2017/03/30 07:29:39 (GMT -500)
  config file =
  configured module search path = [u'/Users/tanner/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  python version = 2.7.10 (default, Jul 30 2016, 19:40:32) [GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)]

Itu berhasil untuk saya juga. Tapi sekarang pindahkan kondisi ke variabel dan coba gunakan variabel sebagai gantinya.

ansible_PSVersionTable adalah variabel dari fakta khusus yang telah saya instal di semua komputer Window.

Coba yang berikut dan saya asumsikan itu tidak akan berhasil (mengingat kondisinya true ):

mycond: "(ansible_PSVersionTable.Major|int < 5) and ('Microsoft Windows 7' in ansible_distribution)"
...
when: mycond

Dalam hal ini Anda akan membutuhkan "{{...}}" - itu hanya 'ketika' bersyarat di mana "{{....}}" tersirat, saya kira.

juga mungkin ingin menggunakan | filter bool untuk memastikan var disimpan sebagai boolean.

Itulah yang saya katakan ... Anda akan membutuhkan "{{...}}" dalam deklarasi variabel atau kondisi when karena tidak akan bekerja (dengan benar) sebaliknya. Dan kemudian Anda akan mendapatkan PERINGATAN yang disebutkan.

Anda dapat menggunakan sesuatu seperti:

- set_fact: content1="{{ var1.stdout }}" content2="{{ var2.stdout }}" dan bandingkan itu.

mungkin dup dari # 23578

Saya juga agak bingung dengan ini. Saya mengerti sekarang kita dapat melakukan myvar daripada "{{ myvar }}" atau {{ myvar }} tetapi ada beberapa kasus penggunaan di mana ini masih belum cukup. Misalnya

when: myvar.stdout != ansible_date_time.date

^ Ini TIDAK akan mengembalikan tanggal sekarang (YYYY-MM-DD). Dalam hal ini saya tidak memiliki cara untuk menggunakan apapun selain pembatas jinja2 dengan sesuatu seperti:

- set_fact:
    ansible_date: "{{ ansible_date_time.date }}"

Kasus penggunaan lainnya adalah, mis

- name: "TEST: The files directory should have correct ownership"
  shell: stat -c %U:%G {{ files_dir }}
  register: styles_dir_ownership
  changed_when: styles_dir_ownership.stdout != "{{ user }}:{{ apache_user }}"
  failed_when: styles_dir_ownership.stdout != "{{ user }}:{{ apache_user }}"

Saya tidak punya cara untuk melakukan user:apache_user karena saya perlu memberikan titik dua dan karenanya harus menggunakan mis.

- set_fact:
    expected_ownership: "{{ user }}:{{ apache_user }}"

Jadi pertanyaan saya adalah: bagaimana saya bisa menjelaskan kedua kasus penggunaan tersebut jika pembatas jinja2 tidak digunakan lagi mulai dari Ansible 2.3? Apakah set_fact sekarang merupakan opsi yang disukai?

Menambahkan kasus penggunaan lain:

pertimbangkan variabel berikut:

to_be_removed_users:
  - name: 'adm'
    remove: False 
  - name: 'ftp'
    remove: True
  - name: 'games'
    remove: False  
  - name: 'gopher'
    remove: True
  - name: 'operator'
    remove: False
  - name: 'uucp'
    remove: True

lalu tugas berikut menghasilkan peringatan. Tidak yakin bagaimana menghindarinya karena item.name adalah hasil dari iterasi pada daftar

``
name: Dapatkan daftar pengguna
getent:
database: passwd
tag:
- userdel

  • name: Pastikan pengguna berikut dihapus
    pengguna:
    nama: "{{item.name}}"
    negara: tidak ada
    hapus: "{{item.remove}}"
    with_items: '{{to_be_removed_users}}'
    kapan: getent_passwd. {{item.name}} ditentukan
    tag:

    • userdel

      ``

@PhilEv , Anda dapat melakukan sesuatu seperti ini untuk menghindari masalah itu (perhatikan bahwa Anda tidak perlu pemeriksaan yang sebenarnya):

`` `` ---

  • tuan rumah:

    • localhost

      tugas:

    • set_fact:

      WARNA:

      MERAH: Benar

      BIRU: Benar

      KUNING: Salah

- name: Favourite colours!
  command: echo "I like {{ item }}"
  # when: COLOURS.{{item}} is defined and COLOURS.{{item}}
  when: item in COLOURS and COLOURS[item]
  with_items:
    - "GREEN"
    - "BLUE"
    - "PURPLE"
    - "YELLOW"```

Kami juga melihat peringatan ini, dan menghapus pembatas jinja dari when sepertinya merusak ini:

- name: Check if redis is installed
  shell: redis-server --version || /bin/true
  register: redis_is_installed

- include: redis_build.yml
  when: "redis_is_installed.stdout.find('v={{ redis_version }}') == -1"

Adakah saran untuk cara alternatif penulisan ini?

@kuliner_jogja

when: "redis_is_installed.stdout.find('v=' ~ redis_version) == -1"

@sivel Luar biasa, terima kasih. Apa yang dilakukan tilde secara khusus dalam kasus ini? Saya tidak dapat menemukan dokumennya dan ingin sekali membacanya.

@jsuter http://jinja.pocoo.org/docs/dev/templates/#other -operators

~
Mengubah semua operan menjadi string dan menggabungkannya.

{{"Halo" ~ nama ~ "!" }} akan kembali (dengan asumsi nama disetel ke 'John') Hello John !.

Terima kasih @streetster seperti yang diposting di grup yang memungkinkan (terima kasih @sivel dan Josh)

when: getent_passwd[item['name']] is defined
semuanya baik untuk kasus saya

Sejujurnya saya tidak mengerti bagaimana Anda bisa menulis pedoman yang berarti tanpa memicu pesan peringatan baru ini. Inti dari Ansible adalah bahwa berbagai hal dapat dimodularisasi menjadi peran. Jika Anda ingin menghentikan peringatan ini agar tidak dipicu, Anda tidak memiliki kesempatan kecuali Anda menulis buku pedoman datar dengan ekspresi jelek saat.

Contoh yang tampaknya tidak dapat diselesaikan:

default

auth_service       : none
auth_service_aws   : aws
auth_service_is_aws: '{{ (auth_service == auth_service_aws) | bool }}'

meta

dependencies:

  - { role: apollo/auth/aws, when: auth_service_is_aws }

melempar peringatan ....

Dan akhirnya (ini sangat sulit untuk diselesaikan!)

Peran Orang Tua - default

bootstrap_ping : true

Peran Induk - meta

dependencies:

  - { role: apollo/platform/ping, ping: '{{ bootstrap_ping }}' }

Peran Anak - tugas

- name: execute

  when: ping

  win_ping:

Saya benar-benar berharap saya menjadi bodoh dan kehilangan sesuatu yang sederhana atau perubahan ini akan dikembalikan di rilis berikutnya.

Warnai aku dengan bingung juga. Semua yang lain di Ansible, sejauh yang saya bisa lihat, menggunakan pembatas Jinja. Apa perbedaan antara "change_when" dan yang lainnya? Berbicara sebagai seseorang yang belajar Ansible, itu membuat segalanya lebih sulit untuk dipahami.

Silakan lihat PR di atas. Saya mungkin akan mendapatkan ikan ditampar cukup keras tetapi jika itu mempengaruhi cukup banyak orang, tolong tunjukkan dukungan Anda dan mungkin peringatan akan dihapus (baik dengan cara ini atau yang lain).

https://github.com/ansible/ansible/pull/24974

Alih-alih mengatakan apa yang tidak boleh dilakukan, sebaiknya dikatakan APA YANG HARUS DILAKUKAN! Kami bukan pesulap. Terima kasih.

Saya mendapatkan peringatan ini di semua tempat sekarang. Saya memiliki peran umum yang 'diperpanjang' dalam peran khusus dengan menentukan beberapa variabel saat mendefinisikan generik ini sebagai ketergantungan seperti ini di meta/main.yml :

dependencies:
  - role: generic_role
    _configuration_needed: "{{custom_configuration_needed}}"

custom_configuration_needed kemudian menjadi default atau dapat diganti per-host atau per-grup saat menyertakan peran khusus.

Kemudian, dalam peran generik saya memiliki langkah-langkah seperti ini:

- name: "configure package if necessary"
  include: configure.yml
  when: _configuration_needed

Namun sekarang saya, di setiap langkah dalam configure.yml dalam peran umum 'dasar' yang dijalankan untuk peran khusus itu, dapatkan peringatan seperti ini:

   [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: {{custom_configuration_needed}}
 ```

This is due to the implicit 'when' clause that's added to every step in that included file, but I'm not sure how to solve this-one. The `_configuration_needed` isn't the only case, it's just the one spamming most warnings right now. Now for this `_configuration_needed` I tried defining the dependency like this:

ketergantungan:

  • peran: generic_role
    _configuration_needed: custom_configuration_needed
    ``

Namun ini tidak berhasil, karena ketika saya men-debug mencetak variabel _configuration_needed itu, saya melihat "custom_configuration_needed" ini sebagai string (tidak kosong), yang selalu bernilai "True". Ini tentunya bukan perilaku yang diharapkan atau diinginkan dan saya tidak tahu cara menghapus peringatan ini.

Jika ada solusi yang berfungsi untuk mencegah peringatan ini dalam kasus ini, yang juga memiliki perilaku yang diharapkan, silakan bagikan - tetapi sekarang, saya tidak dapat menemukan cara untuk melakukan ini.

Juga, untuk kemungkinan 3, harap pertimbangkan untuk membuat template jinja konsisten di seluruh papan. Di mana-mana atau tidak {{}} , tapi ini jelas konyol.

Saya tidak bisa mengembangkan variabel dinamis tanpa {{}} , saya tidak bisa bekerja tanpa tanda kurung kurawal:

vars:
    host_name: ['foo', 'bar']
    foo_wwn_2: "This exist"

  tasks:
    - debug:
        var: "{{item.1}}_wwn_{{item.0}}"
     when: ({{item.1 + '_wwn_' + item.0}}) is defined
      with_nested:
        - ['1', '2']
        - "{{host_name}}"

Tanpa tanda kurung, itu hanya string yang akan dinilai BENAR.

Sungguh mengecewakan melihat bahwa Anda ingin menghapus satu-satunya cara untuk mengevaluasi variabel dalam when .

@bartmeuris dalam contoh Anda, peringatan itu tidak akan lagi muncul di kemungkinan v2.4 yang akan segera dirilis

@MichalTaratuta Anda harus menggunakan yang berikut ini:

when: vars[item.1 ~ '_wnn_' ~ item.0] is defined

Fakta bahwa contoh Anda bekerja sebelumnya tidak disengaja, dan bukan praktik terbaik untuk memeriksa nama variabel.

Bagaimana dengan saat menguji keberadaan string, yang bagiannya berisi variabel?

vars:
  acct:
    name: example_name

tasks:
  - name: Emergency Account | Gather list of usernames
    ios_command:
      commands: show run | i ^username
    register: ios_usernames

  - name: Emergency Account | Remove non-emergency account users
    ios_config:
      lines:
        - no {{ item }}
    with_flattened:
      - "{{ ios_usernames.stdout_lines }}"
    when: '"username {{ acct.name }} privilege 0 secret" not in item'
    no_log: True

Sangat mungkin saya hanya melewatkan cara yang lebih baik atau lebih tepat untuk menulisnya tetapi sejauh ini satu-satunya metode yang berfungsi tampaknya menggunakan tanda kurung dalam string yang dikutip.

EDIT
Maaf sudah mengacaukan utas. Setelah membaca ulang beberapa contoh dan pengujian lebih lanjut dapat membuatnya bekerja dengan memisahkan kutipan dan menggunakan penggabungan. Membuatnya sedikit lebih lama tetapi berhasil.

  when: '"username " ~ localauth.emergency.name ~ " privilege 0 secret" not in item'

Saya melihat bahwa peringatan itu berguna, tetapi dapatkah misalnya ekspresi yang lebih panjang seperti yang berikut ini dapat ditulis tanpa pembatas template:

  when: |-
      {%- set certs = {'sync': False} -%}
      {% if gen_node_certs[inventory_hostname] or
        (not etcdcert_node.results[0].stat.exists|default(False)) or
          (not etcdcert_node.results[1].stat.exists|default(False)) or
            (etcdcert_node.results[1].stat.checksum|default('') != etcdcert_master.files|selectattr("path", "equalto", etcdcert_node.results[1].stat.path)|map(attribute="checksum")|first|default('')) -%}
              {%- set _ = certs.update({'sync': True}) -%}
      {% endif %}
      {{ certs.sync }}

Ini dapat membantu orang baru,
Kami tidak dapat menggunakan variabel di dalam ketika kondisi karena memiliki beberapa batasan dan peringatan di bawah ini akan ditampilkan
PERINGATAN: ketika pernyataan tidak boleh menyertakan pembatas template jinja2 seperti {{}} atau {%%}

jadi untuk menghindari hal-hal seperti itu saat memeriksa kondisi dengan melewatkan variabel, pertama-tama kita perlu mendaftarkan variabel tertentu itu dan kemudian menggunakannya. Di bawah ini adalah contoh kecil

VERSION sudah ditentukan atau diteruskan dengan jelas saat menjalankan buku permainan

- name: Check the java version
   shell: java -version 2>&1 | grep version | awk '{print $3}' | sed 's/"//g' | cut -d "_" -f1
   register: java_versios
 - name: testing senario
   shell: echo '{{ VERSION }}'
   register: r
- name: testing
   file:
     path: /root/Karthik/JAVATEST
     state: directory
     owner: root
     group: root
     mode: 0755
     recurse: yes
   when: java_version.stdout >= r.stdout

Halo,

Bagaimana dengan kasus ketika saya meneruskan nama grup inventaris berdasarkan variabel yang telah ditentukan sebelumnya?
Dalam skenario ini berdasarkan variabel "sync_source", saya memanggil grup inventaris yang diteruskan sebagai variabel oleh pengguna.

    - debug:
        msg:
          - "source instance: {{ inventory_hostname }}"
          - "{{ dir }} size is {{ result_dir_size }} GB"
      when: "inventory_hostname in groups.{{ sync_source }}"

@linlin

when: "inventory_hostname in groups[sync_source]"
Apakah halaman ini membantu?
0 / 5 - 0 peringkat