ようやく理解したのでメモ
TL;DR
- cache がやっていることは、「保存しておいたディレクトリをビルドの最初にまとめて展開している」だけ。
- 自分で cache を活用しようとしたら、当然、「キャッシュがあれば使う。なければダウンロード」というスクリプトを書く必要がある。
はじめに
Bitbucket Pipelines には cache という機能があります。
もともと私がやろうとしていたことは、「make && make install
するようなライブラリのビルドをキャッシュで速くしたい」ということだったのですが、
公式ドキュメントの、特に custom cache に関する部分がわかりにくくてハマってしまいました。
ところで
Bitbucket Pipelines では、任意の Docker image を元にすることができます。
よって、
- 開発環境の docker image を public にすることができる (例えば Dockerhub)
- public ではないものの、private な docker registry から pull することができる (例えば自分で建てた docker registry)
以上のどちらかに該当する人は、そもそも Pipelines のキャッシュではなく、docker build 側のキャッシュ機構に任せたほうが何かと楽だと思います。
以下は、何らかの理由で docker での開発ができなかったり、公開が不可能だったり、あるいは docker ではどうしても不可能なワークフローをキャッシュ化したい人向けとなります。
本題:Pipelines の cache を使う
ここでは、MeCab+IPAdic のビルドをキャッシュ化してみます。
最終的な構成は次のようになりました:
your_repo/
bitbucket-pipelines.yml
bitbucket-pipelines-mecab-download.sh
bitbucket-pipelines-ipadic-download.sh
それぞれ説明していきます。
bitbucket-pipelines.yml
image: python:3.6.4
pipelines:
default:
- step:
caches:
- pip
- mecab
- mecab-ipadic
script:
- bash bitbucket-pipelines-mecab-download.sh
- (cd ~/mecab/mecab/mecab-0.996 && make install && ldconfig)
- bash bitbucket-pipelines-ipadic-download.sh
- (cd ~/mecab/mecab-ipadic/mecab-ipadic-2.7.0-20070801 && make install)
- pip install -r requirements.txt
- python setup.py test # your test here
definitions:
caches:
mecab: ~/mecab/mecab
mecab-ipadic: ~/mecab/mecab-ipadic
script
内の bash bitbucket-pipelines-mecab-download.sh
が、
「mecab のビルド済みキャッシュをチェック。なければソースをダウンロードして make
」
をしています。
その直後の行で make install
をして、実際に mecab をインストールしています。
bash bitbucket-pipelines-ipadic-download.sh
も同様です。
それらが終わったら環境構築が終了なので、python setup.py test
で本当にやりたかったテストを走らせています。
bitbucket-pipelines-mecab-download.sh
#!/bin/bash
CACHE_DIR=${HOME}/mecab/mecab
mkdir -p ${CACHE_DIR}
if [ -d "${CACHE_DIR}/mecab-0.996" ]; then
echo "found mecab cache"
else
wget "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7cENtOXlicTFaRUE" -O mecab-0.996.tar.gz
tar zxfv mecab-0.996.tar.gz -C ${CACHE_DIR}/
cd ${CACHE_DIR}/mecab-0.996
./configure --with-charset=utf8
make
fi
このスクリプトは、先述のように
「最初の if
で mecab のビルド済みキャッシュをチェック。なければソースをダウンロードして make
」
をしています。
Pipelines 上ではどうせ同じ設定でしか動かさないので、./configure
と make
まで済ませてしまいます。(それらが終われば make install
は基本的にコピーしか動かないのですぐ終わります)1
ここでチェックしている「キャッシュ」とは、Pipelines が以前に一度でも成功状態で終了していれば、Pipelines 上で保存されて、新しいビルドの開始時に Pipelines 側で配置してくれているものです。
bitbucket-pipelines.yml
の step: caches:
以下と definitions: caches:
以下で指定しているディレクトリがそれです。
(pip
の definitions
がないのは、よく使われるパッケージマネージャのキャッシュの定義は Pipelines が事前に設定されているからです。)
bitbucket-pipelines-ipadic-download.sh
#!/bin/bash
CACHE_DIR=${HOME}/mecab/mecab-ipadic
mkdir -p ${CACHE_DIR}
if [ -d "${CACHE_DIR}/mecab-ipadic-2.7.0-20070801" ]; then
echo "found ipadic cache"
else
wget "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM" -O mecab-ipadic-2.7.0-20070801.tar.gz
tar zxfv mecab-ipadic-2.7.0-20070801.tar.gz -C ${CACHE_DIR}/
cd ${CACHE_DIR}/mecab-ipadic-2.7.0-20070801
./configure --with-charset=utf8
make
fi
IPAdic についても、先ほどと同じことをしています。
どれだけ早くなるの?
私の環境では、最終的に1/3くらいに短縮されました。
(ちなみに、短縮後の 51 sec のうち、pip install
にかかっている時間が26秒でした。いくらダウンロードにキャッシュが効いているとは言っても、インストールが重い処理だとやはり時間がかかってしまいます。
冒頭で言った通り、できるならば素直に docker image として運用したいところです)
参考資料
-
と思ったけど、ディレクトリまるごと復元されるので、前回の
make
の結果が残っているから Makefile 側の冗長性排除機構が動くのでmake
は毎回やってしまっても実行時間に影響はない気がしてきた ↩