Manually snap packaging Transmission
This is part of a series describing how I got Transmission compiled and running for Snappy Ubuntu Core.
Snap packaging
Having Transmission compiled binaries, we can now build our first snap package1. For that we will need the following extra files: package.yaml
(for the package metadata) and readme.md
.
The package directory/files structure will be:
meta/
package.yaml
readme.md
transmission.png
web/* # HTML/static assets for the web UI (copied from the transmission build)
x86_64/
lib/* # compiled dependencies/libraries (copied from the deps build)
transmission-daemon # binary for the daemon (copied from the transmission build)
settings.json
transmission-daemon # custom script to run the daemon in snappy
Note the above is just how I decided to organize it, but you can change/adapt as desired. The only required bits are the meta directory and the package.yaml
and readme.md
files in there.
A wrapper script to run the daemon is added to define custom environment variables23 to run Transmission daemon taking into account Snappy filesystem structure4. Also, a custom default settings file is provided that enables access to web UI from the local network.
If you take a look, this script will also handle multiple architecture binaries (that will be useful once we compile Transmission for ARM, for example).
Back to snap packaging, the minimal package.yaml
5 for our Transmission package could look something like:
As you can see we are providing our package metadata (icon, version, architectures, etc) and describing how the service is run.
Since the daemon will act as a server and a client, and require access to networking capabilities, we set the respective caps
property. We also declare the ports
we will need to be open, for the web UI (under the ui
label, convention used by webdm to link to the web app) and for the (optional) peers listening.
To build our package, in the package root directory, run:
If everything went ok, you can push it to your Snappy instance as we see in the first post:
Security issues
We have Transmission daemon running, but you will notice a few issues: the web UI freezes, and checking the logs 6 you will see apparmor denials when trying to access mounts and when attempting to do quotactl
syscalls.
This is because our package runs confined, and access to some resources is not allowed by default, for security reasons. You could customize apparmor and security profiles to get access to those resources7, but this will trigger a manual review when uploading the package to the store and it will likely be rejected, since you will be breaking the default confinement. So, instead, let’s try to find a work around.
Checking Transmission source code (this file: libtransmission/platform-quota.c
), you will notice that mounts
and quotactl
calls are related to the free space checks the daemon does. You can also see that there are different implementations for different platforms, guarded by compilation flags. Then, we can tweak our compilation flags to use a different implementation, particularly the one based on statvfs
, which works without any extra requirement in Snappy, and so it won’t require a custom profile and/or trigger a manual review.
After re-compiling with those changes, re-packaging and pushing to our Snappy instance, everything works as expected and there is no error in the logs!
Exposing other binaries
If you want, you could also provide extra binaries (and/or services) in your package. For example, we could also include and provide binaries for the extra Transmission tools, like transmission-remote
.
For that, we will be updating our package.yaml
and add the required extra files: the compiled binary and a wrapper script:
meta/
package.yaml
readme.md
transmission.png
web/*
x86_64/
lib/*
transmission-daemon
transmission-remote # binary for the remote tool (copied from the transmission build)
settings.json
transmission-daemon
transmission-remote # script to run remote, similar (simplified) to the one for daemon
In the package.yaml
description we add a new binaries
keyword where we list our new executable entry:
Repackaging and pushing to our instance will make the transmission.remote
executable available.
Coming next
And that’s it, we have a working Transmission snap package for amd64. Next steps will be:
- Build Transmission for ARM
- Build multi-architecture snap package
- Build Transmission using snapcraft
-
https://developer.ubuntu.com/en/snappy/guides/packaging-format-apps/ ↩
-
https://trac.transmissionbt.com/wiki/EnvironmentVariables ↩
-
https://developer.ubuntu.com/en/snappy/guides/security-policy/ ↩
-
https://developer.ubuntu.com/en/snappy/guides/filesystem-layout/ ↩
-
https://developer.ubuntu.com/en/snappy/guides/package-metadata/ ↩
-
see Debugging section, https://developer.ubuntu.com/en/snappy/guides/security-policy/ ↩
-
https://developer.ubuntu.com/en/snappy/guides/security-policy/ ↩
Comments