ご存知 PT3 による地デジ・BSの録画環境を私も重宝しているのですが、いかんせん環境設定が面倒で、OS の入れ替えを躊躇しがちに。その一因として、関連ツール類がパッケージ化されておらず、ソースを一つ一つ取得してきてインストールせざるを得ないことが挙げられると思います。
それって Docker イメージに押し込んじゃえばいいんじゃね? というわけで始めてみました。なお、録画サーバである EPGREC(トップページ - 録画予約システムepgrec)とそのバックで動く MySQL の設定については、Docker の設定としては極々オーソドックスですので、ここでは触れません(気が向いたら追記するかも)。
なお、下記の手順で、ホストでの PT3 録画環境 → Docker の PT3 録画環境への移行期間中は、ホスト側と Docker 側とで、一枚の B-CAS カードを共用して、同時に録画ができています(ホストが地デジ 3 チューナ、BS 3 チューナで、Docker コンテナは地デジ 1 チューナ・BS 1 チューナを使用)。
全体の構成
ホスト OS 側では PT3 ドライバと PC カードリーダのサーバを動かし、特権モードの Docker コンテナ側からは、PT3 へはデバイスファイルを通じて、カードリーダへは UNIX ドメインソケットを通じて利用するようにします。
Docker ホスト側のセットアップ
そのようなわけで、Docker ホスト環境の側では、以下のように、仮想環境のホストと、ハードウェアの管理だけをしてもらいましょう。とっても今風ですね、ステキ。
- Docker のホスト
- PT3 ドライバ
- PC カードリーダのサーバ
- (各 web サービスへのリバースプロキシとして nginx)
Docker のホスト
ホストの OS としては Ubuntu 14.04 ですので、Docker は「docker.io」の 1.0 系なのですが、このところ Docker は開発が活発すぎるので、下記で「lxc-docker」の最新版(今日時点で 1.3.1)を入れます。右記も参照。 ∥ Ubuntu - Docker Documentation
$ curl --silent --show-error --location https://get.docker.io/ | sh
それでも docker exec
の動作とか、若干変な気もします。後で見てみるか。
追記(Nov 21 2014): どうやら Ubuntu 14.04 の標準 Docker のストレージエンジンのデフォルトは devicemapper(設定ファイルで指定)なのですが、lxc-docker の標準が aufs(設定ファイルに無指定なので)になっているようです。aufs はマイナーな機能が足りていないので、後々痛い目にあわないように、最初に、/etc/default/docker にストレージエンジンを指定してから docker サービスを再起動しておいた方が良いと思われます。多くのケースでは、CentOS で yum(8) を動かす際にハマると思われます。
/etc/default/dockerDOCKER_OPTS="-s devicemapper"
参考:
- Comprehensive Overview of Storage Scalability in Docker | Red Hat Developer Blog
- centos Repository | Docker Hub Registry - Repositories of Docker Images
- cap_set_file not permitted on aufs storage driver only · Issue #6980 · docker/docker
- Why use AUFS as the default Docker storage backend instead of devicemapper? - Stack Overflow
- CentOS, Docker, and Systemd
早く btrfs にしたーい!
PT3 ドライバ
Git でソースをいただいてきて、DKMS(Dell - Dell | Linux - Projects - DKMS)でドライバをインストールします。今どき、DKMS が必要な局面というのも減りましたけれどね。下記のような Chef レシピにまとめて実行しています。
package "dkms"
git "#{Chef::Config[:file_cache_path]}/pt3" do
repository "git://github.com/m-tsudo/pt3.git"
reference "master"
action :sync
notifies :run, "bash[pt3 installation]"
end
bash "pt3 installation" do
only_if ". #{Chef::Config[:file_cache_path]}/pt3/dkms.conf; test -z \"$(dkms status -m $PACKAGE_NAME -v $PACKAGE_VERSION)\""
cwd "#{Chef::Config[:file_cache_path]}/pt3"
code <<-EOH
. dkms.conf;
rm -fr /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
mkdir -p /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
git archive master | sudo tar -x -C /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
dkms add -m $PACKAGE_NAME -v $PACKAGE_VERSION
dkms build -m $PACKAGE_NAME -v $PACKAGE_VERSION
dkms install -m $PACKAGE_NAME -v $PACKAGE_VERSION
lsmod | grep pt3_drv || modprobe pt3_drv
EOH
end
bash "pt3 boot time module loading" do
not_if "grep pt3_drv /etc/modules"
code <<-EOC
echo pt3_drv >> /etc/modules
EOC
end
追記(Tue May 26 2015): 最近は Ansible(Ansible Documentation — Ansible Documentation)に乗り換えました。決め手は、ノードをまたいでオーケストレーションが出来ることと、設定の可読性が高いことでした。
---
- name: DKMS がインストールされていること
apt: name=dkms state=present
- name: pt3 ドライバのソースが git clone されていること
git:
repo: git://github.com/m-tsudo/pt3.git
dest: /root/pt3
accept_hostkey: true
- name: pt3 ドライバの DKMS ステータスを取得する
args:
executable: /bin/bash
chdir: /root/pt3
shell: |
. dkms.conf
dkms status -m $PACKAGE_NAME -v $PACKAGE_VERSION
register: pt3_driver_status
always_run: true
changed_when: false
# - debug: var=pt3_driver_status
- name: pt3 ビルドの要否を取得する
set_fact:
pt3_build_required: force_build or (not pt3_driver_status.stdout)
- name: pt3 ドライバをインストールする
when: pt3_build_required
args:
executable: /bin/bash
chdir: /root/pt3
shell: |
. dkms.conf
rm -fr /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
mkdir -p /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
git archive master | tar -x -C /usr/src/$PACKAGE_NAME-$PACKAGE_VERSION
dkms add -m $PACKAGE_NAME -v $PACKAGE_VERSION
dkms build -m $PACKAGE_NAME -v $PACKAGE_VERSION
dkms install -m $PACKAGE_NAME -v $PACKAGE_VERSION
lsmod | grep pt3_drv || modprobe pt3_drv
# modules-load.d http://www.freedesktop.org/software/systemd/man/modules-load.d.html
- name: 起動時の pt3 ドライバロード設定が存在すること
copy:
content: |
pt3_drv
dest: /etc/modules-load.d/pt3.conf
- name: 標準のドライバを入れないようになっていること
copy:
content: |
blacklist earth-pt1
blacklist earth-pt3
dest: /etc/modprobe.d/blacklist-ath_pci.conf
# To remove:
# # dkms remove $PACKAGE_NAME/$PACKAGE_VERSION --all
...
PC カードリーダのサーバ
B-CAS カードを差すカードリーダードライバ(PCSClite project)の、サーバ側(「pcscd」)だけを動かします。クライアント(「pcsc-tools」)は、動作確認のために入れても構いませんが、ホスト側では必須ではありません。
$ sudo aptitude install pcscd
Docker コンテナ
とりあえずは Dockerfile をさらします。
# Use phusion/baseimage as base image. To make your builds reproducible, make
# sure you lock down to a specific version, not to `latest`!
# See https://github.com/phusion/baseimage-docker/blob/master/Changelog.md for
# a list of version numbers.
FROM phusion/baseimage:latest
MAINTAINER Kiichiro NAKA <knaka@ayutaya.com>
# Set correct environment variables.
ENV HOME /root
# Regenerate SSH host keys. baseimage-docker does not contain any, so you
# have to do that yourself. You may also comment out this instruction; the
# init system will auto-generate one during boot.
RUN /etc/my_init.d/00_regen_ssh_host_keys.sh
# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]
# --------------------------------------------------------------------
RUN echo "Asia/Tokyo" > /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-get install -y wget unzip git
RUN apt-get install -y pkg-config autoconf build-essential
# Card reader
RUN apt-get install -y pcsc-tools
# ARIB library
RUN wget http://hg.honeyplanet.jp/pt1/archive/ec7c87854f2f.zip
RUN unzip ec7c87854f2f.zip
RUN apt-get install -y libpcsclite-dev
RUN cd pt1-ec7c87854f2f/arib25/src/ && make && make install
# recpt1
RUN git clone https://github.com/stz2012/recpt1
RUN cd recpt1/recpt1/ && ./autogen.sh && ./configure --enable-b25 && make && make install
# --------------------------------------------------------------------
# Clean up APT when done.
RUN apt-get clean && rm -fr /var/lib/apt/lists/* /tmp/* /var/tmp/*
頭の部分と尻の部分は Docker baseimage(phusion/baseimage-docker)の定形ですのでどうでも良いとして、肝心なのは中間部分の、各種ツールをインストールしているところです。
要点としては、pcsc-tools は入れているが pcscd は入れていないところでしょうか。この理由については後述します。
その他のツールについては、私のところではこのツール&バージョンの組み合わせが良好だったというところですので、何とも言えません。肝心なのは、Docker イメージとしては OS のバージョンも含めて固定&塩漬けにできるため、ホスト OS のバージョンアップに影響されないというメリットが得られることです。この安心感は大きい。
コンテナからの、PT3 ドライバや PC カードリーダーサーバへのアクセス
問題は、Docker コンテナ側からどうやって PT3 と PC カードリーダーサーバへアクセスするかです。下記は、最終的な Docker コンテナの起動コマンドです。
docker run -d --name epgrec \
--privileged \
--volume /dev/:/dev/ \
--volume /var/run/pcscd/pcscd.comm:/var/run/pcscd/pcscd.comm \
--volume $PWD/config.xml:/var/www/html/settings/config.xml \
-p 127.0.0.1:1026:80 --link mysql-epgrec:mysql \
knaka/epgrec:latest
EPGREC のための設定ファイルや DB 設定も盛り込まれているのでゴチャゴチャしていますが、ここでの要点は、まずは --privileged
オプションです。これによって Docker コンテナは特権モードで動作するので、デバイスファイル(ここでは /dev/pt3video*
)に自由にアクセスすることができるようになります。
さて、そのデバイスファイルはホスト OS 上で udev によって動的に管理されていますので、--volume /dev/:/dev/
としてデバイスファイル群をゴッソリと共有してやります。
次に PC カードリーダーなのですが、PCSC は UNIX ドメインソケットを用いたクライアント・サーバモデルのソフトウェアですので、--volume /var/run/pcscd/pcscd.comm:/var/run/pcscd/pcscd.comm
のようにソケットファイルだけを共有してやれば、あっさり pcsc-tools が、Docker コンテナ上で動作します。
なお、最初の予定では USB のデバイスファイルを共有して pcscd をコンテナ内でも動かそうとしたのですが、そうするとホストの pcscd と Docker コンテナ内の pcscd が先勝ちにリーダーデバイスを取り合ってしまって、ホストと Docker での同時動作ができませんでした。
EPG 抽出ツールと EPGREC の設定
EPGREC のバックエンドである MySQL は別コンテナにしました。一サービス一 DB にすると、分かりやすくて良いですね。特に MySQL は、PostgreSQL などと違って、DB インスタンスを複数ポコスカ起動するように作られていないので。
さて
何か見落としはありませんでしょうか。コメント請う