From 21249547e202fd383d16a3db6a67a53a68f6a29c Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Wed, 21 Jun 2017 18:14:29 +0200 Subject: [PATCH 01/16] yocto-compatible.rst: implementation documentation This targets developers and explains how layers meet the "Yocto Compatible 2.0" criteria and provide optional functionality to other distributions. Signed-off-by: Patrick Ohly --- doc/howtos/yocto-compatible.rst | 190 ++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 doc/howtos/yocto-compatible.rst diff --git a/doc/howtos/yocto-compatible.rst b/doc/howtos/yocto-compatible.rst new file mode 100644 index 0000000000..67c349f738 --- /dev/null +++ b/doc/howtos/yocto-compatible.rst @@ -0,0 +1,190 @@ +Yocto Compatible 2.0 +==================== + +The main goal of the next revision of the Yocto compliance program, +called "Yocto Compatible 2.0", is to increase inter-operability of +different layers. One key aspect is that a layer must not change a +build configuration merely because it gets added to a build. Instead, +only some explicit build configuration change (like setting distro +flags or including a .inc file provided by the layer) may cause the +build to change. + +All meta-refkit layers are "Yocto Compatible 2.0". In addition to +that, it is guaranteed that including :file:`refkit-config.inc` will +also not change the build. It merely provides support for choosing +some of the distro features implemented in intel-iot-refkit, without +actually turning them on. That choice is still left to the developer +or distro. + +The "Layer Overview and Reuse" section in :file:`introduction.rst` +explains how to use this. This document is about the implementation. + + +Implementation +============== + +Optional ``.bbappends`` +----------------------- + +:file:`refkit-config.inc` contains global distro settings, including +"normal" re-configuration of recipes via ``PACKAGECONFIG`` +changes. Everything that goes beyond that needs to be in a +``.bbappend``. Often these are workarounds or new recipe features that +long-term might be more suitable for inclusion into the upstream +recipe. + +Such ``.bbappends`` go into ``meta-refkit-core`` (when they are common +to multiple profiles) or individual profile layers. Normally a layer +can only provide ``.bbappends`` for recipes that are known to be +available. A fatal error aborts parsing when no ``.bb`` file is found +for a ``.bbappend``, to catch cases where the original ``.bb`` was +renamed and the ``.bbappend`` must be updated. + +``meta-refkit-core/bbappends`` contains a directory hierarchy that +matches the structure of upstream layers that are used in +``intel-iot-refkit``. ``BBFILES_DYNAMIC`` instead of the normal +``BBFILES`` is used to enable ``.bbappend`` files only when the +corresponding layer is present in a build, so one still gets the error +when the ``.bb`` file changes, but not when the entire layer is +missing. + +Avoiding Signature Changes +-------------------------- + +:file:`refkit-config.inc` and ``.bbappend`` files must not change the +build when not explicitly enabled via distro features. This is checked by +comparing task signatures. + +There are several different techniques for avoiding task signature +changes, listed here in order of increasing complexity. Use the simplest +approach that works. + +#. conditional ``_append/remove`` + + :file:`refkit-config.inc` defines certain distro features (for + example, ``refkit-config``) which get turned into overrides with + ``df-`` as prefix. By adding those overrides to ``_append`` or + ``_remove``, one can limit that change to configurations where + the feature is active:: + + do_install_append_df-refkit-config () { + ... + } + + Combining multiple overrides applies when all overrides are set + ("and" semantic):: + + do_install_append_df-refkit-firewall_df-refkit-gateway () { + ... + } + + Repeating the variable with different conditions applies the change + when one or more conditions are met ("or" semantic). But beware + that values will be appended more than once when more than one + condition is true. This may be acceptable in some cases, like this + one:: + + EXTRA_OECONF_append_df-refkit-gateway = " --enable-foo" + EXTRA_OECONF_append_df-refkit-industrial = " --enable-foo" + +#. conditional setting of variables + + Setting a variable with an override suffix chooses that value when + the overrides are active:: + + PACKAGECONFIG_pn-foo_df-refkit-config = "bar" + + As before, multiple overrides can be combined again ("and" + semantic). Assignments with more or more important overrides are + chosen over less specific assignments (see the bitbake manual for + details). + + When repeating the same assignment for different cases ("or" + semantic), a helper variable may be useful to avoid repeating code. + Use ``refkit_`` or ``REFKIT_`` as prefix for those:: + + REFKIT_PACKAGECONFIG_FOO = "bar" + PACKAGECONFIG_pn-foo_df-refkit-gateway = "${REFKIT_PACKAGECONFIG_FOO}" + PACKAGECONFIG_pn-foo_df-refkit-industrial = "${REFKIT_PACKAGECONFIG_FOO}" + +#. conditional includes + + Manipulating varflags or some operations (like ``addtask``) do not support + overrides. Such changes can be placed in a .inc file alongside a ``.bbappend`` + and then get included conditionally:: + + require ${@oe.utils.all_distro_features(d, 'refkit-gateway refkit-firewall', 'gateway-and-firewall.inc') } + require ${@oe.utils.any_distro_features(d, 'refkit-gateway refkit-industrial', 'gateway-or-industrial.inc') } + require ${@oe.utils.all_distro_features(d, 'refkit-config', 'config1.inc config2.inc') } + + As shown here, one can check for one or more distro features and + include one or more files at once. The semantic depends on the + function ("or" for ``any_distro_features()``, "and" for + ``all_distro_features()``). When only one feature is listed, + both functions behave the same. When the condition is not satisfied, + these functions return the empty string and nothing gets included. + + They can also be used in a boolean context:: + + if oe.utils.all_distro_features(d, 'refkit-config'): + bb.note('refkit-config is in DISTRO_FEATURES') + + More complex ``${@ }`` expressions are also possible. The two functions + above are merely helper functions that cover the common cases. + + Beware that includes are executed while parsing. Checking for + distro features in a ``.bbappend`` is safe because distro features + are finalized before parsing recipes. For changes affecting the + base configuration, conditional variable changes with overrides + have to be used because these conditions are then checked each time the + variables are used. + + Checking recipe variables is not safe because those might still be + changed later (for example, in another ``.bbappend``). + +#. anonymous Python methods + + Anonymous python methods embedded into a ``.bbappend`` can make + arbitrary changes to the recipe after checking for some condition. + In contrast to conditional includes, anonymous Python methods + are executed at the end of parsing and thus can typically check + recipe variables. The only caveat is that another method might + still change those variables. + + This can be used to replace the ``addtask`` directive without + having to create a separate ``.inc`` file:: + + python () { + if bb.utils.contains('IMAGE_FEATURES', 'ostree', True, False, d) and \ + oe.utils.all_distro_features(d, 'ostree'): + bb.build.addtask('do_ostree_prepare_rootfs', 'do_image_wic', 'do_image', d) + } + + +Testing +======= + +``oe-selftest -r refkit_poky.TestRefkitPokySignatures`` applies the +``yocto-compatible-layer.py`` test script to all ``meta-refkit`` +layers against a base configuration which mirrors the ``Poky`` +distribution. The output in case of a failure contains differences +between task signatures, which usually highlights were some undesired +change is happening. + +``oe-selftest`` can be run in a local build configuration, without +affecting the build itself. See ``oe-selftest --list-tests`` for a +full list of tests that can be run this way. + +The compatibility tests do not guarantee that actual builds will work, +because they only check syntax, dependencies and task +signatures. Actual building is covered by ``oe-selftest -r +refkit_poky.TestRefkitPokyBuilds`` for two build configurations: + +test_common_poky_config + Building ``refkit-image-common`` using just the plain ``Poky`` + distribution settings (for example, without ``systemd``). + +test_common_refkit_config + Building ``refkit-image-common`` using the ``Poky`` + distribution settings plus :file:``enable-refkit-config.inc``, + i.e. all refkit distro features set. From 028a8e23787dbf33c3cf1454544a37cbcbe67f12 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Wed, 21 Jun 2017 18:24:47 +0300 Subject: [PATCH 02/16] meta-iotqa: added minimal flatpak sanity test. Signed-off-by: Krisztian Litkey --- ...kit-image-gateway-flatpak-runtime.manifest | 5 +++ meta-iotqa/lib/oeqa/runtime/sanity/flatpak.py | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest create mode 100644 meta-iotqa/lib/oeqa/runtime/sanity/flatpak.py diff --git a/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest b/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest new file mode 100644 index 0000000000..1b2cd7620b --- /dev/null +++ b/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest @@ -0,0 +1,5 @@ +# Tests for gateway profile +oeqa.runtime.programming.nodejs.apprt_nodejs +oeqa.runtime.core.iotivity.client +oeqa.runtime.multimedia.audio.pulseaudio +oeqa.runtime.sanity.flatpak diff --git a/meta-iotqa/lib/oeqa/runtime/sanity/flatpak.py b/meta-iotqa/lib/oeqa/runtime/sanity/flatpak.py new file mode 100644 index 0000000000..c744632dbf --- /dev/null +++ b/meta-iotqa/lib/oeqa/runtime/sanity/flatpak.py @@ -0,0 +1,32 @@ +import unittest +from oeqa.oetest import oeRuntimeTest, skipModule +from oeqa.utils.decorators import * + +def setUpModule(): + if not oeRuntimeTest.hasFeature('flatpak'): + skipModule("flatpak not enabled, tests skipped") + +class SanityTestFlatpak(oeRuntimeTest): + '''flatpak sanity tests''' + + def test_flatpak_usrmerge(self): + '''check if / and /usr are properly merged''' + links = [ '/bin', '/sbin', '/lib', ] + for l in links: + (status, output) = self.target.run('readlink %s' % l) + self.assertEqual( + status, 0, + "usrmerge error: %s should be a symbolic link" % l) + + def test_basic_binaries(self): + '''check if basic flatpak binaries exist''' + binaries = [ + '/usr/bin/flatpak', + '/usr/bin/gpgme-tool', + '/usr/bin/gpg' + ] + for b in binaries: + (status, output) = self.target.run('ls %s' % b) + self.assertEqual( + status, 0, + 'flatpak basic binary %s missing' % b) From af5ead5c86c0603035ec42e859547013611bdda9 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Wed, 21 Jun 2017 21:39:59 +0300 Subject: [PATCH 03/16] refkit-ci.inc: run gateway flatpak runtime tests as well. Signed-off-by: Krisztian Litkey --- meta-refkit/conf/distro/include/refkit-ci.inc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta-refkit/conf/distro/include/refkit-ci.inc b/meta-refkit/conf/distro/include/refkit-ci.inc index e9e85dd584..0f30f4e056 100644 --- a/meta-refkit/conf/distro/include/refkit-ci.inc +++ b/meta-refkit/conf/distro/include/refkit-ci.inc @@ -94,6 +94,8 @@ REFKIT_CI_TEST_RUNS=" \ refkit-image-computervision,iot-testsuite.tar.gz,iot-testfiles.${MACHINE}.tar.gz,${MACHINE},minnowboardturbot \ refkit-image-gateway,iot-testsuite.tar.gz,iot-testfiles.${MACHINE}.tar.gz,${MACHINE},570x \ refkit-image-gateway,iot-testsuite.tar.gz,iot-testfiles.${MACHINE}.tar.gz,${MACHINE},minnowboardturbot \ + ${@bb.utils.contains('DISTRO_FEATURES', 'flatpak', \ + 'refkit-image-gateway-flatpak-runtime,iot-testsuite.tar.gz,iot-testfiles.${MACHINE}.tar.gz,${MACHINE},minnowboardturbot', '', d)} \ " # Dont use disk space monitor in CI builds, to avoid frequent From 0aa23f104a215cbc811f15f8e3edeea46ab17881 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 13:56:39 +0300 Subject: [PATCH 04/16] flatpak-utils: added recipe for flatpak-utils. Added recipe for flatpak-utils. Currently it only contains flatpak- session, our daemon to start up flatpak sessions, and the associated systemd generator. Also declared flatpak-utils as a supported recipe. Signed-off-by: Krisztian Litkey --- .../flatpak-utils/files/flatpak-utils/AUTHORS | 0 .../flatpak-utils/files/flatpak-utils/COPYING | 0 .../files/flatpak-utils/ChangeLog | 0 .../files/flatpak-utils/LICENSE-BSD | 26 + .../files/flatpak-utils/Makefile.am | 6 + .../flatpak-utils/files/flatpak-utils/NEWS | 0 .../flatpak-utils/files/flatpak-utils/README | 26 + .../files/flatpak-utils/bootstrap | 21 + .../flatpak-utils/build-aux/git-version-gen | 154 +++ .../flatpak-utils/build-aux/shave-libtool.in | 109 ++ .../files/flatpak-utils/build-aux/shave.in | 133 +++ .../files/flatpak-utils/configure.ac | 123 +++ .../files/flatpak-utils/m4/shave.m4 | 113 ++ .../files/flatpak-utils/src/Makefile.am | 48 + .../files/flatpak-utils/src/config.c | 542 ++++++++++ .../files/flatpak-utils/src/filesystem.c | 335 ++++++ .../files/flatpak-utils/src/flatpak-session.c | 153 +++ .../files/flatpak-utils/src/flatpak-session.h | 280 +++++ .../src/flatpak-session@.service | 18 + .../flatpak-utils/src/flatpak-sessions.target | 18 + .../flatpak-utils/src/flatpak-update.service | 12 + .../files/flatpak-utils/src/flatpak.c | 993 ++++++++++++++++++ .../files/flatpak-utils/src/generator.h | 114 ++ .../files/flatpak-utils/src/log.c | 114 ++ .../files/flatpak-utils/src/mainloop.c | 103 ++ .../files/flatpak-utils/src/remote.c | 111 ++ .../files/flatpak-utils/src/service.c | 86 ++ .../files/flatpak-utils/src/template.c | 169 +++ .../flatpak-utils/flatpak-utils_0.0.bb | 34 + .../include/refkit-supported-recipes.txt | 3 +- 30 files changed, 3843 insertions(+), 1 deletion(-) create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/AUTHORS create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/COPYING create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/ChangeLog create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/LICENSE-BSD create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/Makefile.am create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/NEWS create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/README create mode 100755 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/bootstrap create mode 100755 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/git-version-gen create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave-libtool.in create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave.in create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/configure.ac create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/m4/shave.m4 create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/Makefile.am create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/config.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/filesystem.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.h create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session@.service create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-sessions.target create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-update.service create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/generator.h create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/log.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/mainloop.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/remote.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/service.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/template.c create mode 100644 meta-flatpak/recipes-flatpak/flatpak-utils/flatpak-utils_0.0.bb diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/AUTHORS b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/AUTHORS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/COPYING b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/COPYING new file mode 100644 index 0000000000..e69de29bb2 diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/ChangeLog b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/ChangeLog new file mode 100644 index 0000000000..e69de29bb2 diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/LICENSE-BSD b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/LICENSE-BSD new file mode 100644 index 0000000000..a52ad554df --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/LICENSE-BSD @@ -0,0 +1,26 @@ +Copyright (c) 2012, 2013, Intel Corporation + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/Makefile.am b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/Makefile.am new file mode 100644 index 0000000000..15d3b63be0 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/Makefile.am @@ -0,0 +1,6 @@ +SUBDIRS = . src +doc_DATA = AUTHORS ChangeLog NEWS README + +# cleanup +clean-local: + rm -f *~ diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/NEWS b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/NEWS new file mode 100644 index 0000000000..e69de29bb2 diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/README b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/README new file mode 100644 index 0000000000..c6a50c4225 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/README @@ -0,0 +1,26 @@ +flatpak-utils is a collection of extra utilities for Intel IoT RefKit. + +Currently flatpak-utils contains two extra binaries for dealing with +'flatpak sessions'. A 'flatpak session' is an automatically started +login session which runs one or more flatpak applications from a single +flatpak provide/remote. Each such remote has a dedicated user associated +with it and the flatpak applications are run within the login session +of that dedicated user. + +There is currently a single binary provided which can be run in three +different modes: + +- systemd generator + + A systemd generator used to generate a systemd service for each + configured flatpak session during system initialization. + +- session daemon + + A daemon used to run within each flatpak session to start the + flatpaks for that session. + +- update daemon + + A daemon used to monitor remotes, pull in available updates, + and restart any affected flatpak sessions. diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/bootstrap b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/bootstrap new file mode 100755 index 0000000000..ac327fd870 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/bootstrap @@ -0,0 +1,21 @@ +#!/bin/bash + +aclocal -I m4 && \ + autoheader && \ + libtoolize --copy --force && \ + autoconf && \ + automake --add-missing --copy + +status=$? + +if [ $status == 0 ]; then + if [ -n "$1" ]; then + [ "$1" == "configure" ] && shift || : + ./configure $* + status=$? + fi +else + echo "Failed to bootstrap." +fi + +exit $status diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/git-version-gen b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/git-version-gen new file mode 100755 index 0000000000..f38082dffd --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/git-version-gen @@ -0,0 +1,154 @@ +#!/bin/sh +# Print a version string. +scriptversion=2008-04-08.07 + +# Copyright (C) 2007-2008 Free Software Foundation +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/. +# It may be run two ways: +# - from a git repository in which the "git describe" command below +# produces useful output (thus requiring at least one signed tag) +# - from a non-git-repo directory containing a .tarball-version file, which +# presumes this script is invoked like "./git-version-gen .tarball-version". + +# In order to use intra-version strings in your project, you will need two +# separate generated version string files: +# +# .tarball-version - present only in a distribution tarball, and not in +# a checked-out repository. Created with contents that were learned at +# the last time autoconf was run, and used by git-version-gen. Must not +# be present in either $(srcdir) or $(builddir) for git-version-gen to +# give accurate answers during normal development with a checked out tree, +# but must be present in a tarball when there is no version control system. +# Therefore, it cannot be used in any dependencies. GNUmakefile has +# hooks to force a reconfigure at distribution time to get the value +# correct, without penalizing normal development with extra reconfigures. +# +# .version - present in a checked-out repository and in a distribution +# tarball. Usable in dependencies, particularly for files that don't +# want to depend on config.h but do want to track version changes. +# Delete this file prior to any autoconf run where you want to rebuild +# files to pick up a version string change; and leave it stale to +# minimize rebuild time after unrelated changes to configure sources. +# +# It is probably wise to add these two files to .gitignore, so that you +# don't accidentally commit either generated file. +# +# Use the following line in your configure.ac, so that $(VERSION) will +# automatically be up-to-date each time configure is run (and note that +# since configure.ac no longer includes a version string, Makefile rules +# should not depend on configure.ac for version updates). +# +# AC_INIT([GNU project], +# m4_esyscmd([build-aux/git-version-gen .tarball-version]), +# [bug-project@example]) +# +# Then use the following lines in your Makefile.am, so that .version +# will be present for dependencies, and so that .tarball-version will +# exist in distribution tarballs. +# +# BUILT_SOURCES = $(top_srcdir)/.version +# $(top_srcdir)/.version: +# echo $(VERSION) > $@-t && mv $@-t $@ +# dist-hook: +# echo $(VERSION) > $(distdir)/.tarball-version + +case $# in + 1) ;; + *) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version"; exit 1;; +esac + +tarball_version_file=$1 +nl=' +' + +# First see if there is a tarball-only version file. +# then try "git describe", then default. +if test -f $tarball_version_file +then + v=`cat $tarball_version_file` || exit 1 + case $v in + *$nl*) v= ;; # reject multi-line output + [0-9]*) ;; + *) v= ;; + esac + test -z "$v" \ + && echo "$0: WARNING: $tarball_version_file seems to be damaged" 1>&2 +fi + +if test -n "$v" +then + : # use $v +elif test -d .git \ + && v=`git describe --abbrev=4 --match='v*' HEAD 2>/dev/null \ + || git describe --abbrev=4 HEAD 2>/dev/null` \ + && case $v in + v[0-9]*) ;; + *) (exit 1) ;; + esac +then + # Is this a new git that lists number of commits since the last + # tag or the previous older version that did not? + # Newer: v6.10-77-g0f8faeb + # Older: v6.10-g0f8faeb +# case $v in +# *-*-*) : git describe is okay three part flavor ;; +# *-*) +# : git describe is older two part flavor +# # Recreate the number of commits and rewrite such that the +# # result is the same as if we were using the newer version +# # of git describe. +# vtag=`echo "$v" | sed 's/-.*//'` +# numcommits=`git rev-list "$vtag"..HEAD | wc -l` +# v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`; +# ;; +# esac + + # Change the first '-' to a '.', so version-comparing tools work properly. + # Remove the "g" in git describe's output string, to save a byte. +# v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`; + : +else + #v=UNKNOWN + v="0.0.0" +fi + +v=`echo "$v" |sed 's/^v//'` + +# Don't declare a version "dirty" merely because a time stamp has changed. +git status > /dev/null 2>&1 + +dirty=`sh -c 'git diff-index --name-only HEAD' 2>/dev/null` || dirty= +case "$dirty" in + '') ;; + *) # Append the suffix only if there isn't one already. + case $v in + *-dirty) ;; + *) v="$v-dirty" ;; + esac ;; +esac + +# Omit the trailing newline, so that m4_esyscmd can use the result directly. +echo "$v" | tr -d '\012' + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave-libtool.in b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave-libtool.in new file mode 100644 index 0000000000..0f7fb12b67 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave-libtool.in @@ -0,0 +1,109 @@ +#!/bin/sh +# +# Copyright (c) 2009, Damien Lespiau +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the real libtool to use +LIBTOOL="$1" +shift + +# if 1, don't print anything, the underlaying wrapper will do it +pass_though=0 + +# scan the arguments, keep the right ones for libtool, and discover the mode +preserved_args= + +# have we seen the --tag option of libtool in the command line ? +tag_seen=0 + +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + preserved_args="$preserved_args $opt" + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + --tag=*) + tag_seen=1 + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args '$opt'" + ;; + esac +done + +case "$mode" in +compile) + # shave will be called and print the actual CC/CXX/LINK line + preserved_args="$preserved_args --shave-mode=$mode" + pass_though=1 + ;; +link) + preserved_args="$preserved_args --shave-mode=$mode" + Q=" LINK " + ;; +*) + # let's u + # echo "*** libtool: Unimplemented mode: $mode, fill a bug report" + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +# automake does not add a --tag switch to its libtool invocation when +# assembling a .s file and rely on libtool to infer the right action based +# on the compiler name. As shave is using CC to hook a wrapper, libtool gets +# confused. Let's detect these cases and add a --tag=CC option. +tag="" +if test $tag_seen -eq 0 -a x"$mode" = xcompile; then + tag="--tag=CC" +fi + +if test -z $V; then + if test $pass_though -eq 0; then + echo "$Q$output" + fi + eval "$LIBTOOL --silent $tag $preserved_args" +else + echo $LIBTOOL $tag $preserved_args + eval "$LIBTOOL $tag $preserved_args" +fi diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave.in b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave.in new file mode 100644 index 0000000000..5150a4fff1 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/build-aux/shave.in @@ -0,0 +1,133 @@ +#!/bin/sh +# +# Copyright (c) 2009, Damien Lespiau +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +# we need sed +SED=@SED@ +if test -z "$SED" ; then +SED=sed +fi + +lt_unmangle () +{ + last_result=`echo $1 | $SED -e 's#.libs/##' -e 's#[0-9a-zA-Z_\-\.]*_la-##'` +} + +# the tool to wrap (cc, cxx, ar, ranlib, ..) +tool="$1" +shift + +# the reel tool (to call) +REEL_TOOL="$1" +shift + +pass_through=0 +preserved_args= +while test "$#" -gt 0; do + opt="$1" + shift + + case $opt in + --shave-mode=*) + mode=`echo $opt | $SED -e 's/[-_a-zA-Z0-9]*=//'` + ;; + -o) + lt_output="$1" + preserved_args="$preserved_args $opt" + ;; + -out:*|/out:*) + lt_output="${opt#-out:}" + preserved_args="$preserved_args $opt" + ;; + *.l) + if [ "$tool" = "lex" ]; then + lt_output="$opt" + fi + preserved_args="$preserved_args $opt" + ;; + *.y) + if [ "$tool" = "yacc" ]; then + lt_output="$opt" + fi + preserved_args="$preserved_args $opt" + ;; + *) + preserved_args="$preserved_args '$opt'" + ;; + esac +done + +# mode=link is handled in the libtool wrapper +case "$mode,$tool" in +link,*) + pass_through=1 + ;; +*,cxx) + Q=" CXX " + ;; +*,ccas) + Q=" AS " + ;; +*,cc) + Q=" CC " + ;; +*,fc) + Q=" FC " + ;; +*,f77) + Q=" F77 " + ;; +*,objc) + Q=" OBJC " + ;; +*,mcs) + Q=" MCS " + ;; +*,lex) + Q=" LEX " + ;; +*,yacc) + Q=" YACC " + ;; +*,cc_for_build) + Q=" HOSTCC " + ;; +*,*) + # should not happen + Q=" CC " + ;; +esac + +lt_unmangle "$lt_output" +output=$last_result + +if test -z $V; then + if test $pass_through -eq 0; then + echo "$Q$output" + fi + eval "$REEL_TOOL $preserved_args" +else + echo $REEL_TOOL $preserved_args + eval "$REEL_TOOL $preserved_args" +fi diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/configure.ac b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/configure.ac new file mode 100644 index 0000000000..a0e2b02b62 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/configure.ac @@ -0,0 +1,123 @@ + +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.59) + +AC_INIT([flatpak-utils], m4_esyscmd([build-aux/git-version-gen .tarball-version])) + +AC_CONFIG_SRCDIR([src]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADER([src/config.h]) +AM_INIT_AUTOMAKE([-Wno-portability subdir-objects foreign]) + +AC_SUBST(ACLOCAL_AMFLAGS, "-I m4") + +m4_define(version_major, `echo $VERSION | cut -d. -f1 | cut -d- -f1`) +m4_define(version_minor, `echo $VERSION | cut -d. -f2 | cut -d- -f1`) +m4_define(version_patch, `echo $VERSION | cut -d. -f3 | cut -d- -f1`) + +AC_SUBST(VERSION) +AC_SUBST(VERSION_MAJOR, version_major) +AC_SUBST(VERSION_MINOR, version_minor) +AC_SUBST(VERSION_PATCH, version_patch) +AC_SUBST(VERSION_FULL, version_major.version_minor.version_patch) + +IOT_VERSION_INFO="0:0:0" +AC_SUBST(IOT_VERSION_INFO) + +# Disable static libraries. +AC_DISABLE_STATIC + +# Checks for programs. +AC_PROG_CC +AC_PROG_CC_C99 +AC_PROG_INSTALL +AC_PROG_LN_S +AM_PROG_CC_C_O +AM_PROG_LIBTOOL + +# Guesstimate native compiler if we're cross-compiling. +if test "$cross_compiling" != "no"; then + AC_MSG_NOTICE([Looks like we're being cross-compiled...]) + if test -z "$CC_FOR_BUILD"; then + CC_FOR_BUILD=cc + fi +else + AC_MSG_NOTICE([Looks like we're doing a native compilation...]) + CC_FOR_BUILD='$(CC)' +fi +AC_SUBST(CC_FOR_BUILD) +UNSHAVED_CC_FOR_BUILD="$CC_FOR_BUILD" + +# Make first invocation of PKG_CHECK_MODULES 'if-then-else-fi'-safe. +PKG_PROG_PKG_CONFIG + +# Checks for header files. +AC_PATH_X +AC_CHECK_HEADERS([stdio.h stdlib.h errno.h fcntl.h sys/types.h sys/stat.h]) + +# Checks for typedefs, structures, and compiler characteristics. + +# Checks for library functions. + +# Check and enable extra compiler warnings if they are supported. +AC_ARG_ENABLE(extra-warnings, + [ --enable-extra-warnings enable extra compiler warnings], + [extra_warnings=$enableval], [extra_warnings=auto]) + +WARNING_CFLAGS="" +warncflags="-Wall -Wextra" +if test "$extra_warnings" != "no"; then + save_CPPFLAGS="$CPPFLAGS" + for opt in $warncflags; do + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])], + [WARNING_CFLAGS="$WARNING_CFLAGS $opt"]) + done + CPPFLAGS="$save_CPPFLAGS" +fi + +AC_SUBST(WARNING_CFLAGS) + +# Allow overriding systemds' unitdir. +AC_ARG_WITH([systemdunitdir], + AC_HELP_STRING([--with-systemdunitdir=DIR], [systemd unit directory]), + [with_systemdunitdir=${withval}], + [with_systemdunitdir="`$PKG_CONFIG --variable=systemdsystemunitdir systemd`"]) + +if test -n "${with_systemdunitdir}"; then + SYSTEMD_UNITDIR="${with_systemdunitdir}" + AC_SUBST(SYSTEMD_UNITDIR) +fi + +# Check for flatpak libraries. +PKG_CHECK_MODULES(FLATPAK, flatpak) + +# Allow substitution for LIBDIR and SYSCONFDIR. +AC_MSG_CHECKING([libdir]) +AC_MSG_RESULT([$libdir]) +AC_SUBST(LIBDIR, [$libdir]) +AC_MSG_CHECKING([sysconfdir]) +AC_MSG_RESULT([$sysconfdir]) +AC_SUBST(SYSCONFDIR, [$sysconfdir]) + +# Shave by default. +SHAVE_INIT([build-aux], [enable]) + +# Generate output. +AC_CONFIG_FILES([ + build-aux/shave + build-aux/shave-libtool + Makefile + src/Makefile + ]) +AC_OUTPUT + +# Display the configuration. +echo "----- configuration -----" +echo "Extra C warnings flags: $WARNING_CFLAGS" +echo "Cross-compiling: $cross_compiling" +if test "$cross_compiling" != "no"; then + echo " * native compiler: $UNSHAVED_CC_FOR_BUILD" +fi +echo "Systemd unitdir: $SYSTEMD_UNITDIR" diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/m4/shave.m4 b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/m4/shave.m4 new file mode 100644 index 0000000000..94aec1f6ec --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/m4/shave.m4 @@ -0,0 +1,113 @@ +dnl Make automake/libtool output more friendly to humans +dnl +dnl Copyright (c) 2009, Damien Lespiau +dnl +dnl Permission is hereby granted, free of charge, to any person +dnl obtaining a copy of this software and associated documentation +dnl files (the "Software"), to deal in the Software without +dnl restriction, including without limitation the rights to use, +dnl copy, modify, merge, publish, distribute, sublicense, and/or sell +dnl copies of the Software, and to permit persons to whom the +dnl Software is furnished to do so, subject to the following +dnl conditions: +dnl +dnl The above copyright notice and this permission notice shall be +dnl included in all copies or substantial portions of the Software. +dnl +dnl THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +dnl EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +dnl OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +dnl NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +dnl HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +dnl WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +dnl FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +dnl OTHER DEALINGS IN THE SOFTWARE. +dnl +dnl SHAVE_INIT([shavedir],[default_mode]) +dnl +dnl shavedir: the directory where the shave scripts are, it defaults to +dnl $(top_builddir) +dnl default_mode: (enable|disable) default shave mode. This parameter +dnl controls shave's behaviour when no option has been +dnl given to configure. It defaults to disable. +dnl +dnl * SHAVE_INIT should be called late in your configure.(ac|in) file (just +dnl before AC_CONFIG_FILE/AC_OUTPUT is perfect. This macro rewrites CC and +dnl LIBTOOL, you don't want the configure tests to have these variables +dnl re-defined. +dnl * This macro requires GNU make's -s option. + +AC_DEFUN([_SHAVE_ARG_ENABLE], +[ + AC_ARG_ENABLE([shave], + AS_HELP_STRING( + [--enable-shave], + [use shave to make the build pretty [[default=$1]]]),, + [enable_shave=$1] + ) +]) + +AC_DEFUN([SHAVE_INIT], +[ + dnl you can tweak the default value of enable_shave + m4_if([$2], [enable], [_SHAVE_ARG_ENABLE(yes)], [_SHAVE_ARG_ENABLE(no)]) + + if test x"$enable_shave" = xyes; then + dnl where can we find the shave scripts? + m4_if([$1],, + [shavedir="$ac_pwd"], + [shavedir="$ac_pwd/$1"]) + AC_SUBST(shavedir) + + dnl make is now quiet + AC_SUBST([MAKEFLAGS], [-s]) + AC_SUBST([AM_MAKEFLAGS], ['`test -z $V && echo -s`']) + + dnl we need sed + AC_CHECK_PROG(SED,sed,sed,false) + + dnl substitute libtool + SHAVE_SAVED_LIBTOOL=$LIBTOOL + LIBTOOL="${SHELL} ${shavedir}/shave-libtool '${SHAVE_SAVED_LIBTOOL}'" + AC_SUBST(LIBTOOL) + + dnl substitute cc/cxx + SHAVE_SAVED_CCAS=$CCAS + SHAVE_SAVED_CC=$CC + SHAVE_SAVED_CXX=$CXX + SHAVE_SAVED_FC=$FC + SHAVE_SAVED_F77=$F77 + SHAVE_SAVED_OBJC=$OBJC + SHAVE_SAVED_MCS=$MCS + SHAVE_SAVED_LEX=$LEX + SHAVE_SAVED_YACC=$YACC + SHAVE_SAVED_CC_FOR_BUILD=$CC_FOR_BUILD + CCAS="${SHELL} ${shavedir}/shave ccas ${SHAVE_SAVED_CCAS}" + CC="${SHELL} ${shavedir}/shave cc ${SHAVE_SAVED_CC}" + CXX="${SHELL} ${shavedir}/shave cxx ${SHAVE_SAVED_CXX}" + FC="${SHELL} ${shavedir}/shave fc ${SHAVE_SAVED_FC}" + F77="${SHELL} ${shavedir}/shave f77 ${SHAVE_SAVED_F77}" + OBJC="${SHELL} ${shavedir}/shave objc ${SHAVE_SAVED_OBJC}" + MCS="${SHELL} ${shavedir}/shave mcs ${SHAVE_SAVED_MCS}" + LEX="${SHELL} ${shavedir}/shave lex ${SHAVE_SAVED_LEX}" + YACC="${SHELL} ${shavedir}/shave yacc ${SHAVE_SAVED_YACC}" + CC_FOR_BUILD="${SHELL} ${shavedir}/shave cc_for_build ${SHAVE_SAVED_CC_FOR_BUILD}" + AC_SUBST(CCAS) + AC_SUBST(CC) + AC_SUBST(CXX) + AC_SUBST(FC) + AC_SUBST(F77) + AC_SUBST(OBJC) + AC_SUBST(MCS) + AC_SUBST(LEX) + AC_SUBST(YACC) + + V=@ + else + V=1 + fi + Q='$(V:1=)' + AC_SUBST(V) + AC_SUBST(Q) +]) + diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/Makefile.am b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/Makefile.am new file mode 100644 index 0000000000..196afe1d31 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/Makefile.am @@ -0,0 +1,48 @@ +SUBDIRS = . +AM_CFLAGS = $(WARNING_CFLAGS) $(AM_CPPFLAGS) $(PATHDEFS) +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src \ + -I$(top_builddir) -I$(top_builddir)/src +PATHDEFS = -DSYSCONFDIR=\"${sysconfdir}\" \ + -DLIBDIR=\"${libdir}\" \ + -DLIBEXECDIR=\"${libexecdir}\" + +generator_PROGRAMS = flatpak-session-enable +generatordir = @SYSTEMD_UNITDIR@/system-generators + +systemd_DATA = flatpak-session@.service \ + flatpak-sessions.target \ + flatpak-update.service +systemddir = @SYSTEMD_UNITDIR@/system + +bin_PROGRAMS = + +############################################# +# flatpak-service-generator +# + +bin_PROGRAMS += flatpak-session + +flatpak_session_SOURCES = \ + flatpak-session.c \ + config.c \ + log.c \ + mainloop.c \ + remote.c \ + filesystem.c \ + flatpak.c + +flatpak_session_CFLAGS = \ + $(AM_CFLAGS) \ + $(PATHDEFS) \ + $(FLATPAK_CFLAGS) + +flatpak_session_LDADD = \ + $(FLATPAK_LIBS) \ + -lm + +flatpak-session-enable: flatpak-session + rm -f $@ && ln $< $@ + +# cleanup +clean-local: + -rm -f *~ diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/config.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/config.c new file mode 100644 index 0000000000..11e6d225df --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/config.c @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#define _GNU_SOURCE +#include + +#include "flatpak-session.h" + +static __attribute__((noreturn)) +void print_usage(const char *argv0, int exit_code, const char *fmt, ...) +{ + va_list ap; + + if (fmt && *fmt) { + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + fprintf(stderr, "\n"); + va_end(ap); + } + + fprintf(stderr, "usage: %s [common-options] {command} [command-options]}\n" + "\n" + "The possible commands are:\n" + " generate: act as a systemd generator\n" + " Discover all repositories with an associated session user.\n" + " For all repositories found, generate and enable a systemd\n" + " service for starting up the session and populating it with\n" + " applications. %s will be used to start\n" + " the applications within the session. This is the default\n" + " behavior if the executable binary is %s.\n" + " start: start session applications\n" + " Start applications. Discover all applications originating\n" + " from the repository associated with the current user. Start\n" + " all applications which are not marked exempt from auto-\n" + " starting within the current session.\n" + " stop: stop a session (by sending SIGTERM)\n" + " Stop the session for the current or given user. Discover the\n" + " instance (%s) used to start the session\n" + " and send it SIGTERM. That instance is expected to stop all\n" + " applications running within its session, then exit itself.\n" + " list: list sessions\n" + " List all known sessions, all running sessions, or the session\n" + " session associated with the given user/repository.\n" + " signal: send a signal to a session\n" + " Same as stop but the signal can be specified.\n" + "\n" + "The possible common options are:\n" + " -u, --allow-unsigned allow unverifiable (unsigned) remotes\n" + " -n, --dry-run just print, don't generate anything\n" + " -v, --verbose increase logging verbosity\n" + " -d, --debug enable debug messages\n" + " -h, --help print this help message\n" + "\n" + "The possible options for start are:\n" + " -r, --restart-status use n for forced restart exit status\n" + "\n" + "The possible options for update are:\n" + " -o, --one-shot don't daemonize and poll updates\n" + " -i, --poll-interval ival use the given interval for polling\n" + " -s, --start-signal signal sessions after initial update\n", + /* usage */argv0, + /* generate */FPAK_SESSION_PATH, FPAK_SYSTEMD_GENERATOR, + /* stop */FPAK_SESSION_PATH); + + exit(exit_code); +} + + +static inline int is_systemd_generator(const char *argv0) +{ + const char *p; + + if ((p = strrchr(argv0, '/')) == NULL) + p = argv0; + else + p++; + + return !strcmp(p, FPAK_SYSTEMD_GENERATOR); +} + + +static void set_defaults(context_t *c, char **argv) +{ + memset(c, 0, sizeof(*c)); + c->sigfd = -1; + c->argv0 = argv[0]; + c->gpg_verify = 1; + + if (is_systemd_generator(argv[0])) + c->action = ACTION_GENERATE; + else + c->action = ACTION_START; +} + + +static int parse_interval(const char *argv0, const char *val) +{ +# define SUFFIX(_e, _s, _l, _p) \ + (!strcmp(_e, _s) || (_l && !strcmp(_e, _l)) || (_p && !strcmp(_e, _p))) + char *end; + double d; + int interval; + + + d = strtod(val, &end); + + if (end != NULL && *end != '\0') { + if (SUFFIX(end, "s", "sec", "secs")) + interval = d < 30 ? 30 : (int)d; + else if (SUFFIX(end, "m", "min", "mins")) + interval = (int)(d * 60); + else if (SUFFIX(end, "h", "hour", "hours")) + interval = (int)(d * 60 * 60); + else if (SUFFIX(end, "d", "day", "days")) + interval = (int)(d * 24 * 60 * 60); + else + print_usage(argv0, EINVAL, "invalid poll interval '%s'", val); + } + else + interval = (int)d; + + if (interval < FPAK_POLL_MIN_INTERVAL) + interval = FPAK_POLL_MIN_INTERVAL; + + return interval; + +# undef SUFFIX +} + + +static void parse_common_options(context_t *c, int argc, char **argv) +{ +# define OPTIONS "-uvndh" + static struct option options[] = { + { "allow-unsigned", no_argument, NULL, 'u' }, + { "verbose" , no_argument, NULL, 'v' }, + { "dry-run" , no_argument, NULL, 'n' }, + { "debug" , no_argument, NULL, 'd' }, + { "help" , no_argument, NULL, 'h' }, + { NULL, 0, NULL, 0 } + }; + + int opt, m; + + while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { + switch (opt) { + case 'u': + c->gpg_verify = 0; + break; + + case 'n': + c->dry_run = 1; + break; + + case 'v': + m = log_get_mask(); + m = (((m << 1) | 0x1) & ~FPAK_LOG_DEBUG) | (m & FPAK_LOG_DEBUG); + log_set_mask(m); + break; + + case 'd': + log_set_mask(log_get_mask() | FPAK_LOG_DEBUG); + break; + + case 'h': + print_usage(argv[0], 0, ""); + + case 1: + optind--; /* we'll need to rescan it as a command argument */ + return; + + case '?': + print_usage(argv[0], EINVAL, "invalid option"); + break; + } + } +#undef OPTIONS +} + + +static void parse_action(context_t *c, int argc, char **argv) +{ + static struct { + const char *name; + action_t action; + } actions[] = { + { "generate", ACTION_GENERATE }, + { "update" , ACTION_UPDATE }, + { "start" , ACTION_START }, + { "stop" , ACTION_STOP }, + { "list" , ACTION_LIST }, + { "signal" , ACTION_SIGNAL }, + { NULL, 0 }, + }, *a; + const char *action; + + if (c->action == ACTION_GENERATE) + return; + + if (optind >= argc) + return; + + action = argv[optind]; + + if (action[0] == '-' || action[0] == '/') + return; + + for (a = actions; a->name != NULL; a++) { + if (!strcmp(action, a->name)) { + c->action = a->action; + optind++; + return ; + } + } + + print_usage(argv[0], EINVAL, "unknown action '%s'", action); +} + + +static void parse_generate_options(context_t *c, int argc, char **argv) +{ + if (optind + 2 > argc - 1) + print_usage(argv[0], EINVAL, + "missing systemd generator directory arguments"); + + if (argv[optind ][0] == '-' || + argv[optind+1][0] == '-' || + argv[optind+2][0] == '-') { + print_usage(argv[0], EINVAL, + "can't mix options with systemd generator directories"); + } + + c->service_dir = argv[optind]; + optind += 3; + + if (optind <= argc - 1) + print_usage(argv[0], EINVAL, + "unknown options starting at '%s'", argv[optind]); +} + + +static int parse_signal(const char *argv0, const char *sigstr) +{ +#define NSIGNAL (sizeof(signals) / sizeof(signals[0])) + struct signals { + const char *sigstr; + int signo; + int reject : 1; + } signals[] = { +# define ACCEPT(_sig) [SIG##_sig] = { #_sig, SIG##_sig, 0 } +# define REJECT(_sig) [SIG##_sig] = { #_sig, SIG##_sig, 1 } + ACCEPT(HUP) , ACCEPT(INT) , ACCEPT(QUIT) , + REJECT(ILL) , REJECT(TRAP) , REJECT(ABRT) , + REJECT(BUS) , REJECT(FPE) , REJECT(KILL) , + ACCEPT(USR1) , REJECT(SEGV) , ACCEPT(USR2) , + ACCEPT(PIPE) , ACCEPT(ALRM) , ACCEPT(TERM) , + REJECT(STKFLT), REJECT(CHLD) , ACCEPT(CONT) , + REJECT(STOP) , ACCEPT(TSTP) , ACCEPT(TTIN) , + ACCEPT(TTOU) , ACCEPT(URG) , ACCEPT(XCPU) , + ACCEPT(XFSZ) , ACCEPT(VTALRM), ACCEPT(PROF) , + ACCEPT(WINCH) , ACCEPT(IO) , ACCEPT(PWR) , + { NULL, -1, 0 } +# undef ACCEPT +# undef REJECT + }, *s; + + const char *p = sigstr; + char *e; + int signo; + + if ('0' <= *p && *p <= '9') { + signo = strtoul(p, &e, 10); + + if (e && *e != '\0') + goto invalid_signal; + } + else { + if (!strncmp(p, "SIG", 3)) + p += 3; + + for (signo = 0, s = signals + 1; !signo && s < signals + NSIGNAL; s++) { + if (!strcmp(p, s->sigstr)) + signo = s->signo; + } + } + + if (signo < 0 || signo > (int)NSIGNAL) + goto invalid_signal; + + s = signals + signo; + + if (s->reject) + goto reject_signal; + + return signo; + + invalid_signal: + print_usage(argv0, EINVAL, "invalid signal '%s'", sigstr); + return -1; + + reject_signal: + print_usage(argv0, EINVAL, "unusable signal '%s'", sigstr); + return -1; + +#undef NSIGNAL +} + + +static void parse_start_options(context_t *c, int argc, char **argv) +{ +# define OPTIONS "w:r:" + static struct option options[] = { + { "restart-status", required_argument, NULL, 'r' }, + { NULL, 0, NULL, 0 }, + }; + + int opt; + char *e; + + c->remote_uid = geteuid(); + c->forced_restart = 69; + + if (c->remote_uid == 0) + print_usage(argv[0], EINVAL, "cannot start session as root"); + + if (optind >= argc) + return; + + while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { + switch (opt) { + case 'r': + c->forced_restart = strtol(optarg, &e, 10); + + if (e && *e) { + print_usage(argv[0], EINVAL, "invalid restart status '%s'", + optarg); + } + break; + + case '?': + print_usage(argv[0], EINVAL, "invalid start option"); + break; + } + } + +# undef OPTIONS +} + + +static uid_t parse_remote(const char *argv0, const char *remote) +{ + uid_t uid; + + uid = remote_user_id(remote, NULL, 0); + + if (uid == INVALID_UID) + print_usage(argv0, EINVAL, + "failed to resolve user for remote '%s'", remote); + else + return uid; +} + + +static void parse_stop_options(context_t *c, int argc, char **argv) +{ +# define OPTIONS "r:s:" + static struct option options[] = { + { "remote", required_argument, NULL, 'r' }, + { "signal", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0 }, + }; + + int opt; + + c->remote_uid = geteuid(); + + if (optind >= argc) + return; + + while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { + switch (opt) { + case 'r': + c->remote_uid = parse_remote(c->argv0, optarg); + break; + + case 's': + c->signal = parse_signal(c->argv0, optarg); + break; + + case '?': + print_usage(argv[0], EINVAL, "invalid 'stop' option '%c'", opt); + break; + } + } +# undef OPTIONS +} + + +static void parse_list_options(context_t *c, int argc, char **argv) +{ + const char *remote; + + if (optind > argc - 1) + c->remote_uid = geteuid(); + else if (optind == argc - 1) { + remote = optarg; + + if (!strcmp(remote, "all") || !strcmp(remote, ".")) + c->remote_uid = 0; + else + c->remote_uid = parse_remote(c->argv0, remote); + } + else + print_usage(argv[0], EINVAL, "too many arguments for 'list'"); +} + + +static void parse_signal_options(context_t *c, int argc, char **argv) +{ +# define OPTIONS "r:s:" + static struct option options[] = { + { "remote", required_argument, NULL, 'r' }, + { "signal", required_argument, NULL, 's' }, + { NULL, 0, NULL, 0 }, + }; + + int opt; + + c->remote_uid = geteuid(); + c->signal = SIGTERM; + + if (optind >= argc) + return; + + while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { + switch (opt) { + case 'r': + c->remote_uid = parse_remote(c->argv0, optarg); + break; + + case 's': + c->signal = parse_signal(c->argv0, optarg); + break; + + case '?': + print_usage(argv[0], EINVAL, "invalid 'signal' option '%c'", opt); + break; + } + } +# undef OPTIONS +} + + +static void parse_update_options(context_t *c, int argc, char **argv) +{ +# define OPTIONS "oi:" + static struct option options[] = { + { "one-shot" , no_argument , NULL, 'o' }, + { "poll-interval", required_argument, NULL, 'i' }, + { NULL, 0, NULL, 0 }, + }; + + int opt; + + if (c->poll_interval <= 0) + c->poll_interval = FPAK_POLL_MIN_INTERVAL; + + if (optind >= argc) + return; + + while ((opt = getopt_long(argc, argv, OPTIONS, options, NULL)) != -1) { + switch (opt) { + case 'o': + c->poll_interval = -1; + break; + + case 'i': + c->poll_interval = parse_interval(c->argv0, optarg); + break; + + case '?': + print_usage(argv[0], EINVAL, "invalid 'update' option"); + break; + } + } +# undef OPTIONS +} + + +void config_parse_cmdline(context_t *c, int argc, char **argv) +{ + set_defaults(c, argv); + log_open(c); + + parse_common_options(c, argc, argv); + parse_action(c, argc, argv); + + switch (c->action) { + case ACTION_GENERATE: parse_generate_options(c, argc, argv); break; + case ACTION_UPDATE: parse_update_options(c, argc, argv); break; + case ACTION_START: parse_start_options(c, argc, argv); break; + case ACTION_STOP: parse_stop_options(c, argc, argv); break; + case ACTION_SIGNAL: parse_signal_options(c, argc, argv); break; + case ACTION_LIST: parse_list_options(c, argc, argv); break; + default: + break; + } + + log_open(c); +} + diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/filesystem.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/filesystem.c new file mode 100644 index 0000000000..35828d92c1 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/filesystem.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "flatpak-session.h" + + +int fsys_prepare_session(context_t *c) +{ + char *dir = fsys_mkpath(NULL, 0, "%s/%s.wants", + c->service_dir, FPAK_SYSTEMD_TARGET); + + log_info("creating service directory %s...", dir); + + if (c->dry_run) + return 0; + else + return fsys_mkdirp(0755, dir); +} + + +char *fsys_mkpath(char *path, size_t size, const char *fmt, ...) +{ + static char buf[PATH_MAX]; + va_list ap; + int n; + + if (path == NULL) { + path = buf; + size = sizeof(buf); + } + else if (size > PATH_MAX) + size = PATH_MAX; + + va_start(ap, fmt); + n = vsnprintf(path, size, fmt, ap); + va_end(ap); + + if (n < 0 || n >= (int)size) + goto nametoolong; + + return path; + + nametoolong: + errno = ENAMETOOLONG; + return NULL; +} + + +int fsys_mkdir(const char *path, mode_t mode) +{ + const char *p; + char *q, buf[PATH_MAX]; + int n, undo[PATH_MAX / 2]; + struct stat st; + + if (path == NULL || path[0] == '\0') { + errno = path ? EINVAL : EFAULT; + return -1; + } + + log_debug("checking/creating '%s'...", path); + + p = path; + q = buf; + n = 0; + while (1) { + if (q - buf >= (ptrdiff_t)sizeof(buf) - 1) { + errno = ENAMETOOLONG; + goto cleanup; + } + + if (*p && *p != '/') { + *q++ = *p++; + continue; + } + + *q = '\0'; + + if (q != buf) { + log_debug("checking/creating '%s'...", buf); + + if (stat(buf, &st) < 0) { + if (errno != ENOENT) + goto cleanup; + + if (mkdir(buf, mode) < 0) + goto cleanup; + + undo[n++] = q - buf; + } + else { + if (!S_ISDIR(st.st_mode)) { + errno = ENOTDIR; + goto cleanup; + } + } + } + + while (*p == '/') + p++; + + if (!*p) + break; + + *q++ = '/'; + } + + return 0; + + cleanup: + while (--n >= 0) { + buf[undo[n]] = '\0'; + log_debug("cleaning up '%s'...", buf); + rmdir(buf); + } + + return -1; +} + + +int fsys_mkdirp(mode_t mode, const char *fmt, ...) +{ + va_list ap; + char path[PATH_MAX]; + int n; + + va_start(ap, fmt); + n = vsnprintf(path, sizeof(path), fmt, ap); + va_end(ap); + + if (n < 0 || n >= (int)sizeof(path)) + goto nametoolong; + + return fsys_mkdir(path, mode); + + nametoolong: + errno = ENAMETOOLONG; + return -1; +} + + +int fsys_symlink(const char *path, const char *dst) +{ + struct stat stp, std; + + if (lstat(path, &stp) < 0) + return -1; + + if (!S_ISLNK(stp.st_mode)) + return 0; + + if (dst == NULL) + return 1; + + if (stat(path, &std) < 0) + return 0; + + if (stat(path, &stp) < 0) + return -1; + + if (stp.st_dev == std.st_dev && stp.st_ino == std.st_ino) + return 1; + else + return 0; +} + + +char *fsys_service_path(context_t *c, const char *usr, char *path, size_t size) +{ + const char *srvdir = SYSTEMD_SERVICEDIR; + const char *session = FPAK_SYSTEMD_SESSION; + + UNUSED_ARG(c); + UNUSED_ARG(usr); + + return fsys_mkpath(path, size, "%s/%s", srvdir, session); +} + + +char *fsys_service_link(context_t *c, const char *usr, char *path, size_t size) +{ + const char *session = FPAK_SYSTEMD_SESSION, *s; + char *d; + int l, n; + + d = path; + l = (int)size; + + n = snprintf(d, l, "%s/%s.wants/", c->service_dir, FPAK_SYSTEMD_TARGET); + + if (n < 0) + return NULL; + if (n >= l) + goto overflow; + + d += n; + l -= n; + + s = strchr(session, '@'); + + if (s != NULL) { + n = snprintf(d, l, "%.*s", (int)(s - session + 1), session); + + if (n < 0) + return NULL; + if (n >= l) + goto overflow; + + d += n; + l -= n; + s++; + + n = snprintf(d, l, "%s", usr); + + if (n < 0) + return NULL; + if (n >= l) + goto overflow; + + d += n; + l -= n; + } + + n = snprintf(d, l, "%s", s); + + if (n < 0) + return NULL; + if (n >= l) + goto overflow; + + return path; + + overflow: + errno = EOVERFLOW; + return NULL; +} + + +int fs_scan_proc(const char *exe, uid_t uid, + int (*cb)(pid_t pid, void *user_data), void *user_data) +{ + DIR *dp; + struct dirent *de; + struct stat st; + char file[PATH_MAX], *bin; + int n, status; + + if ((dp = opendir("/proc")) == NULL) + return -1; + + while ((de = readdir(dp)) != NULL) { + if (!('0' <= de->d_name[0] && de->d_name[0] <= '9')) + continue; + + snprintf(file, sizeof(file), "/proc/%s/exe", de->d_name); + + if (lstat(file, &st) != 0) + continue; + + if (uid != (uid_t)-1 && st.st_uid != uid) + continue; + + if ((n = readlink(file, file, sizeof(file))) < 0) + continue; + + file[n] = '\0'; + + if (exe[0] == '/') { + bin = file; + } + else { + if ((bin = strrchr(file, '/')) != NULL) + bin++; + else + bin = file; + } + + if (!strcmp(exe, bin)) { + status = cb((pid_t)strtoul(de->d_name, NULL, 10), user_data); + + if (status == 0) + break; + + if (status < 0) + goto fail; + } + } + + closedir(dp); + + return 0; + + fail: + closedir(dp); + + return -1; +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.c new file mode 100644 index 0000000000..3eb6ba2284 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "flatpak-session.h" + + +static int generate_session(context_t *c, remote_t *r) +{ + char srv[PATH_MAX], lnk[PATH_MAX]; + + if (!fsys_service_path(c, r->user, srv, sizeof(srv)) || + !fsys_service_link(c, r->user, lnk, sizeof(lnk))) + return -1; + + log_info("remote %s: generating session (user %s)", r->name, r->user); + + if (c->dry_run) { + log_info("symlinking %s -> %s", lnk, srv); + return 0; + } + + unlink(lnk); + + if (symlink(srv, lnk) < 0) + return -1; + + return 0; +} + + +static void action_generate(context_t *c) +{ + remote_t *r; + + if (fpak_init(c, FPAK_DISCOVER_REMOTES) < 0) + log_fatal("failed to initialize flatpak library"); + + if (fsys_prepare_session(c) < 0) + log_fatal("failed to prepare filesystem for session generation"); + + fpak_foreach_remote(c, r) { + if (generate_session(c, r) < 0) + log_error("remote %s: failed to generate session", r->name); + } +} + + +static void remote_pending_cb(context_t *c) +{ + if (fpak_update_apps(c) < 0) + log_error("failed to update applications"); +} + + +static void action_update(context_t *c) +{ + if (fpak_init(c, FPAK_DISCOVER_APPS) < 0) + log_fatal("failed to initialize flatpak library"); + + if (fpak_poll_updates(c)) + if (fpak_update_apps(c) < 0) + log_error("failed to update applications"); + + if (c->poll_interval > 0) + if (fpak_track_remote_updates(c, remote_pending_cb) < 0) + log_fatal("failed to track remote updates"); +} + + +static void local_updates_cb(context_t *c) +{ + if (fpak_reload_apps(c) < 0) + log_error("failed to reload local updates"); + if (fpak_reload_session(c) < 0) + log_error("failed to reload session for %d", c->remote_uid); +} + + +static void action_start(context_t *c) +{ + if (fpak_init(c, FPAK_DISCOVER_APPS) < 0) + log_fatal("failed to initialize flatpak library"); + + if (fpak_start_session(c) < 0) + log_fatal("failed to start session for user %d", c->remote_uid); + + if (fpak_track_local_updates(c, local_updates_cb) < 0) + log_error("failed to track local updates"); +} + + +int main(int argc, char *argv[]) +{ + context_t ctx, *c = &ctx; + + config_parse_cmdline(c, argc, argv); + + if (mainloop_needed(c)) + mainloop_create(c); + + switch (c->action) { + case ACTION_GENERATE: action_generate(c); break; + case ACTION_UPDATE: action_update(c); break; + case ACTION_START: action_start(c); break; + default: + log_error("internal error: unknown action (%d)", c->action); + exit(1); + } + +#if 0 + switch (c->action) { + case ACTION_STOP: stop_session(c); break; + case ACTION_LIST: list_session(c); break; + case ACTION_SIGNAL: signal_session(c); break; + default: + log_error("internal error: unknown action (%d)", c->action); + exit(1); + } +#endif + + if (c->ml != NULL) + mainloop_run(c); + + exit(c->exit_code); +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.h b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.h new file mode 100644 index 0000000000..38e425dc13 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session.h @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FLATPAK_SESSION_H__ +#define __FLATPAK_SESSION_H__ + +#include +#include +#include +#include + +#include "config.h" + +/* default system path definitions */ +#ifndef SYSCONFDIR +# define SYSCONFDIR "/etc" +#endif + +#ifndef LIBDIR +# define LIBDIR "/usr/lib" +#endif + +#ifndef LIBEXECDIR +# define LIBEXECDIR "/usr/libexec" +#endif + +#ifndef SYSTEMD_SERVICEDIR +# define SYSTEMD_SERVICEDIR LIBDIR"/systemd/system" +#endif + +/* default repo URL and key dir */ +#ifndef FPAK_REPOS_DIR +# define FPAK_REPOS_DIR SYSCONFDIR"/flatpak-session" +#endif + +/* default systemd service, target, and generator */ +#ifndef FPAK_SYSTEMD_SESSION +# define FPAK_SYSTEMD_SESSION "flatpak-session@.service" +#endif + +#ifndef FPAK_SYSTEMD_TARGET +# define FPAK_SYSTEMD_TARGET "flatpak-sessions.target" +#endif + +#ifndef FPAK_SYSTEMD_GENERATOR +# define FPAK_SYSTEMD_GENERATOR "flatpak-session-enable" +#endif + +/* flatpak session binary path */ +#ifndef FPAK_SESSION_PATH +# define FPAK_SESSION_PATH "/usr/bin/flatpak-session" +#endif + +/* default path to systemd user slice top directory */ +#ifndef SYSTEMD_USER_SLICE +# define SYSTEMD_USER_SLICE "/sys/fs/cgroup/systemd/user.slice" +#endif + +/* root directory used by flatpak in application-specific namespaces */ +#ifndef FLATPAK_APP_ROOT +# define FLATPAK_APP_ROOT "/newroot/app" +#endif + +/* gecos prefix we look for to identify remote-specific users */ +#ifndef FPAK_GECOS_PREFIX +# define FPAK_GECOS_PREFIX "flatpak user for " +#endif + +/* section and key names for our extra flatpak metadata */ +#define FPAK_SECTION_REFKIT "Application" /* reuse existing section */ +#define FPAK_KEY_INSTALL "X-Install" /* autoinstall application */ +#define FPAK_KEY_START "X-Start" /* autostart application */ +#define FPAK_KEY_URGENCY "X-Urgency" /* update urgency */ + +/* timers, intervals */ +#define FPAK_UPDATE_LOWPASS_TIMER 15 /* update monitor lowpass filter */ +#define FPAK_POLL_MIN_INTERVAL 15 /* minimum polling interval */ + +/* forward declaration of types */ +typedef struct context_s context_t; +typedef struct remote_s remote_t; +typedef struct application_s application_t; + +/* actions (modes of operation) */ +typedef enum { + ACTION_UNKNOWN = -1, + ACTION_GENERATE, /* generate systemd services for remotes */ + ACTION_UPDATE, /* update flatpaks managed by us */ + ACTION_START, /* start flatpaks for/in a session */ + ACTION_STOP, /* stop flatpaks for/in a session */ + ACTION_SIGNAL, /* signal flatpaks in a session */ + ACTION_LIST, /* list flatpaks */ +} action_t; + +struct context_s { + FlatpakInstallation *f; /* flatpak (system) context */ + remote_t *remotes; /* remotes of interest */ + int nremote; /* number of remotes */ + application_t *apps; /* flatpaks (applications) of interest */ + int napp; /* number of flatpaks */ + GMainLoop *ml; /* main loop, if we need one */ + GFileMonitor *lm; /* flatpak monitor for local changes */ + int lmcn; /* monitor gobject connection */ + unsigned int lmlpt; /* monitor lowpass filter timer */ + unsigned int rpt; /* remote polling timer */ + sigset_t signals; /* signals we catch */ + int sigfd; /* signalfd */ + GIOChannel *sigio; /* I/O channel for sigfd */ + guint sigw; /* watch source id for sigio */ + int exit_code; /* status to exit with */ + + struct { /* various notification callbacks */ + void (*r_up)(context_t *c); /* remote updates available */ + void (*l_up)(context_t *c); /* local updates available */ + } notify; + + /* configuration/command line */ + const char *argv0; /* our binary */ + action_t action; /* action/mode we're running in */ + const char *service_dir; /* systemd generator output directory */ + int forced_restart; /* exit status for forced restart */ + uid_t remote_uid; /* remote to stop/signal session for */ + int poll_interval; /* remote monitor polling interval */ + int signal; /* signal to send */ + int dry_run : 1; /* just show actions, don't execute them */ + int gpg_verify : 1; /* ignore unverifiable remotes */ +}; + +/* a remote repository (associated with a session/user and applications) */ +struct remote_s { + char *name; /* flatpak remote name */ + char *url; /* remote repository URL */ + char *user; /* associated user to run session */ + uid_t uid; /* and its user id */ +}; + +/* a flatpak (application) */ +struct application_s { + char *origin; /* remote repository of origin */ + char *name; /* flatpak application name */ + char *head; /* current latest commit */ + int install : 1; /* automatically install */ + int start : 1; /* automatically start within session */ + int urgent : 1; /* urgent update */ + int pending : 1; /* pending remote updates */ + int updated : 1; /* locally updated */ +}; + + +/* + * miscallaneous macros + */ +#define INVALID_UID ((uid_t)-1) +#define UNUSED_ARG(_arg) (void)(_arg) + +/* + * declarations, function prototypes + */ + +/* config.c */ +void config_parse_cmdline(context_t *c, int argc, char **argv); + +/* mainloop.c */ +int mainloop_needed(context_t *c); +void mainloop_create(context_t *c); +void mainloop_destroy(context_t *c); +void mainloop_run(context_t *c); +void mainloop_quit(context_t *c, int exit_status); +unsigned int mainloop_add_timer(context_t *c, int secs, int (*cb)(void *), + void *user_data); +void mainloop_del_timer(context_t *c, unsigned int id); +unsigned int timer_add(context_t *c, int secs, int (*cb)(void *), + void *user_data); +void timer_del(context_t *c, unsigned int id); + +/* remote.c */ +uid_t remote_user_id(const char *remote, char *usrbuf, size_t size); +char *remote_user_name(uid_t uid, char *usrbuf, size_t size); + +/* filesystem.c */ +int fsys_prepare_session(context_t *c); +char *fsys_mkpath(char *path, size_t size, const char *fmt, ...); +int fsys_mkdir(const char *path, mode_t mode); +int fsys_mkdirp(mode_t mode, const char *fmt, ...); +int fsys_symlink(const char *path, const char *dst); +char *fsys_service_path(context_t *c, const char *usr, char *path, size_t size); +char *fsys_service_link(context_t *c, const char *usr, char *path, size_t size); +int fs_scan_proc(const char *exe, uid_t uid, + int (*cb)(pid_t pid, void *user_data), void *user_data); + +/* flatpak.c */ +typedef enum { + FPAK_DISCOVER_REMOTES = 0x1, + FPAK_DISCOVER_APPS = 0x2, +} fpak_flag_t; + +int fpak_init(context_t *c, int flags); +int fpak_install_remotes(context_t *c, const char *dir); +int fpak_create_remote(context_t *c, const char *name, const char *url, + const char *key, int keylen); +int fpak_discover_remotes(context_t *c); +int fpak_discover_apps(context_t *c); +int fpak_start_app(context_t *c, application_t *a); +int fpak_start_session(context_t *c); +char *fpak_app_systemd_scope(uid_t uid, pid_t session, const char *app, + char *scope, size_t size); +int fpak_poll_updates(context_t *c); +int fpak_update_apps(context_t *c); +int fpak_reload_apps(context_t *c); +int fpak_reload_session(context_t *c); +remote_t *fpak_lookup_remote(context_t *c, const char *name); +remote_t *fpak_remote_for_uid(context_t *c, uid_t uid); +application_t *fpak_lookup_app(context_t *c, const char *name); +int fpak_track_remote_updates(context_t *c, void (*cb)(context_t *)); +int fpak_track_local_updates(context_t *c, void (*cb)(context_t *)); + +#define fpak_foreach_remote(_c, _r) \ + for (_r = _c->remotes; _r && _r->name; _r++) + +#define fpak_foreach_app(_c, _a) \ + for (_a = _c->apps; _a && _a->name; _a++) + +/* log.c */ +typedef enum { + FPAK_LOG_NONE = 0x00, + FPAK_LOG_FATAL = 0x01, + FPAK_LOG_ERROR = 0x02, + FPAK_LOG_WARNING = 0x04, + FPAK_LOG_INFO = 0x08, + FPAK_LOG_DEBUG = 0x10, + FPAK_LOG_ALL = 0x1f, +} fpak_log_level_t; + +int log_set_mask(int mask); +int log_get_mask(void); +void log_open(context_t *c); +void log_close(void); +void log_msg(int lvl, const char *function, const char *file, int line, + const char *fmt, ...); + +#define __LOC__ __FUNCTION__, __FILE__, __LINE__ + +#define log_fatal(_fmt, _args...) log_msg(FPAK_LOG_FATAL , __LOC__, \ + _fmt, ## _args), exit(1) +#define log_error(_fmt, _args...) log_msg(FPAK_LOG_ERROR , __LOC__, \ + _fmt, ## _args) +#define log_warn(_fmt, _args...) log_msg(FPAK_LOG_WARNING, __LOC__, \ + _fmt, ## _args) +#define log_info(_fmt, _args...) log_msg(FPAK_LOG_INFO , __LOC__, \ + _fmt, ## _args) +#define log_debug(_fmt, _args...) log_msg(FPAK_LOG_DEBUG , __LOC__, \ + _fmt, ## _args) + +#endif /* __FLATPAK_SESSION_H__ */ diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session@.service b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session@.service new file mode 100644 index 0000000000..3593d20c8a --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-session@.service @@ -0,0 +1,18 @@ +[Unit] +Description=Automatic flatpak login session for user/remote %i. +After=systemd-user-sessions.service network.service +Before=flatpak-update.service + +[Service] +User=%i +WorkingDirectory=~ +StandardInput=null +StandardOutput=journal +StandardError=journal +PAMName=login +RestartForceExitStatus=69 +Type=simple +ExecStart=/usr/bin/flatpak-session -vvv start -r 69 + +[Install] +WantedBy=multi-user.target diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-sessions.target b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-sessions.target new file mode 100644 index 0000000000..1089c6c32d --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-sessions.target @@ -0,0 +1,18 @@ +# +# Target for autostarting flatpak sessions. +# +# This target is used to collect services that create sessions for users +# corresponding to flatpak remotes and starts flatpaks from the remotes +# in the corresponding user sessions. +# + +[Unit] +Description=Flatpak Sessions +Documentation=man:systemd.special(7) +Conflicts=rescue.service rescue.target +After=network.target +AllowIsolate=no +RefuseManualStart=no + +[Install] +WantedBy=multi-user.target diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-update.service b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-update.service new file mode 100644 index 0000000000..24a2154d62 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak-update.service @@ -0,0 +1,12 @@ +[Unit] +Description=Monitor and pull in available updates for flatpaks. +After=systemd-user-sessions.service network.service + +[Service] +StandardInput=null +StandardOutput=journal +StandardError=journal +ExecStart=/usr/bin/flatpak-session -vvv update --poll-interval 5m + +[Install] +WantedBy=multi-user.target diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak.c new file mode 100644 index 0000000000..a4ea54ce6e --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/flatpak.c @@ -0,0 +1,993 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "flatpak-session.h" + + +static GKeyFile *meta_load(FlatpakInstalledRef *ref); +static GKeyFile *meta_fetch(context_t *c, FlatpakRemoteRef *rref); +static void meta_free(GKeyFile *m); +static const char *meta_get(GKeyFile *m, const char *sec, const char *key, + const char *def); +#define meta_str meta_get +static int meta_int(GKeyFile *m, const char *sec, const char *key, int def); +static int meta_bool(GKeyFile *m, const char *sec, const char *key, int def); + + +int fpak_create_remote(context_t *c, const char *name, const char *url, + const char *key, int keylen) +{ + FlatpakRemote *r; + GError *e; + GBytes *key_bytes; + + e = NULL; + r = flatpak_installation_get_remote_by_name(c->f, name, NULL, &e); + + if (r != NULL) + goto out; + + g_error_free(e); + e = NULL; + + log_info("flatpak: creating remote '%s' (%s)", name, url); + + r = flatpak_remote_new(name); + + if (r == NULL) + return -1; + + flatpak_remote_set_url(r, url); + flatpak_remote_set_gpg_verify(r, TRUE); + flatpak_remote_set_noenumerate(r, FALSE); + flatpak_remote_set_gpg_key(r, key_bytes = g_bytes_new(key, keylen)); + g_bytes_unref(key_bytes); + + if (!flatpak_installation_modify_remote(c->f, r, NULL, &e)) + goto failed; + + out: + g_object_unref(r); + return 0; + + failed: + log_error("flatpak: failed to install remote %s (%s: %d: %s)", + name, g_quark_to_string(e->domain), e->code, e->message); + g_object_unref(r); + g_error_free(e); + + return -1; +} + + +static void strip_whitespace(char *url, int len) +{ + char *p = url; + int n; + + for (p = url; isspace(*p) && p < url + len; p++) + ; + + if (p != url) { + n = p - url; + len -= n; + memmove(url, p, len); + } + + while (len > 0 && isspace(url[len - 1])) + url[--len] = '\0'; +} + + +static ssize_t read_url_and_key(int urlfd, char *url, size_t urlsize, + int keyfd, char *key, size_t keysize) +{ + int len, n; + struct stat st; + + if (fstat(urlfd, &st) < 0) + return -1; + + if (st.st_size > (int)urlsize - 1) + return -1; + + len = 0; + while (len < st.st_size) { + n = read(urlfd, url + len, st.st_size - len); + + if (n < 0) { + if (errno != EINTR) + return -1; + else + continue; + } + + len += n; + } + url[len] = '\0'; + + if (len > 0) + strip_whitespace(url, len - 1); + + if (fstat(keyfd, &st) < 0) + return -1; + + if (st.st_size > (int)keysize) + return -1; + + len = 0; + while (len < st.st_size) { + n = read(keyfd, key + len, st.st_size - len); + + if (n < 0) { + if (errno != EINTR) + return -1; + else + continue; + } + + len += n; + } + + return len; +} + + +int fpak_install_remotes(context_t *c, const char *dir) +{ + DIR *dp; + struct dirent *de; + char *suff, name[PATH_MAX], path[PATH_MAX]; + int keyfd, urlfd, keylen, len; + char key[4096], url[1024 + PATH_MAX]; + + dp = opendir(dir); + + if (dp == NULL) + return errno == ENOENT ? 0 : -1; + + while ((de = readdir(dp)) != NULL) { + if (de->d_type != DT_REG) + continue; + + if ((suff = strrchr(de->d_name, '.')) == NULL) + continue; + + if (strcmp(suff + 1, "url") != 0) + continue; + + len = (int)(suff - de->d_name); + snprintf(name, sizeof(name), "%.*s", len, de->d_name); + + snprintf(path, sizeof(path), "%s/%s.url", dir, name); + urlfd = open(path, O_RDONLY); + snprintf(path, sizeof(path), "%s/%s.key", dir, name); + keyfd = open(path, O_RDONLY); + + keylen = read_url_and_key(urlfd, url, sizeof(url), + keyfd, key, sizeof(key)); + + close(urlfd); + close(keyfd); + + if (keylen > 0) + fpak_create_remote(c, name, url, key, keylen); + else + log_error("flatpak: failed to read URL or key for remote %s", name); + } + + closedir(dp); + + return 0; +} + + +int fpak_init(context_t *c, int flags) +{ + GError *e; + + if (c->f != NULL) + return 0; + + e = NULL; + c->f = flatpak_installation_new_system(NULL, &e); + + if (c->f == NULL) + goto init_failed; + + fpak_install_remotes(c, FPAK_REPOS_DIR); + flatpak_installation_drop_caches(c->f, NULL, &e); + + if (flags & (FPAK_DISCOVER_REMOTES | FPAK_DISCOVER_APPS)) + if (fpak_discover_remotes(c) < 0) + goto fail; + + if (flags & FPAK_DISCOVER_APPS) + if (fpak_discover_apps(c) < 0) + goto fail; + + return 0; + + init_failed: + log_fatal("flatpak: failed to initialize library (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + + fail: + return -1; +} + + +int fpak_discover_remotes(context_t *c) +{ + remote_t *r; + const char *name, *url; + uid_t uid; + GPtrArray *refs; + FlatpakRemote *ref; + GError *e; + int i; + + if (c->remotes != NULL) + return 0; + + e = NULL; + refs = flatpak_installation_list_remotes(c->f, NULL, &e); + + if (refs == NULL) + goto list_failed; + + c->remotes = calloc(refs->len + 1, sizeof(*c->remotes)); + + if (c->remotes == NULL) + log_fatal("flatpak: failed to allocate remotes"); + + r = c->remotes; + for (i = 0; i < (int)refs->len; i++) { + ref = g_ptr_array_index(refs, i); + name = flatpak_remote_get_name(ref); + url = flatpak_remote_get_url(ref); + + if (flatpak_remote_get_disabled(ref)) { + log_warn("flatpak: skipping disabled remote '%s'", name); + continue; + } + + if (c->gpg_verify && !flatpak_remote_get_gpg_verify(ref)) { + log_warn("flatpak: skipping unverifiable remote '%s'", name); + continue; + } + + if ((uid = remote_user_id(name, NULL, 0)) == INVALID_UID) { + log_warn("flatpak: skipping remote without user '%s'", name); + continue; + } + + if (c->remote_uid > 0 && uid != c->remote_uid) { + log_debug("flatpak: skipping other remote '%s'", name); + continue; + } + + r->name = strdup(name); + r->url = strdup(url); + r->user = strdup(remote_user_name(uid, NULL, 0)); + r->uid = uid; + + if (r->name == NULL || r->url == NULL || r->user == NULL) + log_fatal("flatpak: failed to allocate remote"); + + log_info("flatpak: discovered remote '%s' (%s)", r->name, r->url); + + c->nremote++; + r++; + + } + + g_ptr_array_unref(refs); + + return 0; + + list_failed: + log_error("flatpak: failed to query remotes (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + return -1; +} + + +static int update_urgent(const char *urgency) +{ + return !!(!strcmp(urgency, "critical") || !strcmp(urgency, "important")); +} + + +int fpak_discover_apps(context_t *c) +{ + application_t *a; + GKeyFile *m; + const char *origin, *name, *head, *urgency; + GPtrArray *refs; + FlatpakInstalledRef *ref; + FlatpakRefKind knd; + GError *e; + int install, start, urgent; + int i; + + if (c->apps != NULL) + return 0; + + if (fpak_discover_remotes(c) < 0) + return -1; + + knd = FLATPAK_REF_KIND_APP; + e = NULL; + refs = flatpak_installation_list_installed_refs_by_kind(c->f, knd, NULL, &e); + + if (refs == NULL) + goto list_failed; + + c->apps = calloc(refs->len + 1, sizeof(*c->apps)); + + if (c->apps == NULL) + log_fatal("flatpak: failed to allocate applications"); + + a = c->apps; + for (i = 0; i < (int)refs->len; i++) { + ref = g_ptr_array_index(refs, i); + origin = flatpak_installed_ref_get_origin(ref); + name = flatpak_ref_get_name(FLATPAK_REF(ref)); + head = flatpak_ref_get_commit(FLATPAK_REF(ref)); + + if (fpak_lookup_remote(c, origin) == NULL) { + log_debug("flatpak: skipping app '%s' without remote", name); + continue; + } + + if ((m = meta_load(ref)) == NULL) + goto meta_failed; + install = meta_bool(m, FPAK_SECTION_REFKIT, FPAK_KEY_INSTALL, 1); + start = meta_bool(m, FPAK_SECTION_REFKIT, FPAK_KEY_START , 1); + urgency = meta_str (m, FPAK_SECTION_REFKIT, FPAK_KEY_URGENCY, "-"); + urgent = update_urgent(urgency); + meta_free(m); + + a->origin = strdup(origin); + a->name = strdup(name); + a->head = strdup(head); + a->install = install; + a->start = start; + a->urgent = urgent; + + if (a->origin == NULL || a->name == NULL || a->head == NULL) + log_fatal("flatpak: failed to allocate app"); + + c->napp++; + a++; + } + + g_ptr_array_unref(refs); + + return 0; + + list_failed: + log_error("flatpak: failed to query applications (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + return -1; + + meta_failed: + log_error("flatpak: failed to load metadata for '%s'", name); + return -1; +} + + +int fpak_start_app(context_t *c, application_t *a) +{ + GError *e; + int status; + + log_info("flatpak: starting application %s", a->name); + + if (c->dry_run) + return 0; + + sigprocmask(SIG_UNBLOCK, &c->signals, NULL); + e = NULL; + if (!flatpak_installation_launch(c->f, a->name, NULL, NULL, NULL, NULL, &e)) + status = -1; + else + status = 0; + sigprocmask(SIG_BLOCK, &c->signals, NULL); + + if (!status) + return 0; + else { + log_error("flatpak: failed to start '%s' (%s: %d: %s)", a->name, + g_quark_to_string(e->domain), e->code, e->message); + return -1; + } +} + + +int fpak_start_session(context_t *c) +{ + remote_t *r; + application_t *a; + + r = fpak_remote_for_uid(c, c->remote_uid); + + if (r == NULL) + goto no_remote; + + fpak_foreach_app(c, a) { + if (strcmp(a->origin, r->name)) + continue; + + fpak_start_app(c, a); + } + + return 0; + + no_remote: + log_error("flatpak: no remote associated with uid %d", c->remote_uid); + return -1; +} + + +int fpak_reload_session(context_t *c) +{ + application_t *a; + + fpak_foreach_app(c, a) { + if (a->updated) { + log_info("flatpak: %s had updates, should be restarted", a->name); + a->updated = 0; + } + } + + if (c->forced_restart) + exit(c->forced_restart); + + return 0; +} + + +static void progress_cb(const char *status, guint pcnt, gboolean estim, + gpointer user_data) +{ + application_t *a = user_data; + + if (estim) + return; + + log_info("flatpak: %s/%s, %s, %d %% done", a->origin, a->name, status, pcnt); +} + + +int fpak_update_apps(context_t *c) +{ + application_t *a; + FlatpakInstalledRef *u; + const char *name, *origin, *urgency; + GKeyFile *m; + int install, start, urgent; + FlatpakRefKind rk = FLATPAK_REF_KIND_APP; + GError *e; + + fpak_foreach_app(c, a) { + if (!a->pending) + continue; + + name = a->name; + origin = a->origin; + e = NULL; + + log_info("flatpak: %s '%s'", a->head ? "updating" : "installing", name); + + if (c->dry_run) + continue; + + if (a->head != NULL) + u = flatpak_installation_update(c->f, 0, rk, name, NULL, NULL, + progress_cb, a, NULL, &e); + else + u = flatpak_installation_install(c->f, origin, rk, name, NULL, NULL, + progress_cb, a, NULL, &e); + + if (u == NULL) { + if (e && e->code) + log_warn("flatpak: failed to update '%s' (%s: %d: %s)", name, + g_quark_to_string(e->domain), e->code, e->message); + continue; + } + + if ((m = meta_load(u)) == NULL) { + log_warn("flatpak: failed to load metadata for '%s'", name); + goto next; + } + start = meta_bool(m, FPAK_SECTION_REFKIT, FPAK_KEY_START , 1); + install = meta_bool(m, FPAK_SECTION_REFKIT, FPAK_KEY_INSTALL, 1); + urgency = meta_str (m, FPAK_SECTION_REFKIT, FPAK_KEY_URGENCY, "-"); + urgent = update_urgent(urgency); + meta_free(m); + + a->start = start; + a->install = install; + a->urgent = urgent; + + free(a->head); + a->head = strdup(flatpak_ref_get_commit(FLATPAK_REF(u))); + + if (!install) { + /* XXX TODO: I think this will fail if app is running... */ + if (!flatpak_installation_uninstall(c->f, rk, name, NULL, NULL, + progress_cb, a, NULL, &e)) + log_warn("flatpak: failed to uninstall '%s' (%s: %d: %s)", name, + g_quark_to_string(e->domain), e->code, e->message); + } + + next: + g_object_unref(u); + a->pending = 0; + } + + return 0; +} + + +int fpak_reload_apps(context_t *c) +{ + application_t *a; + const char *name, *head; + FlatpakInstalledRef *u; + GError *e; + + e = NULL; + flatpak_installation_drop_caches(c->f, NULL, &e); + + fpak_foreach_app(c, a) { + name = a->name; + e = NULL; + u = flatpak_installation_get_current_installed_app(c->f, name, NULL, &e); + + if (u == NULL) + continue; + + head = flatpak_ref_get_commit(FLATPAK_REF(u)); + if (strcmp(a->head, head)) { + log_info("flatpak: '%s' updated (%s -> %s)", name, a->head, head); + + free(a->head); + a->head = strdup(head); + a->updated = 1; + } + else { + log_info("flatpak: '%s' did not change", name); + a->updated = 0; + } + + g_object_unref(u); + } + + return 0; +} + + +remote_t *fpak_lookup_remote(context_t *c, const char *name) +{ + remote_t *r; + + if (c->remotes == NULL) + return NULL; + + for (r = c->remotes; r->name; r++) + if (!strcmp(r->name, name)) + return r; + + return NULL; +} + + +remote_t *fpak_remote_for_uid(context_t *c, uid_t uid) +{ + remote_t *r; + + if (c->remotes == NULL) + return NULL; + + for (r = c->remotes; r->name; r++) + if (r->uid == uid) + return r; + + return NULL; +} + + +application_t *fpak_lookup_app(context_t *c, const char *name) +{ + application_t *a; + + if (c->apps == NULL) + return NULL; + + for (a = c->apps; a->name; a++) + if (!strcmp(a->name, name)) + return a; + + return NULL; +} + + +int fpak_poll_updates(context_t *c) +{ + remote_t *r; + application_t *a; + GPtrArray *refs; + FlatpakRemoteRef *ref; + const char *origin, *name, *head, *urgency; + GKeyFile *m; + GError *e; + int i, install, urgent, updates; + + updates = 0; + + fpak_foreach_remote(c, r) { + name = r->name; + + log_info("flatpak: polling remote '%s' for updates...", name); + + e = NULL; + refs = flatpak_installation_list_remote_refs_sync(c->f, name, NULL, &e); + + if (refs == NULL) { + log_error("flatpak: failed to query updates for %s (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + continue; + } + + origin = name; + for (i = 0; i < (int)refs->len; i++) { + ref = g_ptr_array_index(refs, i); + + if (flatpak_ref_get_kind(FLATPAK_REF(ref)) != FLATPAK_REF_KIND_APP) + continue; + + name = flatpak_ref_get_name(FLATPAK_REF(ref)); + head = flatpak_ref_get_commit(FLATPAK_REF(ref)); + + if ((m = meta_fetch(c, ref)) == NULL) { + log_error("flatpak: failed to fetch metadata for '%s'", name); + continue; + } + install = meta_bool(m, FPAK_SECTION_REFKIT, FPAK_KEY_INSTALL, 1); + urgency = meta_get (m, FPAK_SECTION_REFKIT, FPAK_KEY_URGENCY, "-"); + urgent = update_urgent(urgency); + meta_free(m); + + a = fpak_lookup_app(c, name); + + if (a == NULL) { + if (!install) + continue; + + log_info("flatpak: pending new app '%s'", name); + + c->apps = realloc(c->apps, (c->napp + 2) * sizeof(*c->apps)); + + if (c->apps == NULL) + log_fatal("flatpak: failed to allocate applications"); + + a = c->apps + c->napp; + + memset(a , 0, sizeof(*a)); /* shouldn't be necessary */ + memset(a + 1, 0, sizeof(*a)); + + a->name = strdup(name); + a->origin = strdup(origin); + a->head = NULL; + + if (a->name == NULL || a->origin == NULL) + log_fatal("flatpak: failed to allocate application"); + + a->pending = 1; + a->urgent = urgent; + + c->napp++; + updates++; + } + else { + if (a->head != NULL && strcmp(a->head, head)) { + log_info("flatpak: pending updates for app '%s'", name); + a->pending = 1; + updates++; + } + else + log_info("flatpak: %s up-to-date", name); + } + } + } + + if (!updates) + log_info("no pending updates"); + + return updates; +} + + +static int check_remote_update(gpointer user_data) +{ + context_t *c = user_data; + + if (fpak_poll_updates(c) > 0) + c->notify.r_up(c); + + return G_SOURCE_CONTINUE; +} + + +int fpak_track_remote_updates(context_t *c, void (*cb)(context_t *)) +{ + if (c->notify.r_up != NULL) + return -1; + + c->rpt = timer_add(c, c->poll_interval, check_remote_update, c); + + c->notify.r_up = cb; + + return 0; +} + + +static int notify_local_update(gpointer user_data) +{ + context_t *c = user_data; + + timer_del(c, c->lmlpt); + c->lmlpt = 0; + + c->notify.l_up(c); + + return G_SOURCE_REMOVE; +} + + +static void l_changed(GFileMonitor *m, GFile *file, GFile *other, + GFileMonitorEvent e, gpointer user_data) +{ + context_t *c = user_data; + char *fpath, *opath; + + UNUSED_ARG(m); + UNUSED_ARG(e); + + fpath = file ? g_file_get_path(file) : NULL; + opath = other ? g_file_get_path(other) : NULL; + log_debug("local change (%s, %s), arming low-pass filter timer...\n", + fpath ? fpath : "-", opath ? opath : "-"); + g_free(fpath); + g_free(opath); + + timer_del(c, c->lmlpt); + c->lmlpt = timer_add(c, FPAK_UPDATE_LOWPASS_TIMER, notify_local_update, c); +} + + +int fpak_track_local_updates(context_t *c, void (*cb)(context_t *)) +{ + GError *e; + + if (c->notify.l_up != NULL) + return -1; + + e = NULL; + c->lm = flatpak_installation_create_monitor(c->f, NULL, &e); + + if (c->lm == NULL) + goto monitor_failed; + + c->lmcn = g_signal_connect(c->lm, "changed", G_CALLBACK(l_changed), c); + + if (c->lmcn <= 0) + goto connect_failed; + + c->notify.l_up = cb; + + return 0; + + monitor_failed: + log_error("flatpak: failed to create installation monitor (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + return -1; + + connect_failed: + log_error("flatpak: failed to connect to installation monitor"); + return -1; + + return 0; +} + + +static GKeyFile *meta_load(FlatpakInstalledRef *ref) +{ + GKeyFile *m; + GBytes *b; + const void *d; + size_t l; + GError *e; + + b = NULL; + m = g_key_file_new(); + + if (m == NULL) + log_fatal("flatpak: failed to allocate metadata"); + + e = NULL; + b = flatpak_installed_ref_load_metadata(ref, NULL, &e); + + if (b == NULL) + goto fail_meta; + + d = g_bytes_get_data(b, &l); + + if (d == NULL) + goto fail_data; + + if (!g_key_file_load_from_data(m, d, l, 0, &e)) + goto fail_load; + + g_bytes_unref(b); + + return m; + + fail_load: + log_error("flatpak: failed to parse metadata (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + fail_meta: + fail_data: + g_key_file_unref(m); + g_bytes_unref(b); + return NULL; +} + + +static GKeyFile *meta_fetch(context_t *c, FlatpakRemoteRef *rref) +{ + GKeyFile *m; + GBytes *b; + const void *d; + size_t l; + FlatpakRef *ref; + const char *remote; + GError *e; + + b = NULL; + m = g_key_file_new(); + + if (m == NULL) + log_fatal("flatpak: failed to allocate metadata"); + + g_object_get(rref, "remote-name", &remote, NULL); + + ref = FLATPAK_REF(rref); + e = NULL; + b = flatpak_installation_fetch_remote_metadata_sync(c->f, remote, ref, + NULL, &e); + + if (b == NULL) + goto fail_meta; + + d = g_bytes_get_data(b, &l); + + if (d == NULL) + goto fail_data; + + if (!g_key_file_load_from_data(m, d, l, 0, &e)) + goto fail_load; + + g_bytes_unref(b); + + return m; + + fail_load: + log_error("flatpak: failed to parse metadata (%s: %d: %s)", + g_quark_to_string(e->domain), e->code, e->message); + fail_meta: + fail_data: + g_key_file_unref(m); + g_bytes_unref(b); + return NULL; +} + + +static void meta_free(GKeyFile *m) +{ + if (m != NULL) + g_key_file_unref(m); +} + + +static const char *meta_get(GKeyFile *m, const char *sec, const char *key, + const char *def) +{ + const char *val; + + if (m == NULL) + return def; + + val = g_key_file_get_value(m, sec, key, NULL); + + return val ? val : def; +} + + +static int meta_int(GKeyFile *m, const char *sec, const char *key, int def) +{ + const char *val; + char *e; + int i; + + if (m == NULL) + return def; + + val = g_key_file_get_value(m, sec, key, NULL); + + if (val == NULL) + return def; + + i = strtol(val, &e, 10); + + if (e && !*e) + return i; + + log_warn("flatpak: invalid metadata integer '%s'", val); + return def; +} + + +static int meta_bool(GKeyFile *m, const char *sec, const char *key, int def) +{ + const char *val; + + UNUSED_ARG(meta_int); + + if (m == NULL) + return !!def; + + val = g_key_file_get_value(m, sec, key, NULL); + + if (val == NULL) + return !!def; + + return !!(!strcasecmp(val, "true") || !strcasecmp(val, "yes")); +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/generator.h b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/generator.h new file mode 100644 index 0000000000..88efd2f804 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/generator.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2015, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSG_GENERATOR_H__ +#define __FSG_GENERATOR_H__ + +#include +#include + +#include + +#include "config.h" + +#ifndef SYSCONFDIR +# define SYSCONFDIR "/etc" +#endif + +#ifndef LIBDIR +# define LIBDIR "/usr/lib" +#endif + +#ifndef LIBEXECDIR +# define LIBEXECDIR "/usr/libexec" +#endif + +#ifndef SYSTEM_SERVICEDIR +# define SYSTEM_SERVICEDIR "/usr/lib/systemd/system" +#endif + +#define PATH_TEMPLATE LIBEXECDIR"/flatpak-utils/flatpak-session.template" + +#define UNUSED_ARG(name) (void)name + +typedef struct { + FlatpakInstallation *f; + GPtrArray *remotes; + char *template; + const char *argv0; + int dry_run : 1; + const char *dir_normal; + const char *dir_early; + const char *dir_late; + const char *dir_service; + const char *path_template; +} generator_t; + + +/* config.c */ +void config_parse_cmdline(generator_t *g, int argc, char **argv); + +/* filesystem.c */ +char *fs_mkpath(char *path, size_t size, const char *fmt, ...); +int fs_mkdir(const char *path, mode_t mode); +int fs_mkdirp(mode_t mode, const char *fmt, ...); +int fs_symlink(const char *path, const char *dst); +char *fs_service_path(generator_t *g, const char *usr, char *path, size_t size); +char *fs_service_link(generator_t *g, const char *usr, char *path, size_t size); +int fs_prepare_directories(generator_t *g); + +/* flatpak.c */ +int fp_discover_remotes(generator_t *g); +uid_t fp_resolve_user(FlatpakRemote *r, char *usrbuf, size_t size); + +/* service.c */ +int service_generate_sessions(generator_t *g); + +/* template.c */ +int template_load(generator_t *g); +int template_eval(generator_t *g, const char *usr, const char *remote, + const char *out); + +/* log.c */ +#define log(fmt, args...) do { \ + dprintf(log_fd, fmt"\n" , ## args); \ + } while (0) + +#define log_info(fmt, args...) log("I: "fmt, ## args) +#define log_warning(fmt, args...) log("W: "fmt, ## args) +#define log_error(fmt, args...) log("E: "fmt, ## args) +#define log_debug(fmt, args...) log("D: "fmt, ## args) + +extern int log_fd; +extern int log_mask; + +void log_open(generator_t *g); + + +#endif /* __FSG_GENERATOR_H__ */ diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/log.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/log.c new file mode 100644 index 0000000000..0dcf8d9495 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/log.c @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#include "flatpak-session.h" + +static int log_fd = -1; +static int log_mask = FPAK_LOG_FATAL | FPAK_LOG_ERROR; + + +int log_set_mask(int mask) +{ + int old_mask = log_mask; + + log_mask = mask; + + return old_mask; +} + + +int log_get_mask(void) +{ + return log_mask; +} + + +void log_open(context_t *c) +{ + log_close(); + + if (c->dry_run || c->action != ACTION_GENERATE) + log_fd = 1; + else + log_fd = open("/dev/kmsg", O_WRONLY); + + if (log_fd < 0) + log_fd = 1; +} + + +void log_close(void) +{ + if (log_fd > 1) + close(log_fd); + + log_fd = -1; +} + + +void log_msg(int lvl, const char *fn, const char *file, int line, + const char *format, ...) +{ + char *hdrstr, hdrbuf[256]; + int hdrlen; + va_list ap; + + UNUSED_ARG(fn); + UNUSED_ARG(file); + UNUSED_ARG(line); + + if (!(log_mask & lvl)) + return; + + switch (lvl) { + case FPAK_LOG_FATAL: hdrstr = "F: "; hdrlen = 3; break; + case FPAK_LOG_ERROR: hdrstr = "E: "; hdrlen = 3; break; + case FPAK_LOG_WARNING: hdrstr = "W: "; hdrlen = 3; break; + case FPAK_LOG_INFO: hdrstr = "I: "; hdrlen = 3; break; + default: hdrstr = "?: "; hdrlen = 3; break; + case FPAK_LOG_DEBUG: + hdrlen = snprintf(hdrstr = hdrbuf, sizeof(hdrbuf), "D: [%s] ", fn); + break; + } + + write(log_fd, hdrstr, hdrlen); + va_start(ap, format); + vdprintf(log_fd, format, ap); + va_end(ap); + write(log_fd, "\n", 1); +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/mainloop.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/mainloop.c new file mode 100644 index 0000000000..415ec8f528 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/mainloop.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "flatpak-session.h" + + +int mainloop_needed(context_t *c) +{ + switch (c->action) { + case ACTION_UPDATE: + return c->poll_interval > 0; + + case ACTION_START: + case ACTION_STOP: + return TRUE; + + default: + return FALSE; + } +} + + +void mainloop_create(context_t *c) +{ + if (c->ml != NULL) + return; + + c->ml = g_main_loop_new(NULL, FALSE); + + if (c->ml == NULL) + log_fatal("failed to create mainloop"); +} + + +void mainloop_destroy(context_t *c) +{ + g_main_loop_unref(c->ml); + c->ml = NULL; +} + + +void mainloop_run(context_t *c) +{ + g_main_loop_run(c->ml); +} + + +void mainloop_quit(context_t *c, int exit_status) +{ + g_main_loop_quit(c->ml); + + if (!c->exit_code && exit_status) + c->exit_code = exit_status; +} + + +unsigned int timer_add(context_t *c, int secs, int (*cb)(void *), + void *user_data) +{ + UNUSED_ARG(c); + + if (c->ml == NULL) + mainloop_create(c); + + return g_timeout_add(1000 * secs, cb, user_data); +} + + +void timer_del(context_t *c, unsigned int id) +{ + UNUSED_ARG(c); + + if (id) + g_source_remove(id); +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/remote.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/remote.c new file mode 100644 index 0000000000..3bc230e9f6 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/remote.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include "flatpak-session.h" + + +static int chkgecos(const char *gecos, const char *remote) +{ + const char *prefix = FPAK_GECOS_PREFIX; + int len = sizeof(FPAK_GECOS_PREFIX) - 1; + + return !strncmp(gecos, prefix, len) && !strcmp(gecos + len, remote); +} + + +static uid_t search_passwd(const char *remote, char *buf, size_t size) +{ + struct passwd *pwd; + + setpwent(); + while ((pwd = getpwent()) != NULL) { + if (chkgecos(pwd->pw_gecos, remote)) { + if (buf != NULL) { + strncpy(buf, pwd->pw_name, size - 1); + buf[size - 1] = '\0'; + } + + return pwd->pw_uid; + } + } + endpwent(); + + return INVALID_UID; +} + + +uid_t remote_user_id(const char *remote, char *buf, size_t size) +{ + struct passwd *pwd; + + if (buf != NULL) + *buf = '\0'; + + if ((pwd = getpwnam(remote)) != NULL) { + if (chkgecos(pwd->pw_gecos, remote)) { + if (buf != NULL) { + strncpy(buf, pwd->pw_name, size - 1); + buf[size - 1] = '\0'; + } + + return pwd->pw_uid; + } + } + + return search_passwd(remote, buf, size); +} + + +char *remote_user_name(uid_t uid, char *buf, size_t size) +{ + static char usr[64], *name; + struct passwd *pwd; + + if (buf != NULL) + *buf = '\0'; + else { + buf = usr; + size = sizeof(usr); + } + + if ((pwd = getpwuid(uid)) != NULL) + name = pwd->pw_name; + else + name = ""; + + strncpy(buf, name, size - 1); + buf[size - 1] = '\0'; + + return buf; +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/service.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/service.c new file mode 100644 index 0000000000..89aca0386c --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/service.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "generator.h" + + +static int service_generate(generator_t *g, FlatpakRemote *r, const char *usr) +{ + char srv[PATH_MAX], lnk[PATH_MAX]; + const char *remote = flatpak_remote_get_name(r); + + log_info("generating session service for user %s (remote %s)...", + usr, remote); + + if (!fs_service_path(g, usr, srv, sizeof(srv)) || + !fs_service_link(g, usr, lnk, sizeof(lnk))) + goto fail; + + if (template_eval(g, usr, remote, srv) < 0) + goto template_fail; + + if (symlink(srv, lnk) < 0) + goto fail; + + return 0; + + template_fail: + log_error("service template evaluation failed for usr %s (remote %s)", + usr, remote); + + fail: + return -1; +} + + +int service_generate_sessions(generator_t *g) +{ + FlatpakRemote *r; + unsigned int i; + char usr[256]; + + for (i = 0; i < g->remotes->len; i++) { + r = g_ptr_array_index(g->remotes, i); + + log_warning("process remote %s...", flatpak_remote_get_name(r)); + + if (fp_resolve_user(r, usr, sizeof(usr)) == (uid_t)-1) { + log_warning("remote %s has no associated user, ignoring...", + flatpak_remote_get_name(r)); + continue; + } + + if (service_generate(g, r, usr) < 0) + log_error("failed to generate session for remote '%s'", + flatpak_remote_get_name(r)); + } + + return 0; +} + diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/template.c b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/template.c new file mode 100644 index 0000000000..0f34b94d95 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/files/flatpak-utils/src/template.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2016, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + + +#include "generator.h" + +int template_load(generator_t *g) +{ + const char *path = g->path_template; + struct stat st; + char *buf, *p; + int fd, n, l; + + if (stat(path, &st) < 0) + goto ioerror; + + if (st.st_size > 16 * 1024) + goto overflow; + + fd = open(path, O_RDONLY); + + if (fd < 0) + goto ioerror; + + buf = calloc(st.st_size + 1, 1); + p = buf; + l = st.st_size; + + while (l > 0) { + n = read(fd, p, l); + + if (n < 0) { + if (errno == EAGAIN || errno == EINTR) + continue; + else + goto ioerror; + } + + p += n; + l -= n; + } + + close(fd); + *p = '\0'; + + g->template = buf; + + return 0; + + ioerror: + log_error("failed to load template file '%s' (%d: %s)", path, + errno, strerror(errno)); + return -1; + + overflow: + log_error("template file '%s' too large", path); + return -1; + +} + + +static int print_tag(int fd, const char *tag, int len, const char *usr, + const char *remote) +{ + if (!strncmp(tag, "USER", len)) + dprintf(fd, "%s", usr); + else if (!strncmp(tag, "REMOTE", len)) + dprintf(fd, "%s", remote); + else + dprintf(fd, "", len, len, tag); + + return 0; +} + + +int template_eval(generator_t *g, const char *usr, const char *remote, + const char *out) +{ + const char *p, *b, *e, *nl, *tag; + int fd, len; + + fd = open(out, O_WRONLY|O_CREAT, 0644); + + if (fd < 0) + goto ioerror; + + p = g->template; + while (p && *p) { + b = strchr(p, '@'); + + if (b != NULL) { + e = strchr(b + 1, '@'); + nl = strchr(b + 1, '\n'); + + if (e != NULL && (nl == NULL || e < nl)) { + dprintf(fd, "%*.*s", (int)(b - p), (int)(b - p), p); + + tag = b + 1; + len = e - b - 1; + + print_tag(fd, tag, len, usr, remote); + + p = e + 1; + } + else { + if (e == NULL && nl == NULL) { + dprintf(fd, "%s", p); + p = NULL; + } + else if (e != NULL) { + dprintf(fd, "%*.*s", (int)(e - p - 1), (int)(e - p - 1), p); + p = e - 1; + } + else { + dprintf(fd, "%s", p); + p = NULL; + } + } + } + else { + dprintf(fd, "%s", p); + p = NULL; + } + } + + close(fd); + + return 0; + + ioerror: + log_error("failed to open output file '%s' (%d: %s)", out, + errno, strerror(errno)); + + return -1; +} diff --git a/meta-flatpak/recipes-flatpak/flatpak-utils/flatpak-utils_0.0.bb b/meta-flatpak/recipes-flatpak/flatpak-utils/flatpak-utils_0.0.bb new file mode 100644 index 0000000000..7619fe7364 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-utils/flatpak-utils_0.0.bb @@ -0,0 +1,34 @@ +DESCRIPTION = "Helper utilities for flatpak-based applications/services." +HOMEPAGE = "http://github.com/klihub/flatpak-utils" +LICENSE = "BSD-3-Clause" + +LIC_FILES_CHKSUM = "file://LICENSE-BSD;md5=f9f435c1bd3a753365e799edf375fc42" + +DEPENDS = "flatpak systemd" + +SRC_URI = " \ + file://flatpak-utils \ + " + +inherit autotools pkgconfig requires-systemd + +AUTO_LIBNAME_PKGS = "" + +S = "${WORKDIR}/flatpak-utils" + +EXTRA_OECONF += "--with-systemdunitdir=${systemd_unitdir}" + +FILES_${PN} = "\ + ${systemd_unitdir}/system-generators/flatpak-session-enable \ + ${bindir}/flatpak-session \ + ${libexecdir}/flatpak-utils \ + ${systemd_unitdir}/system/flatpak-sessions.target \ + ${systemd_unitdir}/system/flatpak-session@.service \ + ${systemd_unitdir}/system/flatpak-update.service \ +" + +FILES_${PN}-dbg =+ "${base_libdir}/systemd/system-generators/.debug" + +SYSTEMD_PACKAGES += "${PN}" +SYSTEMD_SERVICE_${PN} = "flatpak-sessions.target flatpak-update.service" + diff --git a/meta-refkit/conf/distro/include/refkit-supported-recipes.txt b/meta-refkit/conf/distro/include/refkit-supported-recipes.txt index cc1e1af079..c5be428ddb 100644 --- a/meta-refkit/conf/distro/include/refkit-supported-recipes.txt +++ b/meta-refkit/conf/distro/include/refkit-supported-recipes.txt @@ -110,8 +110,9 @@ file@core findutils@core fixesproto@core flac@core -flatpak-image-runtime@flatpak-layer flatpak@flatpak-layer +flatpak-image-runtime@flatpak-layer +flatpak-utils@flatpak-layer flex@core font-util@core fontconfig@core From 1241652f6e564e700659c2acb66b4a46252b4e74 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:00:22 +0300 Subject: [PATCH 05/16] flatpak-predefined-repos: added recipe for predefined flatpak repos. Added recipe for pre-declaring and populating the image with a set of pre-declared flatpak remotes/repositories and their associated flatpak-session users. These are then monitored for applications to automatically pull in/update and start in flatpak-sessions. Signed-off-by: Krisztian Litkey --- .../flatpak-predefined-repos.bb | 55 +++++++++++++++++++ .../include/refkit-supported-recipes.txt | 1 + 2 files changed, 56 insertions(+) create mode 100644 meta-flatpak/recipes-flatpak/flatpak-predefined-repos/flatpak-predefined-repos.bb diff --git a/meta-flatpak/recipes-flatpak/flatpak-predefined-repos/flatpak-predefined-repos.bb b/meta-flatpak/recipes-flatpak/flatpak-predefined-repos/flatpak-predefined-repos.bb new file mode 100644 index 0000000000..932ef5a7e6 --- /dev/null +++ b/meta-flatpak/recipes-flatpak/flatpak-predefined-repos/flatpak-predefined-repos.bb @@ -0,0 +1,55 @@ +DESCRIPTION = "Repository/remo URLs and signing keys for pre-declared flatpak session/application repositories." +HOMEPAGE = "http://127.0.0.1/" +LICENSE = "BSD-3-Clause" + +LIC_FILES_CHKSUM = "file://LICENSE-BSD;md5=f9f435c1bd3a753365e799edf375fc42" + +SRC_URI = " \ + git://git@github.com/klihub/flatpak-predefined-repos.git;protocol=https;branch=master \ +" + +SRCREV = "1181642d571d575783760247792c45635e6d3ebf" + +S = "${WORKDIR}/git" + +inherit autotools flatpak-config + +# For each repo named we expect a .url and .key file (containing +# the repo URL and the repo pubic GPG key), and passwd/group entries for +# the associated users. +# +# Turn the space-separated repo name list into a comma-separated one and +# pass it to configure. +EXTRA_OECONF += " \ + --with-repos=${@','.join(d.getVar('FLATPAK_APP_REPOS').split())} \ +" + +# Inherit useradd only if we have pre-declared repositories. Otherwise +# useradd would bail out with a parse-time error when we don't set +# USERADD_PARAM_${PN} when we don't have pre-declared repos to put into +# the image. +inherit ${@'useradd' if d.getVar('FLATPAK_APP_REPOS') else ''} + +# Ask for the creation of the users/groups associated with the pre-declared +# remotes/repositories. Turn the space-separated list into a semi-colon- +# separated one. +USERADD_PACKAGES = "${PN}" +USERADD_PARAM_${PN} = "${@';'.join(d.getVar('FLATPAK_APP_REPOS').split())}" + +FILES_${PN} = " \ + ${sysconfdir}/flatpak-session/* \ +" + +do_configure_prepend () { + if [ -n "${FLATPAK_APP_REPOS}" ]; then + mkdir -p ${S}/repos + + for _r in ${FLATPAK_APP_REPOS}; do + echo "Copying URL- and key-file for remote/repository $_r..." + cp ${TOPDIR}/conf/$_r.url ${S}/repos + cp ${TOPDIR}/conf/$_r.key ${S}/repos + done + else + echo "No predefined flatpak application remotes/repos." + fi +} diff --git a/meta-refkit/conf/distro/include/refkit-supported-recipes.txt b/meta-refkit/conf/distro/include/refkit-supported-recipes.txt index c5be428ddb..3c5c68aef2 100644 --- a/meta-refkit/conf/distro/include/refkit-supported-recipes.txt +++ b/meta-refkit/conf/distro/include/refkit-supported-recipes.txt @@ -112,6 +112,7 @@ fixesproto@core flac@core flatpak@flatpak-layer flatpak-image-runtime@flatpak-layer +flatpak-predefined-repos@flatpak-layer flatpak-utils@flatpak-layer flex@core font-util@core From dbdafe9337ccd74b1329ac9a77db289d2705c67f Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:06:24 +0300 Subject: [PATCH 06/16] layer.conf,flatpak-config.bbclass: handle pre-declared remotes/repos. Added the necessary configuration bits for, and documented the whole process of, adding pre-declared remotes/repositories. Signed-off-by: Krisztian Litkey --- meta-flatpak/classes/flatpak-config.bbclass | 28 +++++++++++++++++++++ meta-flatpak/conf/layer.conf | 9 +++++++ 2 files changed, 37 insertions(+) diff --git a/meta-flatpak/classes/flatpak-config.bbclass b/meta-flatpak/classes/flatpak-config.bbclass index 094d76316c..188cd82e5a 100644 --- a/meta-flatpak/classes/flatpak-config.bbclass +++ b/meta-flatpak/classes/flatpak-config.bbclass @@ -63,3 +63,31 @@ FLATPAK_BUILD ?= "${DISTRO}/${FLATPAK_PN}/build/${BUILD_ID}" # This is the GPG key id of our repository signing key. If you set this to # empty, signing is disabled altogether. FLATPAK_GPGID ?= "refkit-signing@key" + +# We can pre-populate the image during build with a set of pre-declared +# flatpak repositories and associated dedicated flatpak-session users. +# These repositories will be monitored for flatpaks and any new or updated +# flatpaks which are tagged for automatic installation will be pulled in +# and started within the appropriate flatpak session. +# +# To declare such a remote/repository, you need to +# 1) give the remote a unique name +# 2) provide a remote URL and a GPG public key for signature checking +# 3) associate a user with the remote +# +# The variable FLATPAK_APP_REPOS lists the names of the remotes to pre- +# declare and put into the image. For every remote you have to provide +# +# 1) the remote HTTP URL in ${TOPDIR}/conf/.url +# 2) the remote GPG signing public key in ${TOPDIR}/conf/.key +# 3) provide passwd- and group entries for the associated user in +# ${TOPDIR}/conf/flatpak-passwd and +# ${TOPDIR}/conf/flatpak-group +# The GECOS for the associated entry must be of the form +# 'flatpak user for ', where is the remote name. By +# convention the user's login ID is also , but this is +# not strictly necessary. +# +# By default we do not have any pre-declared application repositories, +# so FLATPAK_APP_REPOS defaults to empty. +FLATPAK_APP_REPOS ?= "" diff --git a/meta-flatpak/conf/layer.conf b/meta-flatpak/conf/layer.conf index 607087c2f8..f3200c2915 100644 --- a/meta-flatpak/conf/layer.conf +++ b/meta-flatpak/conf/layer.conf @@ -14,3 +14,12 @@ LAYERDEPENDS_flatpak-layer = "core openembedded-layer filesystems-layer" # Set a variable for easy access to the top directory of the flatpak layer. FLATPAK_LAYERDIR = '${@os.path.normpath("${LAYERDIR}")}' + +# Pick up our passwd and group fragments for users associated with +# pre-declared remotes/repositories, if we have any. +USERADD_UID_TABLES_append_refkit-config = " \ + ${@ d.getVar('TOPDIR') + '/conf/flatpak-passwd' \ + if d.getVar('FLATPAK_APP_REPOS') else ''}" +USERADD_GID_TABLES_append_refkit-config = " \ + ${@ d.getVar('TOPDIR') + '/conf/flatpak-group' \ + if d.getVar('FLATPAK_APP_REPOS') else ''}" From 7d536fc76a03bea291a8fac83ac30446abf6f5c1 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:16:07 +0300 Subject: [PATCH 07/16] packagegroups: added flatpak-session packagegroup. Added a flatpak-session packagegroup. It pulls in packagegroup-flatpak, flatpak-utils (for flatpak-session), and flatpak-predefined-repos. Signed-off-by: Krisztian Litkey --- .../packagegroups/packagegroup-flatpak-session.bb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 meta-flatpak/recipes-core/packagegroups/packagegroup-flatpak-session.bb diff --git a/meta-flatpak/recipes-core/packagegroups/packagegroup-flatpak-session.bb b/meta-flatpak/recipes-core/packagegroups/packagegroup-flatpak-session.bb new file mode 100644 index 0000000000..d03fae5f81 --- /dev/null +++ b/meta-flatpak/recipes-core/packagegroups/packagegroup-flatpak-session.bb @@ -0,0 +1,10 @@ +SUMMARY = "IoT Reference OS Kit Basic Flatpak Session/Application Support" +LICENSE = "MIT" + +inherit packagegroup + +RDEPENDS_${PN} = "\ + packagegroup-flatpak \ + flatpak-utils \ + flatpak-predefined-repos \ +" From 9e8c66f0fd61d16e10f0eac67a448cafb61f5924 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:40:43 +0300 Subject: [PATCH 08/16] flatpak-image-variants.bbclass: conditional support for flatpak-session. Pull in packagegroup-flatpak-session if flatpak-session is among DISTRO_FEATURES. Signed-off-by: Krisztian Litkey --- meta-flatpak/classes/flatpak-image-variants.bbclass | 2 ++ 1 file changed, 2 insertions(+) diff --git a/meta-flatpak/classes/flatpak-image-variants.bbclass b/meta-flatpak/classes/flatpak-image-variants.bbclass index 153088e78a..0b1461de9e 100644 --- a/meta-flatpak/classes/flatpak-image-variants.bbclass +++ b/meta-flatpak/classes/flatpak-image-variants.bbclass @@ -8,6 +8,8 @@ IMAGE_FEATURES[validitems] += " \ FEATURE_PACKAGES_flatpak = " \ packagegroup-flatpak \ + ${@bb.utils.contains('DISTRO_FEATURES', 'flatpak-session', \ + 'packagegroup-flatpak-session', '', d)} \ " # From ffbdacfa0f8aea353b03eba331b530464b9db101 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:20:28 +0300 Subject: [PATCH 09/16] flatpak-session.inc: added config fragment for enabling flatpak sessions. If included/required, enable flatpak-session in DISTRO_FEATURES and also pull in basic flatpak support. Signed-off-by: Krisztian Litkey --- meta-flatpak/conf/distro/include/flatpak-session.inc | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 meta-flatpak/conf/distro/include/flatpak-session.inc diff --git a/meta-flatpak/conf/distro/include/flatpak-session.inc b/meta-flatpak/conf/distro/include/flatpak-session.inc new file mode 100644 index 0000000000..7a69c52cec --- /dev/null +++ b/meta-flatpak/conf/distro/include/flatpak-session.inc @@ -0,0 +1,3 @@ +REFKIT_DEFAULT_DISTRO_FEATURES += " \ + flatpak-session \ +" From a768a658f25912f1d9c2cf43ae4b2a8e0bf8fbfe Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 14:22:36 +0300 Subject: [PATCH 10/16] enable-refkit-config.inc: require (commented out) flatpak-session fragment. Added a commented out require for flatpak-session.inc and a comment about its purpose. Signed-off-by: Krisztian Litkey --- meta-refkit-core/conf/distro/include/enable-refkit-config.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/meta-refkit-core/conf/distro/include/enable-refkit-config.inc b/meta-refkit-core/conf/distro/include/enable-refkit-config.inc index 4512e60305..ff77968c00 100644 --- a/meta-refkit-core/conf/distro/include/enable-refkit-config.inc +++ b/meta-refkit-core/conf/distro/include/enable-refkit-config.inc @@ -20,3 +20,6 @@ require conf/distro/include/usrmerge.inc # Enable basic flatpak support. include conf/distro/include/flatpak.inc + +# Enable this for flatpak-session/application framework support. +#include conf/distro/include/flatpak-session.inc From 09cc2e4f180d02222c0e2ad88c1161027d28d723 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Wed, 21 Jun 2017 18:26:18 +0300 Subject: [PATCH 11/16] meta-iotqa: added minimal flatpak-session sanity test. Signed-off-by: Krisztian Litkey --- ...kit-image-gateway-flatpak-runtime.manifest | 1 + .../oeqa/runtime/sanity/flatpak-session.py | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 meta-iotqa/lib/oeqa/runtime/sanity/flatpak-session.py diff --git a/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest b/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest index 1b2cd7620b..e0b0843e70 100644 --- a/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest +++ b/meta-iotqa/conf/test/refkit-image-gateway-flatpak-runtime.manifest @@ -3,3 +3,4 @@ oeqa.runtime.programming.nodejs.apprt_nodejs oeqa.runtime.core.iotivity.client oeqa.runtime.multimedia.audio.pulseaudio oeqa.runtime.sanity.flatpak +oeqa.runtime.sanity.flatpak-session diff --git a/meta-iotqa/lib/oeqa/runtime/sanity/flatpak-session.py b/meta-iotqa/lib/oeqa/runtime/sanity/flatpak-session.py new file mode 100644 index 0000000000..68d769fc87 --- /dev/null +++ b/meta-iotqa/lib/oeqa/runtime/sanity/flatpak-session.py @@ -0,0 +1,26 @@ +import unittest +from oeqa.oetest import oeRuntimeTest, skipModule +from oeqa.utils.decorators import * + +def setUpModule(): + if not oeRuntimeTest.hasFeature('flatpak-session'): + skipModule("flatpak not enabled, tests skipped") + +class SanityTestFlatpakSession(oeRuntimeTest): + '''flatpak session sanity tests''' + + def test_session_files(self): + '''check if flatpak session binaries and service files exist''' + files = [ + '/usr/bin/flatpak-session', + '/usr/lib/systemd/system-generators/flatpak-session-enable', + '/usr/lib/systemd/system/flatpak-image-runtime.service', + '/usr/lib/systemd/system/flatpak-update.service', + '/usr/lib/systemd/system/flatpak-session@.service', + '/usr/lib/systemd/system/flatpak-sessions.target', + ] + for f in files: + (status, output) = self.target.run('ls %s' % f) + self.assertEqual( + status, 0, + 'flatpak session binary/file %s missing' % f) From 89d51aa9150fcd10b85e325e9acdee040a777a41 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Thu, 22 Jun 2017 14:44:48 +0300 Subject: [PATCH 12/16] doc: initial documentation about flatpak support. Signed-off-by: Krisztian Litkey --- doc/flatpak-support.rst | 95 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 doc/flatpak-support.rst diff --git a/doc/flatpak-support.rst b/doc/flatpak-support.rst new file mode 100644 index 0000000000..32bcf35636 --- /dev/null +++ b/doc/flatpak-support.rst @@ -0,0 +1,95 @@ +Flatpak Support in IoT Reference OS Kit +####################################### + +IoT Reference OS Kit supports installing and running applications packaged +as `flatpaks `_. + +Flatpak in a Nutshell +---------------------- + +Flatpak is a framework for building, distributing, and managing applications. +It conceptually splits the software stack into + +* a runtime: the core/common bits, +* an SDK: bits necessary for building software for a runtime, +* the applications themselves + +Flatpak decouples the life-cycle of the application from that of the +underlying distro. By doing so it enables updating the distro and the +(flatpak) applications independently from each other. + +Additionally flatpak provides application sandboxing out of the box and +relies largely on `ostree `_ for providing +an infrastructure for application (binary) version control, distribution +and deployment. + +For more information and details see the corresponding documentation of +flatpak and ostree. + +Basic Flatpak Support +--------------------- + +Basic flatpak support includes recipes for flatpak and its runtime and +buildtime dependencies as well as Yocto helper classes for building +flatpak-enabled versions of images. It can be enabled by the *flatpak* +distro feature. Since it has additional prerequisites, the easiest way +to enable it is to include :file:`meta-flatpak/conf/distro/include/flatpak.inc` +in your build configuration. + +Flatpak Image Variants +---------------------- + +When the *flatpak* distro feature is enabled ``meta-flatpak`` defines +two flatpak-specific image variants: + +* *flatpak-runtime*: a flatpak-enabled image to be used on a target device +* *flatpak-sdk*: a *flatpak SDK runtime* to be used on a (development) host + +The *flatpak-runtime* variant adds flatpak, ostree, etc., all the necessary +runtime bits to run flatpak, to the image. With such an image on a target +device you should be able to invoke flatpak to carry out the normal flatpak +operations, including defining flatpak remotes, installing, uninstalling and +running flatpak applications. + +The *flatpak-sdk* variant adds the compiler toolchain, developement packages +debug symbols, version control software, etc., in short everything you might +need to compile and turn your applications into flatpaks intended to be +installed on the *flatpak-runtime* image variant. + +You can refer to these image variants by appending their name to that +of the base image. For instance you can build both of these variants for +*refkit-image-gateway* by running: + +``` +bitbake -c refkit-image-gateway-flatpak-runtime refkit-image-gateway-flatpak-sdk +``` + +Extra Flatpak-based Functionality - Flatpak Session +--------------------------------------------------- + +In addition to stock flatpak support, *meta-flatpak* provides support +for running a set of flatpaks from a common remote using a dedicated +user, monitoring the remote for updates and/or new applications and +automatically installing and activating those. + +Support for this extra set of functionality is controlled by the +*flatpak-session* distro feature. The easiest way to enable it is to +include :file:`meta-flatpak/conf/distro/include/flatpak.inc` in your +build configuration. + +See the comment section in :file:`meta-flatpak/classes/flatpak-config.bbclass` +for more details about the necessary steps or configuration you need to go +through to have a *flatpak session* set up for a remote on your device. + +Caveats +------- + +In addition to the basic flatpak dependencies a *flatpak-runtime* variant +also pulls into the image a systemd service which is used to activate a +'fake' flatpak runtime. This is basically a few files and bind mounts that +are used to emulate an flatpak-installed *flatpak runtime* for the image +itself. If you don't want it in your image, you can exclude it by putting +an appropriately crafted _remove for your image in your build configuration. +Note however, that either this fake runtime or the real flatpak runtime for +the image needs to be installed, otherwise you cannot install and run +flatpaks compiled for your image. From 2c64cceff37a81deb14758d8369cda6e4fa8ea58 Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Fri, 16 Jun 2017 22:11:40 +0300 Subject: [PATCH 13/16] test config change: enable flatpak-session support. --- meta-refkit-core/conf/distro/include/enable-refkit-config.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-refkit-core/conf/distro/include/enable-refkit-config.inc b/meta-refkit-core/conf/distro/include/enable-refkit-config.inc index ff77968c00..6c2cac9b22 100644 --- a/meta-refkit-core/conf/distro/include/enable-refkit-config.inc +++ b/meta-refkit-core/conf/distro/include/enable-refkit-config.inc @@ -22,4 +22,4 @@ require conf/distro/include/usrmerge.inc include conf/distro/include/flatpak.inc # Enable this for flatpak-session/application framework support. -#include conf/distro/include/flatpak-session.inc +include conf/distro/include/flatpak-session.inc From 403d0b334c2c7be6c8778b5149360b5919ee1c29 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 19 Jun 2017 13:52:13 +0200 Subject: [PATCH 14/16] refkit images: move "sensors" out of common into gateway The "sensors" image feature includes mraa, upm and via their dependencies also NodeJS. This is not required by all profiles and having it in common has some downsides: - slower build times in all tests using refkit-image-common (but not much, at least when NodeJS is already built, only 17s less when building twice, which takes several minutes) - dependency on components which are not in OE-core and thus have a higher chance of breaking in other distros Tests needs to be moved from common to gateway, too. While at it, sorting order gets restored in the gateway test list. Signed-off-by: Patrick Ohly --- meta-iotqa/conf/test/refkit-image-common.manifest | 3 --- meta-iotqa/conf/test/refkit-image-gateway.manifest | 5 ++++- meta-refkit-core/classes/refkit-image.bbclass | 1 - .../recipes-image/images/refkit-image-gateway.bb | 7 ++++++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/meta-iotqa/conf/test/refkit-image-common.manifest b/meta-iotqa/conf/test/refkit-image-common.manifest index 5427506a22..1f12a6ecc4 100644 --- a/meta-iotqa/conf/test/refkit-image-common.manifest +++ b/meta-iotqa/conf/test/refkit-image-common.manifest @@ -5,8 +5,5 @@ oeqa.runtime.connectivity.services.managerdaemon oeqa.runtime.connectivity.bluetooth.btcheck oeqa.runtime.connectivity.wifi.wifi_connect oeqa.runtime.programming.python.apprt_python -oeqa.runtime.peripherals.mraa.mraa_hello -oeqa.runtime.peripherals.mraa.mraa_gpio oeqa.runtime.multimedia.audio.alsa -oeqa.runtime.peripherals.upm.upm oeqa.runtime.sanity.nftables diff --git a/meta-iotqa/conf/test/refkit-image-gateway.manifest b/meta-iotqa/conf/test/refkit-image-gateway.manifest index 07dbc3868a..df0ee6543a 100644 --- a/meta-iotqa/conf/test/refkit-image-gateway.manifest +++ b/meta-iotqa/conf/test/refkit-image-gateway.manifest @@ -1,4 +1,7 @@ # Tests for gateway profile -oeqa.runtime.programming.nodejs.apprt_nodejs oeqa.runtime.core.iotivity.client oeqa.runtime.multimedia.audio.pulseaudio +oeqa.runtime.peripherals.mraa.mraa_gpio +oeqa.runtime.peripherals.mraa.mraa_hello +oeqa.runtime.peripherals.upm.upm +oeqa.runtime.programming.nodejs.apprt_nodejs diff --git a/meta-refkit-core/classes/refkit-image.bbclass b/meta-refkit-core/classes/refkit-image.bbclass index 0becc04d30..fb20176a32 100644 --- a/meta-refkit-core/classes/refkit-image.bbclass +++ b/meta-refkit-core/classes/refkit-image.bbclass @@ -145,7 +145,6 @@ REFKIT_IMAGE_FEATURES_COMMON ?= " \ connectivity \ ssh-server-openssh \ alsa \ - sensors \ ${@ 'common-test' if (d.getVar('IMAGE_MODE') or 'production') != 'production' else '' } \ " REFKIT_IMAGE_INSTALL_COMMON ?= "" diff --git a/meta-refkit-gateway/recipes-image/images/refkit-image-gateway.bb b/meta-refkit-gateway/recipes-image/images/refkit-image-gateway.bb index 831d4a2bb3..e1ef5db79c 100644 --- a/meta-refkit-gateway/recipes-image/images/refkit-image-gateway.bb +++ b/meta-refkit-gateway/recipes-image/images/refkit-image-gateway.bb @@ -6,7 +6,12 @@ REFKIT_IMAGE_GATEWAY_EXTRA_INSTALL ?= "${REFKIT_IMAGE_INSTALL_COMMON}" REFKIT_IMAGE_EXTRA_FEATURES += "${REFKIT_IMAGE_GATEWAY_EXTRA_FEATURES}" REFKIT_IMAGE_EXTRA_INSTALL += "${REFKIT_IMAGE_GATEWAY_EXTRA_INSTALL}" -REFKIT_IMAGE_GATEWAY_EXTRA_FEATURES_append = " iotivity nodejs-runtime bluetooth-audio" +REFKIT_IMAGE_GATEWAY_EXTRA_FEATURES += " \ + bluetooth-audio \ + iotivity \ + nodejs-runtime \ + sensors \ +" # Example for customization in local.conf when building # refkit-image-gateway.bb: From a13ae52f86560e5bbaa170c30c64edc477ad2653 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Mon, 19 Jun 2017 14:34:16 +0200 Subject: [PATCH 15/16] image_installer.py: run tests without graphical console This has two advantages: - slightly faster (but not much) - less annoying when run on a developer desktop, because the graphical console window tends to pop up randomly during testing Signed-off-by: Patrick Ohly --- meta-refkit-core/lib/oeqa/selftest/cases/image_installer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/meta-refkit-core/lib/oeqa/selftest/cases/image_installer.py b/meta-refkit-core/lib/oeqa/selftest/cases/image_installer.py index abaa5cd2e3..b06747834a 100644 --- a/meta-refkit-core/lib/oeqa/selftest/cases/image_installer.py +++ b/meta-refkit-core/lib/oeqa/selftest/cases/image_installer.py @@ -96,7 +96,7 @@ def do_install(self, fixed_password="", tpm=False): with runqemu('refkit-installer-image', ssh=False, discard_writes=False, qemuparams='-drive if=virtio,file=%s/internal-image-%s.wic,format=raw%s' % (self.resultdir, self.image_arch, qemuparams_tpm), - runqemuparams='ovmf slirp', + runqemuparams='ovmf slirp nographic', image_fstype='wic') as qemu: # Check that we have booted, with dm-verity if enabled. cmd = "findmnt / --output SOURCE --noheadings" @@ -126,7 +126,7 @@ def do_install(self, fixed_password="", tpm=False): with runqemu('refkit-installer-image', ssh=False, overrides=overrides, qemuparams=qemuparams_tpm, - runqemuparams='ovmf slirp', + runqemuparams='ovmf slirp nographic', image_fstype='wic') as qemu: # Check that we have booted, without device mapper involved. # Can't use the simpler findmnt here. From 0380dce3dd84f9eb7b032b0276cee7c4a29d0581 Mon Sep 17 00:00:00 2001 From: Sudarsana Nagineni Date: Mon, 26 Jun 2017 12:49:29 +0300 Subject: [PATCH 16/16] meta-iot-web: update to latest HEAD. * meta-iot-web 1e515ff...775f6c2 (6): > Merge pull request #46 from nagineni/update_restserver > iot-rest-api-server.bb: Update iot-rest-api-server to v0.5.0 > Merge pull request #45 from nagineni/node_gcc_7 > nodejs: Fix Node.js build errors with gcc7 > Merge pull request #43 from TizenTeam/sandbox/pcoval/on/master/latest > nodejs: Fix FTBFS by adding missing argument to d.getVar Signed-off-by: Sudarsana Nagineni --- meta-iot-web | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta-iot-web b/meta-iot-web index 1e515ff48e..775f6c22c0 160000 --- a/meta-iot-web +++ b/meta-iot-web @@ -1 +1 @@ -Subproject commit 1e515ff48e9d4960e10876b846cfbd9d8b094daa +Subproject commit 775f6c22c0fb0f7cea1254364c0f352677744202