Skip to content

Commit f0ee89d

Browse files
committed
Introduces immutability to OCI image by running everything as non-root user _daemon_; Updated README to include runtime flags for data persistence and USB printer access
1 parent 747761d commit f0ee89d

File tree

5 files changed

+220
-83
lines changed

5 files changed

+220
-83
lines changed

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,20 @@ To pull the image from the GitHub Container Registry, run the following command:
266266
sudo docker pull ghcr.io/openprinting/hplip-printer-app:latest
267267
```
268268

269+
Create a Docker volume:
270+
```sh
271+
sudo docker volume create hplip-printer-app
272+
```
273+
269274
To run the container after pulling the image from the GitHub Container Registry, use:
270275
```sh
271276
sudo docker run -d \
272277
--name hplip-printer-app \
273278
--network host \
274279
-e PORT=<port> \
280+
-v hplip-printer-app:/var/lib/hplip-printer-app \
281+
-v /dev/bus/usb:/dev/bus/usb:ro \
282+
--device-cgroup-rule='c 189:* rmw' \
275283
ghcr.io/openprinting/hplip-printer-app:latest
276284
```
277285

@@ -281,18 +289,30 @@ Alternatively, you can pull the image from Docker Hub, by running:
281289
sudo docker pull openprinting/hplip-printer-app
282290
```
283291

292+
Create a Docker volume:
293+
```sh
294+
sudo docker volume create hplip-printer-app
295+
```
296+
284297
To run the container after pulling the image from Docker Hub, use:
285298
```sh
286299
sudo docker run -d \
287300
--name hplip-printer-app \
288301
--network host \
289302
-e PORT=<port> \
303+
-v hplip-printer-app:/var/lib/hplip-printer-app \
304+
-v /dev/bus/usb:/dev/bus/usb:ro \
305+
--device-cgroup-rule='c 189:* rmw' \
290306
openprinting/hplip-printer-app:latest
291307
```
292308

293309
- `PORT` is an optional environment variable used to start the printer-app on a specified port. If not provided, it will start on the default port 8000 or, if port 8000 is busy, on 8001 and so on.
294310
- **The container must be started in `--network host` mode** to allow the Printer-Application instance inside the container to access and discover printers available in the local network where the host system is in.
295311
- Alternatively using the internal network of the Docker instance (`-p <port>:8000` instead of `--network host -e PORT=<port>`) only gives access to local printers running on the host system itself.
312+
- `-v hplip-printer-app:/var/lib/hplip-printer-app` maps a volume for persistent storage.
313+
- The following volume and device settings are crucial for USB printer access:
314+
- `-v /dev/bus/usb:/dev/bus/usb:ro` mounts the host's USB device directory read-only inside the container for USB printer access.
315+
- `--device-cgroup-rule='c 189:* rmw'` allows the container to read, write, and mknod to USB devices.
296316

297317
### Setting Up and Running hplip-printer-app locally
298318

@@ -330,18 +350,30 @@ Once the rock is built, you need to compile docker image from it.
330350
sudo rockcraft.skopeo --insecure-policy copy oci-archive:<rock_image> docker-daemon:hplip-printer-app:latest
331351
```
332352

353+
Create a Docker volume:
354+
```sh
355+
sudo docker volume create hplip-printer-app
356+
```
357+
333358
**Run the hplip-printer-app Docker Container**
334359

335360
```sh
336361
sudo docker run -d \
337362
--name hplip-printer-app \
338363
--network host \
339364
-e PORT=<port> \
365+
-v hplip-printer-app:/var/lib/hplip-printer-app \
366+
-v /dev/bus/usb:/dev/bus/usb:ro \
367+
--device-cgroup-rule='c 189:* rmw' \
340368
hplip-printer-app:latest
341369
```
342370
- `PORT` is an optional environment variable used to start the printer-app on a specified port. If not provided, it will start on the default port 8000 or, if port 8000 is busy, on 8001 and so on.
343371
- **The container must be started in `--network host` mode** to allow the Printer-Application instance inside the container to access and discover printers available in the local network where the host system is in.
344372
- Alternatively using the internal network of the Docker instance (`-p <port>:8000` instead of `--network host -e PORT=<port>`) only gives access to local printers running on the host system itself.
373+
- `-v hplip-printer-app:/var/lib/hplip-printer-app` maps a volume for persistent storage.
374+
- The following volume and device settings are crucial for USB printer access:
375+
- `-v /dev/bus/usb:/dev/bus/usb:ro` mounts the host's USB device directory read-only inside the container for USB printer access.
376+
- `--device-cgroup-rule='c 189:* rmw'` allows the container to read, write, and mknod to USB devices.
345377

346378
#### Setting up
347379

rockcraft.yaml

+161-30
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,21 @@ platforms:
1919
environment:
2020
MIBDIRS: /hplip-printer-app/current/usr/share/snmp/mibs:/hplip-printer-app/current/usr/share/snmp/mibs/iana:/hplip-printer-app/current/usr/share/snmp/mibs/ietf
2121

22+
run-user: _daemon_
23+
2224
services:
23-
dbus:
24-
command: /scripts/run-dbus.sh
25+
avahi-daemon:
26+
command: /scripts/run-avahi.sh
2527
override: replace
2628
on-failure: restart
2729
startup: enabled
2830

29-
hplip-printer-app:
31+
ps-printer-app:
3032
command: /scripts/start-server.sh
3133
override: replace
3234
on-failure: shutdown
3335
startup: enabled
34-
after: [dbus]
36+
after: [avahi-daemon]
3537

3638
parts:
3739
pappl:
@@ -305,7 +307,7 @@ parts:
305307
# hplip parts to avoid any file clashes.
306308
- libavahi-common3
307309
- libavahi-client3
308-
- avahi-utils
310+
# - avahi-utils
309311
prime:
310312
- -etc/fonts
311313
- -var
@@ -814,28 +816,175 @@ parts:
814816
- -usr/share/man
815817
# Reported unused by snapcraft linter
816818
- -usr/lib/*/libgssapi.*
819+
after: [avahi, pappl-retrofit, pappl, cups, libcupsfilters, libppd, hplip]
820+
821+
avahi:
822+
plugin: autotools
823+
source: https://github.com/avahi/avahi.git
824+
source-type: git
825+
autotools-configure-parameters:
826+
- --prefix=/usr
827+
- --disable-qt3
828+
- --disable-qt4
829+
- --disable-qt5
830+
- --disable-gtk
831+
- --disable-gtk3
832+
- --disable-gdbm
833+
- --disable-python
834+
- --disable-pygtk
835+
- --disable-python-dbus
836+
- --disable-mono
837+
- --disable-monodoc
838+
- --disable-manpages
839+
- --disable-xmltoman
840+
- --with-avahi-user=_daemon_
841+
- --with-avahi-group=_daemon_
842+
# - --with-avahi-priv-access-group=netdev
843+
# - --with-distro=debian
844+
- --disable-gobject
845+
- --datadir=/usr/share
846+
- --libdir=/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR}
847+
- --with-systemdsystemunitdir=/usr/lib/systemd/system
848+
- --localstatedir=/var
849+
- --sysconfdir=/etc
850+
build-packages:
851+
- g++
852+
- gcc
853+
- gettext
854+
- intltool
855+
- libdaemon-dev
856+
- libdbus-1-dev
857+
- libevent-dev
858+
- libexpat1-dev
859+
- libglib2.0-dev
860+
- libsystemd-dev
861+
- xmltoman
862+
override-build: |
863+
craftctl default
864+
# for reference sort systemd service files
865+
sed -i \
866+
-e 's|\(.*\)avahi-daemon -s.*|\1avahi-daemon -s --no-drop-root|g' \
867+
-e 's|\(.*\)avahi-daemon -r.*|\1avahi-daemon -r --no-drop-root|g' \
868+
${CRAFT_PART_INSTALL}/usr/lib/systemd/system/avahi-daemon.service
869+
mkdir -p \
870+
${CRAFT_PART_INSTALL}/usr/lib/systemd/system/multi-user.target.wants
871+
ln -sf \
872+
../avahi-daemon.service \
873+
${CRAFT_PART_INSTALL}/usr/lib/systemd/system/multi-user.target.wants/avahi-daemon.service
874+
build-environment:
875+
- LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib"
876+
override-prime: |
877+
set -eux
878+
craftctl default
879+
sed -i 's/use-ipv6=yes/use-ipv6=no/' ${CRAFT_PRIME}/etc/avahi/avahi-daemon.conf
880+
sed -i 's|<user>messagebus</user>|<user>_daemon_</user>|; /<policy user="root">/,/<\/policy>/d' $CRAFT_PRIME/usr/share/dbus-1/system.conf
881+
sed -i 's/<policy group="netdev">/<policy group="_daemon_">/g; s/<policy user="root">/<policy user="_daemon_">/g' $CRAFT_PRIME/usr/share/dbus-1/system.d/avahi-dbus.conf
882+
stage-packages:
883+
- libdaemon0
884+
- libevent-2.1-7
885+
- avahi-utils
886+
- mdns-scan
887+
# - libavahi-client3
888+
# - libavahi-common3
889+
stage:
890+
- etc/avahi
891+
- usr
892+
- -usr/lib/**/libavahi-client.so*
893+
- -usr/lib/**/libavahi-common.so*
894+
- -usr/lib/**/*.acd
895+
- -usr/lib/**/*.la
896+
- -usr/lib/**/avahi
897+
- -usr/lib/**/libavahi-glib*
898+
- -usr/lib/**/libavahi-libevent*
899+
- -usr/lib/**/libevent-*
900+
# - -usr/lib/**/libnss_mdns*
901+
- -usr/lib/**/pkgconfig
902+
- -usr/include
903+
- -usr/share/doc
904+
- -usr/share/man
905+
- -usr/share/locale
817906
after: [pappl-retrofit, pappl, cups, libcupsfilters, libppd, hplip]
818907

819-
avahi-daemon:
908+
utils:
820909
plugin: nil
821910
overlay-packages:
822-
- avahi-daemon
823-
- avahi-utils
824-
- libnss-mdns
825-
- mdns-scan
826-
- dbus
827911
- python3
912+
- dbus
913+
- libnss-mdns
914+
override-prime: |
915+
set -eux
916+
craftctl default
917+
918+
# Set up Avahi Daemon runtime directory
919+
mkdir -p "$CRAFT_PRIME/var/run/avahi-daemon"
920+
chown 584792:584792 "$CRAFT_PRIME/var/run/avahi-daemon"
921+
chmod 777 "$CRAFT_PRIME/var/run/avahi-daemon"
922+
923+
# Set up D-Bus runtime directory
924+
mkdir -p "$CRAFT_PRIME/var/run/dbus"
925+
chown 584792:584792 "$CRAFT_PRIME/var/run/dbus"
926+
chmod 777 "$CRAFT_PRIME/var/run/dbus"
927+
928+
# Set up the CUPS SSL server root directory
929+
CUPS_SERVERROOT="$CRAFT_PRIME/etc/cups/ssl"
930+
mkdir -p "$CUPS_SERVERROOT"
931+
chown 584792:584792 "$CUPS_SERVERROOT"
932+
chmod 770 "$CUPS_SERVERROOT"
933+
934+
# Set up the state directory and file for the printer app
935+
STATE_DIR="$CRAFT_PRIME/var/lib/hplip-printer-app/"
936+
mkdir -p "$STATE_DIR"
937+
chown 584792:584792 "$STATE_DIR"
938+
chmod 770 "$STATE_DIR"
939+
940+
# Create a state file inside the state directory
941+
STATE_FILE="$STATE_DIR/hplip-printer-app.state"
942+
touch "$STATE_FILE"
943+
chown 584792:584792 "$STATE_FILE"
944+
chmod 644 "$STATE_FILE"
945+
946+
# Set up the hp state directory and file for the printer app
947+
HP_STATE_DIR="$CRAFT_PRIME/var/lib/hp"
948+
mkdir -p "$HP_STATE_DIR"
949+
chown 584792:584792 "$HP_STATE_DIR"
950+
chmod 770 "$HP_STATE_DIR"
951+
952+
# Create a hp state file inside the state directory
953+
HP_STATE_FILE="$HP_STATE_DIR/hplip.state"
954+
touch "$HP_STATE_FILE"
955+
chown 584792:584792 "$HP_STATE_FILE"
956+
chmod 644 "$HP_STATE_FILE"
957+
958+
# Ensure the spool directory is owned properly
959+
SPOOL_DIR="$CRAFT_PRIME/var/spool/hplip-printer-app"
960+
mkdir -p "$SPOOL_DIR"
961+
chown 584792:584792 "$SPOOL_DIR"
962+
chmod 770 "$SPOOL_DIR"
963+
964+
# Create and set permissions for the application log file
965+
touch $CRAFT_PRIME/hplip-printer-app.log
966+
chown 584792:584792 $CRAFT_PRIME/hplip-printer-app.log
967+
chmod 644 $CRAFT_PRIME/hplip-printer-app.log
968+
969+
# Setting up permissions to USB backend
970+
USB_BACKEND="$CRAFT_PRIME/usr/lib/hplip-printer-app/backend/usb"
971+
chmod u+s "$USB_BACKEND"
972+
after: [avahi, pappl-retrofit, pappl, cups, libcupsfilters, libppd, hplip]
828973

829974
scripts:
830975
plugin: dump
831976
source: .
832977
organize:
833-
# "HP" discovery-only CUPS backendto discover
978+
# "HP" discovery-only CUPS backend to discover
834979
# network printers using the hp-probe utility, as
835980
# HPLIP's "hp" backend only discovers USB printers
836981
HP: usr/lib/hplip-printer-app/backend/HP
837982
stage-packages:
838983
- udev
984+
override-prime: |
985+
set -eux
986+
craftctl default
987+
chmod +x $CRAFT_PRIME/scripts/*
839988
prime:
840989
- -etc
841990
- bin
@@ -845,21 +994,3 @@ parts:
845994
- usr/lib/hplip-printer-app/backend/
846995
- -usr/lib/tmpfiles.d
847996
after: [hplip-printer-app]
848-
849-
dbus-scripts:
850-
plugin: dump
851-
source: scripts/
852-
organize:
853-
run-dbus.sh: /scripts/run-dbus.sh
854-
start-server.sh: /scripts/start-server.sh
855-
override-prime: |
856-
set -eux
857-
craftctl default
858-
# Ensure the run-dbus.sh script has executable permissions
859-
if [ -f "$CRAFT_PRIME/scripts/run-dbus.sh" ]; then
860-
chmod +x "$CRAFT_PRIME/scripts/run-dbus.sh"
861-
fi
862-
# Ensure the start-server.sh script has executable permissions
863-
if [ -f "$CRAFT_PRIME/scripts/start-server.sh" ]; then
864-
chmod +x "$CRAFT_PRIME/scripts/start-server.sh"
865-
fi

scripts/run-avahi.sh

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/bin/sh
2+
set -eux
3+
4+
# Start dbus-daemon in the background
5+
/usr/bin/dbus-daemon --system --nofork &
6+
7+
# Wait for the D-Bus system bus to be ready
8+
while [ ! -e /var/run/dbus/system_bus_socket ]; do
9+
echo "Waiting for dbus-daemon to initialize..."
10+
sleep 1
11+
done
12+
13+
# Start avahi-daemon after dbus-daemon is ready
14+
/usr/sbin/avahi-daemon -f /etc/avahi/avahi-daemon.conf --no-drop-root --debug
15+
16+
# Keep the container running
17+
exec tail -f /dev/null

scripts/run-dbus.sh

-32
This file was deleted.

0 commit comments

Comments
 (0)