Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility between AppImages and Snaps #166

Open
shoogle opened this issue Jun 17, 2016 · 9 comments
Open

Compatibility between AppImages and Snaps #166

shoogle opened this issue Jun 17, 2016 · 9 comments

Comments

@shoogle
Copy link

shoogle commented Jun 17, 2016

There's been quite a bit of fuss about snaps in the last few days, with Canonical attempting to push them as the new universal Linux packaging format. So what does this mean for AppImages?

The two formats have much in common, but there are some key differences:

  • Snaps offer shared libraries and certain security features which AppImages can't offer, so Snaps will probably be favoured by distributions and will be more appropriate for IoT devices.
  • AppImages offer installation without root priviledges, compatibility with older distributions, the ability to carry them around on a USB stick, and independence from distributions and package managers. Snaps can't offer those things (not even in principle) so AppImages will be essential for users of older distributions and users who don't have root access (e.g. on a work computer).

So the two formats actually have different uses and will probably exist side-by-side.

But perhaps we can do better than coexistance, and actually work together?

It turns out that converting a snap to an AppImage is very easy to do. Simply:

  • Extract the contents from the snap container into a folder named $APP.AppDir
  • Set some environment variables in the existing launcher script, or create a new launcher script:
#!/bin/sh
export SNAP="$APPDIR"
export SNAP_ARCH="amd64"
export SNAP_VERSION="3" # for example (get the version from the original snap)
export SNAP_USER_DATA="$HOME/snap"

"$APPDIR/"*.wrapper "$@"
  • Name the launcher script "AppRun" and chmod +x
  • Copy the .desktop file and app icon from ./share/... into the root of the AppDir
  • Package with AppImageAssistant.

The resulting "SnapImage" can be carried around on a USB stick and used on other machines. Unfortunately, binary executables packaged this way won't magically become compatible with older distributions, so the result is not as portable as an AppImage compiled the usual way, but it is a good start! Perhaps if the snap packaging system is ported to older distribution and the snap was compiled there it would do the trick?

There are other areas where Snaps and AppImages might be able to work together, for example if the snap daemon were to set up a sandbox for AppImages. If snapd really is to be ported to every distribution then this might be an avenue worth perusing. Of course, AppImages should still work on systems without it.

@probonopd
Copy link
Member

Thanks @shoogle, indeed it would be nice if one could convert between the different formats. The philosophical difference is that AppImage doesn't allow for dependencies other than the base system, whereas Snappy introduces a dependency on the Ubuntu Core image. This might be not so easy to work around without resulting in larger AppImages than need be.

@probonopd
Copy link
Member

probonopd commented Jun 28, 2016

To be clear: This is not a recommended way to build AppImages, because they will not be very compatible to older/different target systems.

@probonopd
Copy link
Member

Turns out that this may become more feasible once the oldest still-supported Ubuntu version is the same version that most Snaps are built against... which may be once 14.04 is no longer supported? cc @zyga

@probonopd
Copy link
Member

Some semi-random notes for future reference.

sudo su

echo "SNAPD_DEBUG=1" >> /etc/environment
echo "SNAPD_DEBUG_HTTP=7" >> /etc/environment

sudo systemctl restart snapd.service

sudo snap install bluemail

journalctl -xeu snapd | grep "GET.*\.snap "

# host snapd[3114]: logger.go:67: DEBUG: > "GET /api/v1/snaps/download/99T7MUlRhtI3U0QFgl5mXXESAiSwt776_7713.snap HTTP/1.1\r\nHost: api.snapcraft.io\r\nUser-Agent: snapd/2.37.1.1+18.04 (series 16; classic) ubuntu/18.04 (amd64) linux/4.18.0-15-generic\r\nAccept: \r\nX-Ubuntu-Architecture: amd64\r\nX-Ubuntu-Classic: true\r\nX-Ubuntu-Series: 16\r\nX-Ubuntu-Wire-Protocol: 1\r\nAccept-Encoding: gzip\r\n\r\n"
# host snapd[3328]: logger.go:67: DEBUG: > "GET /api/v1/snaps/download/ZVlj0qw0GOFd5JgTfL8kk2Y5eIG1IpiH_3.snap HTTP/1.1\r\nHost: api.snapcraft.io\r\nUser-Agent: snapd/2.41 (series 16; classic) ubuntu/18.04 (amd64) linux/4.18.0-15-generic\r\nAccept: \r\nX-Device-Authorization: Macaroon root=\"MDAxZWxvY2F0aW9uIGFwaS5zbmFwY3JhZnQuaW8KMDAxZWlkZW50aWZpZXIgZGV2aWNlLXNlc3Npb24KMDA0MGNpZCBhcGkuc25hcGNyYWZ0LmlvfHZhbGlkX3NpbmNlfDIwMTktMTAtMTBUMDg6Mzk6MjAuMjI4MDk3CjAwNDZjaWQgYXBpLnNuYXBjcmFmdC5pb3xzZXNzaW9ufDI2MzExZTY4LWM5NjgtNDRlYy1iZDUxLTJmZDI5YTI1M2U0MwowMDliY2lkIGFwaS5zbmFwY3JhZnQuaW98ZGV2aWNlfHsiYXV0aG9yaXR5IjogImdlbmVyaWMiLCAibW9kZWwiOiAiZ2VuZXJpYy1jbGFzc2ljIiwgImJyYW5kIjogImdlbmVyaWMiLCAic2VyaWFsIjogImI1ZjRjZDQ5LTlhODQtNGJmZS1hOGUxLTFiMGFmMTgyNTllMyJ9CjAwMjBjaWQgYXBpLnNuYXBjcmFmdC5pb3xzdG9yZXwKMDAyZnNpZ25hdHVyZSDT4PqwtJ1UO_C4QZFvhvFwY1dMh7UpE-UNeWjCNNPTKwo\"\r\nX-Ubuntu-Architecture: amd64\r\nX-Ubuntu-Classic: true\r\nX-Ubuntu-Series: 16\r\nX-Ubuntu-Wire-Protocol: 1\r\nAccept-Encoding: gzip\r\n\r\n"

mount 
# /var/lib/snapd/snaps/core_7713.snap on /snap/core/7713 type squashfs (ro,nodev,relatime,x-gdu.hide)
# /var/lib/snapd/snaps/bluemail_3.snap on /snap/bluemail/3 type squashfs (ro,nodev,relatime,x-gdu.hide)

# command.sh main entrypoint. Like AppRun
me@host:~$ cat /snap/bluemail/3/command.sh 
#!/bin/bash
exec $SNAP/bin/desktop-launch "$SNAP/bluemail"

$SNAP = Directory where the snap is mounted. Like $APPDIR
# /snap/bluemail/3/

# desktop-launch = a wrapper script. Why is this code not in command.sh?
# Does GNOME runtime selection (find the snap)
# We don't seem to need all of that for AppDir
/snap/bluemail/3/bin/desktop-launch

# Here, we have a simple Electron app. It does not even need stuff from the base snap (=runtime?)
LD_LIBRARY_PATH=/snap/bluemail/3/usr/lib/x86_64-linux-gnu/ /snap/bluemail/3/bluemail 

Let's see what the app uses from the system and whether that is acceptable
me@host:~$ LD_LIBRARY_PATH=/snap/bluemail/3/usr/lib/x86_64-linux-gnu/  ldd /snap/bluemail/3/bluemail  | grep -v /snap
	linux-vdso.so.1 (0x00007ffc7b598000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd873cad000)
	libdbus-1.so.3 => /lib/x86_64-linux-gnu/libdbus-1.so.3 (0x00007fd871cc7000)
	libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fd86f9c9000)
	librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fd86e3fc000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd86e1f8000)
	libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fd86dd83000)
	libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd86d9fa000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd86d65c000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd86d444000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd86d053000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd8751a2000)
	libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fd86aa63000)
	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fd86a83b000)
	libresolv.so.2 => /lib/x86_64-linux-gnu/libresolv.so.2 (0x00007fd86a620000)
	libsystemd.so.0 => /lib/x86_64-linux-gnu/libsystemd.so.0 (0x00007fd86a194000)
	libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fd8698f1000)
	liblzma.so.5 => /lib/x86_64-linux-gnu/liblzma.so.5 (0x00007fd867517000)
	liblz4.so.1 => /usr/lib/x86_64-linux-gnu/liblz4.so.1 (0x00007fd8672fb000)
	libgcrypt.so.20 => /lib/x86_64-linux-gnu/libgcrypt.so.20 (0x00007fd866fe0000)
	libcom_err.so.2 => /lib/x86_64-linux-gnu/libcom_err.so.2 (0x00007fd8668db000)
	libgpg-error.so.0 => /lib/x86_64-linux-gnu/libgpg-error.so.0 (0x00007fd8650c1000)
	libkeyutils.so.1 => /lib/x86_64-linux-gnu/libkeyutils.so.1 (0x00007fd864ebd000)

# This is the stuff that we could probably take from the base snap if so required

strings /snap/bluemail/3/bluemail  | grep GLIBC_ | sort -Vr | head -n 1
GLIBC_2.17 # from 2012, so should be alright

me@host:~$ strings /snap/bluemail/3/bluemail  | grep GLIBCXX_ | sort -Vr | head -n 1
GLIBCXX_3.4.19

@zyga
Copy link

zyga commented Oct 18, 2019

If the goal is to run snap packages via appimage then I think you need a bit more to work correctly. Not all snaps can be just unpacked and started successfully. Many snaps require the mount namespace to be configured according to the package description.

You may have some luck with snaps using classic confinement but for strictly confined snaps I think the likelihood of this working long-term is close to zero.

@orowith2os
Copy link

orowith2os commented Mar 5, 2023

I suggested #1251 to achieve maybe the same thing, along with supporting more distros and fixing a number of issues AppImage has in practice. If 1251 was closed and locked, wouldn't it make sense for this to be too?

@probonopd
Copy link
Member

Hi @orowith2os, architecturally Snap is way closer to AppImage than Flatpak is. Both are using squashfs images. I think that a collaboration between the creators of AppImage and Snap might be beneficial for everyone. But then, companies like Canonical have a track record of cancelling projects after a couple of years, so as a community project AppImage with limited resources we need to be careful where to invest time.

@orowith2os
Copy link

orowith2os commented Mar 5, 2023

Supporting Flatpaks rather than Snaps would still end up likely working better, and on more distros. If anything, working something out with Flatpak would be better for everyone. I sense some bias (against Flatpak) here :)

@probonopd
Copy link
Member

As explained elsewhere, I don't see a way to do that without breaking completely what AppImage stands for. If you have concrete ideas on what to do, why to do it, and ideally how to do it, then please open a discussion over at the Ideas section. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants