GitLab 2.7から"Git HTTP"(Git Smart-HTTP)が実装されていたのですが、
いつもはSSH経由で利用しているため、これまでは使っていませんでした。
(※ Git HTTP = HTTP経由でGitLabを通してリポジトリにアクセスする機能)
さて...今日はこのGit HTTP機能をいざ使ってみようと...
GitLab3.0の画面。[SSH]ボタンと並んだ [HTTPS]ボタンをクリックすると Git HTTPによるURLが表示される。 (URLは、プロジェクトの通常のURLに".git"を付加したものとなる) |
何回やっても認証画面がwww
正しいメールアドレス+パスワードを入力しているのに
401エラーが出るという・・・(汗;)w
ところで。GitLabでは、サブディレクトリ下での運用を本来サポートしていません。
ですので、私はリバースプロキシ(nginx)を通して少々無理やり運用しています。
(それについては、記事:Gitlabの導入 (Unicorn+nginxでサブディレクトリへ配置)を参照)
今回は恐らく、そのための問題なのだろう...と仮定して調べてみました。
(他の可能性としては、gitlab.ymlの設定ミスもありますが、今回は問題ありませんでした。)
→ 結果...その通り!やはりサブディレクトリ下で運用していることが問題なようですorz
とりあえず...手探りで試行錯誤してみましたので、
対策方法を以下に残しておきます。
[注意] GitLabのサブディレクトリでの運用が本来サポート外であるうえに、
私はいまのところ Ruby/Unicornに全く詳しくありませんww
そのため保障はできませんが、参考にまで。
...もっと良い方法があればアドバイスお願いします m(_ _)m )
/gitlab/lib/gitlab/backend/grack_auth.rb : 17行目付近〜
@env['PATH_INFO'] = @request.path @env['SCRIPT_NAME'] = "" # Find project by PATH_INFO from env #if m = /^\/([\w-]+).git/.match(@request.path_info).to_a #コメントアウト if m = /^(\/([\w-]+))*?\.git/.match(@request.path_info).to_a self.project = Project.find_by_path(m.last) if m2 = /\/([\w-]+*?.git\/.*)/.match(@request.path).to_a @env['PATH_INFO'] = "/#{m2.last}" end return false unless project end
変更点としてはこれくらいです。
以下に、何を行ったかの解説&メモを書いておきます。
まずGitLabでは、Grackというモジュールを用いることで
このGit HTTPを実現しているようです。
GitLabのルーター(/gitlab/config/routes.rb)はユーザからアクセスを受けると、
Git HTTPのためのアクセスをここで受け取ります。
Grackの認証(Basic認証)には、GitLab上のアカウント情報が用いられます。
実際にその処理を行なっているのは/gitlab/backend/grack_auth.rb ですね。
上のgrack_auth.rbでコメントアウトした行とその次行の
# if m = /^\/([\w-]+).git/.match(@request.path_info).to_a
self.project = Project.find_by_path(m.last)
はリクエストされたパス(@request.path_info)からプロジェクト名を抜き出しています。
本来、パスが"/hoge.git/aaaa"だとしたら、
hogeという部分が正規表現で抜き出され、self.projectに代入されるわけです。
ただ当然これでは、パスがサブディレクトリを含んでいると正しく抜き出せないですね。
ですので...コメントアウトした行の代わりにこのように追加しました:
if m = /^(\/([\w-]+))*?\.git/.match(@request.path_info).to_a
これにより、サブディレクトリであっても正しくプロジェクト名が抜き出せます。
さて...この修正だけで、事態(?)には光が見えてきます(笑)w
プロジェクト名が正しく抜き出せなかったために、
プロジェクトを探せず、401エラーになっていたようです。
これでとりあえず、401エラーが改善し、認証は正常に通るようになります。
が...。
ここでまだ、git cloneしてもうまく行かないはず・・・。
Grackの認証が済むと...
プロジェクト名やパスを環境変数(@env)で渡して次の処理を
/gitlab/vendor/bundle/ruby/*.*.*/bundler/gems/grack-*/lib/grack/*.rb
が行うわけですが・・・。
ここでリポジトリ上のファイルを読み込む時・・・
サブディレクトリのせいでパスを正常に扱えず、ファイルが見つからないのですw
なのでエラーとなります。
この対策のために、前のステップでパスを直しておくことにしました。
先ほどとおなじくgrack_auth.rbでやってしまいましょうw
以上の理由から、先ほどの行の後に2行追加しました:
if m2 = /\/([\w-]+*?.git\/.*)/.match(@request.path).to_a
@env['PATH_INFO'] = "/#{m2.last}"
正規表現マッチもあれな書き方ですが、未だ詳しくないので許してください(><;)
これににより、環境変数に入れるパスからサブディレクトリ部分が削られます。
つまり、本来、GitLabが意図しているパスになるわけです(>ω<)♪
これで一応、解決です。
つまり、本来、GitLabが意図しているパスになるわけです(>ω<)♪
これで一応、解決です。
試しに...クライアントから
$ git clone https://example.com/git/hoge.git
を実行してみてください。正しくcloneできるはずです。
今回は以上となります。
今回もこのヒントを得るためにGitHubやコミュニティを参考にさせていただきました。
ありがとうございました m(_ _)m♪
今回もこのヒントを得るためにGitHubやコミュニティを参考にさせていただきました。
ありがとうございました m(_ _)m♪
- Home · SaitoWu/grack Wiki - grackについて。Saitoさんはgitlabのメンテナさんの一人です。
- Smart HTTP not working? · Issue #1810 · gitlabhq/gitlabhq
- Can't clone repos via http on linux · Issue #1101 · gitlabhq/gitlabhq
- Cloning over http fails if gitlab is not on / · Issue #1228 · gitlabhq/gitlabhq
- http clone doesnt work (latest master) · Issue #1039 · gitlabhq/gitlabhq
- in master branch grack_auth.rb doesn't exist · Issue #1476 · gitlabhq/gitlabhq
- Is it possible to host GitLab in a subdirectory of www root, like http://www.mydomain.com/gitlab ? - Google Group
- git http(s) access not working - Google Group
- その他...
p.s.
そもそもサブディレクトリじゃなくルートでGitLabを運用したらいいのに...
と思われる方もいらっしゃるかもしれません・・・。
私は学生個人でサーバを運用しています。
そしてこういったものに、HTTPSは必須だと考えております。
ところで、ルートディでGitLabを運用するには、当然、サブドメインなり別サーバ/IPアドレスなりの方法を取らなければなりませんが、
それをするとなると、サーバ証明書もGitLab用に別途用意することになります・・・。
サブドメインでも使える証明書は高価ですし・・・。
そこまでの余裕は無いのです(´・ω・`)...。
尚、GitLabはサブディレクトリへの対応を実装することは今のところないそうです。
0 件のコメント:
コメントを投稿
お気軽にコメントをお寄せください m(_ _)m♪
"コメントの記入者"欄から[名前/URL]を選ぶと、登録なしでコメント投稿していただけます。