Of course. Run snapcraft prime
with this snapcraft.yaml
:
name: test-snap
version: '0.1'
summary: summary
description: description
grade: devel
confinement: strict
apps:
hello:
command: echo "hello"
parts:
my-part:
plugin: nil
Even this ultra-simple example rewrites the command to use a wrapper:
$ cat prime/meta/snap.yaml | grep hello
hello:
command: command-hello.wrapper
$ cat prime/command-hello.wrapper
#!/bin/sh
export PATH="$SNAP/usr/sbin:$SNAP/usr/bin:$SNAP/sbin:$SNAP/bin:$PATH"
export LD_LIBRARY_PATH=$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH
exec "echo" "hello" "$@"
In many cases, such as this one, the wrapper consists entirely of environment variables, which nowadays should be using the environment
property (although hooks don’t support that yet). However, depending on the plugins used, the wrappers can be far more complex, well beyond just exporting variables. Avert your eyes:
#!/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:+:$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 "roslaunch" "edukit_bot" "edukit_bot.launch" "$@"
The more plugins involved, the nastier it gets. This proposal is to stop dumping everything into a nasty wrapper, and simply provide an executable instead, telling snapd that it must run before the app
by using the command-chain
keyword.
This comes back to the templates proposal as well: we want to keep templates solely to generating YAML, not throwing more shell code in an opaque, already-nasty wrapper. This empowers it to simply add a command to the chain.