事象
Cloud ComposerのDAG内でファイル参照をしようとした所、IsADirectoryErrorにより弾かれた。
IsADirectoryError: [Errno 21] Is a directory: '/home/airflow/gcs/dags/my_dag/file.txt'
/home/airflow/gcs/dags/
の中身はGCS Fuseによりgs://bucket-name/dags
と対応しているため、該当のGCSバケットを確認。
誤ってfile.txt
という名前のサブディレクトリを作成してしまっていたことに気づき、これを該当バケットから削除。
→ファイルがあり、同名のサブディレクトリが消えたことを確認して再実行するも同様のエラーとなる。
原因
該当ディレクトリでは、一度置いたファイル・ディレクトリの削除が行われない。
https://cloud.google.com/composer/docs/concepts/cloud-storage#data_synchronization
Cloud Composer による dags/ フォルダと plugins/ フォルダの同期は、ローカルにコピーすることによって一方向に行われます。一方向に同期されるため、これらのフォルダのローカルの変更は上書きされます。
data/ フォルダと logs/ フォルダの同期は、Cloud Storage FUSE を使用して双方向に行われます。
dagsフォルダの同期方法は「ローカルにコピー」なので、GCS側のファイル・サブディレクトリを「削除」しても反映されない。
復旧
ローカル側(つまりgs://bucket-name/dags/
ではなく、/home/airflow/gcs/dags/
の方)を直接お掃除して不要ディレクトリを削除。
備忘
そもそもドキュメントには、タスクから読み取るデータはpy_file
を除き/home/airflow/gcs/data/
を使った方がよさそうなことが書いてある。
処理名のサブディレクトリに必要リソースをまとめdags/
配下に配置する方法が見やすいので採用していたのだが、見直した方がよいかもしれない。(data/
ディレクトリの挙動は後日確認したい)
おわりに
いざ問題を解消してみると、この世で他にここで躓く人が居るのだろうかと考えこんでしまうのが世の常。居ない気もする。
でももし居れば……どこかで誰かが同じことで惑う時間が3分の1になったり……したらいいなあ……。