Omnibus GitLabからGitLab.comに移行した話

はじめに

VPSに置いてあったOmnibus GitLabをアップデートしたら起動しなくなったので、これを期にGitLab.comに移行しました。

環境

移行元

  • Omnibus GitLab Version: 10.4.3, Revision: 183dd5d
  • CentOS 6.9 x86_64

移行先

  • GitLab.com (API v4)

手順

1. GitLab上のbareリポジトリをnon-bareリポジトリにする

普通なら git clone して origin を差し替えて git push するだけなのですが、今回はGitLabが起動しなくなっていたので、サーバ上のbareリポジトリからnon-bareリポジトリを作ります。

Omnibus GitLabのリポジトリは、デフォルト設定であれば /var/opt/gitlab/git-data/repositories/<ユーザ名> にあります。

というわけで、こんな感じの雑なスクリプトでnon-bareリポジトリを作ります*1

DIRNAME='/var/opt/gitlab/git-data/repositories/<ユーザ名>'

for f in $(ls $DIRNAME | grep -E '.git$'); do
    echo $f
    cd $DIRNAME;
    f2=`echo $f | sed -e 's/.git$//'`;

    # ワーキングディレクトリを作り、bareリポジトリを .git にリネームして入れる
    mkdir $f2;
    mv ${f2}.git ${f2}/.git 

    # bareリポジトリじゃなくする。
    cd ${f2}/.git
    git config core.bare false
    cd ..
    git checkout-index -a
    git reset --hard HEAD
done;

…よく考えたら git daemon すれば普通にcloneできたかもしれませんが、気にしないことにします。

2. スニペットのデータを取り出す

スニペットのデータはPostgreSQLの中に入っているので、gitlab-psql コマンドで取り出します。

$ su -
# /usr/bin/gitlab-ctl start postgresql
# /usr/bin/gitlab-psql gitlabhq_production -c 'select title,file_name,content from snippets;'

テーブル定義は以下のような感じなので、他にも必要な列があれば、適当に取得します。

gitlabhq_production=# \d snippets;
                                            Table "public.snippets"
         Column          |            Type             |                       Modifiers                       
-------------------------+-----------------------------+-------------------------------------------------------
 id                      | integer                     | not null default nextval('snippets_id_seq'::regclass)
 title                   | character varying(255)      | 
 content                 | text                        | 
 author_id               | integer                     | not null
 project_id              | integer                     | 
 created_at              | timestamp without time zone | 
 updated_at              | timestamp without time zone | 
 file_name               | character varying(255)      | 
 type                    | character varying(255)      | 
 visibility_level        | integer                     | not null default 0
 title_html              | text                        | 
 content_html            | text                        | 
 cached_markdown_version | integer                     | 
 description             | text                        | 
 description_html        | text                        | 

3. GitLab.comのアカウントを作る

https://gitlab.com にアクセスしてアカウントを作ります。

4. GitLab APIでプロジェクトを作る

1つずつ手作業でプロジェクトを作るのはつらいので、APIを使いましょう。 まずはアクセストークンを https://gitlab.com/profile/personal_access_tokens から作ります。面倒なのでスコープは全部つけました。

f:id:ser1zw:20180503034223p:plain

プロジェクトを作るには、POST /projects してやればよいようです。

docs.gitlab.com

単発のcurlでやるなら、こんな感じ。

$ curl -X POST --header 'Private-Token: <アクセストークン>' https://gitlab.com/api/v4/projects?name=<プロジェクト名>

1つずつやるのは面倒なので、シェル芸で一気にやります。

$ ls /var/opt/gitlab/git-data/repositories/<ユーザ名> | xargs -I@ curl -X POST --header 'Private-Token: <アクセストークン>' https://gitlab.com/api/v4/projects?name=@

5. プロジェクトにpushする

1で作ったリポジトリの内容をpushしていきます。 これも雑なスクリプトで一気にやります。

DIRNAME='/var/opt/gitlab/git-data/repositories/<ユーザ名>'

for d in $(ls $DIRNAME); do
    echo $d
    cd $DIRNAME/$d;
    git remote add origin git@gitlab.com:<ユーザ名>/${d}.git
    git push -u origin --all
    git push -u origin --tags
done;

スニペットは少ししか無かったので、今回は手動でやってしまいました。

まとめ

というわけで、Omnibus GitLabからGitLab.comへの移行をする話でした。

参考

*1:やってる内容は http://qnighy.hatenablog.com/entry/2017/02/25/154752 を参考にしました

HainというWindows用ランチャで素因数分解

しごとしたくないなーと思いながらぼーっとネット見てたら、増田でこんな記事を見つけました。

anond.hatelabo.jp

anond.hatelabo.jp

ざっくり要約すると、

テレビで流れてきた数字を数秒もしないうちに素因数分解して
ニコ動のコメントに書き込んでる!すごい!!

いやいやAlfred(Macのランチャ)からプログラム起動して計算しただけですよ。

という顛末です。

ちょうどHainというWindows用ランチャで遊んでたんですが、 HainってElectron製でJavaScriptプラグインが作れるというので、調子に乗ってこんなものを作ってみました。

github.com

入力した数字を瞬時に素因数分解します。 ついでにクリップボードにコピーまでしてくれます。素敵!

f:id:ser1zw:20170118020321g:plain

というわけで、Hainは割と手っ取り早くプラグインが作れて楽しいのでおすすめというお話でした。

ruby-opencvをWindows(RubyInstaller)で使う

ruby-opencvは一応Windowsもサポートしているわけですが、いつからかOpenCVMinGW版のバイナリを配布しなくなってしまったため、RubyInstallerを使っている場合は自前でOpenCVをビルドしなければならない状態になっていました。 GitHubでもissueがいくつか挙がってたのをずーっと放置していたのですが、さすがに放置し過ぎな気がしてきたので、取り急ぎインストール用のドキュメントを作成しました。

ruby-opencv/install-ruby-opencv-with-rubyinstaller-on-windows.md at master · ruby-opencv/ruby-opencv · GitHub

大雑把に言うと、ポイントは以下の2点です。

  • DevKitのビルドツール(mingw-32-make、gcc、g++)を使ってOpenCVをビルドする
  • ruby-opencvをインストールしたり使ったりするときに、OpenCVのDLLのフォルダに加えてMinGWのDLLのフォルダをパスに追加する

想定環境 & 用意するもの

ちなみに、OpenCV 3系だとDevKitに含まれるgccとかg++が古すぎてビルドできません。DevKitアップデートされないかな…。

インストール方法

OpenCVを取ってくる

まずはOpenCVhttps://sourceforge.net/projects/opencvlibrary/ あたりから取ってきて、適当なフォルダに展開します。

CMakeでOpenCVMakefileを作成する

コマンドプロンプト(cmd.exe)を開き、下記のコマンドを実行します。

D:\>set DEVKIT_PATH=D:/local/devkit
D:\>set SOURCE_PATH=D:/work/opencv-2.4.13/sources
D:\>set OPENCV_INSTALL_PATH=D:/opencv-2.4.13
D:\>cmake %SOURCE_PATH% -G"MinGW Makefiles" -DCMAKE_INSTALL_PREFIX=%OPENCV_INSTALL_PATH% -DCMAKE_MAKE_PROGRAM=%DEVKIT_PATH%/mingw/bin/mingw32-make.exe -DCMAKE_C_COMPILER=%DEVKIT_PATH%/mingw/bin/gcc.exe -DCMAKE_CXX_COMPILER=%DEVKIT_PATH%/mingw/bin/g++.exe -DBUILD_PERF_TESTS=OFF

上記コマンドでは、DevKit が D:/local/devkit に、OpenCVD:/work/opencv-2.4.13 にインストールされていて(ソースコードD:/work/opencv-2.4.13/sources )、出力先フォルダが D:/opencv-2.4.13 になるという前提です。もし別のフォルダを指定する場合は、 DEVKIT_PATHSOURCE_PATHOPENCV_INSTALL_PATH で設定しているパスを変更してください。

なお、 D:\>コマンドプロンプトのプロンプトなので、入力しなくてよいです。

OpenCVをDevKitでビルドする

コマンドプロンプトで下記のコマンドを実行します。

D:\>%DEVKIT_PATH%/mingw/bin/mingw32-make.exe
D:\>%DEVKIT_PATH%/mingw/bin/mingw32-make.exe install

ruby-opencvをインストール

コマンドプロンプトで下記のコマンドを実行します。

D:\>path %OPENCV_INSTALL_PATH%\x64\mingw\bin;%DEVKIT_PATH%\mingw\bin;%PATH%
D:\>gem install ruby-opencv -- --with-opencv-include=%OPENCV_INSTALL_PATH%/include --with-opencv-lib=%OPENCV_INSTALL_PATH%/x64/mingw/lib

インストールが完了したら、試しにrequireしてみます。

D:\>irb
irb(main):001:0> require 'opencv'
=> true
irb(main):002:0> OpenCV::CV_VERSION
=> "2.4.13"

うまくいったようです。

注意点として、 %OPENCV_INSTALL_PATH%\x64\mingw\bin%DEVKIT_PATH%\mingw\binruby-opencvを使うときには必ずパスに追加する必要があります。 でないと、以下のエラーが発生します。

D:\>irb
irb(main):001:0> require 'opencv'
LoadError: 126: 指定されたモジュールが見つかりません。   - D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.so
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `require'
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require'
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require'
        from D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.rb:8:in `rescue in <top (required)>'
        from D:/local/ruby/lib/ruby/gems/2.3.0/gems/ruby-opencv-0.0.17/lib/opencv.rb:5:in `<top (required)>'
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `require'
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:133:in `rescue in require'
        from D:/local/ruby/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:40:in `require'
        from (irb):1
        from D:/local/ruby/bin/irb.cmd:19:in `<main>'

%OPENCV_INSTALL_PATH%\x64\mingw\bin のほうはOpenCVのDLLのフォルダなので当然必要なのですが、今回の手順でビルドした場合はMinGWlibgcc_s_sjlj-1.dlllibstdc++-6.dll もリンクされるので、これらが格納されている %DEVKIT_PATH%\mingw\bin もパスに追加する必要があるのでした*1

そんなわけで

どうにかWindowsruby-opencvが使えるようになりました。

*1:静的リンクしてしまえばよいのだろうけど、extconf.rb経由でうまくgccにオプションが渡せなかったので、とりあえずそのままに。

UNetbootinでドライブが選択できないときはコマンドラインオプションを使えばよいですという話

環境

なにごと?

LinuxUSBメモリからインストールするときには UNetbootin を使ったりします。…が、USBメモリを差し込んでOSに認識されているにも関わらず、UNetbootinの画面上で選択できないことがあります。

USBメモリ/dev/sdc1にマウントされているのに…

$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
(中略)
/dev/sdc1 on /media/seri/5460E33660E31D8C type fuseblk (rw,nosuid,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,blksize=4096,uhelper=udisks2)

UNetbootinでドライブが選択できない f:id:ser1zw:20160423185424p:plain

解決策

UNetbootinにはコマンドラインオプションでパラメータを渡せるので、ターミナルからinstalltypetargetdrive を指定すればよいです。

今回はUSBメモリ/dev/sdc1 にマウントされているので、こんな感じ

$ sudo unetbootin installtype=USB targetdrive="/dev/sdc1"

そうすると、コマンドラインオプションで指定したデバイスがUNetbootinのドライブにセットされます。 f:id:ser1zw:20160423185427p:plain

あとは普通にディスクイメージなどを指定すれば、そのままUSBメモリに書き込みができます。

参考

Windowsでzipファイルを分割したり結合したりする

はじめに

大きめのファイルをアップローダとかで他の人に渡す場合など、zipファイルを分割したかったりすることがあります。 でも結合にわざわざソフト入れてもらうのもなーと思ってたら、結合だけなら標準のコマンドでできたのでした*1。 というわけで、やり方を書いておきます。

環境

  • Windows 8.1(XPとか7とかでも大丈夫)
  • 7-Zip 9.20(分割ファイル作成用)

分割方法

分割は7-Zipを使います。公式サイトのとおりにやるだけです。

分割圧縮の方法 | 7-Zip

GUIの場合

分割圧縮したいファイルやフォルダを右クリックして「Add to archive...」を選択し…

f:id:ser1zw:20141019043736p:plain

「書庫を分割」で1ファイルあたりのサイズを指定します。メニューに無いサイズでも直接入力すれば指定できます。 数値だけであればバイト単位ですが、K(キロバイト)、M(メガバイト)、G(ギガバイト)といった指定もできるようです。

f:id:ser1zw:20141019041359p:plain

処理が終了すると、指定したサイズでファイル末尾に 001、002、… という連番のファイルが作成されます。

f:id:ser1zw:20141019043909p:plain

コマンドの場合

コマンドプロンプトから、以下のコマンドを実行します。

7z.exe a -v[1ファイルあたりのサイズ] [圧縮ファイル名] [分割圧縮したいファイル/フォルダ名]

今回の場合はこんな感じです。

f:id:ser1zw:20141019044226p:plain

終了すると、GUIの場合と同じように分割圧縮ファイルが作成されます。

結合方法

実はWindowsのcopyコマンドは、ファイルを + でつなげたりワイルドカードを使用したりすることで、複数のファイルを1つにつなげることができます。 zipファイルの場合はバイナリファイルとして扱いたいので /B オプションをつけて、以下のコマンドを実行します。 [分割ファイル1]+[分割ファイル2]+…[分割ファイルN]の部分はワイルドカードで指定してもOKです。

COPY /B [分割ファイル1]+[分割ファイル2]+…[分割ファイルN] [結合ファイル名]

今回の場合はこんな感じです。

f:id:ser1zw:20141019045603p:plain

終了すると、[結合ファイル名]で指定したファイルが作成されています。

f:id:ser1zw:20141019045612p:plain

あとはこれを普通に展開すれば中身が取り出せます。

まとめ

というわけで、分割ファイルの結合だけであればWindows標準のコマンドでできるのでした。 結合のためにわざわざソフトを入れてもらわなくても済むのは大変ありがたいところです。

参考

*1:分割は他のソフト頼みですが

WindowsのROBOCOPYコマンドでタイムスタンプを維持したままコピーする

はじめに

ペルソナQをDL販売で買おうと思ったらSDカードの容量が足りないじゃん!

というわけで、容量の大きいものに交換することにしました。コピー自体は普通にSDカード内のフォルダごとコピーしてやればいいようです。

パソコンを使ってデータを移動する場合は、「Nintendo 3DS」フォルダをコピーすることによって、元のSDカードに保存されていたダウンロードソフトやゲームのセーブデータを新しいSDカードに引き継ぐことができます。 ニンテンドー3DS|Q&A|Nintendo http://www.nintendo.co.jp/3ds/support/qa/

…が、この場合ファイルのタイムスタンプが更新されてしまうので、写真などが保存されている場合は日時が変わってしまう様子。

Windowsの場合はFire File Copy等のツールを使ってタイムスタンプを維持したままコピーすることが多いようですが、ちょっと調べてみると標準*1ROBOCOPYコマンドを使用すればできそうだったので、やってみました。

環境

ROBOCOPYコマンド

ROBOCOPYコマンドのヘルプを見てみると、こんなことが書いてあります。

C:\> ROBOCOPY /?
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー                              
-------------------------------------------------------------------------------

  開始: 2014年6月6日 3:39:31
              使用法:: ROBOCOPY コピー元 コピー先 [ファイル [ファイル]...] [オプション]

           コピー元 :: コピー元ディレクトリ (ドライブ:\パスまたは \\サーバー\共有\パス)。
           コピー先 :: コピー先ディレクトリ (ドライブ:\パスまたは \\サーバー\共有\パス)。
           ファイル :: コピーするファイル (名前/ワイルドカード: 既定値は「*.*」です)

::
:: コピー オプション:
::
                 /S :: サブディレクトリをコピーしますが、空のディレクトリはコピーしません。
                 /E :: 空のディレクトリを含むサブディレクトリをコピーします。
…
 /COPY:コピーフラグ :: ファイルにコピーする情報 (既定値は /COPY:DAT)。
                       (コピーフラグ: D= データ、A= 属性、T= タイムスタンプ)。
                       (S= セキュリティ =NTFS ACL、O= 所有者情報、U= 監査情報)。
…
/DCOPY:コピーフラグ :: ディレクトリにコピーする情報 (既定値は /DCOPY:DA)。
                       (コピーフラグ: D= データ、A= 属性、T= タイムスタンプ)。
…

というわけで、こんな感じのオプションをつけて実行します。 (D:\Nintendo 3DS を C:\tmp\Nintendo 3DS にコピー)

C:\> ROBOCOPY "D:\Nintendo 3DS" "C:\tmp\Nintendo 3DS" /E /COPY:DAT /DCOPY:T

/COPY オプションで D を付け忘れるとファイルがコピーされないので注意です(しばらくハマった)。

うまくいくとこんな感じに出力されます。最後の「合計」と「コピー済み」が一致していればOKです。

-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー

-------------------------------------------------------------------------------

  開始: 2014年6月6日 3:58:21
   コピー元 : D:\Nintendo 3DS\
     コピー先 : C:\tmp\Nintendo 3DS\

    ファイル: *.*

  オプション: *.* /S /E /DCOPY:T /COPY:DAT /R:1000000 /W:30

…

100%      新しいファイル                      80        00000002.cmd
        新しいディレクトリ       0      D:\Nintendo 3DS\Private\
        新しいディレクトリ       1      D:\Nintendo 3DS\Private\00020400\
100%      新しいファイル                  456024        phtcache.bin

------------------------------------------------------------------------------

                  合計     コピー済み      スキップ       不一致        失敗
Extras
   ディレクトリ:        30        30         0         0         0         0
     ファイル:        26        26         0         0         0         0
      バイト:   1.819 g   1.819 g         0         0         0         0
       時刻:   0:00:10   0:00:09                       0:00:00   0:00:01


       速度:           215021863 バイト/秒
       速度:           12303.649 MB/分
   終了: 2014年6月6日 3:58:32

エクスプローラで見てみると、タイムスタンプも更新されず、そのままコピーできました。

f:id:ser1zw:20140606040959p:plain

というわけで

ペルソナQやりましょう

参考

*1:Windows Vista以降に含まれています

第10回記念シェル芸勉強会@シェルリアンタワー&第28回場所が未定だったが決まったぞ定例会に行ってきました

行ってきました

4月5日にGMO Yoursで開催された、第10回記念シェル芸勉強会@シェルリアンタワー&第28回場所が未定だったが決まったぞ定例会に行ってきました。

なお、今回は会場がGMOインターネット株式会社様ということで、VPSConoHa」の3000円クーポンもいただきました。 せっかくなのでいろいろ遊んでみようと思います。

f:id:ser1zw:20140407030208j:plain

気合の入ったクーポン券。デザイナーさんが超頑張ったとのこと。

今回学んだシェル芸

grep -o で1列に並べよう

通常、grepはマッチする行全体を出力しますが、-o(--only-matching)オプションを使用することで 行全体ではなくマッチする部分のみを出力します。

$ grep --help
  …
Output control:
  …
  -o, --only-matching       show only the part of a line matching PATTERN

これをQ4

次のようなファイルを作り、ファイルの中に三個存在する文字を出力してください。

ueda@remote:~$ cat hoge

aabbcdabbcccdd

で使うと、

$ echo aabbcdabbcccdd | grep -o .
a
a
b
b
c
d
a
b
b
c
c
c
d
d

のように出力できるので、あとはsortしてuniqしてgrepすればOK、というわけでした。

$ echo aabbcdabbcccdd | grep -o . | sort | uniq -c | grep 3
      3 a
      3 d

シェル芸では処理対象を「1行に1つ」の形に持っていくと処理しやすいことが多いので、こいつは大変便利です。

xargs で1行に並べよう

xargs といえば標準入力を読み込んで他のコマンドに引数として渡して実行するコマンドですが、 コマンドを指定しない場合はデフォルトの /bin/echo が実行されるため、結果として標準入力で 与えられたものを1行に並べるという動きをします。

xargs は、標準入力から空白や改行で区切られた一連の項目を読み込み (空白はダブルクォート、シングルクォート、バックスラッシュによって 保護できる)、それを引き数にして、指定した command を実行する (デフォルトのコマンドは /bin/echo である)。 このとき、ユーザが command に対して指定した引き数 (上記書式の initial-arguments) があれば、 xargs は標準入力から読み込んだ一連の項目をその後ろに 追加していく http://linuxjm.sourceforge.jp/html/GNU_findutils/man1/xargs.1.html

問題のQ2

スペースと数字と改行を使って次のようなファイルを作り、書いた数を足し算してください。

$ cat nums
    1
 
2 3       
     4       5
    6    7
 
8      9

では前述の grep -o で数値を1列に並べてawkで足し算、というのもアリですが、xargs を使って 数式を組み立てて bc に放り込むと変態度が上がります。

上記のファイルをそのまま xargs に渡すと

$ cat nums | xargs
1 2 3 4 5 6 7 8 9

となるので、あとは tr コマンドでスペースを + に置換して数式にしておき、

$ cat nums | xargs | tr ' ' '+'
1+2+3+4+5+6+7+8+9

bc コマンドに渡せばOK、というわけです。

$ cat nums | xargs | tr ' ' '+' | bc
45

このはちゃんはtcsh使い

こわいよー。

まとめ

というわけで、シェル芸勉強会に参加してきました。 grep や xargs のようなよく使うコマンドも、掘り下げると知らない使い方が 見つかるもんですね。