I’m currently working a snap that is runnable both under strict and classic confinement, however, some runtime environment changes must be made to make the application work properly in different confinement(strict, classic, and even jail), is there a reliable way to do so?
Currently what I know of:
In classic confinement snap’s HOME environment variable isn’t same as the user’s real home directory
real_home_dir="$(
getent \
passwd \
"${USER}" \
| cut \
--delimiter=: \
--fields=6
)"
# Don't do anything in classic confinement
if test "${HOME}" != "${real_home_dir}"; then
But it didn’t work in --jailmode, where the snap still using the user’s real home directory.
# Don't LD_PRELOAD bindtextdomain for classic snaps
if ! grep -qs "^\s*confinement:\s*classic\s*" $SNAP/meta/snap.yaml; then
if [ -f $SNAP/lib/bindtextdomain.so ]; then
export LD_PRELOAD=$LD_PRELOAD:$SNAP/lib/bindtextdomain.so
fi
fi
IMO there should be a snapctl get-confinement command or a SNAP_CONFINEMENT_MODE environment variable to simplify the detection.
# Output: strict, classic, or jail
detect_snapd_confinenment_mode(){
local \
real_home_dir
real_home_dir="$(
getent \
passwd \
"${USER}" \
| cut \
--delimiter=: \
--fields=6
)"
# strict or classic?
if test "${HOME}" != "${real_home_dir}"; then
printf strict
else # classic or jail?
local file_under_test
if test -e ~/.bashrc; then
file_under_test=~/.bashrc
elif test -e ~/.profile; then
file_under_test=~/.profile
elif test -e ~/.config; then
file_under_test=~/.config
else
file_under_test=none
fi
# In jail mode, HOME is set to the user's real home, but interface restrictions (i.e. no dotfiles access right under HOME) applies.
if test "${file_under_test}" != none; then
if cat "${file_under_test}" &> /dev/null; then
printf classic
else
printf jail
fi
else
# assume classic
printf classic
fi
fi
}
@Lin-Buo-Ren - I’m sure you’re aware, but this method is a little noisy since it will generate a security policy violation every time the function is run.
It might be nice to expose this via snapenv. Eg, SNAP_CONFINEMENT=strict.
$ snap run --shell gimp
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
$ grep confinement $SNAP/meta/snap.yaml|sed 's/^.*: //'
strict
(it is a required field and $SNAP/meta/snap.yaml always exists)