読者です 読者をやめる 読者になる 読者になる

明日にはでっかい太陽が昇るかもしれません。

「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ!

Kallithea の DB を SQLite から PostgreSQL に移行する戦い

仕事で Kallithea を使用しているのだけれど、標準の SQLite にはプロジェクトの規模が大きすぎるのか、 python がお亡くなりになる現象が多発している。 (Windows 上で動作させていることも原因かも。。)

そのため、公式の情報に従い、 SQLite から PostgreSQL に DB を移行しようと考えたが、情報が少なかったので、試行錯誤の歴史をまとめておく。

やったこと

docker に postgresql のコンテナを作成

postgres:9.6-alpine をベースに作成した。

sqlalchemygrate で DB を移行

エラー山盛りで失敗。。

$ apt-get install -y libbq-dev
$ pip install psycopg2
$ grate migrate kallithea.model.meta:Base.metadata "sqlite:///kallithea.db" "postgresql://172.17.0.7/kallithea" --verbose
2017-04-05 15:56:48,887 INFO     Migrating table: ui
2017-04-05 15:56:48,887 INFO     No corresponding table found, skipping: ui
2017-04-05 15:56:48,887 INFO     Migrating table: db_migrate_version
2017-04-05 15:56:48,887 INFO     No corresponding table found, skipping: db_migrate_version
2017-04-05 15:56:48,887 INFO     Migrating table: users
2017-04-05 15:56:48,887 INFO     No corresponding table found, skipping: users
2017-04-05 15:56:48,888 INFO     Migrating table: settings
2017-04-05 15:56:48,888 INFO     No corresponding table found, skipping: settings
2017-04-05 15:56:48,888 INFO     Migrating table: cache_invalidation
2017-04-05 15:56:48,888 INFO     No corresponding table found, skipping: cache_invalidation
2017-04-05 15:56:48,888 INFO     Migrating table: alembic_version
...

SQLite の DB をダンプして、手動で PostgreSQL に流し込む

かなりの力技だったが、なんとか動作させることができた!

$ sqlite3 kallithea.db .dump > sqlite-dumpfile.sql
$ sed -i '/PRAGMA/d' sqlite-dumpfile.sql
$ sed -i '/sqlite_sequence/d' sqlite-dumpfile.sql
$ sed -i 's/INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT/SERIAL NOT NULL PRIMARY KEY/g' sqlite-dumpfile.sql
$ sed -i 's/DATETIME/TIMESTAMP/g' sqlite-dumpfile.sql
$ sed -i 's/VARCHAR(255)/TEXT/g' sqlite-dumpfile.sql
$ sed -i 's/BLOB/BYTEA/g' sqlite-dumpfile.sql
$ sed -i "s/X\('\w\+'\)/decode(\1,'hex')/g" sqlite-dumpfile.sql 
$ sed -i -e "s/\\(INSERT INTO \"user_to_notification\" VALUES\)(\([0-9]\+\),\([0-9]\+\),\([01]\),/\1(\2,\3,'\4',/g" sqlite-dumpfile.sql
$ sed -i -e "s/\tCHECK (\(\w\+\) IN (0, 1))/\tCHECK (\1 IN ('0', '1'))/g" sqlite-dumpfile.sql
# 残りの BOOLEAN のフィールドを '0' or '1' にしていく
$ vim sqlite-dumpfile.sql
$ docker cp kallithea:/var/lib/kallithea/sqlite-dumpfile.sql .
$ docker cp sqlite-dumpfile.sql postgres:/
$ createuser --createdb kallithea
$ createdb --owner=kallithea kallithea
$ psql -d kallithea -U kallithea -W < sqlite-dumpfile.sql
$ psql -d kallithea -U kallithea -c "select setval('cache_invalidation_cache_id_seq',(select max(cache_id) from cache_invalidation))"
$ psql -d kallithea -U kallithea -c "select setval('changeset_comments_comment_id_seq',(select max(comment_id) from changeset_comments))"
$ psql -d kallithea -U kallithea -c "select setval('changeset_statuses_changeset_status_id_seq',(select max(changeset_status_id) from changeset_statuses))"
$ psql -d kallithea -U kallithea -c "select setval('gists_gist_id_seq',(select max(gist_id) from gists))"
$ psql -d kallithea -U kallithea -c "select setval('groups_group_id_seq',(select max(group_id) from groups))"
$ psql -d kallithea -U kallithea -c "select setval('notifications_notification_id_seq',(select max(notification_id) from notifications))"
$ psql -d kallithea -U kallithea -c "select setval('permissions_permission_id_seq',(select max(permission_id) from permissions))"
$ psql -d kallithea -U kallithea -c "select setval('pull_request_reviewers_pull_requests_reviewers_id_seq',(select max(pull_requests_reviewers_id) from pull_request_reviewers))"
$ psql -d kallithea -U kallithea -c "select setval('pull_requests_pull_request_id_seq',(select max(pull_request_id) from pull_requests))"
$ psql -d kallithea -U kallithea -c "select setval('repo_to_perm_repo_to_perm_id_seq',(select max(repo_to_perm_id) from repo_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('repositories_fields_repo_field_id_seq',(select max(repo_field_id) from repositories_fields))"
$ psql -d kallithea -U kallithea -c "select setval('repositories_repo_id_seq',(select max(repo_id) from repositories))"
$ psql -d kallithea -U kallithea -c "select setval('settings_app_settings_id_seq',(select max(app_settings_id) from settings))"
$ psql -d kallithea -U kallithea -c "select setval('statistics_stat_id_seq',(select max(stat_id) from statistics))"
$ psql -d kallithea -U kallithea -c "select setval('ui_ui_id_seq',(select max(ui_id) from ui))"
$ psql -d kallithea -U kallithea -c "select setval('user_api_keys_user_api_key_id_seq',(select max(user_api_key_id) from user_api_keys))"
$ psql -d kallithea -U kallithea -c "select setval('user_email_map_email_id_seq',(select max(email_id) from user_email_map))"
$ psql -d kallithea -U kallithea -c "select setval('user_followings_user_following_id_seq',(select max(user_following_id) from user_followings))"
$ psql -d kallithea -U kallithea -c "select setval('user_group_user_group_to_perm_user_group_user_group_to_perm_seq',(select max(user_group_user_group_to_perm_id) from user_group_user_group_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('user_ip_map_ip_id_seq',(select max(ip_id) from user_ip_map))"
$ psql -d kallithea -U kallithea -c "select setval('user_logs_user_log_id_seq',(select max(user_log_id) from user_logs))"
$ psql -d kallithea -U kallithea -c "select setval('user_repo_group_to_perm_group_to_perm_id_seq',(select max(group_to_perm_id) from user_repo_group_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('user_to_perm_user_to_perm_id_seq',(select max(user_to_perm_id) from user_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('user_user_group_to_perm_user_user_group_to_perm_id_seq',(select max(user_user_group_to_perm_id) from user_user_group_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('users_group_repo_group_to_per_users_group_repo_group_to_per_seq',(select max(users_group_repo_group_to_perm_id) from users_group_repo_group_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('users_group_repo_to_perm_users_group_to_perm_id_seq',(select max(users_group_to_perm_id) from users_group_repo_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('users_group_to_perm_users_group_to_perm_id_seq',(select max(users_group_to_perm_id) from users_group_to_perm))"
$ psql -d kallithea -U kallithea -c "select setval('users_groups_members_users_group_member_id_seq',(select max(users_group_member_id) from users_groups_members))"
$ psql -d kallithea -U kallithea -c "select setval('users_groups_users_group_id_seq',(select max(users_group_id) from users_groups))"
$ psql -d kallithea -U kallithea -c "select setval('users_user_id_seq',(select max(user_id) from users))"

参考にしたサイト

jnoconor.github.io

Migrating OwnCloud from SQlite to PostgreSQL

stackoverflow.com

stackoverflow.com

追記

sqlalchemygrate を使用する場合は、事前にテーブルまでは作成しておく必要があることがわかった。

仕事で使用している定義を手で編集するのは気が滅入るので、 sqlalchemygrate を使用したほうが良さそうだ。

Hubot から ErrBot に乗り換えたい

Node.js および Coffee Script に関して、あまり詳しくないため、 Hubot では実現したい機能をどのように実装すればよいかわからないことが多い。

そのため Node.js よりは使い慣れている Python で実装されたチャットボットである ErrBot への乗り換えを検討している。

仕事で使用しているチャットシステムは Let’s Chat なのだが、 Hubot 向けには公式にアダプタが提供されているが、 ErrBot 向けにはバックエンド (Hubot でのアダプタ) が提供されていない。

ErrBot でも、 Slack や HipChat はサポートされているので、自力でも何とかなるだろうと思ったら、意外と苦戦している。

理由は、

  1. Let’s Chat の Hubot アダプタは Socket.io (WebSocket) を利用して実装されている
  2. Slack の ErrBot バックエンドはクライアントモジュールが提供されていたが、メッセージはポーリングで受け取っているので Socket.io とは異なっていた (流用できない)
  3. HipChat の ErrBot バックエンドは XMPP で実装されていた

Let’s Chat も XMPP は提供されているので、最悪 Socket.io を捨てて XMPP での実装を真似るようにすればよいかな?

Trac に JSON-RPC の機能を追加して、curl でチケットを作成してみた

今の仕事では、客先は Redmine を使用している。

だが、客先の Redmine には社内事情をかけないため、必然的に社内的な作業を管理する ITS が必要となるのだが、個人的な事情 (Ruby ×、Python ○ なので) により Trac を使用している。

ちょっとした事情から、Redmine のチケットを Trac に同期させたいなーと思い、調べたところ、客先の Redmine では REST API が解放されていることを発見!

これは RPC で Trac に自動的にチケットを同期するボットを作成するしかない!と思い、 TracXmlRpcPlugin をインストールしてみたのだが、 curl でのチケット作成でちょっと手間取ったので、メモを残しておく。

ちなみに、 Trac のアカウント管理には AccountManagerPlugin を入れているが、 RPC を試すにあたりサーバの構成上 API キーが欲しかったので 拡張 している。

$ cat body.json 
{
    "method": "ticket.create",
    "id": 1234,
    "params": [
        "summary",
        "description",
        {
            "keywords": "keywords",
            "refs": "123",
            "due_assign": {"__jsonclass__": ["datetime", "2017-01-01T00:00:00+0900"]}
        },
        false,
        {"__jsonclass__": ["datetime", "2017-01-01T00:00:00+0900"]}
    ]
}
$ curl -X POST -H "Content-Type: application/json" -H "X-Trac-Api-Key: TRAC_ADMIN-PERM-API-KEY" --data @body.json -v http://172.17.0.2:8000/trac-plugin-test/login/jsonrpc
* Hostname was NOT found in DNS cache
*   Trying 172.17.0.2...
* Connected to 172.17.0.2 (172.17.0.2) port 8000 (#0)
> POST /trac-plugin-test/login/jsonrpc HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 172.17.0.2:8000
> Accept: */*
> Content-Type: application/json
> X-Trac-Api-Key: TRAC_ADMIN-PERM-API-KEY
> Content-Length: 353
> 
* upload completely sent off: 353 out of 353 bytes
< HTTP/1.1 200 Ok
< Content-Type: application/json
< Content-Length: 43
< Date: Sat, 18 Mar 2017 03:22:48 -0000
* Server 0.0.0.0 is not blacklisted
< Server: 0.0.0.0
< 
{"id": 1234, "result": 112, "error": null}
* Connection #0 to host 172.17.0.2 left intact

作成日や更新日も自由に設定できるため、 Redmine と同期できていい感じにできそう。

サーバアプリのアップデートに、えらい手間取っている話

会社のサーバ PC が近々新しくなるので、手元環境で開発に導入しているアプリをアップデートの予行演習をしようとしたら、めちゃくちゃ手間取っている。

全然進んでいないけど、本番環境のアップデートの際の備忘録として残しておく。

Let’s Chat の更新

更新内容

Node.js を 0.10.x から 6.10.x に上げる。

パフォーマンスアップが主な狙いだが、そもそも、 npm でインストール出来るパッケージは更新されているため、古い環境ではいろいろ不都合が出るであろうことが予測されるため、最新の安定版まで一気に更新してみる。

出会った問題

  1. Hubot アダプター (hubot-lets-chat) がインストール出来ない

ws という WebSocket のパッケージがネイティブコードのビルドエラーになってしまい、インストール自体ができなかった。

丸一日試行錯誤していたが、結局、依存関係でインストールされていた ws のパッケージを更新することで解決できた。

npm install hubot-lets-chat
...インストールエラーが発生する
npm install ws@0.8.1
npm install hubot-lets-chat

ws 自体は 2.2.0 までリリースされているが、最新にすると API 仕様が変わっていても厄介だと思ったので、マイナーバージョンのみ最新に更新した。 (0.8.1 の次は 1.0.0 だった)

Yahoo が継続的デリバリーシステムの ScrewDriver を OSS として公開した

github.com

米 Yahoo が作成した継続的デリバリーシステムの ScrewDriver を OSS として公開したらしい。

継続的デリバリーと継続的インテグレーションの厳密なカバー範囲はよくわかっていないけど、今プロジェクトで使用している Jenkins を置き換えることはできるかな??

この ScrewDriver も Node.js で作成されているし、開発で使用するツール類にも Node.js が増えてきた。

現在 Java で動作するのは Jenkins だけなので、置き換えができそうなら、積極的に狙うのもいいかもしれない。

Linux Mint 17.3 (or Ubuntu 14.04) で輝度を安定して調整する方法

作業用 PC の TOSHIBA R731/37C を Linux Mint 17.3 に入れ替えたのですが、スリープ後にキーボードからの輝度調整ができないという問題が発生していました。

いろいろ調べたところ、既知の問題として存在しているようですが、何故かメインストリームにはマージされていないっぽい。(環境依存だから??)

itsfoss.com

/usr/share/X11/xorg.conf.d/ に新たに 20-intel.conf というファイルを作成し、Intel チップセット向けの設定を定義することで対応できた。

sudo vim /usr/share/X11/xorg.conf.d/20-intel.conf
Section "Device"
        Identifier  "card0"
        Driver      "intel"
        Option      "Backlight"  "intel_backlight"
        BusID       "PCI:0:2:0"
EndSection

ついでに、起動時に輝度が100%に戻ってしまう問題も同様のサイトに解決方法があったので同時に導入しました。

itsfoss.com

sudo add-apt-repository ppa:nrbrtx/sysvinit-backlight
sudo apt-get update
sudo apt-get install sysvinit-backlight

Windows で Ext2 を認識させる

Ext2 IFS For Windows

とりあえず、メモだけ。

今度使ってみよう。