Go
GAE
GoogleAppEngine
GoogleCloudPlatform

Google App Engine for Goを1.8にバージョンアップした

はじめに

Google App Engine for Goが1.8に対応しGAになったため1.6からバージョンアップした際の手順をまとめてみました。

gcloudコンポーネントUpdate

まず、gcloudに含まれるgoappをUpdateしましょう。
CloudSDKに含まれるgoappが1.8に対応します。

gcloud components update 

Go1.8へバージョンアップのための修正

app.yaml

service: sample
runtime: go
api_version: go1.8 #go1から変更

handlers:
- url: /.*
  script: _go_app

api_versionをgo1.8に変更します

contextの修正

go1.7からgolang.org/x/net/contextパッケージは廃止され、contextパッケージへ移行する必要があります。
ただ、特にパッケージの変更だけで大きな改修は必要ありません。
go toolを使うと自動でマイグレーションできます。

go tool fix -force=context *.go  

dep(パッケージ管理ツール)の導入

必ずパッケージ管理を導入しなくてはいけないというものでもないです。
しかし、CI,CDを行っていると、ある日突然失敗するということもあるため導入したほうが良いと思います。
depは公式に提供されているパッケージ管理ツールツールです。depはGo1.8以上が要件となっています。Go1.8にバージョンアップしたことで利用可能になりました。

depをインストールします。

go get -u github.com/golang/dep/cmd/dep

GAEがGo1.8に対応したことで多くのライブラリはcontextに対応しはじめています。
自身のコードはcontextパッケージに対応しましたが、参照しているライブラリは古いままではコンパイルできないので最新に更新します。

go get -u ./... 

次にdepの初期化を行います。

dep init

Gopkg.toml,Gopkg.lockファイルが作成されパッケージがインストールされます。
Gopkg.tomlは依存しているライブラリのリスト、Gopkg.lockすべての依存ライブラリのロックファイルです。
vendorフォルダが作成され依存しているライブラリが取得されます。
vendorフォルダはVendoringと言われ1.5から導入されたライブラリの依存性解決のための機能です。

git clone等でGopkg.toml,Gopkg.lockファイルからパッケージのインストールを行う場合は以下のコマンドを実行します。

dep ensure

ここで問題

gcloudを使用してGAEにデプロイすると以下のようなエラーが発生します。

ERROR: (gcloud.app.deploy) Error Response: [9] Deployment contains files that cannot be compiled: Compile failed:
/work_dir/route.go:4: can't find import: "github.com/gin-gonic/gin"
/work_dir/github.com/hanenao/gaesample/vendor/github.com/gin-gonic/gin/binding/default_validator.go:11: can't find import: "gopkg.in/go-playground/validator.v8"
/work_dir/github.com/hanenao/gaesample/vendor/github.com/gin-gonic/gin/render/msgpack.go:10: can't find import: "github.com/ugorji/go/codec"
/work_dir/github.com/hanenao/gaesample/vendor/github.com/gin-gonic/gin/context.go:19: can't find import: "github.com/gin-contrib/sse"
2018/01/02 17:19:42 go-app-builder: build timing: 10×compile (9.603s total), 0×link (0s total)
2018/01/02 17:19:42 go-app-builder: failed running compile: exit status 2

うまく、vendorフォルダ内のライブラリの依存性解決がうまく言っていないようです。

https://stackoverflow.com/questions/46295469/gcloud-app-deploy-fails-cannot-import-internal-package
https://medium.com/veltra-engineering/be-careful-when-deploying-golang-app-with-vendor-to-gae-4a12ad12b65f
http://blog.wktk.co.jp/ja/entry/2017/10/11/google-app-engine-go-vendor-directory-structure

同様に困っている人がいるようです。
gcloud app deployコマンドの代わりにgoapp deployで回避できました。
GoのVendoringはgcloudコマンドと相性が悪いよいで問題が発生しました。

これで無事にGAEのGo1.8に対応できました。