やりたかったこと: Networkmanagerで存在する接続名しらべて根こそぎipv4.methodをmanualにしてOS再起動でNICの設定がやりなおしになるのを防ぐ。
なんかnmcliモジュールでmethod指定ansible2.4だと見当たらなかったので以下のようにshellモジュールなどで頑張ってみた次第。
(たぶんバージョン上がったらそのうちオプション増えそうだけど需要によるのかな。)
# Networkmanager(nmcli)でipv4methodをautoからmanualに変更
- name: set var of string for network device names
shell: /bin/nmcli --fields NAME con show|grep -e .*[0-9]
register: check_network_devices
# see: http://docs.ansible.com/ansible/latest/playbooks_loops.html#using-register-with-a-loop
- name: check ipv4 connection method
shell: /bin/nmcli connection show "{{ item_device }}"|grep ipv4.method|awk '{print $2}'
register: check_ipv4_conn_method
with_items: "{{ check_network_devices.stdout_lines }}"
loop_control:
loop_var: item_device
ignore_errors: yes
- name: update ipv4 connection method
command: /bin/nmcli connection modify "{{ chkcon4.item_device }}" ipv4.method manual
with_items: "{{ check_ipv4_conn_method.results }}"
when: chkcon4.stdout != 'manual'
loop_control:
loop_var: chkcon4
ignore_errors: yes
私が解説書くよりマニュアル見たほうがよっぽど早い気がしますが一応備忘録として書きますと、
ループ処理でregister
登録した変数がres1
とすると、res1.results
の下に配列でデータが入りまして、
それをそのままwith_items
などに指定すると"{{ item.stdout }}"
などのように配列の中身のdict(mapとかhashともいう)オブジェクトにキー(stdoutのぶぶん)指定でアクセスできる、という話になるようでございますです。
Networkmanagerを有効化しない方向もそれはそれでいい気がします。
あと、stdout_lines
は標準出力結果が入った変数(改行区切り)を1行ずつを配列の1要素に変換してくれるやつです。
(showで取り出したNICごとに複数行の戻り値を配列に入れてwith_itemsで指定してmethodの確認につかう)
今回はむやみにググるよりマニュアルガン見したほうがよかったかなあと思いましたがテスト方法は以下が参考になりました。
https://qiita.com/tbuchi888/items/031c918ce9e542a37cc4
json_queryフィルタとか使わなきゃならんのかと勘違いしたけどそんな必要はなくてよかったです。
ただ、IPアドレスが事前にNetworkmanager的に設定されていないとmethodをmanualにできないエラーがでてたので、
そっちはshellではなくてnmcliモジュール使って設定するのがよさそうかなと思いました。
http://docs.ansible.com/ansible/devel/modules/nmcli_module.html
- name: set ipv4 address(for change method to manual)
nmcli:
type: ethernet
conn_name: "{{ setif.conn_name }}"
state: present
ip4: "{{ setif.ip4 }}"
dns4: 8.8.8.8
with_items: "{{ nmcli_ethernet }}"
when: not setif.conn_name | search("__omit_")
ignore_errors: yes
loop_control:
loop_var: setif
tags: set-ipv4-addr,nmcli
変数の中身が無かったらスキップするomitは指定したらその瞬間にdefinedとかになるらしくwhenとかのconditional的にis definedだとエラーになるのでsearch関数でomitじゃなかったらみたいなのをpython詳しい人に教えてもらったけど、ほんとはリストの長さlenとかで数えてその分だけ読ませるようなのが理想とも聞きました。
あと、set_factつかうとloopのタスクでregisterに登録してresultsに入ってる内容の任意のdictオブジェクトをキー指定で取り出してlistに変換できるようです(以下の例のようなのでマニュアルにも載ってる)
~略~
- name: set fact interfacefiles
set_fact:
ifdests: "{{ cp_nwif_res.results | map(attribute='dest') | list }}" #★これ
- name: debug ifdest setfact
debug: var=ifdests
~略~
上記はloopしてるcopyモジュールのregisterのresultsをdest(コピー先)だけ取り出してるやつ。
モジュール毎に戻り値(registerに入る値)がマニュアルに書いてあるようでした。
参考:
http://docs.ansible.com/ansible/latest/playbooks_loops.html#using-register-with-a-loop
http://docs.ansible.com/ansible/latest/playbooks_filters.html
ansible-doc nmcli
http://www.neko-no-me.net/2015/05/09/956/
http://docs.ansible.com/ansible/latest/set_fact_module.html
http://docs.ansible.com/ansible/latest/copy_module.html#return-values