From 75f098043d87188eecc5b97adf7489fc38ff8530 Mon Sep 17 00:00:00 2001 From: Rudra Pratap Singh Date: Sun, 15 Dec 2024 18:33:09 +0530 Subject: [PATCH] Build and Deploy OCI Image of ps-printer-app Using Rockcraft (#29) - Added rockcraft.yaml, parts taken from snap/snapcraft.yaml - Added scripts to start Avahi and D-Bus support in the container and to start the Printer Application itself, optionally on a user-selected port - Moved patch from snap/ subdirectory to separate patches/ subdirectory for use by both Snap and Rock - Added and updated the GitHub workflows, for updating and versioning automation of the Rock, CI testing, and registering OCI image in Docker and GitHub - Added documentation for the Rock/OCI image to README.md --- .github/workflows/auto-update.yml | 28 +- .github/workflows/ci.yml | 31 + .github/workflows/registry-actions.yml | 114 +++ .gitignore | 2 + README.md | 88 ++- .../cups-dnssd-backend-socket-only.patch | 0 rockcraft.yaml | 732 ++++++++++++++++++ scripts/run-dbus.sh | 30 + scripts/start-server.sh | 12 + snap/snapcraft.yaml | 2 +- 10 files changed, 1032 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/registry-actions.yml create mode 100644 .gitignore rename {snap/local => patches}/cups-dnssd-backend-socket-only.patch (100%) create mode 100644 rockcraft.yaml create mode 100644 scripts/run-dbus.sh create mode 100644 scripts/start-server.sh diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml index 7a74ef8..bba75a8 100644 --- a/.github/workflows/auto-update.yml +++ b/.github/workflows/auto-update.yml @@ -2,19 +2,39 @@ name: Push new tag update to stable branch on: schedule: - # Daily for now - cron: '9 7 * * *' workflow_dispatch: + inputs: + workflow_choice: + description: "Choose YAML to update" + required: true + default: "both" + type: choice + options: + - snapcraft + - rockcraft + - both jobs: - update-snapcraft-yaml: + update-yamls: runs-on: ubuntu-latest steps: - name: Checkout this repo uses: actions/checkout@v3 - - name: Run desktop-snaps action + + - name: Run desktop-snaps action (Snapcraft) + if: ${{ github.event_name == 'schedule' || github.event.inputs.workflow_choice == 'snapcraft' || github.event.inputs.workflow_choice == 'both' }} + uses: ubuntu/desktop-snaps@stable + with: + token: ${{ secrets.GITHUB_TOKEN }} + repo: ${{ github.repository }} + version-schema: '^(\d{8})' + + - name: Run desktop-snaps action (Rockcraft) + if: ${{ github.event_name == 'schedule' || github.event.inputs.workflow_choice == 'rockcraft' || github.event.inputs.workflow_choice == 'both' }} uses: ubuntu/desktop-snaps@stable with: token: ${{ secrets.GITHUB_TOKEN }} repo: ${{ github.repository }} - version-schema: '^(\d{8})' \ No newline at end of file + rock-version-schema: '^(\d{8})' + yaml-path: 'rockcraft.yaml' \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f8ceb18 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI Pipeline for ps-printer-app + +on: + push: + branches: + - main + pull_request: + branches: + - main + workflow_dispatch: + +jobs: + build-rock: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Pack with Rockcraft + uses: canonical/craft-actions/rockcraft-pack@main + id: rockcraft + + build-snap: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Build Snap Package + uses: snapcore/action-build@v1 + id: snapcraft diff --git a/.github/workflows/registry-actions.yml b/.github/workflows/registry-actions.yml new file mode 100644 index 0000000..60a3f4d --- /dev/null +++ b/.github/workflows/registry-actions.yml @@ -0,0 +1,114 @@ +name: Pack and Publish OCI Image to Docker Registry and GitHub Packages + +on: + push: + branches: + - main + workflow_dispatch: + inputs: + workflow_choice: + description: "Choose Release Channel" + required: true + default: "edge" + type: choice + options: + - edge + - stable + - both + workflow_run: + workflows: ["Push new tag update to stable branch"] + types: + - completed + +jobs: + build-rock: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Pack with Rockcraft + uses: canonical/craft-actions/rockcraft-pack@main + id: rockcraft + with: + path: rock + + - name: Upload Rock Artifact + uses: actions/upload-artifact@v4 + with: + name: cups-rock + path: ${{ steps.rockcraft.outputs.rock }} + + publish-rock: + needs: build-rock + if: github.ref_name == 'main' + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Download Rock Artifact + uses: actions/download-artifact@v4 + with: + name: cups-rock + + - name: Install Dependencies + run: | + sudo snap install rockcraft --classic + sudo snap install docker + sudo snap install yq + + - name: Ensure Docker Daemon is Running + run: | + sudo systemctl start docker + sudo systemctl enable docker + sudo systemctl is-active --quiet docker || sudo systemctl start docker + + # - name: Log in to Docker Hub + # uses: docker/login-action@v3.2.0 + # with: + # username: ${{ secrets.DOCKER_USERNAME }} + # password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Log in to GitHub Packages + uses: docker/login-action@v3.2.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push Docker Image (Edge & Latest Channel) + if: github.event.inputs.workflow_choice == 'edge' || github.event.inputs.workflow_choice == 'both' || github.event_name == 'push' || github.event_name == 'workflow_run' + env: + USERNAME: ${{ secrets.DOCKER_USERNAME }} + run: | + IMAGE="$(yq '.name' rockcraft.yaml)" + VERSION="$(yq '.version' rockcraft.yaml)" + ROCK="$(ls *.rock | tail -n 1)" + sudo rockcraft.skopeo --insecure-policy copy oci-archive:"${ROCK}" docker-daemon:"${USERNAME}/${IMAGE}:${VERSION}-edge" + # Push to Docker Hub + # docker push ${USERNAME}/${IMAGE}:${VERSION}-edge + # docker tag ${USERNAME}/${IMAGE}:${VERSION}-edge ${USERNAME}/${IMAGE}:latest + # docker push ${USERNAME}/${IMAGE}:latest + # Push to GitHub Packages + GITHUB_IMAGE="ghcr.io/${{ github.repository_owner }}/${IMAGE}" + docker tag ${USERNAME}/${IMAGE}:${VERSION}-edge ${GITHUB_IMAGE}:${VERSION}-edge + docker push ${GITHUB_IMAGE}:${VERSION}-edge + docker tag ${GITHUB_IMAGE}:${VERSION}-edge ${GITHUB_IMAGE}:latest + docker push ${GITHUB_IMAGE}:latest + + - name: Build and Push Docker Image (Stable Channel) + if: github.event.inputs.workflow_choice == 'stable' || github.event.inputs.workflow_choice == 'both' + env: + USERNAME: ${{ secrets.DOCKER_USERNAME }} + run: | + IMAGE="$(yq '.name' rockcraft.yaml)" + VERSION="$(yq '.version' rockcraft.yaml)" + ROCK="$(ls *.rock | tail -n 1)" + sudo rockcraft.skopeo --insecure-policy copy oci-archive:"${ROCK}" docker-daemon:"${USERNAME}/${IMAGE}:${VERSION}-stable" + # Push to Docker Hub + # docker push ${USERNAME}/${IMAGE}:${VERSION}-stable + # Push to GitHub Packages + GITHUB_IMAGE="ghcr.io/${{ github.repository_owner }}/${IMAGE}" + docker tag ${USERNAME}/${IMAGE}:${VERSION}-stable ${GITHUB_IMAGE}:${VERSION}-stable + docker push ${GITHUB_IMAGE}:${VERSION}-stable diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa9a08a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.rock +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index e285d5a..30a80c2 100644 --- a/README.md +++ b/README.md @@ -293,8 +293,93 @@ new rules). You can edit the `/var/snap/ps-printer-app/common/cups/snmp.conf` file for configuring SNMP network printer discovery. +## THE ROCK (OCI CONTAINER IMAGE) -## BUILDING WITHOUT SNAP +### Install from DockerHub + +#### Prerequisites + +**Docker Installed**: Ensure Docker is installed on your system. You can download it from the [official Docker website](https://www.docker.com/get-started). + +#### Step-by-Step Guide + +The first step is to pull the ps-printer-app Docker image from DockerHub: +``` +sudo docker pull openprinting/ps-printer-app +``` + +Then run the following Docker command to run the ps-printer-app image in a container: +```sh + sudo docker run --rm -d \ + --name ps-printer-app \ + --network host \ + -e PORT: \ + openprinting/ps-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. + +### Setting up and running a ps-printer-app container locally + +#### Prerequisites + +**Docker Installed**: Ensure Docker is installed on your system. You can download it from the [official Docker website](https://www.docker.com/get-started) or from the Snap Store: +``` +sudo snap install docker +``` + +**Rockcraft**: Rockcraft should be installed. You can install Rockcraft using the following command: +``` +sudo snap install rockcraft --classic +``` + +**Skopeo**: Skopeo should be installed to compile `*.rock` files into Docker images. It comes bundled with Rockcraft, so no separate installation is required. + +#### Step-by-Step Guide + +**Build the ps-printer-app Rock** + +The first step is to build the Rock from the `rockcraft.yaml`. This image will contain all the configurations and dependencies required to run ps-printer-app. + +Open your terminal and navigate to the directory containing your `rockcraft.yaml` (base directory of this package), then run the following command: +``` +rockcraft pack -v +``` + +**Compile to Docker image** + +Once the rock is built, you need to compile a docker image from it: +``` +sudo rockcraft.skopeo --insecure-policy copy oci-archive: docker-daemon:ps-printer-app:latest +``` + +**Run the ps-printer-app Docker Container** + +```sh + sudo docker run --rm -d \ + --name ps-printer-app \ + --network host \ + -e PORT: \ + ps-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. + +#### Setting up + +Enter the web interface: +``` +http://localhost:/ +``` +Use the web interface to add a printer. Supply a name, select the +discovered printer, then select automatic driver selection or choose a +make and model. Also set the installed accessories, loaded media and +the option defaults. Accessory configuration and option defaults can +also often get polled from the printer. + +## BUILDING WITHOUT PACKAGING OR INSTALLATION You can also do a "quick-and-dirty" build without snapping and without needing to install [PAPPL](https://www.msweet.org/pappl), @@ -371,7 +456,6 @@ Apple Raster, PWG Raster): TESTPAGE=/path/to/my/testpage/my_testpage.ps PPD_PATHS=/path/to/my/ppds:/my/second/place ./ps-printer-app server ``` - ## LEGAL STUFF The PostScript Printer Application is Copyright © 2020 by Till Kamppeter. diff --git a/snap/local/cups-dnssd-backend-socket-only.patch b/patches/cups-dnssd-backend-socket-only.patch similarity index 100% rename from snap/local/cups-dnssd-backend-socket-only.patch rename to patches/cups-dnssd-backend-socket-only.patch diff --git a/rockcraft.yaml b/rockcraft.yaml new file mode 100644 index 0000000..3189ab5 --- /dev/null +++ b/rockcraft.yaml @@ -0,0 +1,732 @@ +name: ps-printer-app +base: ubuntu@22.04 +version: '20240504-11' +summary: PostScript Printer Application +description: | + The PostScript Printer Application is a PAPPL (Printer Application Framework) based Printer Application + to support PostScript printers. + PAPPL is a simple C-based framework/library for developing + Printer Applications, which are the recommended replacement for + printer drivers. + +license: Apache-2.0 + +platforms: + arm64: + amd64: + armhf: + +# We use the upstream versioning of foomatic-db as it contains most of +# the manufacturer-supplied PostScript PPD files +adopt-info: foomatic-db + +# Only build on the architectures supported + +services: + dbus: + command: /scripts/run-dbus.sh + override: replace + on-failure: restart + startup: enabled + + ps-printer-app: + command: /scripts/start-server.sh + override: replace + on-failure: shutdown + startup: enabled + after: [dbus] + +parts: + pappl: + source: https://github.com/michaelrsweet/pappl + source-type: git + source-tag: 'v1.4.8' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '2' +# no-9x-revisions: true + plugin: autotools + override-build: | + set -eux + # Raise the supported number of vendor-specific options/attributes in + # PAPPL to 256, as the original 32 can be too small for some busy PPD + # files + perl -p -i -e 's/(define\s+PAPPL_MAX_VENDOR\s+)32/\1 256/' pappl/printer.h + # De-activate log-rotating. It does not work with the forked processes + # of the filters + perl -p -i -e 's/(system->logmaxsize\s+=).*/\1 0;/' pappl/system.c + # As we do not use PAPPL's own backends but the CUPS backends using the + # "cups" device scheme of pappl-retrofit, we let the manual "Network + # Printer" device on the "Add Printer" page of the web interface use a + # "cups:socket://..." URI instead of simply "socket://..." + perl -p -i -e 's/(httpAssembleURI\(.*?)"socket"(.*?\))/\1"cups:socket"\2/' pappl/system-webif.c + # PAPPL's build system does not insert the LDFLAGS when linking. + # Patching Makedefs.in to fix this + perl -p -i -e 's/^(\s*DSOFLAGS\s*=\s*\S*\s+)/\1\$\(LDFLAGS\) /' Makedefs.in + craftctl default + autotools-configure-parameters: + - --prefix=/usr + - --enable-libjpeg + - --enable-libpng + - --enable-libusb + - --with-dnssd=avahi + build-packages: + - libavahi-client-dev + - libgnutls28-dev + - libjpeg-dev + - libpam0g-dev + - libpng-dev + - libusb-1.0-0-dev + - zlib1g-dev + - perl-base + stage-packages: + # We have libavahi-client3 already in this Snap via the "cups" part, + # so here we do not stage it again to avoid any file clashes. + #- libavahi-client3 + - libpng16-16 + - libusb-1.0-0 + prime: + - -etc/fonts + - -var + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - -usr/include + - -usr/lib/pkgconfig + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + after: [cups] + + pappl-retrofit: + source: https://github.com/openprinting/pappl-retrofit + source-type: git + # source-tag: '1.0b2' + source-depth: 1 +# ext:updatesnap +# version-format: +# ignore: true +# format: '%V' + plugin: autotools + autotools-configure-parameters: + - --prefix=/usr + # To find the libraries built in this Snap + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + build-packages: + - autoconf + - automake + - libtool + - autotools-dev + - pkg-config + - perl-base + stage-packages: + - libusb-1.0-0 + organize: + usr/share/legacy-printer-app/testpage.pdf: usr/share/ps-printer-app/testpage.pdf + prime: + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - usr/share/ps-printer-app/testpage.pdf + - -var + - -usr/bin/legacy-printer-app + - -usr/include + - -usr/lib/pkgconfig + - -usr/lib/legacy-printer-app + - -usr/share/legacy-printer-app + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + after: [cups, pappl, libcupsfilters, libppd] + + qpdf: + source: https://github.com/qpdf/qpdf/ + source-type: git + source-tag: 'v11.9.1' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '12' +# no-9x-revisions: true + plugin: cmake + cmake-parameters: + - -DCMAKE_INSTALL_PREFIX=/ + - -DCMAKE_BUILD_RPATH_USE_ORIGIN=1 + - -DUSE_IMPLICIT_CRYPTO=0 + - -DREQUIRE_CRYPTO_GNUTLS=1 + - -DSHOW_FAILED_TEST_OUTPUT=1 + - -DCMAKE_BUILD_TYPE=RelWithDebInfo + - -DQTEST_COLOR=0 + build-packages: + - cmake + - g++ + - libjpeg-dev + - zlib1g-dev + - libgnutls28-dev + stage-packages: + - libjpeg-turbo8 + # stage: + # # The *.la file which gets installed by "make install" contains a + # # wrong prefix, breaking parts of this Snap which use this library + # - -usr/lib/lib*.la + prime: + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - -etc/fonts + - -var + - -usr/include + - -share/man + - -share/doc + - -share/lintian + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + - -usr/lib/libqpdf.a + - -usr/lib/libqpdf.la + - -usr/lib/pkgconfig + + ghostscript: + #source: https://git.ghostscript.com/ghostpdl.git + source: https://github.com/ArtifexSoftware/ghostpdl.git + source-type: git + source-tag: 'ghostpdl-10.05.0-test-base-001' + source-depth: 1 +# ext:updatesnap +# version-format: +# format: "ghostpdl-%M.%m.%R" +# lower-than: '11' +# no-9x-revisions: true + plugin: autotools + # We only need PostScript output, for converting PDF input + autotools-configure-parameters: + - --prefix=/usr + - --without-x + - --disable-gtk + - --with-drivers=ps2write + - --enable-freetype + - --without-tesseract + - --without-gpdl + - --without-pcl + - --without-xps + stage-packages: + - libpaper1 + - libfontconfig1 + - libfreetype6 + - libpng16-16 + prime: + - usr/bin/gs + - lib/*/lib*.so* + - usr/lib/*/lib*.so* + - usr/share/ghostscript + - -etc/fonts + - -var + - -usr/include + - -usr/lib/pkgconfig + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + after: [cups] + + cups: + source: https://github.com/OpenPrinting/cups + source-type: git + source-tag: 'v2.4.11' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '3' +# no-9x-revisions: true + plugin: autotools + # We only need libcups (with headers, ...) and the backends + override-build: | + set -eux + patch -p1 < $CRAFT_PROJECT_DIR/patches/cups-dnssd-backend-socket-only.patch + # We use "--with-tls=gnutls" here, as current CUPS defaults to SSL here + # and this is buggy, causing a segfault when serving out a HTTPS web + # interface page. + ./configure --with-tls=gnutls + cd cups + make + cd .. + cd backend + # Have USB quirk ffiles in user-modifiable space for debugging + perl -p -i -e 's/"CUPS_DATADIR"/"USB_QUIRK_DIR"/' usb-libusb.c + make snmp dnssd socket ipp ipps lpd usb + cd .. + mkdir -p $CRAFT_PART_INSTALL/usr/lib + cp cups/libcups.a $CRAFT_PART_INSTALL/usr/lib/ + cp -P cups/libcups.so* $CRAFT_PART_INSTALL/usr/lib/ + mkdir -p $CRAFT_PART_INSTALL/usr/include/cups + cp cups/*.h $CRAFT_PART_INSTALL/usr/include/cups/ + mkdir -p $CRAFT_PART_INSTALL/usr/bin + cp cups-config $CRAFT_PART_INSTALL/usr/bin/ + mkdir -p $CRAFT_PART_INSTALL/usr/lib/ps-printer-app/backend/ + ( cd backend; \ + cp snmp dnssd socket ipp ipps lpd usb org.cups.usb-quirks $CRAFT_PART_INSTALL/usr/lib/ps-printer-app/backend/ \ + ) + cp conf/snmp.conf $CRAFT_PART_INSTALL/usr/lib/ps-printer-app/backend/ + #craftctl default + build-packages: + - patch + - gettext + - autoconf + - automake + - libtool + - autotools-dev + - pkg-config + - libavahi-client-dev + - libavahi-common-dev + - libavahi-compat-libdnssd-dev + - libdbus-1-dev + - libfontconfig1-dev + - libfreetype6-dev + - libgnutls28-dev + - libjpeg-dev + - libldap2-dev + - libkrb5-dev + - libpam0g-dev + - libpaper-dev + - libpng-dev + - libusb-1.0-0-dev + - perl-base + stage-packages: + - libusb-1.0-0 + - libavahi-common3 + - libavahi-client3 + - libicu70 + prime: + - -etc/fonts + - -var + - -usr/include + - -usr/lib/pkgconfig + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - usr/lib/ps-printer-app/backend/* + # Reported unused by snapcraft linter + - -usr/lib/*/libdconf.* + - -usr/lib/*/libicuio.* + - -usr/lib/*/libicutest.* + - -usr/lib/*/libicutu.* + - -usr/lib/*/libicuuc.* + - -usr/lib/*/libicui18n.* + + libcupsfilters: + source: https://github.com/OpenPrinting/libcupsfilters + source-type: git + source-tag: '2.1.0' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '3' +# no-9x-revisions: true + plugin: autotools + # We only need libcupsfilters itself. so we simply do not prime the + # auxiliary files (/usr/share) + autotools-configure-parameters: + - --prefix=/usr + - --disable-avahi + - --disable-mutool + # To find the libraries built in this Snap + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + build-packages: + - gettext + - autoconf + - automake + - autotools-dev + - pkg-config + - g++ + - sharutils + - liblcms2-dev + - libpoppler-cpp-dev + - libpng-dev + - libjpeg-dev + - libtiff5-dev + - zlib1g-dev + - libfontconfig1-dev + - libdbus-1-dev + - libexif-dev + stage-packages: + - libpoppler-cpp0v5 + - libjbig0 + - liblcms2-2 + - libnspr4 + - libnss3 + - libopenjp2-7 + - libpoppler118 + - libtiff5 + - libwebp7 + - libexif12 + stage: + # The *.la file which gets installed by "make install" contains a + # wrong prefix, breaking parts of this Snap which use this library + - -usr/lib/lib*.la + prime: + - -etc + - -var + - -usr/include + - -usr/lib/pkgconfig + - usr/share/cups + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - usr/lib/*/nss + # Reported unused by snapcraft linter + - -usr/lib/*/libssl3.* + after: [cups, qpdf, ghostscript] + + libppd: + source: https://github.com/OpenPrinting/libppd + source-type: git + source-tag: '2.1.0' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '3' +# no-9x-revisions: true + plugin: autotools + # We only need libppd itself, so we also do not prime the auxiliary files + # here. + autotools-configure-parameters: + - --prefix=/usr + - --disable-mutool + - --disable-pdftocairo + - --disable-acroread + # To find the libraries built in this Snap + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + build-packages: + - gettext + - autoconf + - automake + - autotools-dev + - pkg-config + - g++ + - sharutils + - poppler-utils + prime: + - -etc + - -var + - -usr/include + - -usr/lib/pkgconfig + - -usr/share/ppdc + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - usr/lib/*/nss + after: [cups, ghostscript, libcupsfilters] + + cups-filters: + source: https://github.com/OpenPrinting/cups-filters + source-type: git + source-tag: '2.0.1' + source-depth: 1 +# ext:updatesnap +# version-format: +# lower-than: '3' +# no-9x-revisions: true + plugin: autotools + # To find the libraries built in this Snap + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + # We only need pdftops and foomatic-rip (for PIN-protected printing + # on Ricoh and OEM) + override-build: | + set -eux + ./autogen.sh + ./configure --disable-mutool + make foomatic-rip + make pdftops + mkdir -p $CRAFT_PART_INSTALL + cp foomatic-rip $CRAFT_PART_INSTALL + cp pdftops $CRAFT_PART_INSTALL + #craftctl default + build-packages: + - gettext + - autoconf + - automake + - autotools-dev + - pkg-config + - g++ + - sharutils + stage-packages: + - poppler-utils + organize: + foomatic-rip: usr/lib/ps-printer-app/filter/foomatic-rip + pdftops: usr/lib/ps-printer-app/filter/pdftops + prime: + - -etc/fonts + - -var + - -usr/include + - -usr/lib/pkgconfig + - -usr/share/fonts + - -usr/share/man + - -usr/share/doc + - -usr/share/doc-base + - -usr/share/lintian + - lib/*/lib*.so* + - usr/lib/lib*.so* + - usr/lib/*/lib*.so* + - usr/lib/*/nss + - usr/bin/pdftops + - usr/lib/ps-printer-app + # Reported unused by snapcraft linter + - -usr/lib/*/libcairo.* + - -usr/lib/*/libssl3.* + - -usr/lib/*/libX11.* + - -usr/lib/*/libXau.* + - -usr/lib/*/libXdmcp.* + - -usr/lib/*/libXext.* + - -usr/lib/*/libXrender.* + - -usr/lib/*/libpixman-1.* + - -usr/lib/*/libxcb.* + - -usr/lib/*/libxcb-render.* + - -usr/lib/*/libxcb-shm.* + after: [cups, ghostscript, libcupsfilters, libppd] + + pyppd: + source: https://github.com/OpenPrinting/pyppd + source-type: git + source-tag: 'release-1-1-0' + source-depth: 1 + build-packages: + - python3.10 + stage-packages: + - python3.10 +# ext:updatesnap +# version-format: +# format: "release-%M-%m-%R" +# lower-than: '2' +# no-9x-revisions: true + plugin: python + override-prime: "" + + foomatic-db: + source: https://github.com/OpenPrinting/foomatic-db + source-type: git + source-tag: '20240504' + source-depth: 1 +# ext:updatesnap +# version-format: +# format: '%V' + plugin: nil + override-build: | + set -eux + # Remove non-PostScript manufacturer PPD files + rm -rf db/source/PPD/*/PDF + rm -rf db/source/PPD/*/PXL + rm -rf db/source/PPD/*/PCL5 + # Remove executable bits from PPD files + find db/source/PPD -executable -type f -print0 | xargs -0 chmod -x || : + # Remove non-PPD files from PPD file directories + find db/source/PPD -type f \! -name '*.ppd' -print0 | xargs -0 rm || : + # Correct common errors in PPD files: "*CloseUI" without ':' and + # "*1284DeviceId" instead of "*1284DeviceID" + for f in `find db/source/PPD -name '*.ppd'`; do perl -p -i -e 's/^\*CloseUI(\s+)/*CloseUI:\1/' $f; perl -p -i -e 's/\*1284DeviceId/*1284DeviceID/' $f; done + # Compress the PostScript PPDs in a self-extracting archive + pyppd -v -o $CRAFT_PART_INSTALL/foomatic-ps-ppds db/source/PPD + craftctl default + build-packages: + - perl-base + - python3 + - xz-utils + - curl + stage-packages: + - python3 + - xz-utils + - pyppd + organize: + foomatic-ps-ppds: usr/share/ppd/foomatic-ps-ppds + stage: + - usr/bin + - usr/share/ppd + prime: + - usr/bin/xz + - -usr/bin/pdb3 + - -usr/bin/pydoc3 + - -usr/bin/pygettext3 + - usr/share/ppd + after: [pyppd] + + hplip: + # We need only the PostScript printer PPD files and the hpps + # filter executable (for support for PIN-secured printing). We + # clean up the PPDs from some common errors and as the hpps + # executable is very simple, we do not run "./configure; make; + # make install" but call gcc directly instead. + # + # We use the Debian package source instead of the upstream source code + # of HPLIP as the Debian package has ~80 patches fixing bugs which are + # reported upstream but the patches not adopted upstream. + # This way we should have the same user experience in terms of reliability + # and quality as with the Debian package. + # Note that the repository has all patches already applied, so we do + # not need to apply them before building. + # Debian source + source: https://salsa.debian.org/printing-team/hplip.v2.git + source-type: git + source-tag: 'debian/3.22.10+dfsg0-5' + source-depth: 1 +# ext:updatesnap +# version-format: +# format: 'debian/%V' + # Upstream source + #source: https://sourceforge.net/projects/hplip/files/hplip/3.22.10/hplip-3.22.10.tar.gz + plugin: nil + override-build: | + set -eux + cd prnt/hpps + touch config.h + gcc -o hpps *.c -I. -I$CRAFT_STAGE/usr/include/ -L$CRAFT_STAGE/usr/lib/ -lcups + rm config.h + cd ../.. + mkdir -p $CRAFT_PART_INSTALL + cp prnt/hpps/hpps $CRAFT_PART_INSTALL + # Remove executable bits from PPD files + find prnt/ps -executable -type f -print0 | xargs -0 chmod -x || : + # Remove non-PPD files from PPD file directories + find prnt/ps -type f \! -name '*.ppd*' -print0 | xargs -0 rm || : + # Unzip the PPD files (for upstream source) + # find prnt/ps -type f -name '*.ppd.gz' -print0 | xargs -0 gunzip || : + # Correct common errors in PPD files: "*CloseUI" without ':' and + # "*1284DeviceId" instead of "*1284DeviceID" + for f in `find prnt/ps -name '*.ppd'`; do perl -p -i -e 's/^\*CloseUI(\s+)/*CloseUI:\1/' $f; perl -p -i -e 's/\*1284DeviceId/*1284DeviceID/' $f; done + # Compress the PostScript PPDs in a self-extracting archive + pyppd -v -o $CRAFT_PART_INSTALL/hplip-ps-ppds prnt/ps + craftctl default + build-packages: + - perl-base + - python3 + - xz-utils + stage-packages: + - python3 + - xz-utils + - pyppd + organize: + hplip-ps-ppds: usr/share/ppd/hplip-ps-ppds + hpps: usr/lib/ps-printer-app/filter/hpps + stage: + - usr/bin + - usr/share/ppd + - usr/lib/ps-printer-app + prime: + - usr/bin/xz + - -usr/bin/pdb3 + - -usr/bin/pydoc3 + - -usr/bin/pygettext3 + - usr/share/ppd + - usr/lib/ps-printer-app + after: [cups, pyppd] + + ps-printer-app: + plugin: make + source: . + make-parameters: + - LDFLAGS="$LDFLAGS -ljpeg" + - VERSION="$VERSION" + # To find the libraries built in this Snap + build-environment: + - LD_LIBRARY_PATH: "${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$CRAFT_STAGE/usr/lib" + # To improve convenience for developers (and everyone who wants to + # build from source), we do a "make clean" before "make" here, + # because if we had done "make" off-Snap, directly in the source + # tree and afterwards build the Snap with snapcraft, the build + # sucks in our local binary of ps-printer-app instead of + # compiling its own one in the Snap harness with the appropriate + # libraries, ending up with the Snap containing an executable + # which does not work inside the Snap. The "make clean" removes + # any accidentally grabbed binary. + # + # We need to directly call the "make" and "make install" commands + # here as we cannot inject an environment variable into the default + # build process ("craftctl default") and we also cannot call + # "craftctl get version" in the lines of "make-parameters:" or + # "build-environment:". This way we get the version number of our + # Snap (which is extracted from the foomatic-db upstream source) + # into the ps-printer-app executable. + override-build: | + set -eux + make clean + VERSION="`craftctl get version`" + make -j"8" LDFLAGS="$LDFLAGS -ljpeg" VERSION="$VERSION" + make -j"8" install LDFLAGS="$LDFLAGS -ljpeg" VERSION="$VERSION" DESTDIR="$CRAFT_PART_INSTALL" + #craftctl default + build-packages: + - libusb-1.0-0-dev + stage-packages: + - libusb-1.0-0 + - libjbig0 + - liblcms2-2 + - libtiff5 + - libwebp7 + stage: + - -usr/lib/ps-printer-app + prime: + - usr/bin/ps-printer-app + - lib/*/lib*.so* + - usr/lib/*/lib*.so* + - usr/share/ps-printer-app + - usr/share/ppd + - -var + - -usr/share/man + after: [pappl-retrofit, pappl, libcupsfilters, libppd, cups-filters, foomatic-db, hplip] + + avahi-daemon: + plugin: nil + overlay-packages: + - avahi-daemon + - avahi-utils + - libnss-mdns + - mdns-scan + - dbus + - python3 + + utils: + plugin: nil + overlay-packages: + - python3 + + scripts: + plugin: dump + source: scripts/ + organize: + run-dbus.sh: /scripts/run-dbus.sh + start-server.sh: /scripts/start-server.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 diff --git a/scripts/run-dbus.sh b/scripts/run-dbus.sh new file mode 100644 index 0000000..2fa8c0e --- /dev/null +++ b/scripts/run-dbus.sh @@ -0,0 +1,30 @@ +#!/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 +service dbus start +# Check the status of the dbus service +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 new file mode 100644 index 0000000..f21ae40 --- /dev/null +++ b/scripts/start-server.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -eux + +# Precheck: Ensure PORT is a number or undefined +if [ -n "${PORT:-}" ]; then + if ! echo "$PORT" | grep -Eq '^[0-9]+$'; then + echo "Error: PORT must be a valid number" >&2 + exit 1 + fi +fi + +ps-printer-app -o log-file=/ps-printer-app.log ${PORT:+-o server-port=$PORT} server diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 96f8b2a..226e29b 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -259,7 +259,7 @@ parts: # We only need libcups (with headers, ...) and the backends override-build: | set -eux - patch -p1 < $CRAFT_PROJECT_DIR/snap/local/cups-dnssd-backend-socket-only.patch + patch -p1 < $CRAFT_PROJECT_DIR/patches/cups-dnssd-backend-socket-only.patch # We use "--with-tls=gnutls" here, as current CUPS defaults to SSL here # and this is buggy, causing a segfault when serving out a HTTPS web # interface page.