2017/08/16:ROS + Snappy Ubuntu Core (3) : SnappyなROSパッケージの中身

Snappy + ROS, https://www.crowdsupply.com/krtkl/snickerdoodle/updates/1890

作成したSnappyのパッケージはどういう仕組みで動いているのでしょうか?

$ which talker-listener.listener 
/snap/bin/talker-listener.listener
$ ls -l /snap/bin/talker-listener.listener 
lrwxrwxrwx 1 root root 13 Jul 21 16:04 /snap/bin/talker-listener.listener -> /usr/bin/snap

となっています.これは,以下を実行するのと等価になるようです.

$ snap run talker-listener.listener

snapファイルは,単に/snap/に展開されるだけです.currentというのが最新版ですが,これはx1へのシンボリックリンクになっています.容易にロールバックできるようにするためなのでしょう.

$ ls -l /snap/talker-listener/
total 0
lrwxrwxrwx  1 root root   2 Jul 21 16:04 current -> x1
drwxrwxr-x 10 root root 222 Jul 21 16:00 x1
$ ls /snap/talker-listener/current
bin                       command-roscore.wrapper  etc  meta  snap  var
command-listener.wrapper  command-talker.wrapper   lib  opt   usr

command-listener.wrapperというのが目に付きます.中身を見ると,

#!/bin/sh
export PATH="$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH"
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu"
export ROS_MASTER_URI=http://localhost:11311
export ROS_HOME=${SNAP_USER_DATA:-/tmp}/ros
export LC_ALL=C.UTF-8
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib:$SNAP/lib/x86_64-linux-gnu:$SNAP/usr/lib/x86_64-linux-gnu
export PYTHONPATH=$SNAP/usr/lib/python2.7/dist-packages:$PYTHONPATH
export PATH=$PATH:$SNAP/usr/bin


# Shell quote arbitrary string by replacing every occurrence of '
# with '\'', then put ' at the beginning and end of the string.
# Prepare yourself, fun regex ahead.
quote()
{
    for i; do
        printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/"
    done
    echo " "
}

BACKUP_ARGS=$(quote "$@")
set --

if [ -f $SNAP/opt/ros/kinetic/setup.sh ]; then
    _CATKIN_SETUP_DIR=$SNAP/opt/ros/kinetic . $SNAP/opt/ros/kinetic/setup.sh
fi

eval "set -- $BACKUP_ARGS"

export LD_LIBRARY_PATH="$SNAP/opt/ros/kinetic/lib:$SNAP/usr/lib:$SNAP/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH=$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH
exec "rosrun" roscpp_tutorials listener "$@"

となっており,ROSの環境設定などはこのラッパーファイルで行われた上で,コマンドが実行されるようです.つまり,いつもROSでやっているような”source setup.bash”などは必要ないことになります.楽になりそうですね.

snapパッケージにはほかに何が含まれているのでしょうか.

$ tree -L 3 -d /snap/talker-listener/current/
/snap/talker-listener/current/
├── bin
├── etc
│   ├── ca-certificates
│   │   └── update.d
│   ├── dpkg
│   │   └── dpkg.cfg.d
│   ├── emacs
│   │   └── site-start.d
│   ├── gss
│   │   └── mech.d
│   ├── ldap
│   ├── openmpi
│   ├── perl
│   │   ├── CPAN
│   │   └── Net
│   ├── python2.7
│   ├── python3.5
│   ├── sgml
│   ├── ssl
│   │   ├── certs
│   │   └── private
│   ├── systemd
│   │   └── system
│   └── xml
├── lib
│   └── x86_64-linux-gnu
├── meta
│   └── gui
├── opt
│   └── ros
│       └── kinetic
├── snap
├── usr
│   ├── bin
│   ├── include
│   │   ├── apr-1.0
│   │   ├── arpa
│   │   ├── asm-generic
│   │   ├── boost
│   │   ├── c++
│   │   ├── console_bridge
│   │   ├── drm
│   │   ├── gtest
│   │   ├── hwloc
│   │   ├── infiniband
│   │   ├── libltdl
│   │   ├── linux
│   │   ├── log4cxx
│   │   ├── misc
│   │   ├── mtd
│   │   ├── net
│   │   ├── netash
│   │   ├── netatalk
│   │   ├── netax25
│   │   ├── neteconet
│   │   ├── netinet
│   │   ├── netipx
│   │   ├── netiucv
│   │   ├── netpacket
│   │   ├── netrom
│   │   ├── netrose
│   │   ├── nfs
│   │   ├── numpy -> ../lib/python2.7/dist-packages/numpy/core/include/numpy
│   │   ├── openmpi -> ../lib/openmpi/include
│   │   ├── protocols
│   │   ├── python2.7
│   │   ├── rdma
│   │   ├── rpc
│   │   ├── rpcsvc
│   │   ├── scsi
│   │   ├── sound
│   │   ├── uapi
│   │   ├── uuid
│   │   ├── video
│   │   ├── x86_64-linux-gnu
│   │   └── xen
│   ├── lib
│   │   ├── compat-ld
│   │   ├── dpkg
│   │   ├── emacsen-common
│   │   ├── gcc
│   │   ├── gold-ld
│   │   ├── lapack
│   │   ├── ldscripts
│   │   ├── libblas
│   │   ├── mime
│   │   ├── openmpi
│   │   ├── pkgconfig
│   │   ├── python2.7
│   │   ├── python3
│   │   ├── python3.5
│   │   ├── sasl2
│   │   ├── sbcl
│   │   ├── ssl
│   │   ├── valgrind
│   │   └── x86_64-linux-gnu
│   ├── sbin
│   ├── share
│   │   ├── aclocal
│   │   ├── applications
│   │   ├── apps
│   │   ├── apr-1.0
│   │   ├── bash-completion
│   │   ├── binfmts
│   │   ├── boostbook
│   │   ├── boost-build
│   │   ├── bug
│   │   ├── ca-certificates
│   │   ├── cmake-3.5
│   │   ├── debhelper
│   │   ├── dh-python
│   │   ├── distro-info
│   │   ├── doc
│   │   ├── doc-base
│   │   ├── docutils
│   │   ├── dpkg
│   │   ├── emacs
│   │   ├── glib-2.0
│   │   ├── icu
│   │   ├── libtool
│   │   ├── lintian
│   │   ├── man
│   │   ├── mime
│   │   ├── mpi-default-dev
│   │   ├── numpy
│   │   ├── openmpi
│   │   ├── perl
│   │   ├── perl5
│   │   ├── pixmaps
│   │   ├── pkgconfig
│   │   ├── pyshared
│   │   ├── python
│   │   ├── python3
│   │   ├── sgml
│   │   ├── sgml-base
│   │   ├── xml
│   │   └── xml-core
│   └── src
│       └── gtest
└── var
    └── lib
        ├── sgml-base
        ├── systemd
        └── xml-core

144 directories

ワオ! talker-listenerのsnapパッケージには,ROSはもちろん,必要なLinuxシステムのディレクトリ構造がまるごと含まれています.ちょっと無駄な気がしますね…しかし,これがdockerなどで最近の流行りの,アプリごとに1つのコンテナを持つ(コンテナ仮想化),というやり方なのですね.

ちなみに,生成されたsnapファイルは,

$ ls -sh talker-listener_0.1_amd64.snap 
154M talker-listener_0.1_amd64.snap

なんと154Mbyteもあります.こんなに大きくて,パッケージが増えた時には大丈夫なんでしょうか…どう見ても必要のないファイルがパッケージにたくさん含まれているので,このへんはおそらく解決する方法があるのでしょう.