Ubuntu 16.04: snapパッケージのインストール方法と作成方法

snapパッケージのインストール方法と作成方法について記載します。

 

1 snapパッケージ

コマンドが必要とするライブラリを専用のルートファイルシステムに含めて提供するパッケージです。ライブラリ入れ替えによって他のパッケージを壊すことがなくなります。ただし、ライブラリが重複するので容量は大きくなります。DLLファイルをアプリケーションフォルダに含めるWindowsアプリケーションに近いものです。

例えば、bluezの専用ルートファイルシステムは以下のとおりです。

$ tree /snap/bluez/6/
/snap/bluez/6/
├── command-bluetoothctl.wrapper
├── command-bluez.wrapper
├── command-obexctl.wrapper
├── command-obex.wrapper
├── meta
│   ├── gui
│   │   └── icon.png
│   └── snap.yaml
└── usr
    ├── bin
    │   ├── bluetoothctl
    │   └── obexctl
    ├── lib
    │   ├── bluetooth
    │   │   ├── bluetoothd
    │   │   └── obexd
    │   └── x86_64-linux-gnu
    │       ├── libical.so.1 -> libical.so.1.0.1
    │       ├── libical.so.1.0.1
    │       ├── libicalss.so.1 -> libicalss.so.1.0.1
    │       ├── libicalss.so.1.0.1
    │       ├── libicalvcal.so.1 -> libicalvcal.so.1.0.1
    │       └── libicalvcal.so.1.0.1
    └── share
        └── doc
            ├── bluez
            │   ├── copyright
            │   └── overview.md
            └── libical1a
                └── copyright

2 snapdのインストール

snapパッケージをインストールする為のツールです。おそらくsnappyからsnapdに名前が変わってます。

$ sudo apt install -y snapd

2.1 snapコマンド

パッケージに関連するsnapコマンドは以下のとおりです。

 

snap find インストールできるパッケージ一覧
snap find <pattern> パターンにマッチするパッケージ一覧
snap list インストール済みのパッケージ一覧
snap install <package> インストール
snap remove <package> アンインストール

 

2.2 インストールできるパッケージ一覧

2016年6月28日現在のパッケージ一覧は以下のとおりです。

ab alsa-utils apktool atom-cwayne audovia base beagleblack bluez
canonical-dragon canonical-i386 canonical-pc canonical-pc-linux
canonical-pi2 cassandra cla-check compass-straightedge drmips eeevil
ejabberd filebot foobar21 freecad freechartgeany gdoc-html-cleaner
ghex-udt gmailfilter gnuchess go-example-webserver hangups hello
hello-huge hello-snap hello-world htop http jenkins john-the-ripper
kale keepassx-elopio kpcli-elopio krita languagetool links
littlewatcher minecraft-server-jdstrand miniterm-joc moon-buggy
morse-converter-py nextcloud nikola nmap notes open-solitaire-classic
openscad-plars owncloud pciutils pen roseapple-pi scummvm serial-vault
shadowsocks shout simplenote-jamiebennett snapd-hacker-toolbelt
snappy-debug snapstore-example speed-test spread sshtron
stellarium-plars sudo systesterpro64 taskwarrior-plars teatime-unity
telegram-sergiusens tic-tac-toe tio tor-middle-relay tpad tproxy
ubuntu-calculator-app ubuntu-clock-app ubuntu-core ufw vaca
vault-elopio vlc vtop webcam-webui-stylerrr webdm x11-apps
xkcd-webserver xkcdpass-codersquid yacas yagy

例えば、jenkinsパッケージの場合はopenjdkも専用のルートファイルシステムに含まれています。

3 snapパッケージの構成

snapパッケージの構成について記述します。

3.1 /var/lib/snapd/snaps/<package>.snap

専用ルートファイルシステムのsquashfsイメージです。/snap/<package>/<rev>にマウントされます。squashfsですので、読み込み専用となります。

$ mount | grep snap
/var/lib/snapd/snaps/ubuntu-core_122.snap on /snap/ubuntu-core/122 type squashfs (ro,relatime)
/var/lib/snapd/snaps/jenkins_6.snap on /snap/jenkins/6 type squashfs (ro,relatime)

3.2 /etc/systemd/system/snap-<package>-<rev>.mount

<package>.snapをマウントするsystemdスクリプトです。snap.<package>.<component>.serviceより早い段階で実行されます。

3.3 /etc/systemd/system/snap.<package>.<component>.service

command-<component>.wrapperをサービスとして起動するsystemdスクリプトです。SNAP_DATAやSNAP_USER_DATA等を設定します。snapd.frameworks.target以降に呼ばれます。

3.4 /snap/bin/<component>

command-<componetn>.wrapperを呼び出すスクリプトです。SNAP_DATAやSNAP_USER_DATA等を設定します。/etc/profile.d/apps-bin-path.shで/snap/binへPATHが設定されます。

3.5 /snap/<package>/<rev>/command-<component>.wrapper

/snap/bin/<component>とsnap.<package>.<component>.serviceから呼び出されるラッパースクリプトです。SNAP_DATAやSNAP_USER_DATA等を実際のコマンド向けに変換して、実際のコマンドを実行します。実際のコマンドとは/snap/bluez/6/usr/bin/bluetoothctl等の元来使われてきたコマンドです。

3.6 SNAP_DATA

ほとんどのパッケージで/var/snap/<package>/<rev>が設定されます。ログやデータベース等の出力先です。おそらく/etc/<package>.conf等の設定ファイルもここで実装すべきなのですが、command-<component>.wrapper次第です。例えば、jenkinsの/snap/jenkins/6/command-jenkins.wrapperは設定ファイル読み込みをサポートしておらず、TCPポートを変更する手段がありません。

3.7 SNAP_USER_DATA

ほとんどのパッケージは/<user>/snap/<package>/<rev>が設定されます。ユーザ毎のファイルが出力されます。

4 snapcraftのインストール

snapパッケージを作成する為のツールです。

$ sudo apt install -y snapcraft

4.1 snapcraftコマンド

パッケージ作成に関わるコマンドは以下のとおりです。

 

snapcraft パッケージのビルド
snapcraft clean ディレクトリのclean

 

4.2 snapcraft-examplesのインストール

snapパッケージを作成する為のビルドツリーのサンプルです。

$ sudo apt install -y snapcraft-examples
$ ls /usr/share/doc/snapcraft-examples/examples/git
96boards-kernel             godd              mosquitto    ros                  webchat
busybox                     gopaste           opencv       shout
downloader-with-wiki-parts  java-hello-world  py2-project  tomcat-maven-webapp
git                         libpipeline       py3-project  webcam-webui

gitを見てみます。

$ cp -a /usr/share/doc/snapcraft-examples/examples/git .
$ cd git
$ tree
.
├── setup
│   └── gui
│       └── icon.png
└── snapcraft.yaml

snapcraft.yamlがsnapパッケージを作成する為の設定ファイルです。内容は簡単になっています。

$ cat snapcraft.yaml
name: git
version: 2.8.0
summary: Git is a free and open source distributed version control system.
description: This example is not really production quality
confinement: strict

apps:
  server:
    command: bin/git

parts:
  git:
    plugin: make
    source: https://github.com/git/git
    source-type: git
    make-parameters:
      - prefix=
    build-packages: [gettext, libssl-dev, libcurl4-openssl-dev, libexpat1-dev]

snapcraftが提供するmakeプラグインはmake allとmake install DESTDIR=xxxを実行します。DESTDIRが適切に使われているMakefileの場合、ソースコードのURLとビルドに必要なパッケージの記述だけで済みます。

プラグインの一覧は以下のとおりです。

$ snapcraft list-plugins
ant        catkin  copy  jdk     kernel  maven  nodejs   python3 tar-content
autotools  cmake   go    kbuild  make    nil    python2  scons

gitのsnapパッケージをビルドします。

$ snapcraft
$ sudo snap install git_2.8.0_amd64.snap
$ ls /snap/git
current  x1

5 独自のsnapパッケージを作成する

ここでは単純なMakefileしか使わないテトリスのコードを用います。snapパッケージにしない場合は以下の手順でncursesコマンドとsdlコマンドが作成できます。

$ sudo apt install -y libsdl2-dev libsdl2-image-dev \
libsdl2-ttf-dev libncurses5-dev
$ git clone https://github.com/hiroom2/tetris-sdl-and-ncurses
$ cd tetris-sdl-and-ncurses
$ make $ ./jni/src/ncurses # or ./jni/src/sdl

ディレクトリを作成して、snapcraft initでsnapcraft.ymlのテンプレートを作成します。

$ mkdir tetris
$ snapcraft init # Generate template snapcraft.yml

snapcraft.ymlを以下の内容に変更します。appsの記述内容により、/snap/bin/<package>.<component>とラッパースクリプトが追加されます。

$ cat snapcraft.yaml
name: tetris
version: 1.0
summary: tetris with ncurses or sdl2
description: https://github.com/hiroom2/tetris-sdl-and-ncurses
confinement: strict

# /snap/bin/<package>.<component>
apps:
  sdl:
    command: bin/sdl
  ncurses:
    command: bin/ncurses

# Build package
parts:
  tetris:
    plugin: make
    source: https://github.com/hiroom2/tetris-sdl-and-ncurses
    source-type: git
    build-packages: [libsdl2-dev, libsdl2-image-dev, libsdl2-ttf-dev, libncurses5-dev]

ビルドします。

$ snapcraft
Preparing to pull tetris
Pulling tetris
Cloning into '/home/hiroom2/tetris/parts/tetris/src'...
remote: Counting objects: 26, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 26 (delta 1), reused 25 (delta 1), pack-reused 0
Unpacking objects: 100% (26/26), done.
Checking connectivity... done.
Preparing to build tetris
Building tetris
make -j1
make -C jni/src
make[1]: Entering directory '/home/hiroom2/tetris/parts/tetris/build/jni/src'
rm -rf sdl ncurses *.dSYM
g++ -Wall -I.  `sdl2-config --cflags` -o sdl Tetris.cpp TetrisSDL.cpp SDL.cpp -lpthread -lSDL2 -lSDL2_ttf
g++ -Wall -I. -o ncurses Tetris.cpp TetrisNcurses.cpp ncurses.cpp -lpthread -lncurses
make[1]: Leaving directory '/home/hiroom2/tetris/parts/tetris/build/jni/src'
make install DESTDIR=/home/hiroom2/tetris/parts/tetris/install
install -d -m755  /home/hiroom2/tetris/parts/tetris/install/bin/
install -m755 jni/src/sdl /home/hiroom2/tetris/parts/tetris/install/bin/
install -m755 jni/src/ncurses /home/hiroom2/tetris/parts/tetris/install/bin/ncurses
Staging tetris
Priming tetris
Snapping 'tetris' -
Snapped tetris_1.0_amd64.snap

インストールします。

$ sudo snap install tetris_1.0_amd64.snap

Name    Version  Rev  Developer  Notes
tetris  1.0      x1              -

/snap/tetrisにsquashfsがマウントされます。

$ tree /snap/tetris/
/snap/tetris/
├── current -> x1
└── x1
    ├── bin
    │   ├── ncurses
    │   └── sdl
    ├── command-ncurses.wrapper
    ├── command-sdl.wrapper
    ├── meta
    │   └── snap.yaml
    └── usr
        └── lib
            └── x86_64-linux-gnu
                ├── libasound.so.2
                ├── libasyncns.so.0
                ├── libFLAC.so.8
                ├── libogg.so.0
                ├── libpulse.so.0
                ├── libSDL2-2.0.so.0
                ├── libSDL2_ttf-2.0.so.0
                ├── libsndfile.so.1
                ├── libsndio.so.6.1
                ├── libvorbisenc.so.2
                ├── libvorbis.so.0
                ├── libwayland-client.so.0
                ├── libwayland-cursor.so.0
                ├── libwayland-egl.so.1
                ├── libX11.so.6
                ├── libXau.so.6
                ├── libxcb.so.1
                ├── libXcursor.so.1
                ├── libXdmcp.so.6
                ├── libXext.so.6
                ├── libXfixes.so.3
                ├── libXinerama.so.1
                ├── libXi.so.6
                ├── libxkbcommon.so.0
                ├── libXrandr.so.2
                ├── libXrender.so.1
                ├── libXss.so.1
                ├── libXxf86vm.so.1
                └── pulseaudio
                    └── libpulsecommon-8.0.so

/snap/bin/<package>.<component>が追加されました。

$ ls /snap/bin/tetris.*
/snap/bin/tetris.ncurses  /snap/bin/tetris.sdl