Skip to content

Commit

Permalink
Add systemd units to sideload from hotplugged USBs
Browse files Browse the repository at this point in the history
Currently with the sideload implementation of offline updates you have
to manually create a symlink to your USB drive to sideload from it,
which is a regression compared to the previous implementation which
scanned all mounted filesystems in OstreeRepoFinderMount in libostree.
So this commit adds a few systemd units and a bash script so that any
time a USB drive is plugged in and automatically mounted by udisks, a
symlink to it is created in /run/flatpak/sideload-repos. When the drive
is unplugged the symlink is removed.

However this solution still has a lot of moving parts, so we may want to
instead have libflatpak use GVolumeMonitor and find the mounted
filesystems itself; see #3705

Fixes #3490
  • Loading branch information
mwleeds authored and alexlarsson committed Jun 23, 2020
1 parent e84b756 commit 9caf664
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 2 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,11 @@ flatpak-dbus-proxy
permission-store-dbus.[ch]
flatpak-system-helper
xdg-desktop-portal
*.service
oci-authenticator/*.service
portal/*.service
session-helper/*.service
system-helper/*.service
tests/*.service
flatpak.conf
flatpak.env
flatpak.sh
Expand Down
3 changes: 3 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ SUBDIRS += po
%.service: %.service.in config.log
$(AM_V_GEN) $(SED) -e "s|\@libexecdir\@|$(libexecdir)|" \
-e "s|\@localstatedir\@|$(localstatedir)|" \
-e "s|\@media_dir\@|$(RUN_MEDIA_DIR)|" \
-e "s|\@extraargs\@||" $< > $@

dbus_servicedir = $(DBUS_SERVICE_DIR)
service_in_files = $(NULL)
dbus_service_DATA = $(NULL)
systemdsystemunit_DATA = $(NULL)
systemduserunit_DATA = $(NULL)
CLEANFILES += $(dbus_service_DATA)
CLEANFILES += $(systemduserunit_DATA)
Expand Down Expand Up @@ -101,6 +103,7 @@ include oci-authenticator/Makefile.am.inc
include icon-validator/Makefile.am.inc
include revokefs/Makefile.am.inc
include selinux/Makefile.am.inc
include sideload-repos-systemd/Makefile.am.inc
include tests/Makefile.am.inc

if !WITH_SYSTEM_DBUS_PROXY
Expand Down
16 changes: 16 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,13 @@ if test "x$enable_system_helper" = "xyes"; then
fi
AM_CONDITIONAL(BUILD_SYSTEM_HELPER, test x$enable_system_helper = xyes)

AC_ARG_ENABLE([auto-sideloading],
AC_HELP_STRING([--enable-auto-sideloading],
[Enable systemd units which make Flatpak sideload from inserted USB drives]),
[],
[enable_auto_sideloading=no])
AM_CONDITIONAL(BUILD_AUTO_SIDELOADING, test x$enable_auto_sideloading = xyes)

PKG_CHECK_MODULES(FUSE, fuse >= 2.9.2)

AC_ARG_ENABLE([xauth],
Expand Down Expand Up @@ -351,6 +358,14 @@ AC_ARG_WITH(system-install-dir,
SYSTEM_INSTALL_DIR=$with_system_install_dir
AC_SUBST(SYSTEM_INSTALL_DIR)

AC_ARG_WITH(run-media-dir,
[AS_HELP_STRING([--with-run-media-dir=DIR],
[Location of auto-mounted USB drives [/run/media]])],
[],
[with_run_media_dir='/run/media'])
RUN_MEDIA_DIR=$with_run_media_dir
AC_SUBST(RUN_MEDIA_DIR)

AC_ARG_WITH([sysusersdir],
[AS_HELP_STRING([--with-sysusersdir=DIR],
[Directory for systemd sysusers.d configuration files (default=PREFIX/lib/sysusers.d)])],
Expand Down Expand Up @@ -565,4 +580,5 @@ echo " Use dconf: $have_dconf"
echo " Use libsystemd: $have_libsystemd"
echo " Use libmalcontent: $have_libmalcontent"
echo " Use libzstd: $have_zstd"
echo " Use auto sideloading: $enable_auto_sideloading"
echo ""
18 changes: 18 additions & 0 deletions sideload-repos-systemd/Makefile.am.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
if BUILD_AUTO_SIDELOADING

dist_libexec_SCRIPTS = sideload-repos-systemd/flatpak-create-sideload-symlinks.sh

service_in_files += sideload-repos-systemd/flatpak-sideload-usb-repo.service.in
systemduserunit_DATA += sideload-repos-systemd/flatpak-sideload-usb-repo.service

path_in_files = sideload-repos-systemd/flatpak-sideload-usb-repo.path.in
systemduserunit_DATA += sideload-repos-systemd/flatpak-sideload-usb-repo.path

systemdsystemunit_DATA += sideload-repos-systemd/flatpak-sideload-repos-dir.service

%.path: %.path.in config.log
$(AM_V_GEN) $(SED) -e "s|\@media_dir\@|$(RUN_MEDIA_DIR)|" $< > $@

endif

EXTRA_DIST += sideload-repos-systemd/flatpak-sideload-usb-repo.path.in sideload-repos-systemd/flatpak-sideload-repos-dir.service
30 changes: 30 additions & 0 deletions sideload-repos-systemd/flatpak-create-sideload-symlinks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

# This script is intended to be run by flatpak-sideload-usb-repo.service

if ! test $# -eq 1 || ! test -d "$1"; then
echo "Error: first argument must be a directory"
exit 1
fi

# Add a link to any newly inserted drives which might have been copied to with
# "flatpak create-usb". If we were to check for a repo on the drive that would
# break the case of using it for sideloading directly after copying to it (e.g.
# for testing).
for f in "$1"/*; do
if ! test -d "$f"; then
continue
fi
unique_name=automount-$(echo "$f" | sha256sum | cut -f 1 -d ' ')
if test -e "/run/flatpak/sideload-repos/$unique_name"; then
continue
fi
ln -s "$f" "/run/flatpak/sideload-repos/$unique_name"
done

# Remove any broken symlinks e.g. from drives that were removed
for f in /run/flatpak/sideload-repos/automount-*; do
if ! test -e "$f"; then
rm "$f"
fi
done
15 changes: 15 additions & 0 deletions sideload-repos-systemd/flatpak-sideload-repos-dir.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This unit is intended to be installed in the systemd system instance, so that
# flatpak-sideload-usb-repo.{path,service} can work in the user instance
[Service]
Type=oneshot
ExecStart=/bin/mkdir -p /run/flatpak; /bin/mkdir -p -m 777 /run/flatpak/sideload-repos

[Unit]
# Use basic.target to guarantee we run before flatpak-sideload-usb-repos.path
# in the user systemd instance
Before=basic.target
After=sysinit.target
DefaultDependencies=no

[Install]
WantedBy=basic.target
12 changes: 12 additions & 0 deletions sideload-repos-systemd/flatpak-sideload-usb-repo.path.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This unit is intended to be installed in the systemd user instance, and
# depends on flatpak-sideload-repos-dir.service being in the system instance
# and running first. The idea here is that we add any USB drive mounts to the
# appropriate directory so Flatpak can find and pull from them in case they
# have flatpaks on them, both when a new drive is inserted and at the start of
# the user session.
[Path]
PathExists=@media_dir@/%u
PathChanged=@media_dir@/%u

[Install]
WantedBy=default.target
5 changes: 5 additions & 0 deletions sideload-repos-systemd/flatpak-sideload-usb-repo.service.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This unit is intended to be installed in the systemd user instance; see the
# docs in flatpak-sideload-usb-repo.path
[Service]
Type=oneshot
ExecStart=@libexecdir@/flatpak-create-sideload-symlinks.sh @media_dir@/%u
2 changes: 1 addition & 1 deletion system-helper/Makefile.am.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dbusconfdir = $(DBUS_CONFIG_DIR)
dist_dbusconf_DATA = system-helper/org.freedesktop.Flatpak.SystemHelper.conf

service_in_files += system-helper/flatpak-system-helper.service.in
systemdsystemunit_DATA = system-helper/flatpak-system-helper.service
systemdsystemunit_DATA += system-helper/flatpak-system-helper.service

flatpak_system_helper_SOURCES = \
system-helper/flatpak-system-helper.c \
Expand Down

0 comments on commit 9caf664

Please sign in to comment.