Fedora 25: Install and build Flatpak

This article will describe installing and building Flatpak. Flatpak is renamed from xdg-apps.

1 Update ostree

The ostree package in Fedora 24/Fedora 25 will cause segmentation fault on flatpak.

Segmentation fault
(core dumped) flatpak --user install gnome org.gnome.Platform 3.22

This will be resolved by 21aca3fa83d7365376f6be2056fc1bac33f9998d. Update ostree to this commit.

#!/bin/sh

sudo dnf install -y rpm-build
sudo dnf builddep -y ostree

dnf download --source ostree
rpm -i ostree-2016.15-1.fc25.src.rpm
cd ~/rpmbuild

git clone https://github.com/ostreedev/ostree.git
cd ostree
git checkout 21aca3fa83d7365376f6be2056fc1bac33f9998d -b v2016.15.1
cd ..
mv ostree ostree-2016.15.1
tar cf SOURCES/ostree-2016.15.1.tar.xz ostree-2016.15.1

sed -e 's/^Version: 2016\.15/Version: 2016.15.1/g' \
    -e 's/^%autosetup.*/%setup -q -n %{name}-%{version}/g' \
    -i SPECS/ostree.spec

rpmbuild -ba SPECS/ostree.spec
sudo dnf install -y RPMS/x86_64/ostree-2016.15.1-1.fc25.x86_64.rpm

2 Install flatpak package

flatpak package is a tools for installing and building Flatpak. Install flatpak and flatpak-libs with dnf.

$ sudo dnf install -y flatpak flatpak-libs

3 Install application and runtime

Install application and runtime for user.

Import GPG key of GNOME repository.

$ wget https://sdk.gnome.org/keys/gnome-sdk.gpg
$ flatpak --user remote-add --gpg-import=gnome-sdk.gpg gnome \
https://sdk.gnome.org/repo/

Import remote repository.

$ flatpak --user remote-add --gpg-import=gnome-sdk.gpg gnome-apps \
https://sdk.gnome.org/repo-apps/

Install org.gnome.Platform which is runtime. Runtime will be installed to ${HOME}/.local/share/flatpak/runtime.

$ flatpak --user install gnome org.gnome.Platform 3.20

Install org.gnome.gedit which is application. Application is installled to ${HOME}/.local/share/flatpak/app.

$ flatpak --user install gnome-apps org.gnome.gedit stable

Run org.gnome.gedit.

$ flatpak --user run org.gnome.gedit

gedit window is poped.

0001_gedit.png

3.1 Install Flatpak to system for sharing with all user

Running flatpak command without –user option but with privilege will install application to /var/lib/flatpak/app and runtime to /var/lib/flatpak/runtime. All user can access to these application and runtime.

$ sudo flatpak remote-add --gpg-import=gnome-sdk.gpg gnome \
     https://sdk.gnome.org/repo/
$ sudo flatpak remote-add --gpg-import=gnome-sdk.gpg gnome-apps \
     https://sdk.gnome.org/repo-apps/
$ sudo flatpak install gnome org.gnome.Platform 3.20
$ sudo flatpak install gnome-apps org.gnome.gedit stable
$ flatpak run org.gnome.gedit

3.2 List of Flatpak in repository

Run remote-ls command with remote repository name.

$ flatpak remote-ls gnome-apps
org.gnome.Builder
org.gnome.Builder.Debug
org.gnome.Builder.Locale
org.gnome.Calculator
org.gnome.Calculator.Debug
org.gnome.Calculator.Locale
org.gnome.Calendar
org.gnome.Calendar.Debug
org.gnome.Calendar.Locale
org.gnome.Characters
org.gnome.Characters.Debug
org.gnome.Characters.Locale
org.gnome.Dictionary
org.gnome.Dictionary.Debug
org.gnome.Dictionary.Locale
org.gnome.Epiphany
org.gnome.Epiphany.Debug
org.gnome.Epiphany.Locale
org.gnome.Evince
org.gnome.Evince.Debug
org.gnome.Evince.Locale
org.gnome.Maps
org.gnome.Maps.Debug
org.gnome.Maps.Locale
org.gnome.Polari
org.gnome.Polari.Debug
org.gnome.Polari.Locale
org.gnome.Rhythmbox3
org.gnome.Rhythmbox3.Debug
org.gnome.Rhythmbox3.Locale
org.gnome.Todo
org.gnome.Todo.Debug
org.gnome.Todo.Locale
org.gnome.Weather
org.gnome.Weather.Debug
org.gnome.Weather.Locale
org.gnome.bijiben
org.gnome.bijiben.Debug
org.gnome.bijiben.Locale
org.gnome.clocks
org.gnome.clocks.Debug
org.gnome.clocks.Locale
org.gnome.eog
org.gnome.eog.Debug
org.gnome.eog.Locale
org.gnome.gedit
org.gnome.gedit.Debug
org.gnome.gedit.Locale
org.gnome.iagno
org.gnome.iagno.Debug
org.gnome.iagno.Locale

3.3 List of installed Flatpak

Run list command.

$ flatpak list
org.gnome.gedit

4 Build application

Please build application with flatpak build. Building application withou flatpak build is for tutorial and building application with flatpak build is compatible with original building way (You only need to wrap command with flatpak build).

4.1 Building application without flatpak build (Not recommended)

Create simple application which run /bin/sh on SandBox.

Create directory.

$ mkdir shell
$ mkdir shell/files
$ mkdir shell/files/bin
$ mkdir shell/export

Application provides command which named shell.sh.

  • Running /bin/sh with arguments.
  • Running /bin/sh when no arguments.
$ cat <<EOF > shell/files/bin/shell.sh
#!/bin/sh

if [ \$# -eq 0 ]; then
  PS1="shell> " /bin/sh
else
  echo "shell> \$@"
  eval "\$@"
fi

EOF
$ chmod a+x shell/files/bin/shell.sh

Create metadata which includes configuration of application.

  • Application name is com.example.shell. Application name is ${name} in this article.
  • Using org.gnome.Platform as runtime.
  • Running com.example.shell will call shell.sh.
  • Application access to "hosts" filesystem.
$ cat <<EOF > shell/metadata
[Application]
name=com.example.shell
runtime=org.gnome.Platform/x86_64/3.20
command=shell.sh

[Context]
filesystems=host;

EOF

Export shell directory to repo directory.

$ flatpak build-export repo shell
$ ls repo/
config  objects  refs  state  summary  tmp  uncompressed-objects-cache

Register repo directory as example-repo. Install com.example.shell from example-repo.

$ flatpak --user remote-add --no-gpg-verify example-repo repo
$ flatpak --user install example-repo com.example.shell

4.2 Building application with flatpak build (Recommended)

flatpak build command can build application on SandBox. This is not cross compile but own compile.

Install org.gnome.Sdk for building application.

$ flatpak --user install gnome org.gnome.Sdk 3.20

This article will simple make source tree, but flatpak supports various build system like configure and cmake.

In case of normal binary is as below.

$ sudo dnf install -y ncurses-devel SDL2-devel SDL2_image-devel
$ git clone https://github.com/hiroom2/tetris-sdl-and-ncurses
$ cd tetris-sdl-and-ncurses
$ make
$ ./jni/src/ncurses # or ./jni/src/sdl

Build Flatpak as below.

  • flatpak build-init starts flatpak build.
  • Wrapping command with flatpak build is running on SandBox.
  • flatpak build-finish finishes flatpak build.
$ flatpak build-init tetris com.hiroom2.tetris org.gnome.Sdk \
org.gnome.Platform 3.20
$ git clone https://github.com/hiroom2/tetris-sdl-and-ncurses
$ cd tetris-sdl-and-ncurses/
$ flatpak build ../tetris make all install DESTDIR=/app
$ cd ..
$ flatpak build-finish tetris --command=ncurses

flatpak build uses org.gnome.Sdk and flatpak run uses org.gnome.Platform.

metadata is as below. You can change metadata manually.

$ cat tetris/metadata
[Application]
name=com.hiroom2.tetris
runtime=org.gnome.Platform/x86_64/3.20
sdk=org.gnome.Sdk/x86_64/3.20
command=ncurses

Register repository and install application.

$ flatpak build-export repo tetris
$ flatpak --user remote-add --no-gpg-verify tetris-repo repo
$ flatpak --user install tetris-repo com.hiroom2.tetris

Run application.

$ flatpak run com.hiroom2.tetris

tetris is running.

0002_tetris.png

4.3 Update application

Change source tree and export source tree to repo.

$ # update shell or tetris-sdl-and-ncurses directory
$ flatpak build-export repo shell # or tetris-sdl-and-ncurses

flatpak udpate receives application update. flatpak update without application will receives all application update.

$ flatpak --user update com.example.shell # or com.hiroom2.tetris

4.4 Runtime

There are GNOME runtime and KDE runtime. It is nice to create daemon runtime for server and minimum runtime for embedded system.

GNOME runtime size is as below. This runtime can be shared with multiple application.

$ du -sh .local/share/flatpak/runtime/org.gnome.Platform
613M    .local/share/flatpak/runtime/org.gnome.Platform
$ du -sh .local/share/flatpak/runtime/org.freedesktop.Platform/
391M    .local/share/flatpak/runtime/org.freedesktop.Platform/

5 Structure of Flatpak

This article will describe structure of Flatpak according to this.

5.1 /app

Application is in ${HOME}/.local/share/flatpak/app/${name}/. When running application, files directory in this directory will be mounted to /app on SandBox. And /app is append to PATH and LD_LIBRARY_PATH on SandBox.

shell> echo $PATH
/app/bin:/usr/bin
shell> echo $LD_LIBRARY_PATH
/app/lib:/usr/lib/GL

5.2 /usr

Runtime is in ${HOME}/.local/share/flatpak/runtim/${name}/. When running application, files directory in this directory will be mounted to /usr on SandBox.

$ ls .local/share/flatpak/runtime/org.gnome.Platform/x86_64/3.20/active/files/
bin    etc    include  lib64    local          sbin   src
cache  games  lib      libexec  manifest.json  share  var
$ flatpak run com.example.shell ls /usr
shell> ls /usr
bin    etc    include  lib64    local          sbin   src
cache  games  lib      libexec  manifest.json  share  var

/bin is linked to /usr/bin, /lib is linked to /usr/lib, and /lib64 is linked to /usr/lib64.

$ flatpak run com.example.shell ls -l /
shell> ls -l /
total 44
drwxrwxr-x   3 hiroom2   hiroom2    4096 Jul  2 06:22 app
lrwxrwxrwx   1 hiroom2   hiroom2       7 Jul  2 06:27 bin -> usr/bin
drwxr-xr-x   4 hiroom2   hiroom2     300 Jul  2 06:27 dev
drwxr-xr-x  20 hiroom2   hiroom2    1000 Jul  2 06:27 etc
drwxr-xr-x   3 nfsnobody nfsnobody  4096 Jun 22 04:59 home
lrwxrwxrwx   1 hiroom2   hiroom2       7 Jul  2 06:27 lib -> usr/lib
lrwxrwxrwx   1 hiroom2   hiroom2       9 Jul  2 06:27 lib64 -> usr/lib64
drwx------   2 nfsnobody nfsnobody 16384 Jun 15 01:25 lost+found
drwxr-xr-x   2 nfsnobody nfsnobody  4096 Feb  4 07:10 media
drwxr-xr-x   2 nfsnobody nfsnobody  4096 Feb  4 07:10 mnt
drwxr-xr-x   2 nfsnobody nfsnobody  4096 Feb  4 07:10 opt
dr-xr-xr-x 147 nfsnobody nfsnobody     0 Jul  2 06:27 proc
drwxr-xr-x   4 hiroom2   hiroom2     120 Jul  2 06:27 run
lrwxrwxrwx   1 hiroom2   hiroom2       8 Jul  2 06:27 sbin -> usr/sbin
drwxr-xr-x   2 nfsnobody nfsnobody  4096 Feb  4 07:10 srv
drwxr-xr-x   7 hiroom2   hiroom2     140 Jul  2 06:27 sys
drwxr-xr-x   3 hiroom2   hiroom2      60 Jul  2 06:27 tmp
drwxrwxr-x  13 hiroom2   hiroom2    4096 Jul  2 06:11 usr
drwxr-xr-x   5 hiroom2   hiroom2     140 Jul  2 06:27 var

5.3 /etc

/etc files on SandBox are mounted from /etc files on host machine.

shell> cat /proc/mounts | grep /etc/
 /etc/passwd tmpfs rw,seclabel,nosuid,nodev,relatime,uid=1000,gid=1000 0 0
 /etc/group tmpfs rw,seclabel,nosuid,nodev,relatime,uid=1000,gid=1000 0 0
/dev/mapper/fedora-root /etc/machine-id ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/shells ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/default ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/issue ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/timezone ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/host.conf ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/filesystems ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
/dev/mapper/fedora-root /etc/xdg ext4 rw,seclabel,nosuid,nodev,relatime,data=ordered 0 0
<snip>

/etc/passwd and /etc/group includes only user who run application and nfsnobody.

shell> cat /etc/passwd
hiroom2:x:1000:1000:Unknown:/home/hiroom2:/bin/sh
nfsnobody:x:65534:65534:Unmapped user:/:/sbin/nologin
shell> cat /etc/group
hiroom2:x:1000:hiroom2
nfsnobody:x:65534:

5.4 /dev

Basic device file is mounted.

shell> ls /dev
console  full  null  ptmx  pts  random  shm  stderr  stdin  stdout  tty  urandom  zero

5.5 /proc

Running "ps a" on SandBox outputs as below.

shell> ps a
  PID TTY      STAT   TIME COMMAND
    1 ?        S+     0:00 /usr/libexec/flatpak-bwrap --args 13 shell.sh ps a
    2 ?        S+     0:00 /bin/sh /app/bin/shell.sh ps a
    3 ?        R+     0:00 ps a

This tells that flatpak-bwrap is running command.

flatpak-bwrap -> /bin/sh -> shell.sh

/proc on SandBox is as below. Only application's PID files are there. PID 1 is flatpak-bwrap, PID 2 is /bin/sh, PID 3 is shell.sh and PID 70 is ls command.

shell> ls /proc/
1          cpuinfo      iomem        latency_stats  partitions     sysvipc
2          crypto       ioports      loadavg        sched_debug    thread-self
3          devices      irq          locks          schedstat      timer_list
70         diskstats    kallsyms     mdstat         scsi           timer_stats
acpi       dma          kcore        meminfo        self           tty
asound     driver       key-users    misc           slabinfo       uptime
buddyinfo  execdomains  keys         modules        softirqs       version
bus        fb           kmsg         mounts         stat           vmallocinfo
cgroups    filesystems  kpagecgroup  mtrr           swaps          vmstat
cmdline    fs           kpagecount   net            sys            zoneinfo
consoles   interrupts   kpageflags   pagetypeinfo   sysrq-trigger

5.6 /sys

Basic /sys files is mounted.

$ ls /sys/
block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power
$ flatpak run com.example.shell ls /sys
shell> ls /sys/
block  bus  class  dev  devices

5.7 /var

/var has writable directories.

Host machine Shell
${HOME}/.var/app/${name}/cache /var/cache
${HOME}/.var/app/${name}/config /var/config
${HOME}/.var/app/${name}/data /var/data

5.8 Context filesystems in metadata

Application can use writable directory with Context filesystems in metadata.

Context filesystems supports below directories.

host Host Mahine filesystem except dev, proc, /sys and /var
home User homedirectory
xdg-xxx XDG_XXX variable directory
Absolute path opt/path/to or ~.local/path/to

The mapping xdg variable and XDG variable are as below.

xdg variable XDG variable Fedora 24
xdg-desktop XDG_DESKTOP_DIR ${HOME}/Desktop
xdg-documents XDG_DOCUMENTS_DIR ${HOME}/Documents
xdg-download XDG_DOWNLOAD_DIR ${HOME}/Downloads
xdg-music XDG_MUSIC_DIR ${HOME}/Music
xdg-pictures XDG_PICTURES_DIR ${HOME}/Pictures
xdg-public-share XDG_PUBLICSHARE_DIR ${HOME}/Public
xdg-templates XDG_TEMPLATES_DIR ${HOME}/Templates
xdg-videos XDG_VIDEOS_DIR ${HOME}/Videos
xdg-run XDG_RUNTIME_DIR /var/user/<pid>

You can use multiple directory with ; like org.gnome.gedit.

filesystems=xdg-run/dconf;host;~/.config/dconf:ro;