From a15a31fbf0b05c90fa4a5b5c52d4b75be042c5bb Mon Sep 17 00:00:00 2001 From: Antonio Murdaca Date: Wed, 31 Jan 2024 11:47:38 +0100 Subject: [PATCH] examples: add kiosk Signed-off-by: Antonio Murdaca --- examples/README.md | 1 + examples/kiosk/Containerfile | 13 ++++ examples/kiosk/Containerfile.flatpak | 7 ++ examples/kiosk/Containerfile.update | 3 + examples/kiosk/LICENSE | 21 ++++++ examples/kiosk/README.md | 82 +++++++++++++++++++++++ examples/kiosk/core.conf | 1 + examples/kiosk/custom.conf | 13 ++++ examples/kiosk/example.ks | 32 +++++++++ examples/kiosk/gnome-kiosk-script | 4 ++ examples/kiosk/gnome-kiosk-script.flatpak | 4 ++ examples/kiosk/gnome-kiosk-script.update | 4 ++ examples/kiosk/image.conf | 2 + examples/kiosk/kiosk-gdm | 3 + examples/kiosk/kiosk.conf | 5 ++ examples/kiosk/run.sh | 10 +++ 16 files changed, 205 insertions(+) create mode 100644 examples/kiosk/Containerfile create mode 100644 examples/kiosk/Containerfile.flatpak create mode 100644 examples/kiosk/Containerfile.update create mode 100644 examples/kiosk/LICENSE create mode 100644 examples/kiosk/README.md create mode 100644 examples/kiosk/core.conf create mode 100644 examples/kiosk/custom.conf create mode 100644 examples/kiosk/example.ks create mode 100644 examples/kiosk/gnome-kiosk-script create mode 100644 examples/kiosk/gnome-kiosk-script.flatpak create mode 100644 examples/kiosk/gnome-kiosk-script.update create mode 100644 examples/kiosk/image.conf create mode 100644 examples/kiosk/kiosk-gdm create mode 100644 examples/kiosk/kiosk.conf create mode 100755 examples/kiosk/run.sh diff --git a/examples/README.md b/examples/README.md index 0e015e9..3c1f822 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,6 +4,7 @@ This repository contains example bootable containers. ## Examples +- [kiosk](kiosk/): Configure a kiosk application - [nvidia](nvidia/): Install the nvidia driver - [tailscale](tailscale/): Demos - [wifi](wifi/): Install support for wireless networks along with pre-baked diff --git a/examples/kiosk/Containerfile b/examples/kiosk/Containerfile new file mode 100644 index 0000000..4f173be --- /dev/null +++ b/examples/kiosk/Containerfile @@ -0,0 +1,13 @@ +FROM quay.io/centos-bootc/centos-bootc-dev:stream9 +RUN rpm-ostree install gdm firefox gnome-kiosk-script-session plymouth-system-theme firewalld +RUN rm -rf /var/lib/gdm/.config/pulse/default.pa && rm -rf /var/lib/xkb/README.compiled +COPY custom.conf /etc/gdm/ +COPY core.conf /usr/lib/sysusers.d/ +COPY --chmod=0755 --chown=1042:1042 gnome-kiosk-script /usr/lib/ +COPY kiosk-gdm /usr/lib/ +COPY kiosk.conf /usr/lib/tmpfiles.d/ +RUN mkdir -p /usr/etc-system/ && \ + echo 'AuthorizedKeysFile /usr/etc-system/%u.keys' >> /etc/ssh/sshd_config.d/30-auth-system.conf && \ + echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL7xFq1HtZKZiaD8MfkhNtn37m8GSc1W168NoSaT9RSf cardno:000F_C36A3FC0' > /usr/etc-system/root.keys && chmod 0600 /usr/etc-system/root.keys +RUN systemctl enable sshd && firewall-offline-cmd --disabled +RUN systemctl set-default graphical.target && ostree container commit diff --git a/examples/kiosk/Containerfile.flatpak b/examples/kiosk/Containerfile.flatpak new file mode 100644 index 0000000..64f20b4 --- /dev/null +++ b/examples/kiosk/Containerfile.flatpak @@ -0,0 +1,7 @@ +FROM quay.io/runcom/kiosk-base:latest +COPY image.conf /etc/flatpak/installations.d/ +RUN rpm-ostree install flatpak && \ + flatpak remote-add --installation=image --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo && \ + flatpak install --installation=image -y flathub org.gimp.GIMP +COPY --chmod=0755 --chown=1042:1042 gnome-kiosk-script.flatpak /usr/lib/gnome-kiosk-script +RUN ostree container commit \ No newline at end of file diff --git a/examples/kiosk/Containerfile.update b/examples/kiosk/Containerfile.update new file mode 100644 index 0000000..f416aef --- /dev/null +++ b/examples/kiosk/Containerfile.update @@ -0,0 +1,3 @@ +FROM quay.io/runcom/kiosk-base:latest +COPY --chmod=0755 --chown=1042:1042 gnome-kiosk-script.update /usr/lib/gnome-kiosk-script +RUN ostree container commit \ No newline at end of file diff --git a/examples/kiosk/LICENSE b/examples/kiosk/LICENSE new file mode 100644 index 0000000..efb6fe9 --- /dev/null +++ b/examples/kiosk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Antonio Murdaca + +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. diff --git a/examples/kiosk/README.md b/examples/kiosk/README.md new file mode 100644 index 0000000..f06a927 --- /dev/null +++ b/examples/kiosk/README.md @@ -0,0 +1,82 @@ +# kiosk-sagano-example + +Demonstration of using the container workflow to build a bootable container image that includes kiosk and a simple script running firefox. + +## Notable issues/ergonomics + +- Anaconda sets `multi-user.target` as default and whatever we set in the container build isn't honored (will have to file a bug, see https://github.com/rhinstaller/anaconda/blob/ee0b61fa135ba555f29bc6e3d035fbca8bcc14d5/pyanaconda/modules/services/installation.py#L174-L241) +- `useradd` in the container seems to be a no-no, if there was a way to translate that to something using `sysusers.d` that'd be awesome (something in `ostree container commit` perhaps?) +- there are RPMs that writes to `/var` - that's not ideal, either remove or copy them somewhere to later re-inject them using `tmpfiles.d` +- where do we set credentials? root ssh keys in the container may be ok but crendentials in an image seems wrong (also, we can't get rid of `rootpw --iscrypted locked` in the kickstart file) +- where does day 2 mgmt like `flatpak update` belong? since we have to dance a little bit to get the root's flatpak's dir under `/usr` I expect people to _rebuild_ the image right? meaning, nobody runs `flatpak update` on the system, right? +- update size isn't small + +## What went well + +- There's no thinking around managing updates; just push the image on quay.io or any registry and choose a tag to either rebase to or follow and that's it +- iterating on changes is super fast, just rebuld, push, rebase +- checking what's inside the ostree commit is just a `podman run` away + +## Images + +If you don't want to build youserlf, the following base image is available to be used directly in kickstart: + +- `quay.io/runcom/kiosk-base:latest` + +You can then follow what's done in `Containerfile.update` and `Containerfile.flatpak` to get an idea about deriving from the base image from your own needs. +The other images are also available: + +- `quay.io/runcom/kiosk-base:update` +- `quay.io/runcom/kiosk-base:flatpak` + +## Running + +There are various ways to test this example: + +- install with Anaconda + kickstart +- rebase an existing ostree system +- use a tool to create a bootable disk image + +### changing the root ssh key + +The ssh key for the root user lives in the main `Containerfile` - change it there as needed. Another option would be to set it in the kickstart file. + +### install with Anaconda + kickstart + +This has been tested on Fedora 39 and should work simply by following these instructions. _Notice we have to disable secure boot since we're using CentOS stream._ + +```sh +# optional +$ sudo podman build -t quay.io/runcom/kiosk-base:latest . +$ sudo podman push quay.io/runcom/kiosk-base:latest +$ ... +$ sudo cp /usr/share/edk2/ovmf/OVMF_VARS.fd /var/lib/libvirt/qemu/nvram/sagano-demo_VARS.fd +$ ./run.sh +``` + +### rebase an existing ostree system + +```sh +$ sudo rpm-ostree rebase ostree-unverified-registry:quay.io/runcom/kiosk-base:latest +$ sudo systemctl reboot +``` + +### bootc-image-builder + +Use [bootc-image-builder](https://github.com/osbuild/bootc-image-builder) to create a bootable disk image. + +## Updating + +You can build and get the update with the following: + +```sh +# optional +$ sudo podman build -f Containerfile.update -t quay.io/runcom/kiosk-base:update . +$ sudo podman push quay.io/runcom/kiosk-base:update +$ ... +# in the running vm +$ sudo rpm-ostree rebase ostree-unverified-registry:quay.io/runcom/kiosk-base:update +$ sudo systemctl reboot +``` + +With the above flow you could also create and rebase to an image that has flatpak and runs GIMP as a kiosk app, see `Containerfile.flatpak`. diff --git a/examples/kiosk/core.conf b/examples/kiosk/core.conf new file mode 100644 index 0000000..a15224f --- /dev/null +++ b/examples/kiosk/core.conf @@ -0,0 +1 @@ +u core 1042 "kiosk user" /var/lib/corehome /bin/sh diff --git a/examples/kiosk/custom.conf b/examples/kiosk/custom.conf new file mode 100644 index 0000000..0d78278 --- /dev/null +++ b/examples/kiosk/custom.conf @@ -0,0 +1,13 @@ +#Enable autologin for the user core +# GDM configuration storage +[daemon] +# Uncomment the line below to force the login screen to use Xorg +#WaylandEnable=false +AutomaticLogin=core +AutomaticLoginEnable=True +[security] +[xdmcp] +[chooser] +[debug] +# Uncomment the line below to turn on debugging +Enable=true diff --git a/examples/kiosk/example.ks b/examples/kiosk/example.ks new file mode 100644 index 0000000..7924b7e --- /dev/null +++ b/examples/kiosk/example.ks @@ -0,0 +1,32 @@ +text + +# Basic partitioning +clearpart --all --initlabel --disklabel=gpt +part prepboot --size=4 --fstype=prepboot +part biosboot --size=1 --fstype=biosboot +part /boot/efi --size=100 --fstype=efi +part /boot --size=1000 --fstype=ext4 --label=boot +part / --grow --fstype xfs + +ostreecontainer --url quay.io/runcom/kiosk-base:latest --no-signature-verification + +# we can inject the ssh key for the root account in the container but we can't +# get rid of this line unfortunately +rootpw --iscrypted locked +reboot + +# Workarounds until https://github.com/rhinstaller/anaconda/pull/5298/ lands +bootloader --location=none --disabled +%post --erroronfail +set -euo pipefail +# Work around anaconda wanting a root password +passwd -l root +rootdevice=$(findmnt -nv -o SOURCE /) +device=$(lsblk -n -o PKNAME ${rootdevice}) +/usr/bin/bootupctl backend install --auto --with-static-configs --device /dev/${device} / + +# anaconda will set multi-user.target by default and won't honor what we've set in the Container +# https://github.com/rhinstaller/anaconda/blob/ee0b61fa135ba555f29bc6e3d035fbca8bcc14d5/pyanaconda/modules/services/installation.py#L174-L241 +systemctl set-default graphical.target + +%end diff --git a/examples/kiosk/gnome-kiosk-script b/examples/kiosk/gnome-kiosk-script new file mode 100644 index 0000000..078c8c1 --- /dev/null +++ b/examples/kiosk/gnome-kiosk-script @@ -0,0 +1,4 @@ +#!/bin/sh +while true; do + firefox --profile /var/lib/corehome -kiosk https://time.gov +done diff --git a/examples/kiosk/gnome-kiosk-script.flatpak b/examples/kiosk/gnome-kiosk-script.flatpak new file mode 100644 index 0000000..b1fbba9 --- /dev/null +++ b/examples/kiosk/gnome-kiosk-script.flatpak @@ -0,0 +1,4 @@ +#!/bin/sh +while true; do + flatpak run org.gimp.GIMP +done \ No newline at end of file diff --git a/examples/kiosk/gnome-kiosk-script.update b/examples/kiosk/gnome-kiosk-script.update new file mode 100644 index 0000000..70d59b7 --- /dev/null +++ b/examples/kiosk/gnome-kiosk-script.update @@ -0,0 +1,4 @@ +#!/bin/sh +while true; do + firefox --profile /var/lib/corehome -kiosk https://time.is +done diff --git a/examples/kiosk/image.conf b/examples/kiosk/image.conf new file mode 100644 index 0000000..cbd6e48 --- /dev/null +++ b/examples/kiosk/image.conf @@ -0,0 +1,2 @@ +[Installation "image"] +Path=/usr/share/flatpaks \ No newline at end of file diff --git a/examples/kiosk/kiosk-gdm b/examples/kiosk/kiosk-gdm new file mode 100644 index 0000000..abd459e --- /dev/null +++ b/examples/kiosk/kiosk-gdm @@ -0,0 +1,3 @@ +[User] +Session=gnome-kiosk-script +SystemAccount=false diff --git a/examples/kiosk/kiosk.conf b/examples/kiosk/kiosk.conf new file mode 100644 index 0000000..9efce02 --- /dev/null +++ b/examples/kiosk/kiosk.conf @@ -0,0 +1,5 @@ +C /var/lib/AccountsService/users/core 0600 - - - /usr/lib/kiosk-gdm +d /var/lib/corehome - 1042 1042 - - +d /var/lib/corehome/.local - 1042 1042 - - +d /var/lib/corehome/.local/bin - 1042 1042 - - +L+ /var/lib/corehome/.local/bin/gnome-kiosk-script - - - - /usr/lib/gnome-kiosk-script diff --git a/examples/kiosk/run.sh b/examples/kiosk/run.sh new file mode 100755 index 0000000..01be19a --- /dev/null +++ b/examples/kiosk/run.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +FILE="$PWD"/boot.iso +if [ ! -f "$FILE" ]; then + curl -O https://dl.fedoraproject.org/pub/fedora/linux/releases/38/Everything/x86_64/os/images/boot.iso +fi +virt-install --connect qemu:///system --name sagano-demo --memory 2048 --vcpus 4 --disk size=40 \ + --boot loader=/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd,loader.readonly=yes,loader.secure='no',loader.type=pflash,nvram=/var/lib/libvirt/qemu/nvram/sagano-demo_VARS.fd --network=network=default,model=virtio \ + --os-variant rhel9.0 --location boot.iso \ + --noautoconsole --initrd-inject $(pwd)/example.ks --extra-args="inst.ks=file:/example.ks console=tty0 console=ttyS0,115200 inst.profile=rhel" \ No newline at end of file