プロジェクトでglogフラグlog_dirを使用しています。最近、私はkubernetesライブラリをインポートし、このランタイムパニックを取得し始めました
パニック:./aaa.testフラグの再定義:log_dir
May 16 23:51:35 ecmdev03-core01 docker[26867]: goroutine 1 [running]:
May 16 23:51:35 ecmdev03-core01 docker[26867]: panic(0x15ebc60, 0xc8201aae90)
May 16 23:51:35 ecmdev03-core01 docker[26867]: /usr/local/go/src/runtime/panic.go:464 +0x3e6
May 16 23:51:35 ecmdev03-core01 docker[26867]: flag.(*FlagSet).Var(0xc8200160c0, 0x7f561118c1c0, 0xc8201aae40, 0x1bddd70, 0x7, 0x1d75860, 0x2f)
May 16 23:51:35 ecmdev03-core01 docker[26867]: /usr/local/go/src/flag/flag.go:776 +0x454
May 16 23:51:35 ecmdev03-core01 docker[26867]: flag.(*FlagSet).StringVar(0xc8200160c0, 0xc8201aae40, 0x1bddd70, 0x7, 0x0, 0x0, 0x1d75860, 0x2f)
May 16 23:51:35 ecmdev03-core01 docker[26867]: /usr/local/go/src/flag/flag.go:679 +0xc7
May 16 23:51:35 ecmdev03-core01 docker[26867]: flag.(*FlagSet).String(0xc8200160c0, 0x1bddd70, 0x7, 0x0, 0x0, 0x1d75860, 0x2f, 0xc8201aae30)
May 16 23:51:35 ecmdev03-core01 docker[26867]: /usr/local/go/src/flag/flag.go:692 +0x83
May 16 23:51:35 ecmdev03-core01 docker[26867]: flag.String(0x1bddd70, 0x7, 0x0, 0x0, 0x1d75860, 0x2f, 0xba3950)
May 16 23:51:35 ecmdev03-core01 docker[26867]: /usr/local/go/src/flag/flag.go:699 +0x5f
May 16 23:51:35 ecmdev03-core01 docker[26867]: k8s.io/kubernetes/vendor/github.com/golang/glog.init()
May 16 23:51:35 ecmdev03-core01 docker[26867]: /src/ecm_infra/go/src/k8s.io/kubernetes/vendor/github.com/golang/glog/glog_file.go:41 +0x13e
May 16 23:51:35 ecmdev03-core01 docker[26867]: k8s.io/kubernetes/pkg/labels.init()
May 16 23:51:35 ecmdev03-core01 docker[26867]: /src/ecm_infra/go/src/k8s.io/kubernetes/pkg/labels/selector.go:810 +0x6b
May 16 23:51:35 ecmdev03-core01 docker[26867]: k8s.io/kubernetes/pkg/api/unversioned.init()
May 16 23:51:35 ecmdev03-core01 docker[26867]: /src/ecm_infra/go/src/k8s.io/kubernetes/pkg/api/unversioned/well_known_labels.go:30 +0x6f
May 16 23:51:35 ecmdev03-core01 docker[26867]: k8s.io/kubernetes/pkg/api.init()
May 16 23:51:35 ecmdev03-core01 docker[26867]: /src/ecm_infra/go/src/k8s.io/kubernetes/pkg/api/types.go:2731 +0x64
K8sから提供されているglogライブラリが、私が使用しているものと競合しているようです。ベンダーディレクトリの導入はこの問題の解決策ですか? glide、govendor、gbなどのベンダーライブラリを使用する必要がありますか?はいの場合、どちらが好ましいですか?
このエラーは、競合するライブラリとは関係がなく、競合するフラグ(log_dir
)です。これは、「-log_dir」フラグを追加していることを意味し、kubernetesで使用されるglogライブラリにもlog_dir
フラグがあります。これは、パッケージの初期化中にライブラリにフラグを追加する際の問題です。残念ながら、ベンダーは何も変更しません。ログライブラリまたはkubernetesをインポートするときにflag.CommandLine
グローバル変数を操作して別のflag.FlagSet
を指すようにすると、これを回避できる場合がありますが、インポートの順序に依存するため、注意が必要です。
グライドを使用して依存関係をベンダリングするときにも、同様の問題に直面しました。
https://github.com/kubernetes/kubernetes/issues/25572 によると、kubernetesにはglide.lock/glide.ymlがないため、依存関係の平坦化は行われず、最終的にglogが2回定義されますvendor/k8s.io/kubernetes/vendorも含まれているため。
上記のリンクからの回避策は私にとってうまくいきました:
glide install --strip-vendor --strip-vcs
私はk8sライブラリを使用しており、flag redefined: log_dir
の問題にも直面しています。 Kubernetesのいくつかのパッケージがベンダーにないことを発見しました。次に、それらをgovendor add
して、修正されました。
これらのパッケージがベンダーフォルダーに見つからない場合、glogの2つのコピー(ベンダーフォルダーに1つ、$ GOPATHのk8s.io/kubernetes/vendorに1つ)が作成されたと思います。
不足しているパッケージを見つける方法は?私は愚かな方法を使用して、$ GOPATH/src/k8s.ioを別の名前に変更してプロジェクトをビルドし、見つからなかったものを確認します。次に追加してください〜
私は見てた flag redefined: log_dir
エラーとスタックトレースが指すglog/glog_file.go:41 +0xd3
。
問題の根本的な原因はGOPATH
でした。
同じリポジトリの2つのコピーが別の場所にありました。コピーの1つでテストを実行しようとしたときに、goパッケージが他のリポジトリから選択されました。したがって、glog
にはすべての定義が2つありました。
他のリポジトリの名前を新しい名前に変更すると、動作し始めました。
したがって、GOPATH
を確認し、他の場所からライブラリをインポートしていないことを確認してください。