rust-lang-ja/rust-by-example-ja

CI: cargo run が unknown error で失敗する

Closed this issue · 7 comments

ビルド 108 から失敗するようになった。

cargo run
    Updating registry `https://github.com/rust-lang/crates.io-index`
warning: spurious network error (2 tries remaining): [12/-12] Malformed URL 'ssh://git@github.com:/rust-lang/crates.io-index'
warning: spurious network error (1 tries remaining): [12/-12] Malformed URL 'ssh://git@github.com:/rust-lang/crates.io-index'
error: An unknown error occurred

To learn more, run the command again with --verbose.

Rust と Cargo のバージョン

$ rustc --version --verbose
rustc 1.11.0-nightly (601eb13dc 2016-05-31)
binary: rustc
commit-hash: 601eb13dc4dd075f82f03c85bbf8a1fbadfe2d6e
commit-date: 2016-05-31
host: x86_64-unknown-linux-gnu
release: 1.11.0-nightly
$ cargo --version --verbose
cargo 0.12.0-nightly (7d79da0 2016-05-31)

調査状況

  • "Rebuild"
    • → 効果なし。ビルド失敗
  • "Rebuild without cache"
    • (これにより上記の nightly 2016-05-31 の Rust と Cargo が再インストールされる)
    • → 効果なし。ビルド失敗

"Rebuild with ssh" で調査する予定。

昨日と今日で合計3時間ほど調査したが、解決には至らず。

  • CircleCI の環境に ssh で接続して調査している
  • 自分の環境(ただし OS 違い。FreeBSD)では再現できず

状況

cargo buildRUST_LOG=debug--verbose を付けて実行

ubuntu@box2517:~/rust-by-example-ja$ RUST_LOG=debug cargo build --verbose
DEBUG:cargo::build: executing; cmd=cargo-build; args=["cargo", "build", "--verbose"]
DEBUG:cargo::ops::cargo_compile: compile; manifest-path=/home/ubuntu/rust-by-example-ja/Cargo.toml
DEBUG:cargo::ops::cargo_compile: loaded package; package=update v0.0.1 (file:///home/ubuntu/rust-by-example-ja)
DEBUG:cargo::core::registry: load/missing  file:///home/ubuntu/rust-by-example-ja
DEBUG:cargo::core::registry: load/missing  registry https://github.com/rust-lang/crates.io-index
   Updating registry `https://github.com/rust-lang/crates.io-index`
warning: spurious network error (2 tries remaining): [12/-12] Malformed URL 'ssh://git@github.com:/rust-lang/crates.io-index'
warning: spurious network error (1 tries remaining): [12/-12] Malformed URL 'ssh://git@github.com:/rust-lang/crates.io-index'
DEBUG:cargo: handle_error; err=CliError { error: ChainedError { error: failed to fetch `https://github.com/rust-lang/crates.io-index`, cause: Error { code: -12, klass: 12, message: "Malformed URL \'ssh://git@github.com:/rust-lang/crates.io-index\'" } }, unknown: true, exit_code: 101 }
error: failed to fetch `https://github.com/rust-lang/crates.io-index`
  • ログを見る限り openssl や openssh-clients のバージョンは以前と変わっていない
    • openssl は新しいバージョンがでていたので、念のためアップデートするが変わらず
  • Rust と Cargo は、circle.yaml で以前と同じバージョンを使用している
    • 念のため最新(2016-07-29)も試したが状況変わらず
  • Cargo などのソースコードをざっと確認
    • Cargo は registry (crates.io-index) の取得に、git2 クレートを使用している
    • git2 クレートは libgit2-sys クレートに依存している
    • libgit2-sys クレートは C言語で書かれた libgit2 を使用している。libgit2 は static library としてビルドされる
    • Malformed URL のエラーは、libgit2 が返している
    • git2 クレートを含む Cargo 側では、git の URL として https://github.com/rust-lang/crates.io-index を使っているようで、URL を ssh://git@github.com:/rust-lang/crates.io-index へ変換しているのは、恐らく libgit2 の側だと考えられる

考察

エラーメッセージの通り、URL が malformed?

  • libgit2 の テストケース では、以下の URL 形式のみテストしており、今回の形式はテストされていない
    • ssh://somehost:somepath
    • ssh+git://somehost:somepath
    • git+ssh://somehost:somepath
    • git@somehost:somepath
  • しかし、URL を変換している(?)のは libgit2 側のように思えるので、だとすると、malformed なものを生成するのもおかしいような

今後の対応

本日は時間切れ。次回、次のような調査を予定。

  • 切り分けのために、簡単の Rust プロジェクトで、git2 クレートを直接使ってみる。
    • git2 と libgit2-sys クレート(含む libgit2)を手元の環境でビルドするとどうなるか?
    • Cargo に含まれている git2、libgit2-sys、(libgit2)を使うとどうなるか?
KeenS commented

参考になるかは分かりませんが私がCargoを使うとたまにunknown errorで落ちることがあります。そういうときはリトライすると実行出来るようなので失敗したらリトライするようにしてみたらワークアラウンドにはなるかもしれません。

調査ありがとうございます。
私の方でも調べてみます。

CircleCIの環境のBoxの~/.gitconfigに以下のように書かれています。

[url "ssh://git@github.com:"]
        insteadOf = https://github.com

CargoがSSH経由でdependencyをcloneしようとしているのは、これが原因のようです。まだfixしていないためこちらのwork aroundを試してみます。

参考: (rust-lang/cargo#1851

work aroundが有効に機能しなかったため、ボックス中の~/.gitconfigを削除したところテストが通るようになったのですが、これってセキュリティ的に大丈夫なんですかね…OSSだから大きな問題はないと思うのですが自信がありません。

@joemphilips

ああ、なるほど。Box 環境に ~/.gitconfig があって、そこでリポジトリのURLを変換するように指定されていたんですね。 よく見付けましたね! 助かりました。

work aroundが有効に機能しなかったため、ボックス中の~/.gitconfigを削除したところテストが通るようになったのですが、これってセキュリティ的に大丈夫なんですかね…

ssh と https はどちらも通信が暗号化されますので、セキュリティ面では問題ないです。この2つが異なるのは、プライベートリポジトリにアクセスする時の認証のしかたです。前者が ssh キーを使用して、後者が https のリクエストでユーザー名とパスワードを送信します。

CircleCI は前者(ssh キーを使った git リポジトリの認証)だけに対応しているので、CI の最中に後者(https)でプライベートリポジトリにアクセスするようなプロジェクトだと、認証ができなくて fail するのだと思います。多分、CircleCI では、その対応として最近 ~/.gitconfig での変換設定を追加したのではないでしょうか。しかし Cargo では、この対応があだとなっていたのですね...。

参考: (rust-lang/cargo#1851

我々の環境の場合、 ~/.gitconfig を消すという対応で構わないと思います。あるいは、いまの~/.gitconfig の設定を残しつつ、https://github.com/rust-lang/crates.io-index だけは変換しないような設定を追加するか、ですかね。

p.s.
日本滞在の後半(7月下旬から8月末まで)は時間ができると考えていたのですが、なかなかそうなりませんね。8月末までには上海の自宅に帰る予定なので、帰ったら元通りの生活になると思います。

ありがとうございます。よく理解できました。

とりあえず~/.gitconfigを消すことで対応しました #39

日本滞在の後半(7月下旬から8月末まで)は時間ができると考えていたのですが、なかなかそうなりませんね。8月末までには上海の自宅に帰る予定なので、帰ったら元通りの生活になると思います。

手伝っていただけて大変助かりますが、どうか私生活に影響が出ない範囲で...