2017/08/16:ROS + Snappy Ubuntu Core (3) : Looking into the Snappy package

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

How does the Snappy package work?

$ 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

This seems to be equivalent to doing the following.

$ snap run talker-listener.listener

The snap file is simply expanded to /snap/. The directory ‘current’ should the latest version, but this is a symbolic link to ‘x1’. It will be easy to roll back.

$ 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

I see the command-listener.wrapper. Looking inside,

#!/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 "$@"

It seems that the command is executed after ROS environment setting etc are done with this wrapper file. In other words, you do not need “source setup.bash” which you always do with ROS. It seems to be easier.

What else is included in the snap package?

$ 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

Wow!

The talker-listener ‘s snap package contains the entire directory structure of the required Linux system as well as ROS. It feels a little overkill… But this is nowadays popular as Docker and other do, so-called container virtualization.

By the way, the generated snap file,

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

There are also 154 Mbyte! Is it acceptable when the package increases?
There are probably ways to solve this because the package contains a lot of unnecessary files.