"continuous publication" with python: another approach

115
"Continuous Publication" with Python: Another Approach This presentation will be in JAPANESE

Upload: daisuke-miyakawa

Post on 05-Dec-2014

2.057 views

Category:

Software


5 download

DESCRIPTION

Presentation slide for #pyconjp2014

TRANSCRIPT

Page 1: "Continuous Publication" with Python: Another Approach

"Continuous Publication" with Python:

Another Approach This presentation will be in JAPANESE

Page 2: "Continuous Publication" with Python: Another Approach

英語必須と勘違いした orz

Page 3: "Continuous Publication" with Python: Another Approach

発表者自己紹介

• 宮川大輔 (@amedama)

• 株式会社 mokha 取締役

• 「もか」 (もくは)

• 前職: Google Inc. (U.S, Android部門)

Page 4: "Continuous Publication" with Python: Another Approach

Continuous Publication継続的出版

Page 5: "Continuous Publication" with Python: Another Approach

造語

Page 6: "Continuous Publication" with Python: Another Approach

「書籍」ビルドシステム を作ってみた

Page 7: "Continuous Publication" with Python: Another Approach

「書籍」ビルドシステム Griflet

• PDF, epub, InDesign, …

• Re:VIEWを採用

• 同人誌~商業書籍の「ビルド」

• 「書籍執筆」を支援

Page 8: "Continuous Publication" with Python: Another Approach

Re:VIEW• 書籍執筆に強い軽量マークアップ言語

• https://github.com/kmuto/review

• @kmuto, @takahashim, @kdmsnr, …

• TeX, epub, HTML, InDesign, …

• 参考図書: https://github.com/TechBooster/FirstStepReVIEW

Page 9: "Continuous Publication" with Python: Another Approach

Grifletのきっかけ• 同人誌『Effective Android』

• C84 (2013年 夏コミ)

• 著者22人, 184ページ

• Re:VIEW + GitHub → すごい!

• だが……

TechBooster代表 @mhidaka

Page 10: "Continuous Publication" with Python: Another Approach

ビルド失敗に気づかない

Page 11: "Continuous Publication" with Python: Another Approach

ビルド失敗に気づかない

• 執筆中はビルド結果に無頓着なことが多い

• 「HTMLが作れてるのでコミット」→PDFのビルドが成功するとは限らない

• Continuous Integration 環境が( ゚д゚)ホスィ…

Page 12: "Continuous Publication" with Python: Another Approach

自分で作った

Page 13: "Continuous Publication" with Python: Another Approach

(1) commit

(2) WebHook

(3) Build Req.

(4) Build

(6) Download

(5) Notify

Linux

Re:VIEW

Page 14: "Continuous Publication" with Python: Another Approach

デモ

Page 15: "Continuous Publication" with Python: Another Approach

……のサブセット

Page 16: "Continuous Publication" with Python: Another Approach
Page 17: "Continuous Publication" with Python: Another Approach
Page 18: "Continuous Publication" with Python: Another Approach
Page 19: "Continuous Publication" with Python: Another Approach
Page 20: "Continuous Publication" with Python: Another Approach
Page 21: "Continuous Publication" with Python: Another Approach

割と手探り

• Django, Celery初めて

• 「virtualenvって何 (́・ω・`)」

• 当初、1プロジェクトのみサポート

Page 22: "Continuous Publication" with Python: Another Approach

同人誌 → 商業書籍• 『Effective Android』(TechBooster) = 同人誌『Effective Android』(達人出版会) = 電子書籍『Effective Android』(インプレスジャパン) = 紙商業

• 共著者 22人 → 33人

• epub もサポート

• Re:VIEW偉大 (>ヮ<)

Page 23: "Continuous Publication" with Python: Another Approach

次のお題• TechBooster @ C85 (2013年 冬コミ)

• 4冊同時刊行

• 合計1書籍 -> 合計5書籍

Page 24: "Continuous Publication" with Python: Another Approach

ビルドがたまに止まる orz

Page 25: "Continuous Publication" with Python: Another Approach

「たまに止まる」問題

• たまに … 1週間に一回とか

• 原因: Celery + GitPythonの組み合わせ

• 根本原因は未解明

• 迂回策: subprocess.Popen + git

Page 26: "Continuous Publication" with Python: Another Approach

Re:VIEWが暴走する

Page 27: "Continuous Publication" with Python: Another Approach

Re:VIEW暴走事件

• Re:VIEW側のバグ (正規表現が無限ループ化)

• Celeryのタイムアウトも効かず……

Page 28: "Continuous Publication" with Python: Another Approach

動かなくなったらすぐ教えて欲しい

Page 29: "Continuous Publication" with Python: Another Approach

Zabbix

• OSSの監視ソフト

Page 30: "Continuous Publication" with Python: Another Approach

C85 も無事に終了

Page 31: "Continuous Publication" with Python: Another Approach

そこそこ評判が良い

Page 32: "Continuous Publication" with Python: Another Approach

クチコミヽ(=́▽`=)ノ

Page 33: "Continuous Publication" with Python: Another Approach

クチコミ

• 「友人の友人」のプロジェクトも扱い始める

Page 34: "Continuous Publication" with Python: Another Approach

……えっ (゚Д゚)

Page 35: "Continuous Publication" with Python: Another Approach

知らない人のRe:VIEWプロジェクト

Page 36: "Continuous Publication" with Python: Another Approach

is 脅威

Page 37: "Continuous Publication" with Python: Another Approach

あるいは

Page 38: "Continuous Publication" with Python: Another Approach

Re:VIEW is 脆弱性

Page 39: "Continuous Publication" with Python: Another Approach

「Re:VIEWは脆弱性」問題

• Re:VIEWではRubyコードで命令を拡張出来る

• OSコマンドインジェクションそのものじゃね?

• サンドボックスが( ゚д゚)ホスィ…

Page 40: "Continuous Publication" with Python: Another Approach

• Immutable Infrastructure

• 「軽量VMでOSを囲って実行 -> 廃棄」

• ぴったり(●́ω`●)

• ……と油断していると

Page 41: "Continuous Publication" with Python: Another Approach

_人人人人人人_ > 突然の死 < ‾Y^Y^Y^Y^Y^Y‾

Page 42: "Continuous Publication" with Python: Another Approach

Dockerは不安定?

• あくまで過去形 = 今は比較的安定している

• 実際、Dockerのバグには何度か出会った

• 自分のミスという部分も多々あった

• モニタリング大事

Page 43: "Continuous Publication" with Python: Another Approach

(1) commit

(2) WebHook

(3) Build Req.

(4) Build

(6) Download

(5) Notify

Linux

Re:VIEW

Page 44: "Continuous Publication" with Python: Another Approach

(1) commit

(2) WebHook

(3) Build Req.

Re:VIEW

(4) Build

(6) Download

(5) Notify

Linux

Page 45: "Continuous Publication" with Python: Another Approach

C86 (2014年 夏)• またもやTechBooster

• 他サークルの同人誌も

Page 46: "Continuous Publication" with Python: Another Approach

粛々と開発

Page 47: "Continuous Publication" with Python: Another Approach

開発上の課題

Page 48: "Continuous Publication" with Python: Another Approach

「片手間」開発

Page 49: "Continuous Publication" with Python: Another Approach

「片手間」開発

• 長いスパンで少量の実装をちまちま

• 一人で「1ヶ月に2~3日。まとめて」

Page 50: "Continuous Publication" with Python: Another Approach

そして忘れる• 設計・実装・運用の詳細を、忘れる

• どのような問題が発生していたかを、忘れる

• ユーザフィードバックを、忘れる

• 自分が何を達成したいのかまで、忘れる

• しばしばここで作るのをやめてしまう

Page 51: "Continuous Publication" with Python: Another Approach

よくあるよね

Page 52: "Continuous Publication" with Python: Another Approach

諦めない(`・ω・́)

Page 53: "Continuous Publication" with Python: Another Approach

対策を考えてみる

Page 54: "Continuous Publication" with Python: Another Approach

対策 1

Page 55: "Continuous Publication" with Python: Another Approach

メモる

Page 56: "Continuous Publication" with Python: Another Approach

対策 1: メモる

!

• Redmineのチケットに、メモる

• ソースコードへのコメントに、メモる

Page 57: "Continuous Publication" with Python: Another Approach

「古くてアホくさいメモ」忘れるよりマシ

Page 58: "Continuous Publication" with Python: Another Approach

見るのはハズカシィ (∩∀`*)

Page 59: "Continuous Publication" with Python: Another Approach

Redmineのチケット

• 作りたい機能、設計上の課題、未解明な点を記録

• 現在: 合計200チケット超 (未完了100超)

• 不定期の見直しで「思い出す」

Page 60: "Continuous Publication" with Python: Another Approach

コードへのコメント

• 「理由」「意図」「疑問」をなるべく残す

• 含「よく分かってないんだけど何故かこうなる」

• 「何をしているか」のコメントは避ける

• 整合性がとれなくなると余計に混乱する

Page 61: "Continuous Publication" with Python: Another Approach

対策 2

Page 62: "Continuous Publication" with Python: Another Approach

ログる

Page 63: "Continuous Publication" with Python: Another Approach

対策 2: ログる• = ログに残す

• 「ここ通ったら、あかーん」というログも

• コメントの代わりにログにしてしまう

• RotatingFileHandlerでサイズを抑える

• 注: サービス規模が大きくなったらもちろん無理

Page 64: "Continuous Publication" with Python: Another Approach

それでも見失う

• print() になってる

• logging.debug() って書いてる

Page 65: "Continuous Publication" with Python: Another Approach

Loggerを活用する• print()を避ける

• “logging”自体インポートしない

• 関数の仮引数にlogger

• http://qiita.com/amedama/items/b856b2f30c2f38665701

from logging import getLogger, DEBUG from logging import NullHandler local_logger = getLogger(__name__) handler = NullHandler() handler.setLevel(DEBUG) local_logger.setLevel(DEBUG) local_logger.addHandler(handler) !def some_func(…, logger=None): logger = logger or local_logger logger.error(u“some_func() なう”)

Page 66: "Continuous Publication" with Python: Another Approach

「開発ログ」と「運用ログ」

• Logging Context が与えられない

• 1つの関数で2つのloggerを管理したくはない

Page 67: "Continuous Publication" with Python: Another Approach

テスト……?

Page 68: "Continuous Publication" with Python: Another Approach

ユニットテスト

• モックアウトが「無駄」になりやすい

• 「外部ツールのリアルな挙動」が問題の発生源

• Viewについて重点的に

Page 69: "Continuous Publication" with Python: Another Approach

回帰テスト/結合テスト

• 外部の世界: Docker, Re:VIEW, ……

• 片手間の最中に「変わってしまう」ことがある

• 効率的にこの変化を捉える(́・ω・`)

Page 70: "Continuous Publication" with Python: Another Approach

Python処理系も外部に?

• 例: Python 2 v.s. Python 3

Page 71: "Continuous Publication" with Python: Another Approach

Linux

Re:VIEW

Re:VIEW

Re:VIEW

Python 2.7Python 3.4

Python 3.5

(願望です)

Page 72: "Continuous Publication" with Python: Another Approach

今後について

Page 73: "Continuous Publication" with Python: Another Approach

今後のGriflet• 未だ「粛々と開発」

• 「一般公開」出来る水準にしたい

• 一部オープンソース化

• https://github.com/dmiyakawa/pyrev

• Re:VIEWのメタデータ解析 + Lintチェッカ

Page 74: "Continuous Publication" with Python: Another Approach

ありがとうございましたこの後オフィスアワーにいます

Page 75: "Continuous Publication" with Python: Another Approach

This page is intentionally left blank

Page 76: "Continuous Publication" with Python: Another Approach

……

Page 77: "Continuous Publication" with Python: Another Approach

まだまだ続くんじゃ (`・ω・́)

発表で使わなかったスライドが延々続きます

Page 78: "Continuous Publication" with Python: Another Approach

「片手間」開発≒ 趣味

Page 79: "Continuous Publication" with Python: Another Approach

問題を愉しむ

Page 80: "Continuous Publication" with Python: Another Approach

運用環境の裏でテストしたい

• 新しい原稿データでその場で「A/B テスト」

• ここはあくまで今後の「希望」

Page 81: "Continuous Publication" with Python: Another Approach

Re:VIEW

Linux

Page 82: "Continuous Publication" with Python: Another Approach

Re:VIEW

Linux

(WSGI)

Page 83: "Continuous Publication" with Python: Another Approach

Linux

(WSGI)

Re:VIEW

Page 84: "Continuous Publication" with Python: Another Approach

Linux

Re:VIEW

Re:VIEW

Re:VIEW

Page 85: "Continuous Publication" with Python: Another Approach

Linux

Re:VIEW

Re:VIEW

Re:VIEW

Python 2.7Python 3.4

Python 3.5

Page 86: "Continuous Publication" with Python: Another Approach

Linux

Re:VIEW

Re:VIEW

Re:VIEW

Python 2.7Python 3.4

Python 3.5

Page 87: "Continuous Publication" with Python: Another Approach

あくまでアイディア

Page 88: "Continuous Publication" with Python: Another Approach

楽か?(́・ω・`)

Page 89: "Continuous Publication" with Python: Another Approach

バージョン管理の苦悩• 分離した部分でのセキュリティは自分で責任を持つ

• 他人 (OSディストリビューション等) にどこまで頼って、どこから自分でやるのか?

• 全環境を expose するわけではないので……

• ただ、考えておく必要はある

Page 90: "Continuous Publication" with Python: Another Approach

新しい何か≒ 新しい問題≒新しい発見

• 「検証 ~= 実装」

• 公開サービスではないので落ちてても切れる赤の他人がいない (今回助かるポイント)

• 簡単な部分で敢えて一歩踏み出す

• 経験値目当て

• ただし、ヤバそうな点は忘れないようにメモする

Page 91: "Continuous Publication" with Python: Another Approach

ライブラリなのか それより下なのか

• 多様な条件を切り替えられると気分が楽

• CentOSに乗っける?問題ないだろ(`・ω・́)

• ……systemdコワイ(́・ω・`)

• OS固有の問題、Python環境の問題、ライブラリの問題、外部サービスの問題

• 切り分けられるポイントで切り替える練習

Page 92: "Continuous Publication" with Python: Another Approach

実際、環境の一本化に やや難を感じている

• 個人の事情もあるものの

• 開発マシン: Debian 7 (wheezy)

• 個人サーバ: Debian 7 (wheezy)

• テスト環境: Ubuntu 12.04 LTS / Ubuntu 14.04 LTS

• 「これも経験」と割り切る

• (仕事の運用環境は一本化するのがベター)

• BSDマダー

Page 93: "Continuous Publication" with Python: Another Approach

違うLinux 細かいところでズレる

!

• Ubuntu 12.04 -> django 1.3

• 使っていた reverse_lazy() がない

• Pythonから上のレベルではせめて統一……

Page 94: "Continuous Publication" with Python: Another Approach

分離

Page 95: "Continuous Publication" with Python: Another Approach

virtualenv / venv• Python実行環境分離

• 実行環境を(言語バージョン同じで)もう一つ作る

• PyPiのパッケージも別管理

• 最近 (3.3以降) なら(py)venv

• 以降 venv = virtualenv or pyvenv

• ……というか、どう呼ぶのがベストなの?

Page 96: "Continuous Publication" with Python: Another Approach

Django + venv の苦悩

• activate忘れ (Apache, Celery含めて)

• しかもある程度動作してしまうこともある……

• OS本体側にsudo pip全くしないのはどう?

• あるいはmanage.pyの段階で強制?

Page 97: "Continuous Publication" with Python: Another Approach

Python環境も選びたくなる

Page 98: "Continuous Publication" with Python: Another Approach

Python環境も選びたい

• virtualenvはPythonバージョン固定

• make install すればいいのだが

• 何かラフにでいいから管理したい

Page 99: "Continuous Publication" with Python: Another Approach

pyenv + venv• pyenv で任意のPython実行環境を(ユーザレベルで)用意

• virtualenvのPython実行環境まるごと版みたいなの

• https://github.com/yyuu/pyenv

• rbenvのPython版なのでpyenv

• 注意: pyenv ≠ pyvenv

• venvを用いて、プロジェクト固有の環境をもう一つ作る

• 3.系のpyvenvでは--copyを付けた方がベター

Page 100: "Continuous Publication" with Python: Another Approach

pyenv 実用例

• Debian 7 のPython 2.7.3にマイナーなバグが……

• PyPiへのWindowsバイナリがアップ出来ない?

• pyenvで2.7.6を入れることで回避出来た様子

• 言語環境の軽いA/Bテストに使える

Page 101: "Continuous Publication" with Python: Another Approach

3種類のPython環境• システムレベル (OSパッケージ管理)

• 保守的、OSに付属する環境が使う

• ユーザレベル (pyenv)

• 複数のPython環境をユーザが切り替える

• OS付属のマイナーバージョンに不満がある場合にも便利

• プロジェクトレベル (pyenv + venv)

• プロジェクト毎にPython (+ PyPi) 環境を独立して持つ

Page 102: "Continuous Publication" with Python: Another Approach

mod_wsgiの苦悩• venvはApache + mod_wsgi のバージョンを強制できるわけではない

• mod_wsgiのPythonバージョンはOS毎に異なる

• 特に2と3の両立は不可

• 他のWSGI依存のプロジェクトに影響する

• 安易に変更はできない

Page 103: "Continuous Publication" with Python: Another Approach

WSGIを境界に

Page 104: "Continuous Publication" with Python: Another Approach

今試していること

• pyenv + venv + Supervisor + tornado + Apache mod_proxy

• どんどん複雑化していておじさん悲しいな

Page 105: "Continuous Publication" with Python: Another Approach

Supervisor• daemon管理のためのdaemon

• Celeryを複数のDjangoプロジェクトで使いたいなら必須

• 後述するtornadoの管理にも使う

• OSによっては標準のバージョンが超古くアレなことが?

• Debian 7 -> 2010年の頃のもの

• 必要なら sid (unstable) からソースビルド

Page 106: "Continuous Publication" with Python: Another Approach

tornado• スタンドアローンWeb(WSGI)サーバ

• http://www.tornadoweb.org/en/stable/

• Apacheのmod_wsgiを迂回するために使う。

• Django 1.7 + tornadoでの注意

• django.setup() 忘れるなや

• 古い「tornado + Djangoを試してみた」系の記事内容だけだとハマる

• http://qiita.com/amedama/items/a8f511bd75a14aac0277

• 「異なるバージョンのPython(wsgi)アプリを一つの開発環境上で動かす」

Page 107: "Continuous Publication" with Python: Another Approach

素朴な疑問 Supervisor v.s. systemd

• 全く分からん(́・ω・`)

Page 108: "Continuous Publication" with Python: Another Approach

気軽に試せる環境が嬉しい

• 「Python 3.X + Django 1.Y」をさっくり用意

• /opt 下に一度に飼える

• http://qiita.com/amedama/items/a8f511bd75a14aac0277

• http://qiita.com/amedama/items/79994598d9f4daa69d13

Page 109: "Continuous Publication" with Python: Another Approach

楽しい!!!✌('ω'✌ )三✌('ω')✌三( ✌'ω')✌

Page 110: "Continuous Publication" with Python: Another Approach

ふたたび ありがとうございました

Page 111: "Continuous Publication" with Python: Another Approach

想定問答集

Page 112: "Continuous Publication" with Python: Another Approach

なぜmd/rst/etc.じゃない?• 極端な話、非常に抽象的なXMLを定義すれば なんでも書ける……はず。

• それをしたくない適切な「軽量マークアップ」は何か

• Re:VIEWは複数種類のアウトプット向け

• 新しい文法的に拡張をし易い

• 文法定義毎に固有の命令を埋め込みやすい

• ただし「HTML出たけどPDFとInDesignが死んでる」が起こる

• 日本の書籍事情に関与している方々が主導している

• 参考: https://github.com/TechBooster/FirstStepReVIEW

Page 113: "Continuous Publication" with Python: Another Approach

Sphinx?

• あ、ほら、最初良く知らなかったし(́・ω・`)

Page 114: "Continuous Publication" with Python: Another Approach

それ使ってみたい

• Ask @amedama (Facebook dmiyakawa)

Page 115: "Continuous Publication" with Python: Another Approach

☆(ゝω・)vキャピ