During installation of an app we rewrite and clean up the
deployed export directory, but don't actually export it.
Instead we export only the "current" version of the application
when we run update_exports (passing in which app changed). This way
we ensure that any newly exported files in the current app are exported
before we remove all dangling symlinks.
To make the symlinks properly dangle we also make the export symlinks
point use the "current" and "active" symlinks so non-current deployed
dirs don't keep an old symlink from being removed.
When installed a branch is made current, and we list this in list-apps.
This means nothing atm, but will be used to limit exports to the current
branch of an app.
Having /var writable is pretty weird for a desktop app, this
is typically a system location. Instead of doing this
we assume the user writes writable data into ~/.var/app/$appid.
This means an app following this can run both as standalone or
as an xdg-app without changes.
If the app has access to the home directory, then this just works. If
it does not, then we ensure we have this directory in the volatile
home directory and then bind mount in the real directory there.
We also pre-create config/data/cache subdirectories in this
directory and set XDG_DATA/CONFIG/CACHE_HOME to point to them, which
means apps that use these "just work".
For builds, reproducability and not accidentally getting
the host environment details into the build is pretty important,
so we rebuild the entire environment, controlling exactly
what gets into it.
Instead of creating real device nodes we just bind mount the system
ones. This means that we require no mknod capabilities, which is good
in itself, but it also allows us to eventually run completely
unprivileged with user namespaces.
All exported regular files (not directories) need to have a filename
that starts with the application name, followed by either a dot or
any character that is invalid in an app name.
For instance, given an app name of org.gnome.gedit, these filenames
are exported:
org.gnome.gedit
org.gnome.gedit.png
org.gnome.gedit.plugin1.png
org.gnome.gedit-symbolic.svg (- is not a valid character)
However, these are not exported:
org.gnome.geditor
gedit.png
This has several advantages. First of all it ensures that there are no
conflicts between unrelated applications, secondly we also only allow
applications to install dbus services and desktop ids that are the
same as the app id, or sub-services of it.
Rather than keeping around a symlink to the temporary file we rename
the temporary over the original name. Also we keep all seen
files and temporary files in a hashtable so we don't accidentally
process anything twice.
There are several reasons to verify these. First of all
we use these as filename elements, so we need to sure that dangerous
things like "..", "/" etc don't appear in them.
Secondly, we want to guarantee that app names are valid dbus well
known bus names as they are used as app-ids in e.g. desktop files.
We also want to enforce the app name as prefix for exported files to
avoid conflicts. This means we disallow two-element names like
"org.gnome", and we disallow "-" in app names, so that "-" can be used
to separate the app name prefix from the rest of the filename. In
particular, this is important for icons, like
"org.gnome.app-symbolic.svg", where we want the only valid prefix to be
org.gnome.app.
When we add a remote, load the summary from the repository, and
use the title if there is one. This at the same time serves as
(minimal) validation of the repository url.