diff --git a/README.md b/README.md index 055d5f5..f0d90a0 100644 --- a/README.md +++ b/README.md @@ -360,12 +360,20 @@ To pull the image from the GitHub Container Registry, run the following command: sudo docker pull ghcr.io/openprinting/ghostscript-printer-app:latest ``` +Create a Docker volume: +```sh + sudo docker volume create ghostscript-printer-app +``` + To run the container after pulling the image from the GitHub Container Registry, use: ```sh sudo docker run -d \ --name ghostscript-printer-app \ --network host \ -e PORT= \ + -v ghostscript-printer-app:/var/lib/ghostscript-printer-app \ + -v /dev/bus/usb:/dev/bus/usb:ro \ + --device-cgroup-rule='c 189:* rmw' \ ghcr.io/openprinting/ghostscript-printer-app:latest ``` @@ -375,20 +383,32 @@ Alternatively, you can pull the image from Docker Hub, by running: sudo docker pull openprinting/ghostscript-printer-app ``` +Create a Docker volume: +```sh + sudo docker volume create ghostscript-printer-app +``` + To run the container after pulling the image from Docker Hub, use: ```sh sudo docker run -d \ --name ghostscript-printer-app \ --network host \ -e PORT= \ + -v ghostscript-printer-app:/var/lib/ghostscript-printer-app \ + -v /dev/bus/usb:/dev/bus/usb:ro \ + --device-cgroup-rule='c 189:* rmw' \ openprinting/ghostscript-printer-app:latest ``` - `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. - **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. - Alternatively using the internal network of the Docker instance (`-p :8000` instead of `--network host -e PORT=`) only gives access to local printers running on the host system itself. +- `-v ghostscript-printer-app:/var/lib/ghostscript-printer-app` maps a volume for persistent storage. +- The following volume and device settings are crucial for USB printer access: + - `-v /dev/bus/usb:/dev/bus/usb:ro` mounts the host's USB device directory read-only inside the container for USB printer access. + - `--device-cgroup-rule='c 189:* rmw'` allows the container to read, write, and mknod to USB devices. -### Setting Up and Running gutenprint-printer-app locally +### Setting Up and Running ghostscript-printer-app locally #### Prerequisites @@ -424,6 +444,11 @@ Once the rock is built, you need to compile docker image from it. sudo rockcraft.skopeo --insecure-policy copy oci-archive: docker-daemon:ghostscript-printer-app:latest ``` +Create a Docker volume: +```sh + sudo docker volume create ghostscript-printer-app +``` + **Run the ghostscript-printer-app Docker Container** ```sh @@ -431,11 +456,18 @@ Once the rock is built, you need to compile docker image from it. --name ghostscript-printer-app \ --network host \ -e PORT= \ + -v ghostscript-printer-app:/var/lib/ghostscript-printer-app \ + -v /dev/bus/usb:/dev/bus/usb:ro \ + --device-cgroup-rule='c 189:* rmw' \ ghostscript-printer-app:latest ``` - `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. - **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. - Alternatively using the internal network of the Docker instance (`-p :8000` instead of `--network host -e PORT=`) only gives access to local printers running on the host system itself. +- `-v ghostscript-printer-app:/var/lib/ghostscript-printer-app` maps a volume for persistent storage. +- The following volume and device settings are crucial for USB printer access: + - `-v /dev/bus/usb:/dev/bus/usb:ro` mounts the host's USB device directory read-only inside the container for USB printer access. + - `--device-cgroup-rule='c 189:* rmw'` allows the container to read, write, and mknod to USB devices. #### Setting up diff --git a/rockcraft.yaml b/rockcraft.yaml index f458e09..7a181a0 100644 --- a/rockcraft.yaml +++ b/rockcraft.yaml @@ -15,9 +15,11 @@ platforms: amd64: armhf: +run-user: _daemon_ + services: - dbus: - command: /scripts/run-dbus.sh + avahi-daemon: + command: /scripts/run-avahi.sh override: replace on-failure: restart startup: enabled @@ -27,7 +29,7 @@ services: override: replace on-failure: shutdown startup: enabled - after: [dbus] + after: [avahi-daemon] parts: pappl: @@ -780,6 +782,7 @@ parts: stage-packages: - libsnmp40 - python3-dev + - libavahi-client-dev organize: ghostscript-printer-app/current/etc/hp/hplip.conf: etc/hp/hplip.conf prime: @@ -1449,32 +1452,158 @@ parts: - usr/share/ghostscript-printer-app - -var - -usr/share/man + after: [avahi, pappl-retrofit, pappl, ghostscript, libcupsfilters, libppd, cups-filters, foomatic-db] + + avahi: + plugin: autotools + source: https://github.com/avahi/avahi.git + source-type: git + autotools-configure-parameters: + - --prefix=/usr + - --disable-qt3 + - --disable-qt4 + - --disable-qt5 + - --disable-gtk + - --disable-gtk3 + - --disable-gdbm + - --disable-python + - --disable-pygtk + - --disable-python-dbus + - --disable-mono + - --disable-monodoc + - --disable-manpages + - --disable-xmltoman + - --with-avahi-user=_daemon_ + - --with-avahi-group=_daemon_ + # - --with-avahi-priv-access-group=netdev + # - --with-distro=debian + - --disable-gobject + - --datadir=/usr/share + - --libdir=/usr/lib/${CRAFT_ARCH_TRIPLET_BUILD_FOR} + - --with-systemdsystemunitdir=/usr/lib/systemd/system + - --localstatedir=/var + - --sysconfdir=/etc + build-packages: + - g++ + - gcc + - gettext + - intltool + - libdaemon-dev + - libdbus-1-dev + - libevent-dev + - libexpat1-dev + - libglib2.0-dev + - libsystemd-dev + - xmltoman + override-build: | + craftctl default + # for reference sort systemd service files + sed -i \ + -e 's|\(.*\)avahi-daemon -s.*|\1avahi-daemon -s --no-drop-root|g' \ + -e 's|\(.*\)avahi-daemon -r.*|\1avahi-daemon -r --no-drop-root|g' \ + ${CRAFT_PART_INSTALL}/usr/lib/systemd/system/avahi-daemon.service + mkdir -p \ + ${CRAFT_PART_INSTALL}/usr/lib/systemd/system/multi-user.target.wants + ln -sf \ + ../avahi-daemon.service \ + ${CRAFT_PART_INSTALL}/usr/lib/systemd/system/multi-user.target.wants/avahi-daemon.service + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + override-prime: | + set -eux + craftctl default + sed -i 's/use-ipv6=yes/use-ipv6=no/' ${CRAFT_PRIME}/etc/avahi/avahi-daemon.conf + sed -i 's|messagebus|_daemon_|; //,/<\/policy>/d' $CRAFT_PRIME/usr/share/dbus-1/system.conf + sed -i 's///g; s///g' $CRAFT_PRIME/usr/share/dbus-1/system.d/avahi-dbus.conf + stage-packages: + - libdaemon0 + - libevent-2.1-7 + - avahi-utils + - mdns-scan + # - libavahi-client3 + # - libavahi-common3 + stage: + - etc/avahi + - usr + - -usr/lib/**/libavahi-client.a + - -usr/lib/**/libavahi-common.a + - -usr/lib/**/libavahi-client.so* + - -usr/lib/**/libavahi-common.so* + - -usr/lib/**/*.acd + - -usr/lib/**/*.la + - -usr/lib/**/avahi + - -usr/lib/**/libavahi-glib* + - -usr/lib/**/libavahi-libevent* + - -usr/lib/**/libevent-* + # - -usr/lib/**/libnss_mdns* + - -usr/lib/**/pkgconfig + - -usr/include + - -usr/share/doc + - -usr/share/man + - -usr/share/locale after: [pappl-retrofit, pappl, ghostscript, libcupsfilters, libppd, cups-filters, foomatic-db] - avahi-daemon: + utils: plugin: nil overlay-packages: - - avahi-daemon - - avahi-utils - - libnss-mdns - - mdns-scan - - dbus - python3 + - dbus + - libnss-mdns + override-prime: | + set -eux + craftctl default + + # Set up Avahi Daemon runtime directory + mkdir -p "$CRAFT_PRIME/var/run/avahi-daemon" + chown 584792:584792 "$CRAFT_PRIME/var/run/avahi-daemon" + chmod 777 "$CRAFT_PRIME/var/run/avahi-daemon" + + # Set up D-Bus runtime directory + mkdir -p "$CRAFT_PRIME/var/run/dbus" + chown 584792:584792 "$CRAFT_PRIME/var/run/dbus" + chmod 777 "$CRAFT_PRIME/var/run/dbus" + + # Set up the CUPS SSL server root directory + CUPS_SERVERROOT="$CRAFT_PRIME/etc/cups/ssl" + mkdir -p "$CUPS_SERVERROOT" + chown 584792:584792 "$CUPS_SERVERROOT" + chmod 770 "$CUPS_SERVERROOT" + + # Set up the state directory and file for the printer app + STATE_DIR="$CRAFT_PRIME/var/lib/ghostscript-printer-app" + mkdir -p "$STATE_DIR" + chown 584792:584792 "$STATE_DIR" + chmod 770 "$STATE_DIR" + + # Create a state file inside the state directory + STATE_FILE="$STATE_DIR/ghostscript-printer-app.state" + touch "$STATE_FILE" + chown 584792:584792 "$STATE_FILE" + chmod 644 "$STATE_FILE" + + # Ensure the spool directory is owned properly + SPOOL_DIR="$CRAFT_PRIME/var/spool/ghostscript-printer-app" + mkdir -p "$SPOOL_DIR" + chown 584792:584792 "$SPOOL_DIR" + chmod 770 "$SPOOL_DIR" + + # Create and set permissions for the application log file + touch $CRAFT_PRIME/ghostscript-printer-app.log + chown 584792:584792 $CRAFT_PRIME/ghostscript-printer-app.log + chmod 644 $CRAFT_PRIME/ghostscript-printer-app.log + + # Setting up permissions to USB backend + USB_BACKEND="$CRAFT_PRIME/usr/lib/ghostscript-printer-app/backend/usb" + chmod u+s "$USB_BACKEND" + after: [ghostscript-printer-app, avahi, pappl-retrofit, pappl, ghostscript, libcupsfilters, libppd, cups-filters, foomatic-db] scripts: plugin: dump source: scripts/ organize: - run-dbus.sh: /scripts/run-dbus.sh start-server.sh: /scripts/start-server.sh + run-avahi.sh: /scripts/run-avahi.sh override-prime: | set -eux craftctl default - # Ensure the run-dbus.sh script has executable permissions - if [ -f "$CRAFT_PRIME/scripts/run-dbus.sh" ]; then - chmod +x "$CRAFT_PRIME/scripts/run-dbus.sh" - fi - # Ensure the start-server.sh script has executable permissions - if [ -f "$CRAFT_PRIME/scripts/start-server.sh" ]; then - chmod +x "$CRAFT_PRIME/scripts/start-server.sh" - fi + chmod +x $CRAFT_PRIME/scripts/* diff --git a/scripts/run-avahi.sh b/scripts/run-avahi.sh new file mode 100644 index 0000000..5f3d854 --- /dev/null +++ b/scripts/run-avahi.sh @@ -0,0 +1,17 @@ +#!/bin/sh +set -eux + +# Start dbus-daemon in the background +/usr/bin/dbus-daemon --system --nofork & + +# Wait for the D-Bus system bus to be ready +while [ ! -e /var/run/dbus/system_bus_socket ]; do + echo "Waiting for dbus-daemon to initialize..." + sleep 1 +done + +# Start avahi-daemon after dbus-daemon is ready +/usr/sbin/avahi-daemon -f /etc/avahi/avahi-daemon.conf --no-drop-root --debug + +# Keep the container running +exec tail -f /dev/null diff --git a/scripts/run-dbus.sh b/scripts/run-dbus.sh deleted file mode 100644 index 23f91ea..0000000 --- a/scripts/run-dbus.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/sh -set -eux - -echo "Creating system users" - -# Create system users with system accounts and no home directories, using nologin shell -useradd --system --no-create-home --shell /usr/sbin/nologin systemd-resolve || true -useradd --system --no-create-home --shell /usr/sbin/nologin systemd-network || true - -echo "Creating directories" - -# Create the /run/dbus directory if it doesn't exist, set permissions, and ownership -mkdir -p /run/dbus -chmod 755 /run/dbus -chown root:root /run/dbus - -echo "Starting dbus" - -# Start the dbus daemon in the foreground -# dbus-daemon --system --nofork --nopidfile & - -# Check the status of the dbus service -service dbus start -service dbus status || true - -echo "Starting avahi-daemon" - -# Start the avahi-daemon in the background without dropping root privileges -avahi-daemon --daemonize --no-drop-root - -# Keep the script running to avoid container exit -tail -f /dev/null \ No newline at end of file diff --git a/scripts/start-server.sh b/scripts/start-server.sh index 8227e84..e583a1a 100644 --- a/scripts/start-server.sh +++ b/scripts/start-server.sh @@ -9,27 +9,16 @@ if [ -n "${PORT:-}" ]; then fi fi -# Ensure the /etc/cups/ssl directory exists with proper permissions -CUPS_SERVERROOT="/etc/cups/ssl" -if [ ! -d "$CUPS_SERVERROOT" ]; then - mkdir -p "$CUPS_SERVERROOT" -fi -chmod 755 "$CUPS_SERVERROOT" - -# Ensure /var/lib/ghostscript-printer-app directory exists -STATE_DIR="/var/lib/ghostscript-printer-app" - -if [ ! -d "$STATE_DIR" ]; then - mkdir -p "$STATE_DIR" -fi -chmod 755 "$STATE_DIR" +# Wait for avahi-daemon to initialize +while true; do + if [ -f "/var/run/avahi-daemon/pid" ] || [ -f "/run/avahi-daemon/pid" ]; then + echo "avahi-daemon is active. Starting ps-printer-app..." + break + fi -# Ensure ghostscript-printer-app.state file exists -STATE_FILE="$STATE_DIR/ghostscript-printer-app.state" -if [ ! -f "$STATE_FILE" ]; then - touch "$STATE_FILE" -fi -chmod 755 "$STATE_FILE" + echo "Waiting for avahi-daemon to initialize..." + sleep 1 +done # Start the ghostscript-printer-app server -ghostscript-printer-app -o log-file=/ghostscript-printer-app.log ${PORT:+-o server-port=$PORT} server +ghostscript-printer-app -o log-file="/ghostscript-printer-app.log" ${PORT:+-o server-port="$PORT"} server