Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Engine Standard Go 1.9 migration to Go 1.11 の知見 #102

Open
sinmetal opened this issue Jul 1, 2019 · 12 comments
Open

App Engine Standard Go 1.9 migration to Go 1.11 の知見 #102

sinmetal opened this issue Jul 1, 2019 · 12 comments

Comments

@sinmetal
Copy link
Member

sinmetal commented Jul 1, 2019

WHAT

App Engine Standard Go 1.9 migration to Go 1.11の知見を集約していく
このissueにそのまま書いてもよいし、やった時に書いたBlogなどへのLinkでもよい

  • 移行時にやったこと
  • 移行時にはまったことや解決策, ワークアラウンド

WHY

App Engine Standardにはたくさんの機能が存在していて、開発環境なども絡むと結構ややこしいので、色んな人のケースを集めてみよう。

Refs

@emahiro
Copy link

emahiro commented Jul 1, 2019

https://speakerdeck.com/emahiro/go-conference-2019-spring-go1-dot-9-to-go1-dot-11

@ryo-yamaoka
Copy link

@KeisukeYamashita
Copy link

KeisukeYamashita commented Jul 1, 2019

ドキュメント読んでて気づかなかったのでシェアします。

Go1.11ランタイムではAppEngineTokenSourceをつかっていると怒られました。

2019/07/01 10:45:54 google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11) and App Engine flexible. Please use DefaultTokenSource or ComputeTokenSource.

そうしないとGCP APIが叩けません。

oauth2/google: can't get a token from the metadata service; not running on GCE

@apstndb
Copy link
Contributor

apstndb commented Jul 1, 2019

AppEngineTokenSource が deprecated なのは事実として、 ComputeTokenSource に delegate しているはずなので動かないとしたら golang.org/x/oauth2 のバグのような気もしますね。

https://godoc.org/golang.org/x/oauth2/google#AppEngineTokenSource

Second generation App Engine runtimes (>= Go 1.11) and App Engine flexible: AppEngineTokenSource is DEPRECATED on second generation runtimes and on the flexible environment. It delegates to ComputeTokenSource, and the provided context and scopes are not used. Please use DefaultTokenSource (or ComputeTokenSource, which DefaultTokenSource will use in this case) instead.

https://github.com/golang/oauth2/blob/master/google/appengine_gen2_flex.go#L21

@apstndb
Copy link
Contributor

apstndb commented Jul 1, 2019

2018年11月時点で動くようには書かれているはずなので、動かなかった条件が少し知りたいところですね。 aetest とか dev_appserver.py で動かないのは間違いないと思います。
golang/oauth2#341

@KeisukeYamashita
Copy link

KeisukeYamashita commented Jul 2, 2019

oauth2/google: can't get a token from the metadata service; not running on GCE

これはAppEngineTokenSourceにしていたときにエラーが出たもので、DefaultTokenSourceにするとすんなり解決したためComputeTokenSourceは試していません。

2019/07/01 10:45:54 google: AppEngineTokenSource is deprecated on App Engine standard second generation runtimes (>= Go 1.11)

ここはGo1.11はsecond generation runtimes扱いなんだとびっくりしましたw

@apstndb
Copy link
Contributor

apstndb commented Jul 2, 2019

試しに google.AppEngineTokenSource を使ったものを App Engine Go 1.11 にデプロイしてみたところAppEngineTokenSource is deprecated のログは出力されたものの動いたので、動かないというのはやはり何か前提条件がおかしい気がしますね。

oauth2/google: can't get a token from the metadata service; not running on GCE

が出ているということは、デプロイ先がおかしい OR デプロイしないローカル環境での結果ではないでしょうか。
下は実際に動かしてみたもの。

package main

import (
	"fmt"
	"io"
	"net/http"
	"os"

	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	"google.golang.org/appengine"
)
func main() {
	http.HandleFunc("/", func(rw http.ResponseWriter, r *http.Request) {
		tokenSource := google.AppEngineTokenSource(r.Context())
		client := oauth2.NewClient(r.Context(), tokenSource)
		resp, err := client.Get(fmt.Sprintf(`https://appengine.googleapis.com/v1/apps/%s/services`, os.Getenv("GOOGLE_CLOUD_PROJECT")))
		if err != nil {
			http.Error(rw, err.Error(), http.StatusInternalServerError)
			return
		}
		defer resp.Body.Close()
		io.Copy(rw, resp.Body)
	})
	appengine.Main()
}
runtime: go111
service: go111-tokensource

@nanasi880
Copy link

nanasi880 commented Jul 4, 2019

移行時にはまったことや解決策, ワークアラウンド

  • ソースコードはGitHubのprivate repoで管理している
  • デプロイするアプリケーションは社内で開発しているprivate repoにあるライブラリに依存している
  • Go1.11ランタイムを使用し、ローカルではGo Moduleによる依存関係解決をしている

ような場合、そのままgcloud app deployしてしまうとGAEのapp_builderさんがCloudBuildマシンから認証が必要なGitHubリポジトリにアクセスしようとしてビルド出来ないので、デプロイ前に小細工が必要でした

具体的には

go mod vendor
mv ./go.mod ./go.mod.temp
mv ./go.sum ./go.sum.temp
gcloud app deploy

のように、vendorフォルダを作った後、go.modファイルをリネームするなり何なりしてやる必要があります
go111ランタイムの初期の頃はgcloud app deployする際に環境変数GO111MODULEが参照されているような挙動だったのですが、いつからかgo.modファイルがあるかどうかでGo Moduleを使うかどうかが変わるようになりました

@apstndb
Copy link
Contributor

apstndb commented Jul 4, 2019

実は go mod vendor については Cloud Functions のドキュメントの方が詳しくて、 go.mod を無視するために .gcloudignore が使えることも書いてあったりしますね。こちらに挙動が合わせられている様子。
https://cloud.google.com/functions/docs/writing/specifying-dependencies-go?hl=en#using_a_vendor_directory

@sinmetal
Copy link
Member Author

sinmetal commented Jul 4, 2019

https://github.com/gcpug/nouhau/tree/master/app-engine/note/gaego111-private-repo-deploy も合わせてどうぞ!

@nanasi880
Copy link

誘導ありがとうございます
今は.gcloudignoreでちゃんと間引けるようになってるんですね :)

@hogedigo
Copy link

hogedigo commented Jul 5, 2019

dev_appserver.pyにbug。

handlers:

- url: /hello
  script: auto

- url: /(.+)
  static_files: static/\1
  upload: static/.*

上記の様に scriptハンドラを上書きするURLパターンのstatic_filesハンドラがあると、scriptハンドラが処理されず404エラーとなる。
(dev_appserverはgo1.11の場合にscriptハンドラを全て無視してデフォルトハンドラで処理している為)

プロダクションでは問題なし。

↓issue
https://issuetracker.google.com/issues/128170900

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants