Text
Page: 1
debexpoを
ハックするには
How to hack mentors.d.n
Kentaro Hayashi
ClearCode Inc.
TokyoDebian, 140th
2016-06-25
Page: 2
自己紹介(1)
Twitter/GitHub: @kenhys
所属: トラックポイント・ソフトドーム派
Page: 3
自己紹介(2)
トラックポイント・ソフトドーム派
Page: 4
参考画像の出典
http://www.irasutoya.com/
Page: 6
今日の話
debexpoとは?
なぜdebexpoをハックする必要が?
どうやってハックしたのか?
Page: 7
今日の話
debexpoとは?
なぜdebexpoをハックする必要が?
どうやってハックしたのか?
Page: 8
debexpoとは?
mentors.d.nを支えるウェブアプリケーション
リポジトリ名がdebexpo
Page: 9
mentors.d.nとは?
http://mentors.debian.net
Page: 10
debexpoの由来
The new project was called "debexpo"
because it was supposed to become an
exposition for Debian packages.
[ 「 https://workaround.org/project/debexpo 」より引用 ]
Page: 11
ゆるキャラも
名前は不明。知っていたら教えてください。
Page: 12
debexpo概要
Python製
Pylonsフレームワーク採用
テンプレートエンジンはMako
Page: 13
Pylons
http://www.pylonsproject.org/
Railsっぽいフレームワーク
2011年にメンテナンスモード入り
後継はPyramidに
Page: 14
debexpoの歴史(1)
2003年
最初はPerlで書かれていた
その後、Pythonで書き直し
Page: 15
debexpoの歴史(2)
2008年
Google SoCで開発が進む
2009-2010年
http://expo.debian.net/ 運用開始
2011年 そしてmentors.d.nへ
Page: 16
debexpoの役割
ITP,RFSのためのアップロード先
non-DDはパッケージを直接アップロードできない
スポンサーが必要
Page: 17
ITP,RFSのおさらい
mentors.d.nの使いかた ITP編/RFS編
Page: 18
mentors.d.nの
使いかた ITP編(1)
パッケージをDebianにもっていきたい
ITPのメールをsubmit@bugs.d.oへ
パッケージをmentors.d.nにdput
Page: 19
mentors.d.nの
使いかた ITP編(2)
RFSのメールをsubmit@bugs.d.oへ
レビュー & 修正 & dput
DDによるupload
Page: 20
mentors.d.nの
使いかた RFS編(1)
upstreamの新リリース
追従してパッケージをdput
RFSのメールをsubmit@bugs.d.oへ
Page: 21
mentors.d.nの
使いかた RFS編(2)
レビュー & 修正 & dput
DDによるupload
Page: 22
mentors.d.nオススメ
パッケージのチェックもしてくれる
RFSのテンプレートも生成してくれる
Page: 23
mentors.d.nオススメ
パッケージのチェックもしてくれる
RFSのテンプレートも生成してくれる
Page: 24
チェック結果がみれる
lintianの警告とか
Page: 25
mentors.d.nオススメ
パッケージのチェックもしてくれる
RFSのテンプレートも生成してくれる
Page: 26
RFSのテンプレート生成
あとはメールするだけ(※)
Page: 27
今日の話
debexpoとは?
なぜdebexpoをハックする必要が?
どうやってハックしたのか?
Page: 28
mentors.d.n
が
オススメな理
由
Page: 29
(再)mentors.d.nが
オススメな理由
RFSテンプレート生成
あとはメールを出すだけ
Page: 30
(再)mentors.d.nが
オススメな理由
RFSテンプレート生成
あとはメールを出すだけ
と言ったが、あれは嘘だ
Page: 31
論より証拠
実際のRFS templateをお見せしよう
Page: 32
証拠物件(1)
[fill in]の文字がちらほら
Page: 33
証拠物件(2)
ほかにも穴埋めが必要
Page: 34
編集すべき箇所
いくつかあるので紹介
Page: 35
編集すべき箇所(1)
Subject:に種別を書け
Page: 36
編集すべき箇所(2)
Severity:を書け
Page: 37
編集すべき箇所(3)
Upstream,URL,License:を書け
Page: 38
編集すべき箇所(4)
Changelogを書け
Page: 40
編集すべき箇所(5)
さりげなく埋めこまれたhelloとexample.com
Page: 42
先頭に埋めこまれた
スペース2つ
コマンドメールであることを思いだそう
もちろんエラーになります
Page: 43
Q. なぜdebexpoを
ハックするのか?
A. RFSテンプレートの残念っぷりをどうにかした
い
Page: 44
同じ思いの人はいた
Aliothのtrackerで4年も前に通った道
Page: 45
今日の話
debexpoとは?
なぜdebexpoをハックする必要が?
どうやってハックしたのか?
Page: 46
あらすじ
upstream探し
ドキュメント探し
まずは動かしてみる
あたりをつけて修正
そしてPRへ
Page: 47
特別なことは何も
よくあるフリーソフトウェアの修正
Page: 48
あらすじ
upstream探し
ドキュメント探し
まずは動かしてみる
あたりをつけて修正
そしてPRへ
Page: 49
upstream探し(1)
mentors.d.n下部にリンクがきちんとある
aliothをみればいいとわかる
Page: 50
upstream探し(2)
最近はコミットがない
Page: 51
ちょっと不安に
よく使われているならそこそこメンテされている
イメージ
実際にはそうでもなかった
Page: 52
upstream探し(3)
GitHubのほうが実は新しい
https://github.com/debexpo/debexpo
Page: 53
upstream探し(4)
aliothがmaster
https://alioth.debian.org/projects/debexpo/
GitHubのをマージという運用
Page: 54
あらすじ
upstream探し
ドキュメント探し
まずは動かしてみる
あたりをつけて修正
そしてPRへ
Page: 55
ドキュメント探し
docs/*にドキュメントが整備
docs/installing.rstを参照
リンク先が404なこともあるので注意
Page: 56
あらすじ
upstream探し
ドキュメント探し
まずは動かしてみる
あたりをつけて修正
そしてPRへ
Page: 57
まずは動かしてみる
セットアップ方法は3種
既存システムにインストール
virtualenvでインストール
VirtualBoxでインストール
Page: 58
まずはVirtualBoxで
環境を分けたいのでVirtualBoxを選択
Page: 59
Vagrantfileがアレ
# Every Vagrant virtual environment requires a box to build off of.
config.vm.box = "chef/debian-7.6"
Debian 7.6 (2014年7月12日)?
Debian 7.10でてるよ?
Page: 60
vagrant upしてみると
% vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'chef/debian-7.6' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
The box 'chef/debian-7.6' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Atlas, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:
URL: ["https://atlas.hashicorp.com/chef/debian-7.6"]
Error: The requested URL returned error: 404 Not Found
boxが見つからなくてコケる
Page: 61
PR#32で修正
Bento projectに移行していたせいだった
Page: 62
起動してログインするまで
$ vagrant up --provision
$ vagrant ssh
よくあるやりかた
Page: 63
vagrant sshして
サーバーを起動
$ cd debexpo
$ . venv/bin/activate
$ paster serve development.ini
Page: 64
5000ポートでサーバー起動
ブラウザでアクセス可能に
Page: 65
ユーザーの追加(1)
方法は2つある
ブラウザ経由で追加
JSONで追加
Page: 66
ユーザーの追加(2)
ブラウザ経由で追加
Page: 67
ユーザーの追加(3)
JSONで追加するなら
{
"realname":"Hayashi Kentaro",
"password":"password",
"email":"hayashi@clear-code.com"
}
Page: 68
ユーザーの追加(4)
追加用のスクリプトを利用
$ python ./bin/user_importer.py \
-i development.ini -u user.json
Page: 69
アカウントの有効化
verification (ログインに必要)
dmup (アップロードに必要)
Page: 70
verificationの設定
verificationを空にする
メールの確認をバイパス
Page: 71
DMUP?
マシン使用ポリシーのこと
Page: 72
dmupの設定
dmupフィールドを更新
同意したことにする
Page: 73
.dput.cfの設定をする
[debexpo]
fqdn = localhost:5000
incoming = /upload/kenhys@gmail.com/password
method = http
allow_unsigned_uploads = 0
アップロードの準備をする
Page: 74
試しにパッケージを
アップロード
Uploading to debexpo (via http to localhost:5000):
Uploading groonga_6.0.2-1.dsc:
Upload failed: 500 Internal Server Error
500 Internal Server Error
Page: 75
さっそくバグを踏む
あるべきディレクトリがないというオチ
Page: 76
PR#34で修正
ちゃんとディレクトリを作る
Page: 77
PR出して気づいた怖い話
最後にテストが通ったの8ヶ月前
Page: 78
なぜか?
Travis-CIの環境の変化
しばらくコミットされてないので誰も気づかない
Page: 79
PR#38で修正
テストが通るように
Page: 80
PR#37で修正
Python2.6でCIはもういいんじゃ
Page: 81
パッケージのとりこみ
$ ./bin/debexpo_importer.py \
-c /tmp/debexpo/growl-for-linux_0.8.5-1_source.changes \
-i development.ini --skip-gpg-check --skip-email
インポートスクリプト実行
Page: 82
とりこみできずに
Traceback
Traceback (most recent call last):
File "./bin/debexpo_importer.py", line 60, in
i.main()
File "/home/vagrant/debexpo/debexpo/importer/importer.py", line 473, in main
gpg = get_gnupg()
File "/home/vagrant/debexpo/debexpo/lib/utils.py", line 119, in get_gnupg
return gnupg.GnuPG(config['debexpo.gpg_path'],
File "/home/vagrant/debexpo/venv/local/lib/python2.7/site-packages/paste/registry.py", line 146, in getitem
return self._current_obj()[key]
KeyError: 'debexpo.gpg_path'
Page: 83
PR#39で修正
オプションを正しく解釈するように
Page: 84
パッケージリスト
リストアップされるように
Page: 85
あらすじ
upstream探し
ドキュメント探し
まずは動かしてみる
あたりをつけて修正
そしてPRへ
Page: 86
ディレクトリ構成
config
controllers
cronjobs
importer
i18n
lib
model
plugins
public
templates
tests
Page: 87
手がかりはURL
知りたいのはこのリンク
Page: 88
こんなリンク先
http://localhost:5000/sponsors/rfs-howto/
xxxx
Page: 89
コントローラを探す
def rfs_howto(self, packagename = None):
c.package = None
c.package_dir = None
if packagename:
package = meta.session.query(Package)
.filter_by(name=packagename).first()
if package:
c.package = package
c.package_dir = get_package_dir(package.name)
return render('/sponsor/rfs_howto.mako')
controllers/sponsor.py
Page: 90
テンプレートを見る
Package: sponsorship-requests
Severity: normal [important for RC bugs, wishlist for new packages]
Dear mentors,
%if c.package:
I am looking for a sponsor for my package "${ c.package.name }"
%else:
I am looking for a sponsor for my package "hello":
%endif
templates/sponsor/rfs_howto.mako
Page: 91
やりたいこと
RFSテンプレートから
[fill in]撲滅
mailto:リンクの生成
Page: 92
当初の目論見
${ c.package.name }とかあるぞ
テンプレートを書き換えればいいのでは?
Page: 94
なぜか?
必要なメタ情報を保持していない
持ってないものは表示できない orz...
ないならかき集めればいいじゃない
Page: 95
収集するにはどうすればい
いか
インポートの処理の流れを把握する
どのタイミングで収集すべきか知る
不足している情報は何かを知る
Page: 96
インポート処理の流れ(1)
dputでmentors.d.nへアップロード
インポート前処理
パッケージのインポート処理
Page: 97
インポート処理の流れ(2)
もう少し詳しく言うと
dputしたファイルは/tmp/debexpo/pubへ保存
インポート前処理で/tmp/debexpoヘ移動
orig.tar.gzがなかったりするとrejectメール
Page: 98
インポート処理の流れ(3)
もう少し詳しく言うと
インポート処理で/tmp/debexpo/filesへ移動
/tmp/debexpo/files以下
pool
dist
git
Page: 99
収集すべきデータは?
現状、メタ情報はどう保持されているのかを把握
する
テーブルを覗いてみよう
Page: 100
主要なテーブル
主なものは3つ
packages
package_versions
package_info
Page: 101
packagesテーブル
パッケージのマスターテーブル
名前や説明などのメタ情報を保持
Page: 102
packagesテーブル
sqlite> .schema packages
CREATE TABLE packages (
id INTEGER NOT NULL,
name TEXT NOT NULL,
user_id INTEGER,
description TEXT,
watch_counter INTEGER,
download_counter INTEGER,
needs_sponsor INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES users (id)
);
Page: 103
package_versions
テーブル
パッケージの版管理
何度もアップロードすると増加
Page: 104
package_versions
テーブル
sqlite> .schema package_versions
CREATE TABLE package_versions (
id INTEGER NOT NULL,
package_id INTEGER,
version TEXT NOT NULL,
maintainer TEXT NOT NULL,
section TEXT NOT NULL,
distribution TEXT NOT NULL,
qa_status INTEGER NOT NULL,
component TEXT NOT NULL,
priority TEXT,
closes TEXT,
uploaded DATETIME NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(package_id) REFERENCES packages (id)
);
Page: 105
package_infoテーブル
プラグインの適用結果を管理
メタ情報を保持
Page: 106
package_infoテーブル
sqlite> .schema package_info
CREATE TABLE package_info (
id INTEGER NOT NULL,
package_version_id INTEGER,
from_plugin VARCHAR(200) NOT NULL,
outcome VARCHAR(200) NOT NULL,
data TEXT,
severity INTEGER NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY(package_version_id) REFERENCES package_versions (id)
);
Page: 107
package_infoテーブル
from_plugin
どのプラグインか
outcome
説明文(エラーメッセージ)
data
JSONデータ
Page: 108
package_infoの例
sqlite> select * from package_info;
1|1|native|Package is not native|{"native": false}|1
2|1|maintaineremail|"Maintainer" email is the same as the uploader|{
"user-email":
"hayashi@clear-code.com",
"uploader-emails": [],
"maintainer-email": "hayashi@clear-code.com",
"user-is-maintainer": true
}|1
3|1|debianqa|Package is already in Debian|{
"nmu": false,
"in-debian": true,
"is-debian-maintainer": true
}|1
Page: 109
やりたいこと
RFSテンプレートから
[fill in]撲滅
mailto:リンクの生成
Page: 110
修正方針
プラグインで追加のメタ情報を収集
メール用のテンプレート追加
詳細ページでメタ情報を表示しつつmailto:リンク
生成
Page: 111
プラグイン?
debexpoはプラグインで機能拡張する
パッケージのチェックもプラグインを組み合わせ
て実現
Page: 112
プラグインの作り方
docs/writing_plugins.rst
Page: 113
プラグインの雛形
class FooPlugin(BasePlugin):
def test_xxx(self):
self.passed(outcome, data, severity)
or
self.failed(outcome, data, severity)
plugin = FooPlugin
debexpo/plugins/foo.py
Page: 114
プラグインいろいろ
% wc -l debexpo/plugins/*.py
99 debexpo/plugins/buildsystem.py
67 debexpo/plugins/changeslist.py
141 debexpo/plugins/closedbugs.py
85 debexpo/plugins/controlfields.py
185 debexpo/plugins/debianqa.py
85 debexpo/plugins/diffclean.py
63 debexpo/plugins/distribution.py
123 debexpo/plugins/getorigtarball.py
116 debexpo/plugins/lintian.py
100 debexpo/plugins/maintaineremail.py
69 debexpo/plugins/native.py
77 debexpo/plugins/notuploader.py
86 debexpo/plugins/removepackage.py
60 debexpo/plugins/ubuntuversion.py
110 debexpo/plugins/watchfile.py
Page: 115
プラグインの適用方法
設定ファイル(.ini)で制御
インポート前処理
QA処理
Debian入りした時
インポート処理後
Page: 116
プラグインを設定(1)
debexpo.plugins.post_upload
インポート前処理で適用
getorigtarballプラグイン
Page: 117
プラグインを設定(2)
debexpo.plugins.qa
QA処理で適用
lintianプラグイン
Page: 118
プラグインを設定(3)
debexpo.plugins.post_upload_to_debian
パッケージがDebian入りしたときに適用
removepackageプラグイン
Page: 119
プラグインを設定(4)
debexpo.plugins.post_successful_upload
インポート処理後に適用
changeslistプラグイン
Page: 120
プラグインの書きかた
なんとなくわかったのでいざ実践へ
Page: 121
やったこと
プラグインの処理を実装
プラグインを適用
mailto用テンプレート追加
rfstemplateのデータを表示
Page: 122
プラグインの処理を実装
debexpo/plugins/rfstemplate.pyを実装
実質100行ないくらい
debian/changelogやdebian/controlから抽出
deb822, copyrightモジュールを活用
Page: 123
プラグインを適用
debexpo.plugins.qa = ... rfstemplate ...
development.iniに設定
Page: 124
mailto用テンプレート追
加
%if c.rfstemplate:
Upstream Author :
* URL
:
* License
:
%else:
Upstream Author :
* URL
:
* License
:
%endif
${ c.rfstemplate['upstream-author'] }
${ c.rfstemplate['upstream-url'] }
${ c.rfstemplate['upstream-license'] }
[fill in name and email of upstream]
[fill in URL of upstreams web site]
[fill in]
debexpo/templates/sponsor/
rfs_template.mako
Page: 125
rfstemplateの
データを表示
if latest:
rfstemplate = meta.session.query(PackageInfo)
.filter_by(package_version_id=latest.id)
.filter_by(from_plugin='rfstemplate').first()
if rfstemplate:
c.rfstemplate = json.loads(rfstemplate.data)
c.mailbody = render('/sponsor/rfs_template.mako')
return render('/sponsor/rfs_howto.mako')
debexpo/controllers/sponsor.py
Page: 127
成果物をPR#35で出した
https://github.com/debexpo/debexpo/pull/35
Page: 128
PR#35の経過(1)
May 4
@olasdさんから好意的な反応
May 14
どうなった?とつついてみるも反応なし
Page: 129
PR#35の経過(2)
May 21
Debian勉強会でまだマージされてない話をする
あれやこれやでしばし放置
Page: 130
PR#35の経過(3)
June 19
@paulproteusさんをつついてみる
June 19
20日にみれるかもと@paulproteusさんから反応あ
り
Page: 131
PR#35の経過(4)
どうもDebConf16待ち
Page: 132
まとめ
debexpoとはmentors.d.nのこと
RFSテンプレートが残念だったので改善した
そのうちマージされる(多分)ので乞御期待
Page: 133
補足
マージへ向けた懸念事項
mentors.d.nは運用環境がwheezyらしい
wheezyのままならrejectされるかも
実装したプラグインがwheezyでは動かない(0.1.23以
降が必要)
wheezyではpython-debianが古い(0.1.21)
jessieなら0.1.27なので動作する
Page: 134
会場からのフィードバック
メールのリンクをもっと目立たせたほうがよいの
では
=> その通りなので直しておきたい