go get k8s.io/kubectl のリポジトリURLはどこから取得しているか
TL;DR
go get k8s.io/kubectl
の場合 k8s.io/kubectl?go-get=1
なURLを参照して、中に書いてあるmetaタグの情報からgithubへの参照URLを得ている。
動作の詳細は go help importpath
に書いてある。
経緯
go get k8s.io/kubectl
とかやったときにちゃんと github.com/kubernetes/kubectl のリポジトリからコードを取得してくれると思います。
一方で、Webブラウザで k8s.io/kubectl にアクセスすると kubernetes.io/kubectl を参照すると思います。
この挙動の違いはどこから来るのだろうと思ったわけですね。
わかったこと
go help importpath
に動作の詳細が書いてある。
Githubなど有名なところはgoコマンドがよろしく判断してくれる。
一方、自分たちでホストするようなモジュールの場合は、返却に含まれる<meta name="go-import" ......>
の内容から参照先のリポジトリ情報を得ている。
例えば logのモジュール go.uber.org/zap
とかは以下のような感じ。
タグからたどっていける。
なるほど。
$ curl https://go.uber.org/zap <!DOCTYPE html> <html> <head> <meta name="go-import" content="go.uber.org/zap git https://github.com/uber-go/zap"> <meta name="go-source" content="go.uber.org/zap https://github.com/uber-go/zap https://github.com/uber-go/zap/tree/master{/dir} https://github.com/uber-go/zap/tree/master{/dir}/{file}#L{line}"> <meta http-equiv="refresh" content="0; url=https://pkg.go.dev/go.uber.org/zap"> </head> <body> Nothing to see here. Please <a href="https://pkg.go.dev/go.uber.org/zap">move along</a>. </body> </html>
じゃあ k8s.io/kubectl も同じだろうと思ったらそれだけだと出てこない。
$ curl https://k8s.io/kubectl <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.10.3</center> </body> </html>
ここで go help importpath
にかかれている内容を詳しく見ると go-get=1
というクエリを付加して呼び出す形式が見つかる。
$ curl https://k8s.io/kubectl?go-get=1 <html><head> <meta name="go-import" content="k8s.io/kubectl git https://github.com/kubernetes/kubectl"> <meta name="go-source" content="k8s.io/kubectl https://github.com/kubernetes/kubectl https://github.com/kubernetes/kubectl/tree/master{/dir} https://github.com/kubernetes/kubectl/blob/master{/dir}/{file}#L{line}"> </head></html>
出てきた。
こうやってリポジトリへのURLを取得しているのか。
ちなみに go-get=1
が付いていない場合は最終的に kubernetes.io/kubectl
へのリダイレクトになっている。(ページ自体存在しないという404になる。)