ローカルの様々なリポジトリを GitLab につっこんだ記録
やったこと
- Gitlab を VM にインストール
- ローカルの未公開リポジトリを Gitlab にプッシュ
- あるリポジトリをジョブ管理ツールでジョブ実行した時に git push で更新
- BitBucket のリポジトリを Gitlab にバックアップ
- GitHub のリポジトリを 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 を更新
基本は上記記事の
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
参考リンク
/etc/ssh/ssh_host_* の SSH 鍵を再生成する
結論から言うと、上記記事の通り 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 しても既存の接続が切れることはない。詳しくは以下の記事を参照。
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.url
の SSH 鍵を /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_REMOTE
に gitlab
を追加
# 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 から)
こっちの手順も自動化したい。 たくさんコマンドラインツールがあるみたいだけどあんまり調べてない。そのうちやるかも。
- 各ホストのユーザを作成
- ログアウトした状態のトップページでアカウントを作成すれば、パスワードも一緒に設定できる
- Admin Area からだとメール記載の URL から設定する必要がある
- ユーザのSSH鍵を追加 (各ホストごとの手順で作成)
- 各ホストのリポジトリを作成
- 各ホストのユーザを etckeeper/{ユーザ名} のプロジェクトに Master として追加
以上
これで /etc/cron.daily/etckeeper が実行されるたびに git push される。