From 10fbb6fc0754f46839b916e3902cf412f97f97ea Mon Sep 17 00:00:00 2001 From: NetworK Date: Fri, 17 Mar 2023 15:28:22 +0200 Subject: [PATCH] Ubuntu base. Add printer drivers. DSM7 --- Dockerfile | 47 +++++++++++++++-------- README.md | 68 ++++++++++++++++++++++------------ buildspec-manifest.yml | 35 +++++++++++++++++ buildspec.yml | 26 +++++++++++++ docker-compose.yml | 15 ++++++++ root/root/airprint-generate.py | 22 ++++++++--- root/root/printer-update.sh | 11 +++++- root/root/run_cups.sh | 26 ++++++++++++- version.txt | 1 + 9 files changed, 203 insertions(+), 48 deletions(-) create mode 100644 buildspec-manifest.yml create mode 100644 buildspec.yml create mode 100644 docker-compose.yml create mode 100644 version.txt diff --git a/Dockerfile b/Dockerfile index 97d0be4..c30d6ee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,33 @@ -FROM ubuntu:zesty +FROM ubuntu:jammy +LABEL maintainer="znetwork@me.com" +LABEL version="0.3" +LABEL description="AIRPRINT FROM SYNOLOGY DSM 7 (HP, SAMSUNG, ETC)" -# Add repos -RUN echo 'deb http://us.archive.ubuntu.com/ubuntu/ zesty multiverse' >> /etc/apt/sources.list.d/multiverse.list && \ - echo 'deb-src http://us.archive.ubuntu.com/ubuntu/ zesty multiverse' >> /etc/apt/sources.list.d/multiverse.list && \ - echo 'deb http://us.archive.ubuntu.com/ubuntu/ zesty-updates multiverse' >> /etc/apt/sources.list.d/multiverse.list && \ - echo 'deb-src http://us.archive.ubuntu.com/ubuntu/ zesty-updates multiverse' >> /etc/apt/sources.list.d/multiverse.list && \ - echo 'deb http://archive.ubuntu.com/ubuntu/ zesty-security multiverse' >> /etc/apt/sources.list.d/multiverse.list && \ - echo 'deb-src http://archive.ubuntu.com/ubuntu/ zesty-security multiverse' >> /etc/apt/sources.list.d/multiverse.list - -# Install the packages we need. Avahi will be included RUN apt-get update && apt-get install -y \ + locales \ brother-lpr-drivers-extra brother-cups-wrapper-extra \ + printer-driver-splix \ + printer-driver-gutenprint \ + gutenprint-doc \ + gutenprint-locales \ + libgutenprint9 \ + libgutenprint-doc \ + ghostscript \ + hplip \ cups \ cups-pdf \ + cups-client \ + cups-filters \ inotify-tools \ - python-cups \ -&& rm -rf /var/lib/apt/lists/* + avahi-daemon \ + avahi-discover \ + python3 \ + python3-dev \ + python3-pip \ + python3-cups \ + wget \ + rsync \ + && rm -rf /var/lib/apt/lists/* # This will use port 631 EXPOSE 631 @@ -27,14 +39,17 @@ VOLUME /services # Add scripts ADD root / RUN chmod +x /root/* + +#Run Script CMD ["/root/run_cups.sh"] # Baked-in config file changes -RUN sed -i 's/Listen localhost:631/Listen 0.0.0.0:631/' /etc/cups/cupsd.conf && \ - sed -i 's/Browsing Off/Browsing On/' /etc/cups/cupsd.conf && \ +RUN sed -i 's/Listen localhost:631/Listen *:631/' /etc/cups/cupsd.conf && \ + sed -i 's/Browsing No/Browsing On/' /etc/cups/cupsd.conf && \ sed -i 's//\n Allow All/' /etc/cups/cupsd.conf && \ sed -i 's//\n Allow All\n Require user @SYSTEM/' /etc/cups/cupsd.conf && \ sed -i 's//\n Allow All/' /etc/cups/cupsd.conf && \ + sed -i 's/.*enable\-dbus=.*/enable\-dbus\=no/' /etc/avahi/avahi-daemon.conf && \ echo "ServerAlias *" >> /etc/cups/cupsd.conf && \ - echo "DefaultEncryption Never" >> /etc/cups/cupsd.conf - + echo "DefaultEncryption Never" >> /etc/cups/cupsd.conf && \ + echo "BrowseWebIF Yes" >> /etc/cups/cupsd.conf diff --git a/README.md b/README.md index 5fc7487..cf3a780 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,56 @@ -# quadportnick/cups-airprint +# znetwork/cups-avahi-airprint [docker-image](https://hub.docker.com/r/znetwork/synology-airprint) -This Ubuntu-based Docker image runs a CUPS instance that is meant as an AirPrint relay for printers that are already on the network but not AirPrint capable. I'm using it on a Synology NAS because the built in server doesn't work properly with my printers. The local Avahi will be utilized for advertising the printers on the network. +# Working on Synology DSM 7 (!!!) and AMD64 -This is also an excuse to dip my toes into GitHub/Docker more, so why not? Hopefully someone else finds this useful. +Fork from [quadportnick/docker-cups-airprint](https://github.com/quadportnick/docker-cups-airprint) and [chuckcharlie/docker-cups-airprint](https://github.com/chuckcharlie/docker-cups-airprint) -Update: Clearly I haven't been maintaining this as I no longer use Synology for printing -- Recommend trying this fork instead: https://github.com/chuckcharlie/cups-avahi-airprint +This Ubuntu-based Docker image runs a CUPS instance that is meant as an AirPrint relay for printers that are already on the network but not AirPrint capable. +* `Included drivers HP, Samsung, Canon, Xerox, etc.` -## Prereqs -* No other printers should be shared under Control Panel>External Devices>Printer so that the DSM's CUPS is not running. -* `Enable Bonjour service discovery` needs to be marked under Control Panel>Network>DSM Settings +## Easy run command (use username and password: admin/admin): +```docker run --name airprint --restart unless-stopped --net host znetwork/synology-airprint:latest``` -## Configuration +### Before run docker conteiner on DSM7 Synology run this commands in ssh terminal: +* `sudo synosystemctl stop cupsd` +* `sudo synosystemctl stop cups-lpd` +* `sudo synosystemctl stop cups-service-handler` +* `sudo synosystemctl disable cupsd` +* `sudo synosystemctl disable cups-lpd` +* `sudo synosystemctl disable cups-service-handler` + +### Add and setup printer: +* CUPS will be configurable at http://[host ip]:631 using the CUPSADMIN/CUPSPASSWORD. +* Make sure you select `Share This Printer` when configuring the printer in CUPS. +* ***After configuring your printer, you need to close the web browser for at least 60 seconds. CUPS will not write the config files until it detects the connection is closed for as long as a minute.*** + +### After setup and testing AirPrint, you can back run on services. (maybe you will need restart nas) +* `sudo synosystemctl start cupsd` +* `sudo synosystemctl start cups-lpd` +* `sudo synosystemctl start cups-service-handler` +* `sudo synosystemctl anable cupsd` +* `sudo synosystemctl anable cups-lpd` +* `sudo synosystemctl anable cups-service-handler` + +## Manual Configuration ### Volumes: * `/config`: where the persistent printer configs will be stored * `/services`: where the Avahi service files will be generated ### Variables: -* `CUPSADMIN`: the CUPS admin user you want created -* `CUPSPASSWORD`: the password for the CUPS admin user - -### Ports: -* `631`: the TCP port for CUPS must be exposed - -## Using -CUPS will be configurable at http://[diskstation]:631 using the CUPSADMIN/CUPSPASSWORD when you do something administrative. - -If the `/services` volume isn't mapping to `/etc/avahi/services` then you will have to manually copy the .service files to that path at the command line. - -## Notes -* CUPS doesn't write out `printers.conf` immediately when making changes even though they're live in CUPS. Therefore it will take a few moments before the services files update -* Don't stop the container immediately if you intend to have a persistent configuration for this same reason -  +* `CUPSADMIN`: the CUPS admin user you want created - default is `admin` if unspecified +* `CUPSPASSWORD`: the password for the CUPS admin user - default is `admin` username if unspecified + +### Ports/Network: +* Must be run on host network. This is required to support multicasting which is needed for Airprint. + + +### Example run env command: +``` +docker run --name cups --restart unless-stopped --net host\ + -v :/services \ + -v :/config \ + -e CUPSADMIN="" \ + -e CUPSPASSWORD="" \ + znetwork/cups-avahi-airprint:latest +``` \ No newline at end of file diff --git a/buildspec-manifest.yml b/buildspec-manifest.yml new file mode 100644 index 0000000..8077aaa --- /dev/null +++ b/buildspec-manifest.yml @@ -0,0 +1,35 @@ +version: 0.2 +#Buildspec file for AWS Codebuild +#Generates multi-arch manifest + +env: + secrets-manager: + DOCKERHUB_PASS: "/dockerhub/credentials:password" + DOCKERHUB_USERNAME: "/dockerhub/credentials:username" +phases: + install: + commands: + - yum update -y + pre_build: + commands: + - echo Logging in to DOCKER... + - docker login --username $DOCKERHUB_USERNAME --password $DOCKERHUB_PASS + build: + commands: + - echo Build started on `date` + - echo Building the Docker manifest... + - VERSION=$(cat version.txt) + - export DOCKER_CLI_EXPERIMENTAL=enabled + - docker manifest create $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-arm64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-amd64 + - docker manifest annotate --arch arm64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-arm64 + - docker manifest annotate --arch amd64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-amd64 + - docker manifest create $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:latest $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-arm64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-amd64 + - docker manifest annotate --arch arm64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-arm64 + - docker manifest annotate --arch amd64 $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-amd64 + + post_build: + commands: + - echo Build completed on `date` + - echo Pushing the Docker image... + - docker manifest push $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION + - docker manifest push $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:latest diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 0000000..55d63cf --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,26 @@ +version: 0.2 +#Generic buildspec file for AWS Codebuild +#Works for both ARM and AMD builds +env: + secrets-manager: + DOCKERHUB_PASS: "/dockerhub/credentials:password" + DOCKERHUB_USERNAME: "/dockerhub/credentials:username" +phases: + install: + commands: + - yum update -y + pre_build: + commands: + - echo Logging in to DOCKER... + - docker login --username $DOCKERHUB_USERNAME --password $DOCKERHUB_PASS + build: + commands: + - echo Build started on `date` + - echo Building the Docker image... + - VERSION=$(cat version.txt) + - docker build -t $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$VERSION-$ARCH -t $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME:$IMAGE_TAG-$ARCH . + post_build: + commands: + - echo Build completed on `date` + - echo Pushing the Docker image... + - docker push $DOCKERHUB_USERNAME/$IMAGE_REPO_NAME --all-tags diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..02b4e6d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.5' + +services: + airprint: + container_name: airprint + image: znetwork/synology-airprint:0.3 + build: . + restart: always + network_mode: "host" + environment: + CUPSADMIN: admin + CUPSPASSWORD: admin + volumes: + - "./services:/services" + - "./config:/config" diff --git a/root/root/airprint-generate.py b/root/root/airprint-generate.py index 989f63b..146e3f2 100644 --- a/root/root/airprint-generate.py +++ b/root/root/airprint-generate.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ Copyright (c) 2010 Timothy J Fontaine @@ -22,9 +22,10 @@ THE SOFTWARE. """ -import cups, os, optparse, re, urlparse +import cups, os, optparse, re +import urllib.parse as urlparse import os.path -from StringIO import StringIO +from io import StringIO from xml.dom.minidom import parseString from xml.dom import minidom @@ -43,7 +44,8 @@ from elementtree import Element, ElementTree, tostring etree = None except: - raise 'Failed to find python libxml or elementtree, please install one of those or use python >= 2.5' + print('Failed to find python libxml or elementtree, please install one of those or use python >= 2.5') + raise XML_TEMPLATE = """ @@ -121,7 +123,7 @@ def generate(self): printers = conn.getPrinters() - for p, v in printers.items(): + for p, v in list(printers.items()): if v['printer-is-shared']: attrs = conn.getPrinterAttributes(p) uri = urlparse.urlparse(v['printer-uri-supported']) @@ -179,6 +181,16 @@ def generate(self): ptype.text = 'printer-type=%s' % (hex(v['printer-type'])) service.append(ptype) + if attrs['color-supported']: + color = Element('txt-record') + color.text = 'Color=T' + service.append(color) + + if attrs['media-default'] == 'iso_a4_210x297mm': + max_paper = Element('txt-record') + max_paper.text = 'PaperMax=legal-A4' + service.append(max_paper) + pdl = Element('txt-record') fmts = [] defer = [] diff --git a/root/root/printer-update.sh b/root/root/printer-update.sh index 4bbf1e2..649f7bd 100644 --- a/root/root/printer-update.sh +++ b/root/root/printer-update.sh @@ -1,9 +1,16 @@ -#!/bin/bash -inotifywait -m -e close_write,moved_to,create /etc/cups | +#!/bin/sh +/usr/bin/inotifywait -m -e close_write,moved_to,create /etc/cups | while read -r directory events filename; do if [ "$filename" = "printers.conf" ]; then rm -rf /services/AirPrint-*.service /root/airprint-generate.py -d /services cp /etc/cups/printers.conf /config/printers.conf + rsync -avh /services/ /etc/avahi/services/ + chmod 755 /var/cache/cups + rm -rf /var/cache/cups/* + fi + if [ "$filename" = "cupsd.conf" ]; then + cp /etc/cups/cupsd.conf /config/cupsd.conf fi done +#/usr/sbin/lpinfo --include-schemes dnssd -v \ No newline at end of file diff --git a/root/root/run_cups.sh b/root/root/run_cups.sh index cd1e172..f76f8d1 100644 --- a/root/root/run_cups.sh +++ b/root/root/run_cups.sh @@ -2,19 +2,41 @@ set -e set -x +# Is CUPSADMIN set? If not, set to default +if [ -z "$CUPSADMIN" ]; then + CUPSADMIN="admin" +fi + +# Is CUPSPASSWORD set? If not, set to $CUPSADMIN +if [ -z "$CUPSPASSWORD" ]; then + CUPSPASSWORD=$CUPSADMIN +fi + if [ $(grep -ci $CUPSADMIN /etc/shadow) -eq 0 ]; then - useradd -r -G lpadmin -M $CUPSADMIN + #adduser -S -G lpadmin --no-create-home $CUPSADMIN + useradd -r -G lpadmin -M $CUPSADMIN fi echo $CUPSADMIN:$CUPSPASSWORD | chpasswd mkdir -p /config/ppd mkdir -p /services +rm -rf /etc/avahi/services/* rm -rf /etc/cups/ppd ln -s /config/ppd /etc/cups -if [ ! -f /config/printers.conf ]; then + +if [ `ls -l /services/*.service 2>/dev/null | wc -l` -gt 0 ]; then + cp -f /services/*.service /etc/avahi/services/ +fi + +if [ `ls -l /config/printers.conf 2>/dev/null | wc -l` -eq 0 ]; then touch /config/printers.conf fi cp /config/printers.conf /etc/cups/printers.conf +if [ `ls -l /config/cupsd.conf 2>/dev/null | wc -l` -ne 0 ]; then + cp /config/cupsd.conf /etc/cups/cupsd.conf +fi + +/usr/sbin/avahi-daemon --daemonize /root/printer-update.sh & exec /usr/sbin/cupsd -f diff --git a/version.txt b/version.txt new file mode 100644 index 0000000..0d91a54 --- /dev/null +++ b/version.txt @@ -0,0 +1 @@ +0.3.0