gsutilでアップロードしたファイルがgcsfuseでマウントした場合に見えない

Google Cloud Storage(GCS)へのファイルアップロードは、gcloud sdkについていたgsutilを使う方法と、gcsfuseを使って自分のPCやインスタンスにmountして触る方法の二つあります。

* [gsutil Tool ][link-gsutil]
* [Cloud Storage FUSE ][link-gcsfuse]

## gsutil
gsutilはgcloud sdkに付属しているのでインストールの手間が少なくていいですし、
rsync機能やマルチプロセスオプション(-m)などもついています。
s3から直接移動とかも可能です。

比較的古くからあるのでドキュメントやナレッジが豊富です。

## GCSFuse
GCSFuseは比較的新しいツールで、しかもGoで書かれているので高速かもしれません。
参考：[GCS Fuse][link-gcsfuse-qiita]
また、OSX/Linuxにストレージとしてマウントして扱えるので、S3等と同じように触れるのが利点でしょう。
gcloud sdkの認証が通った環境ならすぐに使えるのが利点です。

ただし、gcloud sdkに追加でインストールが必要なので若干面倒です。(OSXならOSXFUSEも必要)

# gsutilで作成したディレクトリがマウントしても見えない。

自分はものぐさでgcsfuseをインストール、OSX環境からgsutilではdirectoryごとrsync等でアップロードなど行っていました。
(しかも実はrsyncではgsutil -m rsyncの方がgcsfuseより早いらしいです)

しかし、GCSはストレージに見立てたデータベースに過ぎないため、pathはkeyに過ぎず、実際にはディレクトリ構造は保持していません。
そのため、gsutilでディレクトリごとアップロードした場合、ディレクトリがないためにgcsfuseで見た時に見ることができないケースが起きます。

```bash
# gsutilでは問題なく見える。
$ gsutil ls gs://mybucket/
gs://mybucket/404.html
gs://mybucket/favicon.ico
gs://mybucket/index.html
gs://mybucket/img/
gs://mybucket/scripts/
gs://mybucket/styles/

# gcsfuseでマウントすると見えない。
$ gcsfuse mybucket /mnt/mybucket
$ ls -l /mnt/mybucket 
-rw-r--r--  1 xxx  xxx   3296  8 11 13:07 404.html
-rw-r--r--  1 xxx  xxx    411  8 11 13:07 favicon.ico
-rw-r--r--  1 xxx  xxx   5000  8 11 13:07 index.html
```


# 解決策

解決法は二つあります。
この記事が参考になります。
[Data written with gsutil is not visible with gcsfuse][link-stackoverflow]

## ファイルのあるpathにmkdirしてディレクトリを作る
ディレクトリがないため、lsやcd等で辿れないだけでファイル自体は存在しています。
（辿れないとfileとしてアクセスできませんが。。）

mkdirでパスのディレクトリを作ると中身を見ることができます。

```bash
# あるけど見えない。
$ ls -l /mnt/mybucket/img
ls: /mnt/mybucket/img: No such file or directory

# ディレクトリを作ると
$ mkdir -p /mnt/mybucket/img

# 見えます
$ ls -l /mnt/mybucket/img
-rw-r--r--  1 xxx  xxx   14732  8 11 13:08 facebook.png
-rw-r--r--  1 xxx  xxx   14946  8 11 13:09 twitter.png
-rw-r--r--  1 xxx  xxx   15388  8 11 13:09 yahoo.png
```

数が少なければこの方がいいかもしれませんね。

## --implicit-dirsオプションをつけてマウントする
gcsfuse自体に--implicit-dirsというオプションをつけるとディレクトリのないファイルもたどってlsで見れるようにラップしてくれます。
[Implicit directories][link-implicit-dirs]

```bash
# --implicit-dirsオプションをつけると
$ gcsfuse --implicit-dirs mybucket /mnt/mybucket
Using mount point: /mnt/mybucket
Opening GCS connection...
Opening bucket...
Mounting file system...
File system has been successfully mounted.

# ディレクトリも見えます
$ ls -l /mnt/mybucket
-rw-r--r--  1 xxx  xxx   3296  8 11 13:07 404.html
-rw-r--r--  1 xxx  xxx    411  8 11 13:07 favicon.ico
drwxr-xr-x  1 xxx  xxx      0  8 15 18:09 img
-rw-r--r--  1 xxx  xxx   5000  8 11 13:07 index.html
drwxr-xr-x  1 xxx  xxx      0  8 15 18:09 scripts
drwxr-xr-x  1 xxx  xxx      0  8 15 18:09 styles
```

ただ、ドキュメントにも書かれている通り、こちらはパフォーマンスへの影響が大きいです。
lsだけで数分かかる可能性があると書かれています。。
なるべくならmkdirしてしまう方が良さそうです。

# まとめ


# 参考URL


* [gsutil Tool][link-gsutil]の公式
* [Cloud Storage FUSE][link-gcsfuse]の公式
* [GCS Fuse][link-gcsfuse-qiita]の紹介記事
* [元ネタのStackoverflow][link-stackoverflow]
* [GCSFuseのimplicit directoriesに関するドキュメント][link-implicit-dirs]

[link-gsutil]:https://cloud.google.com/storage/docs/gsutil
[link-gcsfuse]:https://cloud.google.com/storage/docs/gcs-fuse
[link-gcsfuse-qiita]:http://qiita.com/MiCHiLU/items/f6fda81a7ca0715cc1c8
[link-stackoverflow]:http://stackoverflow.com/questions/31083715/data-written-with-gsutil-is-not-visible-with-gcsfuse
[link-implicit-dirs]:https://github.com/GoogleCloudPlatform/gcsfuse/blob/master/docs/semantics.md#implicit-directories