EC2＋goofysでS3バケットをマウントしたい

# 概要
- S3をファイルシステムとしてマウントしたいと思い試行錯誤したメモ。
- 実現するためのOSSでは メジャーなもので `s3fs` と `goofys` があるっぽい。
- goofys の方が評判が良いようなのでgoofysで検証。

# 目標
- golangおよび gooyfs を導入
- fstab で起動時に毎回マウントしたいので諸々の設定を整備

## 本家情報
- golang本家: https://golang.org/
- goofys本家: https://github.com/kahing/goofys

## goofysインストールの参考情報
- http://dev.classmethod.jp/cloud/aws/how-to-use-s3fs-goofys/
- http://qiita.com/kooohei/items/a14f22cb0381342d1861
- http://takeshiyako.blogspot.jp/2016/04/s3-mount-goofys.html

---

## 作業環境
- AWS + EC2(AmazonLinux) + S3

## 事前準備
- 参考: http://dev.classmethod.jp/cloud/aws/how-to-use-s3fs-goofys/

```
1. マウント対象のS3バケットを新規作成。
2. 作成したバケットにアクセス可能となる IAMアカウントを用意
3. AmazonLinuxのEC2を作成し ec2-user または root でaws configure でIAMの設定を完了させておく
4. マウントポイントを先に作成しておく: 例) `mkdir -p /mnt/s3test`
```

---

# 参考サイトに従ってインストールを進めたが最新版goofysはそのままでは実装できなかった。とりあえずメモ残し。
- 参考: http://dev.classmethod.jp/cloud/aws/how-to-use-s3fs-goofys/
- yumで関連パッケージをインストール
- `sudo yum install golang fuse -y`
- golang の実行環境と fuse をインストール

## バージョン確認
-  `go version` → `go version go1.7.5 linux/amd64` が入った

## goofys インストール
- `go get github.com/kahing/goofys`
- バージョン確認: `goofys --version` → `goofys version 0.0.17-use `make build' to fill version hash correctly`

## マウント実行（エラー）
- `goofys <bucket> <mountpoint>`

> エラーメッセージ:  `goofys/internal/handles.go:456: undefined: url.PathUnescape`
> 作者のkahing氏コメント: https://github.com/kahing/goofys/issues/196
> go 1.8以上を入れてね、との事なのだが AmazonLinuxのリポジトリでは go 1.7.5 が入るので yumではNGか…

## yumで導入したパッケージ一式を撤去
- `yum remove golang fuse -y`

# go lang本家からLinux用バイナリを取得して再度環境を構築
- https://golang.org/dl/ から Linux用のリンクURLを取得

## go lang のLinux用バイナリファイルを`/usr/local/src` へDL
- `cd /usr/local/src`
- `wget https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz`

## go lang のバイナリファイルを展開
- `tar -C /usr/local -xzf /usr/local/src/go1.9.linux-amd64.tar.gz`
- `ls -al /usr/local/go`

## go lang バイナリを展開した先へ path を通す
- `export GOROOT=/usr/local/go`
- `export PATH=$PATH:$GOROOT/bin`
- `env | grep -i go`

> ${GOROOT} は goライブラリの設置されているパスを設定する環境変数らしい...
> 参考: `GOROOT と GOPATH` : "http://qiita.com/1000ch/items/e42e7c28cf7a7b798a02#goroot-%E3%81%A8-gopath"

## go lang のパスが通った事とバージョンを確認
- `go version` → `go version go1.9 linux/amd64` が入った

## goofysを再度インストール
- `export GOPATH=${HOME}/go`
- `go get github.com/kahing/goofys`
- `go install github.com/kahing/goofys`

> ${GOPATH} は作業ディレクトリを指す環境変数らしい...
> 参考: "http://qiita.com/1000ch/items/e42e7c28cf7a7b798a02#goroot-%E3%81%A8-gopath"

## goofys 実行ファイルのあるディレクトリにもpathを通す
- `export PATH=${PATH}:${GOPATH}/bin`

## S3バケットをマウントしてみる
- `goofys <bucket> <mountpoint>`

> エラーが出る > `main.FATAL Unable to mount file system, see syslog for details` syslogを見てねとの事なので確認。
> syslogには `main.FATAL Mounting file system: Mount: mount: running fusermount: exec: "fusermount": executable file not found in $PATH#012#012stderr:#012` という事で `fusemount` コマンドが無い、というエラーのためマウントできないっぽい。

## エラー対処
- `yum install fuse` でfuseを追加インストール
- 参考: http://qiita.com/quickguard/items/e9de5d7ed79735a2c167

> goofys本家のInstallation の項目で `On Linux, install via pre-built binaries. You may also need to install fuse-utils first.` って書いてた…
> そういえば↑の手順の中で fuseパッケージを１回 yumで入れたものを消してたな...
> fuse についてよく知らなかったので、go関連のパッケージであればgolangが関連パッケージで上書きインストールされてしまう？とも思ったがfuse パッケージ単体でOKだった
> fuseとは : https://ja.wikipedia.org/wiki/Filesystem_in_Userspace
> fuseとは : https://www.ibm.com/developerworks/jp/linux/library/l-fuse/index.html
> libfuse公式 : https://github.com/libfuse/libfuse

## goofys マウント実行
- マウント: `goofys <bucket> <mountpoint>`
- アンマウント : `umount <mountpoint>`

# その他調整

- DocumentRootに利用できるか
- fstab で再起動後も設定反映させたい
- 関連環境変数設定のまとめ
- 再起動して確認

## DocumentRootに利用できるか
- `mount <bucket> <mountpoint>/ -o allow_other,--uid=<uid>,--gid=<gid>`
- uid gid の確認 : `id apache` または `id nginx` などで

> `allow_other`オプション無しでマウントしていると apache/nginx の実行ユーザーから読めないっぽい...
> `allow_other`オプション＋ uid gid はdaemon実行ユーザと同じ設定にしてマウントすれば動いた: 

##  fstab で再起動後も設定反映させたい

- /etc/fstab に設定を追記
- `<fullpath/to/>goofys#<bucket> <mountpoint> fuse _netdev,allow_other,--dir-mode=0755,--file-mode=0666,--uid=<uid>,--gid=<gid> 0 0`

> 本家のUsage にfstab で使う場合は root にAWS credentials 設定をせよとあるのでrootのユーザ環境に設定。
> fstab のサンプルもUsageにある : `goofys#bucket   /mnt/mountpoint        fuse     _netdev,allow_other,--file-mode=0666    0       0`
> その他参考: http://caters.works/2016/08/%E3%81%95%E3%81%8F%E3%82%89%E3%81%AEvps%E3%81%AB-goofys-%E3%81%A7-s3-%E3%82%92%E3%83%9E%E3%82%A6%E3%83%B3%E3%83%88/

## fstab 設定の試行(再起動無しで)
- `sudo mount -a`

> fstabに記載したのと同じ`<mountpoint>`をマウントした状態で実行している場合は、umountした後に実行

## aws credential の profile を指定したい場合（未検証）
- `goofys#<bucket> <mountpoint> fuse _netdev,allow_other,--file-mode=<filemode>,--profile=<profile>    0       0` っぽい

> 本家のissues でやり取りを発見 : https://github.com/kahing/goofys/issues/222

## 環境変数回りをまとめる
- rootユーザの環境変数へ設定を追加 : `/root/.bashrc`

```
export GOROOT=/usr/local/go
export GOPATH=${HOME}/go
export PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin
```

# システム再起動後にも各所の設定が反映される事を確認

> 環境変数 : `sudo env | grep -i go`
> go lang  : `go version`
> goofys   : `goofys -v`
> fstabログ : `sudo tail -f /var/log/messages | grep goofys` : `main.INFO File system has been successfully mounted.`
> マウント状況 : `df -ah` # s3の空き表示って 1ペタになるのか…