alexander larsson, red hatalexl/presentations/all-systems-go-2018.pdf · alexander larsson, red hat...
TRANSCRIPT
Alexander Larsson, Red Hat
Flatpak – a technical walk-through
What is Flatpak?
“apps” for the Linux Desktop
Distribute your app
Run it anywhere
Build in anywhere
Run it sandboxed
How is this different from containers?
Non-privileged user● Must not require root permissions● Must not grant root permissions● No root-only features
Desktop integration● Icon shows up in desktop● Automatic setup of X11/Wayland/Pulseaudio● DBus integration● OpenGL / DRI support● Uses freedesktop specs● Interactive permissions system
Building blocks
● OSTree● Bubblewrap
OSTree
“its like git for operating systems”
Repo layoutapp├── bin│ └── hello.sh└── README
$ cat app/README This is some example content
Repo layoutapp├── bin│ └── hello.sh└── README
$ cat app/README This is some example content
$ ostree --repo=repo init$ ostree --repo=repo commit \ --subject="Foobar" \ --branch=master app8528ed0cee
$ ostree --repo=repo show mastercommit 8528ed0ceeDate: 2018-08-22 14:18:11 +0000 Foobar
Repo layoutapp├── bin│ └── hello.sh└── READMErepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 85/28ed0cee.commit│ └── d9/f4b64256.dirmeta└── refs/heads/master
$ cat app/README This is some example content
$ cat repo/refs/heads/master8528ed0cee
$ cat repo/objects/80/04dd449f.fileThis is some example content
Repo layoutapp├── bin│ └── hello.sh└── READMErepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 85/28ed0cee.commit│ └── d9/f4b64256.dirmeta└── refs/heads/master
$ cat app/README This is some example content
$ cat repo/refs/heads/master8528ed0cee
$ cat repo/objects/80/04dd449f.fileThis is some example content
$ echo -n "..." >> app/README$ ostree --repo=repo commit \ --subject=”Changed stuff” --branch=master app2e9472ca3f
Repo layoutapp├── bin│ └── hello.sh└── READMErepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── c6/171320dd.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 67/a1a77c36.file│ ├── 85/28ed0cee.commit│ ├── 2e/9472ca3f.commit│ └── d9/f4b64256.dirmeta└── refs/heads/master
$ cat app/README This is some example content
$ cat repo/refs/heads/master2e9472ca3f
$ cat repo/objects/80/04dd449f.fileThis is some example content
$ cat repo/objects/67/a1a77c36.fileThis is some example content...
Checkoutrepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── c6/171320dd.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 67/a1a77c36.file│ ├── 85/28ed0cee.commit│ ├── 2e/9472ca3f.commit│ └── d9/f4b64256.dirmeta└── refs/heads/master
Checkoutrepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── c6/171320dd.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 67/a1a77c36.file│ ├── 85/28ed0cee.commit│ ├── 2e/9472ca3f.commit│ └── d9/f4b64256.dirmeta└── refs/heads/master
$ ostree --repo=repo checkout \ master new
Checkoutrepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── c6/171320dd.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 67/a1a77c36.file│ ├── 85/28ed0cee.commit│ ├── 2e/9472ca3f.commit│ └── d9/f4b64256.dirmeta└── refs/heads/masternew├── bin│ └── hello.sh└── README
$ ls -lR newnew:drwxr-xr-x. 2 alex alex 60 bin-rw-r--r--. 2 alex alex 19 READMEnew/bin:-rw-r--r--. 2 alex alex 38 hello.sh
$ cat app/README This is some example content...
Checkoutrepo/├── config├── objects│ ├── 94/b60b8c7a.dirtree│ ├── c6/171320dd.dirtree│ ├── f2/13a94e40.dirtree│ ├── 30/d1d158ec.file│ ├── 80/04dd449f.file│ ├── 67/a1a77c36.file│ ├── 85/28ed0cee.commit│ ├── 2e/9472ca3f.commit│ └── d9/f4b64256.dirmeta└── refs/heads/masternew├── bin│ └── hello.sh└── README
$ ls -lR newnew:drwxr-xr-x. 2 alex alex 60 bin-rw-r--r--. 2 alex alex 19 READMEnew/bin:-rw-r--r--. 2 alex alex 38 hello.sh
$ cat new/README This is some example content...
$ stat new/README | grep InodeDevice: 2fh/47d Inode: 276193 Links: 2$ stat repo/objects/67/a1a77c36.file \ | grep InodeDevice: 2fh/47d Inode: 276193 Links: 2
Hosting a repo● Repo mode “archive-z2”
├── config├── objects│ ├── 35/b2a1ffa5.dirtree│ ├── 67/a1a77c36.filez│ ├── 80/04dd449f.filez│ ├── c6/171320dd.dirtree│ ├── d9/f4b64256.dirmeta│ ├── db/92a318a1.commit│ └── db/92a318a1.commitmeta├── refs/heads/master├── summary.sig└── summary
● Host on HTTP server● GPG sign commits● Static deltas
OSTree advantages
● Automatic deduplication● Disk● RAM
● Efficient updates● Atomic updates● No privileges needed● No kernel requirements
bubblewrap
“unprivileged chroot on steroids”
The virtual filesystem
FS Root Mount point
A / /
B / /a1
C / /a1/b1
C /c1 /a1/b2
A
B
C
a1
b1
c
a2
a3
b2
b3
c1
c2
c3
foo
a1
a2
a3
b1
b2
b3
c1
foo
c2
c3
foo
chroot
FS Root Mount point
A / /
B / /a1
C / /a1/b1
C /c1 /a1/b2
A
B
C
a1
b1
c
a2
a3
b2
b3
c1
c2
c3
fooProcess root
/a1
b1
b2
b3
c1
foo
c2
c3
foo
namespaces
FS Root Mount point
A / /
B / /a1
C / /a1/b1
C /c1 /a1/b2
A
B
C
a1
b1
c
a2
a3
b2
b3
c1
c2
c3
fooProcess root
/a1
b1
b2
b3
c1
foo
c2
c3
foo
Process mount table
What is wrong with chroot?● Must be root● Why?
Unprivileged user namespaces● prctl(PR_SET_NO_NEW_PRIVS)● User mappings
bubblewrap● Simple tool to use user namespaces● Starts with / as empty tmpfs● Add bindmounts and dirs/files/symlinks
$ bwrap --dir /tmp --ro-bind /usr /usr --symlink usr/lib64 /lib64 /usr/bin/ls /lib64 tmp usr
Other features● Namspaces: net, ipc, pid, uts, cgroup● Filesystems: tmpfs, proc, dev● Pid 1 handler● seccomp
Setuid version● For distros that disable user namespaces
Flatpak – 10000 feet view● Each installation has an OSTree repo● Apps and runtimes are branches
– app/org.gnome.gedit/x86_64/stable– runtime/org.gnome.Platform/x86_64/3.28
● Checked out (deployed) next to repo● Run with bubblewrap
bwrap --ro-bind $app /app --ro-bind $runtime /usr ...
Deployed app$ cd /var/lib/flatpak
$ ls -l app/org.gnome.gedit/x86_64/stable
drwxr-xr-x. 4 alex wheel 63 849ce9102a...lrwxrwxrwx. 1 alex wheel 64 active -> 849ce9102a..
$ ls -l app/org.gnome.gedit/x86_64/stable/active/
-rw-r--r--. 2 alex alex 966 metadatadrwxr-xr-x. 6 alex alex 89 filesdrwxr-xr-x. 4 alex alex 30 export-rw-r--r--. 1 alex alex 134 deploy
$ ls -la app/org.gnome.gedit/x86_64/stable/active/files/
drwxr-xr-x. 2 alex alex 56 bindrwxr-xr-x. 7 alex alex 4096 libdrwxr-xr-x. 17 alex alex 238 share-rw-r--r--. 1 alex alex 0 .ref
flatpak install flathub org.gnome.gedit
● ostree pull flathub $REF● COMMIT=$(ostree rev-parse flathub:$REF)● ostree checkout --branch $REF $REF/$COMMIT● create $REF/$COMMIT/{deploy, files/.ref}● syncfs()● ln -sf $COMMIT $REF/active● process $REF/$COMMIT/export into exports/
flatpak update org.gnome.gedit● Same, but after:
– mv $REF/$OLDCOMMIT .removed– for D in .removed/*; do
if flock --exclusive --nonblock $D/.ref; then rm -rf $D; fidone
Flatpak sandbox● Namespaces: user, fs, pid, ● Optional namespaces: net, ipc● Seccomp
– Disable weird network types– no ptrace, perf, personality, multiarch, keyring, weird syscalls– No recursive namespaces
● Per-app /tmp● Runs in transient systemd --user scope● Filtering DBus proxy● Writable per-app storage in ~/.var/app/$APPID
Questions● Links:
– https://flatpak.org/
– https://github.com/flatpak/flatpak/
– https://github.com/ostreedev/ostree
– https://github.com/projectatomic/bubblewrap/
● Reaching us
– #flatpak on freenode