Is snap portable across other UNIX (example macOS)?

Solution 1:

Yes, thanks to the stability of the Linux syscall interface, this is possible.

One of Linus Torvalds' great commitments to Linux users is that the set of interfaces offered by the kernel is stable. Many people don't appreciate the value of this, or how challenging it is as a leader of an open project to achieve that commitment. Consider for example how unpredictable changes in the GNOME APIs are by contrast! When you hear about Linus getting intense on a mailing list, it's almost always because some committer to the kernel decided to change such an interface 'because they had a better idea'. Linus says you can innovate wildly INSIDE the kernel, but please don't break the 'userspace' apps which depend on existing syscalls.

As a consequence of that stability it is possible for other kernels to offer the same syscalls, allowing apps built on Linux to run on those other kernels.

One example of that is the Joyent Triton project, which offer Linux-compatible syscalls in containers on SmartOS (a descendent of IllumOS, a descendent of Solaris).

A more widely known example is the new Linux subsystem in Windows.

Of course, how many of the syscalls are offered, and how bug-for-bug compatible they are, is the real question. At least for now, there is not another environment where all the necessary syscalls are in place, because the ones snaps use are relatively new and deep in the way the kernel thinks about the things it manages.

But they will certainnly come, in time, and I think snaps will thus be usable in a wide range of contexts.

Which is very cool, patches welcome :)

Solution 2:

While I can't find any information about macOS, this OMG! Ubuntu article has an interesting quote from Mark Shuttleworth:

As for running Snaps on Windows 10? “It’s absolutely plausible” Shuttleworth said.

“Snaps are using modern features in the Linux kernel to do security confinement, set up file system access, etc, and all of that involves using modern mechanisms in the kernel. And Canonical lead a lot of [this work]. It’ll take a while for Microsoft to [get to hook in to it].”

If it's "plausible" to get it running in Windows, I'd say the same for macOS, except that Microsoft seems to be cooperating with Canonical, which is not something I have heard about Apple doing.


The documentation on Snap security policy and sandboxing and the Arch Wiki entry on snapd are informative:

From the Arch Wiki:

Note that snap-confine is built with the --disable-confinement option; full confinement relies on an AppArmor enabled kernel and related profile for the snap.

From the policy:

Under the hood, the launcher:

  • Sets up various environment variables: […]
  • When hardware is assigned to the snap, sets up a device cgroup with default devices (eg, /dev/null, /dev/urandom, etc) and any devices that are assigned to this snap
  • Sets up a private /tmp using a per-command private mount namespace and mounting a per-command directory on /tmp
  • Sets up a per-command devpts new instance
  • Sets up the seccomp filter for the command
  • Executes the command under the command-specific AppArmor profile under a default nice value

This combination of restrictive AppArmor profiles (which mediate file access, application execution, Linux capabilities(7), mount, ptrace, IPC, signals, coarse-grained networking), clearly defined application-specific filesystem areas, whitelist syscall filtering via seccomp, private /tmp, new instance devpts and device cgroups provides for strong application confinement and isolation.

While AppArmor and seccomp are Linux only, it looks like confinement can be made optional, so we can ignore that. Then there's usage of devpts, cgroups and mount namespaces. If there's any blocking, I think it would be for those. I'm not familiar enough with the BSDs to say what the equivalents are.

The snapd application itself is written in Go, which should make it reasonably cross-platform. Indeed, some files have very interesting build targets:

osutil/group_other.go:

// -*- Mode: Go; indent-tabs-mode: t -*-
// +build !linux,!darwin,!freebsd

osutil/group_linux.go:

// -*- Mode: Go; indent-tabs-mode: t -*-
// +build darwin freebsd linux
// +build cgo

So it looks like someone has an interest in this.