86
90

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PT3 地デジ・BS録画環境を Docker コンテナ内に押し込める

Last updated at Posted at 2014-11-12

ご存知 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/docker
DOCKER_OPTS="-s devicemapper"

参考:

早く btrfs にしたーい!

PT3 ドライバ

Git でソースをいただいてきて、DKMS(Dell - Dell | Linux - Projects - DKMS)でドライバをインストールします。今どき、DKMS が必要な局面というのも減りましたけれどね。下記のような Chef レシピにまとめて実行しています。

pt3/recipies/default.rb
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)に乗り換えました。決め手は、ノードをまたいでオーケストレーションが出来ることと、設定の可読性が高いことでした。

roles/pt3/tasks/main.yml
---

- 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 をさらします。

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 インスタンスを複数ポコスカ起動するように作られていないので。

さて

何か見落としはありませんでしょうか。コメント請う

86
90
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
86
90

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?