Humanity

Edit the world by your favorite way

ローカルの様々なリポジトリを GitLab につっこんだ記録

やったこと

Gitlab を VM にインストール

インストールは公式サイトの手順通りにやればすんなり入る。

Download GitLab Community Edition (CE) | GitLab


しかし、Web にアクセスしてみたら頻繁に 502 が返ってきて、ログを調べてみたらいろんなプロセスが kill されていた。 メモリが足りないっぽい(そういや前さくらVPSに立てた時もこんな事があった)。

2GB RAM is the recommended memory size for all installations and supports up to 100 users

VM に割り当てるメモリは安全のために 3072M(3G) にしといた。

2 cores is the recommended number of cores and supports up to 500 users

とも書いてあったが、CPU は 1 core のままにしといた(ケチった)。


ホスト名が local-the-host のため、リポジトリの URL が git@local-the-host:user/repos.git になってしまう。 CNAME を設定してそちらにアクセスする予定なので、ホスト名を変える。 変えるには /etc/gitlab/gitlab.rb をいじって反映させるコマンドを実行する必要がある。

For an Omnibus install, it is a little different.

The correct place in an Omnibus install is:

/etc/gitlab/gitlab.rb external_url 'http://gitlab.example.com' Finally, you'll need to execute sudo gitlab-ctl reconfigure and sudo gitlab-ctl restart so the changes apply.

How to change URL of a working GitLab install? - Stack Overflow

Omnibus っていうのは、ざっくり言ってパッケージ化されたバージョンの Gitlab。 gitlab-ctl コマンドを使って設定を反映する。

あるリポジトリをジョブ管理ツールでジョブ実行した時に git push で更新

まず今回対象のとあるリポジトリ用のユーザを Gitlab と CentOS にそれぞれ作っておく。

Gitlab では Members に Developer(push できるユーザ)として加え、 ユーザごとに作れるプロジェクト数なんてものがデフォルトで 10 に設定されてるらしいので、 Project limit を念のため 1 にした(Admin 設定からいける)。 もう動確めんどいのでやらないけど、プロジェクト作れないようにしたいなら 0 にすればいいらしい。 あと上記リポジトリ用ユーザに不要なリポジトリが見えないよう、基本全てのリポジトリは Private にしておく。

CentOS ではユーザと専用のホームディレクトリを作成し、~/.netrc に以下のように書いておく(パスワードプロンプトをスキップさせるための設定ファイル)。 セキュリティ的によろしくないけどとりあえずこれで。 SSH 鍵を転送とか考えたけど、結局ファイルやホームディレクトリのパーミッションだけ気を付けるようにした。

machine gitlab.lan
login hogeuser
password xxxxx

で、実行ユーザに注意しながらジョブ管理ツールに実行させる。 すると無事実行したスクリプトで git push して Gitlab にプッシュさせる事ができた。

ちなみにジョブ管理ツールは惰性で Hinemos 使ってるけどいい加減 Rundeck とかに移行したい(エージェントが重い)。 やるとは言ってない。

BitBucket のリポジトリを Gitlab にバックアップ

BitBucket 連携したものの、バックアップするリポジトリがなかった(終)。

(なんかあったと思ったけどゴミしかなかった)

GitHubリポジトリを Gitlab にバックアップ

GitHub 連携で楽できた。

インポートしたら GitHub のユーザ名と同じ名前空間リポジトリが作られるけど、 自分は /tyru/repo じゃなく /github/repo に作ってほしかったので、せっせこ手動で Transfer した。

ちなみに取得するリポジトリ一覧には fork したものも含まれるので、 http://<gitlab>/thinca/vim-ambicmd/ みたいに Gitlab が勝手に thinca グループ作ってくれて便利。*1

*1:こっちもせこせこ手動で削除した

非対話的に ~/.ssh/known_hosts を更新

qiita.com

基本は上記記事の

host="target-hostname"
ssh-keygen -R $host
ssh-keyscan -H $host >> ~/.ssh/known_hosts

でいいのだけど、(少なくとも自分の環境だと) ssh-keyscan で出力した1列目のカラムにホスト名しか出力されず、 その後別のレコード(行)としてIPアドレスが登録されてしまっていた。

hoge ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCq9UXuh/sKm4oBs68VlfAvjc/WaV83brTXkoTOLr2339XxMMzDQQ1FX9jP4Ie6rUfoDrvA1t8N2peJoG2e1rvPgtNAabZxz92l0V1+XYYhEf6Y0n0ZzXv4pf+YWfcj6VtXcQaoaxQ0PieREStTluOShAdA8MpJBAX1qId2qCZ2koF5mPIT/vUF8kEzzXBZjYGx1nOEBL6Caqg1P4wJS4trwOGfeV3/eIZW0jwrujOxYD0NHvaV/UJBZsPceYZthD8G4xAFqkCm5ZXJCiHyEtVRicbB2VddsPpKh6J8+FPMCINHrFmAVGLNG1H424STVacXPqdpdnvdRnYFf6dhjYH
(hogeのIPアドレス) ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCq9UXuh/sKm4oBs68VlfAvjc/WaV83brTXkoTOLr2339XxMMzDQQ1FX9jP4Ie6rUfoDrvA1t8N2peJoG2e1rvPgtNAabZxz92l0V1+XYYhEf6Y0n0ZzXv4pf+YWfcj6VtXcQaoaxQ0PieREStTluOShAdA8MpJBAX1qId2qCZ2koF5mPIT/vUF8kEzzXBZjYGx1nOEBL6Caqg1P4wJS4trwOGfeV3/eIZW0jwrujOxYD0NHvaV/UJBZsPceYZthD8G4xAFqkCm5ZXJCiHyEtVRicbB2VddsPpKh6J8+FPMCINHrFmAVGLNG1H424STVacXPqdpdnvdRnYFf6dhjYH

これによって新たにプロンプトが出て待たされることはない(ホスト名が既に登録されている場合はプロンプトは出ないらしい。「Warning: Permanently added the ECDSA host key for IP address 'xxx.xxx.xxx.xxx' to the list of known hosts.」といつものメッセージが表示されて静かに追加される)。 ただ、いくつも行ができるのは何となく気持ち悪い。

そこで以下のように、

  • ホスト名から引いたIPアドレスを付加させるようにした
  • 自分の環境だと対象が CNAME で実 IP は複数ある可能性があったので、$HOST_LIST に全てのホスト名を列挙することにした *1
  • ついでに ~/.ssh/known_hosts がない時に ssh-keygen -R でエラーが出ないようガードするようにした
  • ちなみにパースできなくなるので ssh-keyscan-H はつけていない…(外した)
HOST_LIST='hostA hostB hostC'
HOST=...

get_ip_list() {
    local host
    for host in $HOST $HOST_LIST; do
        getent hosts $host || true
    done | awk '$0=$1' | sort -u | paste -d , -s
}


[ -f ~/.ssh/known_hosts ] && ssh-keygen -R $HOST
ssh-keyscan $HOST |
    awk -v "hosts=$(get_ip_list)" '$1 = $1 "," hosts' \
        >>~/.ssh/known_hosts

これにより冒頭でも示した ~/.ssh/known_hosts に追加される行は以下のようになる。

Before

hoge ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCq9UXuh/sKm4oBs68VlfAvjc/WaV83brTXkoTOLr2339XxMMzDQQ1FX9jP4Ie6rUfoDrvA1t8N2peJoG2e1rvPgtNAabZxz92l0V1+XYYhEf6Y0n0ZzXv4pf+YWfcj6VtXcQaoaxQ0PieREStTluOShAdA8MpJBAX1qId2qCZ2koF5mPIT/vUF8kEzzXBZjYGx1nOEBL6Caqg1P4wJS4trwOGfeV3/eIZW0jwrujOxYD0NHvaV/UJBZsPceYZthD8G4xAFqkCm5ZXJCiHyEtVRicbB2VddsPpKh6J8+FPMCINHrFmAVGLNG1H424STVacXPqdpdnvdRnYFf6dhjYH
(hogeのIPアドレス) ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCq9UXuh/sKm4oBs68VlfAvjc/WaV83brTXkoTOLr2339XxMMzDQQ1FX9jP4Ie6rUfoDrvA1t8N2peJoG2e1rvPgtNAabZxz92l0V1+XYYhEf6Y0n0ZzXv4pf+YWfcj6VtXcQaoaxQ0PieREStTluOShAdA8MpJBAX1qId2qCZ2koF5mPIT/vUF8kEzzXBZjYGx1nOEBL6Caqg1P4wJS4trwOGfeV3/eIZW0jwrujOxYD0NHvaV/UJBZsPceYZthD8G4xAFqkCm5ZXJCiHyEtVRicbB2VddsPpKh6J8+FPMCINHrFmAVGLNG1H424STVacXPqdpdnvdRnYFf6dhjYH

After

hoge,(hogeのIPアドレスのリスト) ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCq9UXuh/sKm4oBs68VlfAvjc/WaV83brTXkoTOLr2339XxMMzDQQ1FX9jP4Ie6rUfoDrvA1t8N2peJoG2e1rvPgtNAabZxz92l0V1+XYYhEf6Y0n0ZzXv4pf+YWfcj6VtXcQaoaxQ0PieREStTluOShAdA8MpJBAX1qId2qCZ2koF5mPIT/vUF8kEzzXBZjYGx1nOEBL6Caqg1P4wJS4trwOGfeV3/eIZW0jwrujOxYD0NHvaV/UJBZsPceYZthD8G4xAFqkCm5ZXJCiHyEtVRicbB2VddsPpKh6J8+FPMCINHrFmAVGLNG1H424STVacXPqdpdnvdRnYFf6dhjYH

参考リンク

*1:アドホックなので他にいい方法があれば教えてほしい

/etc/ssh/ssh_host_* の SSH 鍵を再生成する

d.hatena.ne.jp

結論から言うと、上記記事の通り SSH 鍵を削除するなり移動するなりして sshd を再起動すれば自動的に生成してくれる。

# rm -f ssh_host_{ecdsa,ed25519,rsa}_key{,.pub}
# systemctl restart sshd

どんな風に実装されてるか気になったので調べた。のでまとめる。 CentOS 7 上だと以下の Unit が生成処理を行っている(終)。

/usr/lib/systemd/system/sshd-keygen.service

[Unit]
Description=OpenSSH Server Key Generation
ConditionPathExists=|!/etc/ssh/ssh_host_rsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_ecdsa_key
ConditionPathExists=|!/etc/ssh/ssh_host_ed25519_key
PartOf=sshd.service sshd.socket

[Service]
ExecStart=/usr/sbin/sshd-keygen
Type=oneshot
RemainAfterExit=yes

通常はやることがないのでこんなログになる。

$ sudo systemctl status sshd-keygen.service
● sshd-keygen.service - OpenSSH Server Key Generation
   Loaded: loaded (/usr/lib/systemd/system/sshd-keygen.service; static; vendor preset: disabled)
   Active: inactive (dead)
Condition: start condition failed at 日 2016-09-04 02:13:33 JST; 16h ago
           none of the trigger conditions were met

 9月 04 02:13:33 myhost systemd[1]: Started OpenSSH Server Key Generation.

キーを移動して sshd-keygen.service を再起動してみる。

$ mkdir -p sshkeys.old; for i in ssh_host_{ecdsa,ed25519,rsa}_key{,.pub}; do sudo mv /etc/ssh/$i sshkeys.old/$i; done
$ ls sshkeys.old/
ssh_host_ecdsa_key  ssh_host_ecdsa_key.pub  ssh_host_ed25519_key  ssh_host_ed25519_key.pub  ssh_host_rsa_key  ssh_host_rsa_key.pub
$ sudo systemctl restart sshd-keygen.service

そうするとこうなる。

$ sudo systemctl status sshd-keygen.service
● sshd-keygen.service - OpenSSH Server Key Generation
   Loaded: loaded (/usr/lib/systemd/system/sshd-keygen.service; static; vendor preset: disabled)
   Active: active (exited) since 日 2016-09-04 18:32:28 JST; 3s ago
  Process: 2417 ExecStart=/usr/sbin/sshd-keygen (code=exited, status=0/SUCCESS)
 Main PID: 2417 (code=exited, status=0/SUCCESS)

 9月 04 18:32:28 myhost systemd[1]: Starting OpenSSH Server Key Generation...
 9月 04 18:32:28 myhost sshd-keygen[2417]: Generating SSH2 RSA host key: [  OK  ]
 9月 04 18:32:28 myhost sshd-keygen[2417]: Generating SSH2 ECDSA host key: [  OK  ]
 9月 04 18:32:28 myhost sshd-keygen[2417]: Generating SSH2 ED25519 host key: [  OK  ]
 9月 04 18:32:28 myhost systemd[1]: Started OpenSSH Server Key Generation.

今回は sshd-keygen.service を restart したけど、sshd.service は sshd-keygen.service に依存しているので systemctl restart sshd.service しても再生成されるのを確認した。 ので、普通は sshd.service を restart すればいい。

ちなみに sshd は restart しても既存の接続が切れることはない。詳しくは以下の記事を参照。

equj65.net

etckeeper で commit されたら GitLab に push する

手順 (各ホスト)

以下の手順を自動化したスクリプトはこちら(実際のものとは多少異なります)。

etckeeper-setup-host.sh · GitHub

1. SSH鍵を生成

# ssh-keygen -t rsa -C "$(hostname)@gitlab-root.url" -N '' -f /root/.ssh/gitlab-$(hostname)

2. /root/.ssh/config に以下を追記

Host gitlab-root.url
    User (ホスト名)
    IdentityFile /root/.ssh/gitlab-(ホスト名)

3. gitlab-root.urlSSH 鍵を /root/.ssh/known_hosts に登録する

自動化されたスクリプトでは ssh-keyscan コマンドを使っている(関連:非対話的に ~/.ssh/known_hosts を更新 - Humanity)。

# ssh gitlab-root.url

4. リポジトリの初期化

# etckeeper init

5. GitLab の remote URL を追加

# etckeeper vcs remote add gitlab git@gitlab-root.url:etckeeper/etckeeper-$(hostname).git

6. 設定ファイルの PUSH_REMOTEgitlab を追加

# vim /etc/etckeeper/etckeeper.conf

# To push each commit to a remote, put the name of the remote here.
# (eg, "origin" for git). Space-separated lists of multiple remotes
# also work (eg, "origin gitlab github" for git).
PUSH_REMOTE="gitlab"

手順 (GitLab の Web GUI から)

こっちの手順も自動化したい。 たくさんコマンドラインツールがあるみたいだけどあんまり調べてない。そのうちやるかも。

  1. 各ホストのユーザを作成
  2. ログアウトした状態のトップページでアカウントを作成すれば、パスワードも一緒に設定できる
  3. Admin Area からだとメール記載の URL から設定する必要がある
  4. ユーザのSSH鍵を追加 (各ホストごとの手順で作成)
  5. 各ホストのリポジトリを作成
  6. 各ホストのユーザを etckeeper/{ユーザ名} のプロジェクトに Master として追加

以上

これで /etc/cron.daily/etckeeper が実行されるたびに git push される。