- YAMLで8進数を書くときは、クォーテーションをしよう!
- クォーテーションしないと、こういう意味のわからんパーミッションが急に出てきて、死ぬぞ
user@deskmeetserver:/tmp$ ls -ld test_dir/
d-wxrw--wt 2 user user 4096 May 17 09:41 test_dir/
登場人物
・インフラ園児 ニアちゃん
・Linuxを中心に触っているインフラエンジニア。
3歳児だと自分のことを思い込んでいる。
・現場のおねえさん
・現場のおねえさん。やさしい。
※パーミッションが変だったのはホントですが、ほかは全部フィクションです。フィクションなんだってば。
ある日の昼下がりのこと。
おねえさん「あのー……」
ニアちゃん「なぁに?」
おねえさん「ニアちゃんが作ったこのディレクトリ、パーミッションおかしくない…………?」
user@deskmeetserver:/tmp$ ls -ld test_dir/
d-wxrw--wt 2 user user 4096 May 17 09:41 test_dir/
ニアちゃん「なにこれ」
おかしいですね。奇っ怪なパーミッションです。
数字にすると1363でしょうか。
いくら経験の浅い私ニアちゃんといえど、chmod 1363
なんて打ったら違和感を感じるはずです。
こんな変なパーミッション、設定したらどうなるんでしょうか?ちょっと見てみましょうか。
ニアちゃん「中のファイルとかもどうなってるんだろう、これ」
ニアちゃん「lsでディレクトリの中身を見ることは…できないね」
おねえさん「ユーザに読み取り権限がないものね」
ニアちゃん「だけどグループには読み取り権限があるから、見られそうな気もするけど」
おねえさん「所有ユーザの場合は、そもそもグループの読み取り権限を参照しないのね。普通ユーザのほうが狭いパーミッションなんてつけないから、おねえさんも知らなかったな」
user@deskmeetserver:/tmp$ ls -la test_dir/
ls: cannot open directory 'test_dir/': Permission denied
ニアちゃん「あっ、中には入れるんだね」
おねえさん「実行権限があるからね」
ニアちゃん「でも読み取り権限はないから、cdしたあとでもやっぱりファイルの一覧は見れないんだね」
user@deskmeetserver:~$ cd test_dir/
user@deskmeetserver:~/test_dir$ ls -la
ls: cannot open directory '.': Permission denied
ニアちゃん「ディレクトリ内にファイルの作成・削除は…できる。書き込み権限はあるからね」
おねえさん「あの、ちょっと勝手に変なファイル作らないで……」
user@deskmeetserver:~/test_dir$ echo hoge > hoge
user@deskmeetserver:~/test_dir$ ls -l hoge
-rw-rw-r-- 1 user user 5 May 17 10:52 hoge
user@deskmeetserver:~/test_dir$ cat hoge
hoge
user@deskmeetserver:~/test_dir$ rm hoge
user@deskmeetserver:~/test_dir$ ls -l hoge
ls: cannot access 'hoge': No such file or directory
ニアちゃん「中にいるファイルは…見れないけど、書き込めるんだね」
おねえさん「ファイルにも書き込み権限がついているみたい」
user@deskmeetserver:~/test_dir$ ll test.txt
--w----r-T 1 user user 21 Jul 7 12:27 test.txt
user@deskmeetserver:~/test_dir$ cat test.txt
cat: test.txt: Permission denied
user@deskmeetserver:~/test_dir$ sudo cat test.txt
test file
user@deskmeetserver:~/test_dir$ cat test.txt
cat: test.txt: Permission denied
user@deskmeetserver:~/test_dir$ sudo cat test.txt
test file
write test
ニアちゃん「削除もできる」
ニアちゃん「ファイルの削除は、ディレクトリの書き込み権限に依存するからね」
おねえさん「あの……勝手にいじらないで……」
user@deskmeetserver:~/test_dir$ rm test.txt
user@deskmeetserver:~/test_dir$ ll test.txt
ls: cannot access 'test.txt': No such file or directory
閑話休題。
問題を起こしたのは、ざっくり下記みたいなPlaybookでした。
(記憶をもとに雑に再現しています)
- hosts: servers
tasks:
- name: directory creation
file:
path: /tmp/test_dir
state: directory
owner: user
group: user
mode: 755
- name: copy test1
copy:
src: test.txt
dest: /tmp/test_dir/test.txt
owner: user
group: user
mode: 644
- name: copy test2
copy:
src: test.txt
dest: /tmp/test_dir/test2.txt
owner: user
group: user
mode: 600
まずいのはmode: 755
の部分。
YAMLの仕様で、0始まりでなくクオートされていない数字は、10進数として解釈されてしまうようです。
そしてこの現象が起こると、かなりの確率で、ユーザに読み取りを許可していない謎のパーミッション状態が誕生します……755(10進数)
=1363(8進数)
d-wxrw–wt644(10進数)
=1204(8進数)
–w—-r-t600(10進数)
=1130(8進数)
—x-wx–t
ひどい罠かと思いきゃ、公式ドキュメントにも、この仕様はちゃんと載っています。
For consistent results, quote octal numbers (for example, ‘644’ or ‘1777’) so Ansible receives a string and can do its own conversion from string into number. Adding a leading zero (for example, 0755) works sometimes, but can fail in loops and some other circumstances.
Giving Ansible a number without following either of these rules will end up with a decimal number which will have unexpected results.(参考訳)
意図した通りの結果を得るためには、8進数はクォートされなくてはなりません(‘644’や’1777’のように)。これにより、Ansibleは値を文字列として受け取り、Ansible自身で(8進数として)変換されます。
先頭にゼロを付与する方法(0755のように)は、ときに機能しますが、ループやその他の状況下では失敗する可能性があります。
これらのいずれの方法にもよらずに、Ansibleに数値を与えた場合、10進数として解釈され、意図しない結果をもたらします。
上記に則って修正すると……
- hosts: servers
tasks:
- name: directory creation
file:
path: /home/user/test_dir
state: directory
owner: user
group: user
mode: '0755'
- name: copy test1
copy:
src: test.txt
dest: /home/user/test_dir/test.txt
owner: user
group: user
mode: '0644'
- name: copy test2
copy:
src: test.txt
dest: /home/user/test_dir/test2.txt
owner: user
group: user
mode: '0600'
user@deskmeetserver:~$ ls -ld test_dir/
drwxr-xr-x 2 user user 4096 Jul 7 12:39 test_dir
user@deskmeetserver:~$ ls -l test_dir/
total 8
-rw------- 1 user user 10 Jul 7 12:39 test2.txt
-rw-r--r-- 1 user user 10 Jul 7 12:39 test.txt
想定通りのパーミッションでファイルを作ることができました!
- YAMLに10進数以外の数字を渡すときには、クォーテーションが必要
- この問題を踏みやすいものの一つに、ファイルパーミッションの指定がある
- 騒ぐ前にドキュメントを読もう(自戒)
Views: 0