$ 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)]
Stock ansible.cfg
MacOS host manajemen 10.12.3
Tugas yang telah saya gunakan selama lebih dari 7 bulan mulai memberikan peringatan.
- 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
Tugas akan berjalan tanpa peringatan
TASK [win_powershell : install powershell] *************************************
[WARNING]: when statements should not include jinja2 templating delimiters
such as {{ }} or {% %}. Found: {{ ansible_PSVersionTable.Major|int < 5 }}
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
@PhilEv , Anda dapat melakukan sesuatu seperti ini untuk menghindari masalah itu (perhatikan bahwa Anda tidak perlu pemeriksaan yang sebenarnya):
`` `` ---
- 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).
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:
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]"
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
meta
melempar peringatan ....
Dan akhirnya (ini sangat sulit untuk diselesaikan!)
Peran Orang Tua - default
Peran Induk - meta
Peran Anak - tugas
Saya benar-benar berharap saya menjadi bodoh dan kehilangan sesuatu yang sederhana atau perubahan ini akan dikembalikan di rilis berikutnya.