In case a runtime becomes unused and then later becomes End-Of-Life, it
is currently not removed. So this commit removes such runtimes in the
update command, as discussed in #2639. A unit test is included.
I am planning to propose to use the FlatpakTransaction API added here in
gnome-software, so that users don't have to use the CLI at all for
runtimes to be cleaned up. KDE Discover already removes unused runtimes
periodically.
We normally don't remove a runtime when the last app using it is
uninstalled, since runtimes are large and re-downloading it in the
future may be difficult. But if the runtime is end-of-life, there's a
reasonable chance it won't be used again, so uninstall it in that case.
Similarly, if the last app using a runtime is upgraded to a different
runtime, and the runtime is EOL, uninstall it.
A unit test is included, and the subsequent unit test also had to be
modified. Otherwise we get a "Update is older than current version"
error, since the runtime is installed from test-repo but
setup_repo_no_add() calls make_runtime() which uses the one in
runtime-repo instead, which is older than the one in test-repo.
In a few places we are using
flatpak_installation_list_unused_refs() and then only
using the ref strings not the FlatpakInstalledRef objects, so the
resources used to construct those objects are wasted. Add a flatpak_dir_
function to be used internally instead. One day we will figure out how
to make flatpak-dir.c less of a wilderness.
This also adds the flatpak_installation_list_unused_refs_with_options()
verion that has extended features.
commit 6b46d9a0ed that added DConf path
skewering to camelcase conversion only allowed it in one direction
(skewered path1 and camelcase path2).
That turned out to be not enough to allow /org/gnome/sound-juicer/ to
/org/gnome/SoundJuicer/ conversion as the caller had the
flatpak_dconf_path_is_similar() arguments the other way around.
This commit implements it both ways to avoid confusion which way it
should be called.
F: Ignoring D-Conf migrate-path setting /org/gnome/sound-juicer/
I'm not documenting the individual methods here, only the fact that the
interface exists and is private to the Flatpak source tree (it's the
communication between libflatpak and the system helper).
Signed-off-by: Simon McVittie <smcv@collabora.com>
This is based on documentation that I wrote for Steam's pressure-vessel,
which has a Launcher interface based on the API and implementation of
the Flatpak portal.
I haven't renamed exit_status to wait_status like commit 63feb3cc in
flatpak-xdg-utils, just in case the name is significant in someone's
code-generation. However, don't be fooled: it's a wait-status, not
an exit status.
Signed-off-by: Simon McVittie <smcv@collabora.com>
They aren't currently in any installed header file, but that doesn't
mean we can't suggest a name for dependent projects to #define.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Flags are assumed to be critical, similar to the convention for modern
Linux syscalls: if an unknown flag is given, the call will fail.
Callers are expected to guard their use of flags with a version check
or a fallback.
Conversely, options are assumed to be non-critical "hints", similar
to org.freedesktop.Notifications: if an unknown option is given, the
call will succeed as though the option had not been present. Callers
are expected to carry out an explicit version check if they need to
know whether an option is going to be respected or not.
Signed-off-by: Simon McVittie <smcv@collabora.com>
When launched when the session starts, /run/media/%u may not exist if
the user has never mounted any removable storage devices. This causes
the unit to fail on login.
Relax the check to just validate that the argument has been provided.
Since we use shopt -s nullglob, the "$media_dir"/* glob will expand to
the empty list if $media_dir does not exist.
(The other option is to add a condition check to the .service, but the
script might conceivably want to clean up some stale symlinks.)
Check file ownership to ensure flatpak-create-sideload-symlinks.sh
only cleans up links it created. This could be relevant on multi-user
systems with fast user switching.
man systemd.path has the following to say:
> When a service unit triggered by a path unit terminates (regardless
> whether it exited successfully or failed), monitored paths are checked
> immediately again, and the service accordingly restarted instantly.
On my system, I observe that once /run/media/wjt is created,
flatpak-sideload-usb-repo.service is invoked in a tight loop. I think
what's happening is that PathExists=/run/media/wjt continues to be true,
so the service keeps getting restarted.
What we instead want is to activate the .service:
- On login
- When the media directory *changes* (because mount points beneath it
appear or disappear)
Remove PathExists from the .path, and instead mark the .service as
WantedBy default.target so it is launched on login.
Previously, if there were no existing symlinks, this script would fail:
wjt@camille:~$ LANG=en_GB.utf8 bash -x /usr/libexec/flatpak-create-sideload-symlinks.sh /run/media/wjt
+ test 1 -eq 1
+ test -d /run/media/wjt
+ for f in "$1"/*
+ test -d '/run/media/wjt/*'
+ continue
+ for f in /run/flatpak/sideload-repos/automount-*
+ test -e '/run/flatpak/sideload-repos/automount-*'
+ rm '/run/flatpak/sideload-repos/automount-*'
rm: cannot remove '/run/flatpak/sideload-repos/automount-*': No such file or directory
This is due to the surprising POSIX shell behaviour that a glob that
matches no files expands to itself, rather than to the empty list.
http://mywiki.wooledge.org/BashFAQ/004
The POSIX solution is to add 'test -L $f' inside the loop to check if
the variable actually exists. The first loop in this script uses this
technique: it has a 'test -d "$f"', seen in the trace above.
Bash implements a 'nullglob' feature which gives globs the behaviour you
might hope for. Set it in this script.
Allow a snake-case in the app-id to convert to a '-' or '_' in the
DConf path to be considered similar enough for DConf migration purposes.
This allows the org.gnome.SoundJuicer app-id to migrate its
/org/gnome/sound-juicer DConf path.
F: Ignoring D-Conf migrate-path setting /org/gnome/sound-juicer/
This is no longer needed since a FlatpakRemoteState is passed in, which
ensures the repo exists. The similar call was already removed from
flatpak_dir_install().
Avoid shadowing variables that are already declared in a previous scope,
and make such occurrences compile-time errors. These are not functional
changes.
In a few places do related code cleanup.
A similar ostree PR is here:
https://github.com/ostreedev/ostree/pull/2195
Fix lookup_installation_for_path() to not leave the GError pointer unset
on its error code path. This error is only used by the caller for a
debug message, and shouldn't be hit normally, but it could mean a NULL
pointer dereference when we try to print error->message.
Now that FlatpakExports can be told to look for /etc and /usr in a
fake directory hierarchy, we can assert that systems resembling
particular OSs' layouts still work, even if we are not running on that
OS right now. In particular, this provides unit tests for commits
12e3dc05, 08d65c54, 7872935e and fe2536b8.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The previous implementation was rather simplistic, and assumed that
all symlinks that get exported are in /tmp/something/test_full/.
Tighten up the assertions, while also coping with symlinks that are
created at top level, such as /bin -> usr/bin.
Signed-off-by: Simon McVittie <smcv@collabora.com>
This is primarily for test coverage ("design for test"): it will let us
pretend a temporary directory is the host for the purposes of testing
--filesystem=host-etc, --filesystem=host-os, and the os-release handling
from #3733.
It can also be used to build a bwrap command-line that will be used on
the host, while already inside a container, which will be useful for
Steam's pressure-vessel tool (which copies some of the Flatpak code).
Signed-off-by: Simon McVittie <smcv@collabora.com>
Instead of using a systemd service to create the directory we need for
sideloading (/run/flatpak/sideload-repos), use a systemd-tmpfiles conf
file. This is more elegant, and the service also had a bug which meant
it would create a "/run/flatpak;" directory instead of the one intended.
Since systemd-tmpfiles-setup.service runs before sysinit.target and path
units are run after sysinit.target, the tmp directory should be in place
when flatpak-sideload-usb-repo.path runs in the systemd user instance.
Endless OS already has a file at /lib/tmpfiles.d/flatpak.conf, so we
can't use that filename.
Without this patch, the remote-info command will sometimes emit a
critical error "g_utf8_strlen: assertion 'p != NULL || max == 0' failed"
and print (null) for the "Commit:" field, since the commit doesn't get
initialized properly.
In case we need to authenticate for updates (in my test case i was
doing an OCI downgrade) we might need to download a commit object (or
in the OCI case a manifest json), so it did a request_required_tokens(),
but that noticed during the flatpak_transaction_normalize_ops() call
that the partial resolve to a particular commit actually was the
same as the local installed commit and marked op->skip = TRUE.
However, when we got back to resolving the op again we didn't actually
look at the skip, so it kept looping wanting (but never doing) auth.
The fix is to just directly resolve ops marked as skipped.