lineinfileのクォート処理で、バグらしきものを見つけたので、メモ。
あとで GitHub に issue 登録しておこうかしら。 登録した(#174)。
2014/10/15追記
どうも " '...' " によるクォート処理は、他の箇所でも怪しい。
" '...' " で変な動作になったら、' "..." '(ダブル/シングルを逆にする)を試すと、うまく動くことがあるみたい。
環境
Ansible 1.7.2で発生。1.7.1 では発生しないようだ。
今回は、"pip install ansible"して、1.7.2 を使ったら発生。びっくりした。
"yum install ansible"で 1.7.1 に戻したら治まった。
OSはCentOS7。
問題
ある条件が揃うと、lineinfileの挿入行で "\t" を展開できない。
例えば、こんなテキストファイルがあったとして(インデントは"\t")
# a sample text
Insert after this line: single-quoted-nomix '...'
the next line
Insert after this line: double-quoted-nomix "..."
the next line
Insert after this line: single-quoted-mix '"..."'
the next line
Insert after this line: double-quoted-mix "'...'"
the next line
Insert after this line: single-quoted-jinja2-mix '{{xx}} "..."'
the next line
Insert after this line: double-quoted-jinja2-mix "{{xx}} '...'"
the next line
以下のAnsible playbookは期待通りに動作しない。ケース4がダメ。"\t"が効かない。
--- # file: lineinfile.yml
- hosts: all
gather_facts: False
vars:
original_file: ./test.txt.org
target_file: ./test.txt
fresh_start: yes
tasks:
- name: copy the data file
copy: src={{ original_file }} dest={{ target_file }}
force={{ fresh_start }}
- name: case1 insert the line '...'
lineinfile: dest={{ target_file }} state=present
insertafter='\t.*single-quoted-nomix'
line='\ta line with tab 1'
regexp='a line with tab 1'
- name: case2 insert the line "..."
lineinfile: dest={{ target_file }} state=present
insertafter="\t.*double-quoted-nomix"
line="\ta line with tab 2"
regexp="a line with tab 2"
- name: case3 insert the line with '"..."'
lineinfile: dest={{ target_file }} state=present
insertafter='\t.*single-quoted-mix'
line='\ta line with "tab" 3'
regexp='a line with "tab" 3'
- name: case4 insert the line "'...'"
lineinfile: dest={{ target_file }} state=present
insertafter="\t.*double-quoted-mix"
line="\ta line with 'tab' 4"
regexp="a line with 'tab' 4"
- name: case5 insert the line with '"..."' with jinja2
lineinfile: dest={{ target_file }} state=present
insertafter='\t.*single-quoted-jinja2-mix'
line='{{ "\t" }}a line with "tab" 5'
regexp='a line with "tab" 5'
- name: case6 insert the line "'...'" with jinja2
lineinfile: dest={{ target_file }} state=present
insertafter="\t.*double-quoted-jinja2-mix"
line="{{ '\t' }}a line with 'tab' 6"
regexp="a line with 'tab' 6"
結果
case4だけ、"\t" が文字列として挿入されてしまった。
# a sample text
Insert after this line: single-quoted-nomix '...'
a line with tab 1
the next line
Insert after this line: double-quoted-nomix "..."
a line with tab 2
the next line
Insert after this line: single-quoted-mix '"..."'
a line with "tab" 3
the next line
Insert after this line: double-quoted-mix "'...'"
\ta line with 'tab' 4
the next line
Insert after this line: single-quoted-jinja2-mix '{{xx}} "..."'
a line with "tab" 5
the next line
Insert after this line: double-quoted-jinja2-mix "{{xx}} '...'"
a line with 'tab' 6
the next line
回避方法
以下のようにすれば問題ない様子。
- Ansible 1.7.2は使わない
- クォートを混ぜない(解にならないかも)
- 外側のクォートをシングルクォートにして、そのなかで "\t" を使う
- Jinja2 を駆使する
こんなところで、なんでバグったんだろうな~。