それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

Gitlab をAPIで使ってレポジトリ(プロジェクト)を管理。レポジトリのコピーと移動

Gitlab を整理したんですが。

レポジトリの取捨選択と移動が手間なので、APIでコマンドから行いました。

レポジトリを整理し選抜して新サーバーに移動するかどうか決めるときに、100件くらいと削除を繰り返すのが面倒だったので、インポートを使わずに必要なレポジトリだけをclone して push することにした。

Gitlab のAPIで解決させる

APIはパーソナルアクセストークンを使って、プロジェクトの一覧、グループの一覧、グループのプロジェクトの一覧から、プロジェクトのレポジトリを一覧したり削除したり、新規作成できる。

APIを使って面倒な削除処理とClone処理を少しでも改善することにする。

GitLabのAPIを使う。

APIを使えば、アクセス可能なプロジェクトの名前やURLを取得し、git clone や git push を連続的に行うことができる。

APIキーの作成

パーソナルトークンを発行する。

ここで発行したアクセス・トークンを使う。

APIキーのテスト(自分のユーザー情報を取得)

自分のユーザー情報

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
## 確認する。
curl -s -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/user"  | jq  -r .id
## 保存する。
USERID=$(curl -s -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/user"  | jq  -r .id)

このように、TOKENを使えば簡単にアクセスできることがわかる。TOKENの確認に自分のユーザー情報取得し、動作チェックすとする。

プロジェクト一覧を取得する

自分がアクセス可能なプロジェクト一覧を取得する。

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
curl --header "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/projects"

自分のプロジェクト一覧

自分のパーソナルなプロジェクト(レポジトリ)を一覧する。

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
USERID=$(curl -s -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/user"  | jq  -r .id)
curl -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/users/$USERID/projects"  | jq .

一覧系は、all_available をつけないと、一部が欠損する。

グループ一覧

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
curl --header "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/groups?all_available=yes&top_level_only=yes"  

一覧系は、all_available をつけないと、一部が欠損する。

グループ内のプロジェクト一覧

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
curl --header "PRIVATE-TOKEN: $MY_TOKEN" \
  "https://$HOST/api/v4/groups/154/projects"

bashやjs で使いやすく可能する

プロジェクトを見やすく、整形して加工する。配列などにしておけば、シェルコマンドから使いやすい。

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
USERID=$(curl -s -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/user"  | jq  -r .id)

curl -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/users/$USERID/projects" > p.json
cat p.json | jq '[ .[] | { id:.id, name:.name, desc: .description , path: .path, ssh: .ssh_url_to_repo } ]'
cat p.json | jq .[] | jq ' "\(.name) \(.ssh_url_to_repo)" ' -r
cat p.json | jq .[] | jq ' "\"\(.path)\": \(.ssh_url_to_repo)" ' -r
cat p.json | jq .[] | jq ' "project=\"\(.name)\";project_path=\"\(.path)\"" ' -r

プロジェクト個別の情報を見る。

プロジェクトの設定情報や参加者などを個別に見る。

PRJID=55
curl -X GET -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/projects/$PRJID" 

プロジェクトを消す。

要らないな。と思ったプロジェクト消す。

PRJID=55
curl -X DELETE -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/projects/$PRJID" 

もっと簡単にまとめて消す

ARR='35 37 39'
for i in $ARR; do 
    echo $i
    curl -s -X DELETE -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/projects/${i}"  | jq . 
done

WEB画面から行うと確認が入ってめんどくさいので、APIから削除する。削除は即座に行われる。二度と復活できない。

プロジェクトをまとめてCloneする。

自分の個人プロジェクトのレポジトリをまとめてgit clone する。

MY_TOKEN=glpat-XXXXXXXXX-2g
HOST=git.example.com
USERID=$(curl -s -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/user"  | jq  -r .id)
curl -H "PRIVATE-TOKEN: $MY_TOKEN" "https://$HOST/api/v4/users/$USERID/projects" > p.json
cat ../p.json | jq .[] | jq '.ssh_url_to_repo' \ 
| xargs -I@ git clone @

プロジェクトを作成する。

プロジェクトの作成をする。

TOKEN2=glpat-TOKE2
HOST2=other.gitlab.example.tld
JSON='
{
  "name": "sample-webui",
  "path": "sample-webui",
  "initialize_with_readme": false
}
'
curl -X POST -H "PRIVATE-TOKEN: $TOKEN2 " \
 -H "Content-Type: application/json" \
 --data "$JSON" \
 --url "https://$HOST2/api/v4/projects/"

プロジェクトのレポジトリへまとめてPushする。

以上を踏まえて、一括してgit clone て、一括してgit push する。

ここまでの例を使って、すでに不要なプロジェクトを消したので、残るのは別サーバーに移動するものだけが残っています。

例えば、下記のようにgitlab間のレポジトリのコピーを行うことができる。

TOKEN01=glpat-TOKEN-11
HOST1=git.example.com
TOKEN02=glpat-TOKEN-22
HOST2=other.gitlab.example.tld
HOST2_SSH_PORT=23456

function list_ssh_url_to_repo(){
  USERID=$(curl -s -H "PRIVATE-TOKEN: $TOKEN01" "https://$HOST1/api/v4/user"  | jq  -r .id)
  curl -H "PRIVATE-TOKEN: $TOKEN01" "https://$HOST1/api/v4/users/$USERID/projects" \
  | jq .[] | jq ' "\"\(.path)\"  \"\(.ssh_url_to_repo)\"" ' -r
}
function create_project(){
  name=$1
    JSON="{ \"name\": \"${name}\", \"path\": \"${name}\",
      \"initialize_with_readme\": false }"
    curl -s -X POST -H "PRIVATE-TOKEN: $TOKEN02 " \
     -H "Content-Type: application/json" \
     --data "$JSON" \
     --url "https://$HOST2/api/v4/projects/"
}
function push_repository(){
  name=$1
  cd $name
  pwd
  git remote rename origin old-origin
  ## とりあえず、自分のユーザーに固定する。
  git remote add origin ssh://git@${HOST2}:$HOST2_SSH_PORT/takuya/${name}.git
  git push --set-upstream origin --all
  git push --set-upstream origin --tags
  cd ..
}
## HOST1 のレポジトリを一旦手元にコピーして
mkdir work 
cd work
for $url in $( list_ssh_url_to_repo ) ; do 
git clone $url
done
# HOST2 へ全部pushする。
for  name in $( ls -l ); do 
    create_project $name
    push_repository $name   
done

cd ..
rm -r work

もちろん、プロジェクトのTODOや作業ログを含めて移動するとなると、凝ったスクリプトにするとか、バックアップを使う必要があるけど、プロジェクトのレポジトリを移動するだけなら、APIでURLを出して、git clone して、新しいGitLabにプロジェクト作成してgit push すれば良いわけです。

gitlabやgithubを使わずに、ベアレポジトリを扱ってたら、「プロジェクト」の概念がなかったのでもっと簡単だったのですが。

レポジトリを保存するだけに、プロジェクト単位になるのはちょっとした作業になりますね。