diff --git a/cups/CHANGELOG.md b/cups/CHANGELOG.md index a73a0c8..9be8f58 100644 --- a/cups/CHANGELOG.md +++ b/cups/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 3.0.0 -- 16.11.2023 + +- Rewrite based on the work of [zajac-grzegorz](https://github.com/zajac-grzegorz/homeassistant-addon-cups-airprint) - thanks for letting me steal it ❤️ + ## 2.2.0 -- 09.06.2023 - Try to fix startup issues with OS 10* / \_Docker v23* - - see [#152](https://github.com/MaxWinterstein/homeassistant-addons/issues/152) for more diff --git a/cups/Dockerfile b/cups/Dockerfile index ff28d53..22bdd70 100644 --- a/cups/Dockerfile +++ b/cups/Dockerfile @@ -1,37 +1,51 @@ ARG BUILD_FROM FROM $BUILD_FROM -LABEL io.hass.version="1" io.hass.type="addon" io.hass.arch="armhf|aarch64|i386|amd64" +LABEL io.hass.version="1.0" io.hass.type="addon" io.hass.arch="aarch64|amd64" + +# Set shell +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update \ && apt-get install -y --no-install-recommends \ + sudo \ + locales \ cups \ avahi-daemon \ libnss-mdns \ dbus \ colord \ - printer-driver-all-enforce \ + printer-driver-all \ + printer-driver-gutenprint \ openprinting-ppds \ hpijs-ppds \ hp-ppd \ hplip \ + printer-driver-foo2zjs \ + cups-pdf \ gnupg2 \ lsb-release \ nano \ samba \ bash-completion \ - nginx \ + procps \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* COPY rootfs / -# Corrects permissions for s6 v3 -RUN if [ -d /etc/cont-init.d ]; then chmod -R 755 /etc/cont-init.d; fi && \ - if [ -d /etc/services.d ]; then chmod -R 755 /etc/services.d; fi && \ - if [ -f /entrypoint.sh ]; then chmod 755 /entrypoint.sh; fi +# Add user and disable sudo password checking +RUN useradd \ + --groups=sudo,lp,lpadmin \ + --create-home \ + --home-dir=/home/print \ + --shell=/bin/bash \ + --password=$(mkpasswd print) \ + print \ +&& sed -i '/%sudo[[:space:]]/ s/ALL[[:space:]]*$/NOPASSWD:ALL/' /etc/sudoers -EXPOSE 631 445 137 139 +EXPOSE 631 RUN chmod a+x /run.sh + CMD ["/run.sh"] diff --git a/cups/README.md b/cups/README.md index 254dfdc..4017708 100644 --- a/cups/README.md +++ b/cups/README.md @@ -1,12 +1,17 @@ -# Home Assistant Add-on: CUPS Printer server +**Based on the work of [zajac-grzegorz](https://github.com/zajac-grzegorz/homeassistant-addon-cups-airprint) - thanks for letting me steal it ❤️** -Buy Me a Coffee at ko-fi.com +--- -## Credits +Original README.md -This Add-On is based on the work of https://github.com/Luk164/addon-repository - and just slighty adjusted to make it work. Thanks <3 +# homeassistant addon cups airprint -## Known Issues 🚨 +CUPS addon with working Avahi in reflector mode -- mDNS is not working, therefore e.g. printeres are not announced via Avahi / Bonjour - see [#128](https://github.com/MaxWinterstein/homeassistant-addons/issues/128) -- Ingress is not working, so I disabled it for now. Please access the Webinterface via port 631, e.g. https://192.168.1.2:631 - see [#129](https://github.com/MaxWinterstein/homeassistant-addons/issues/129) +Tested with Home Assistant version **2023.9** + +CUPS administrator login: **print**, password: **print** (can be changed in the Dockerfile) + +Configuration data is stored in **/data/cups** folder + +[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fzajac-grzegorz%2Fhomeassistant-addon-cups-airprint) diff --git a/cups/build.json b/cups/build.json index 8084aac..fe51cc2 100644 --- a/cups/build.json +++ b/cups/build.json @@ -1,6 +1,5 @@ { "build_from": { - "armv7": "ghcr.io/home-assistant/armv7-base-debian:bullseye", "aarch64": "ghcr.io/home-assistant/aarch64-base-debian:bullseye", "amd64": "ghcr.io/home-assistant/amd64-base-debian:bullseye" } diff --git a/cups/config.yaml b/cups/config.yaml index 97cf527..0336c25 100644 --- a/cups/config.yaml +++ b/cups/config.yaml @@ -1,19 +1,16 @@ ---- -name: CUPS Print Server -version: "2.2.0" -stage: experimental -slug: cups -image: ghcr.io/maxwinterstein/homeassistant-addon-cups-{arch} -description: A CUPS print server with Avahi installed +name: CUPS +version: 3.0.0 url: https://github.com/MaxWinterstein/homeassistant-addons/ +image: ghcr.io/maxwinterstein/homeassistant-addon-cups-{arch} +slug: cups +description: A CUPS print server with working AirPrint arch: - amd64 - - armv7 - aarch64 usb: true init: false homeassistant_api: true -# host_network: true +host_network: true ports: 631/tcp: 631 631/udp: 631 @@ -22,15 +19,5 @@ ports_description: 631/udp: For other devices on the local network to print to this server # ingress: false map: - - ssl -options: - ssl: true - certfile: fullchain.pem - keyfile: privkey.pem - require_ssl: true -schema: - ssl: bool - cafile: str? - certfile: str - keyfile: str - require_ssl: bool + - config:rw +stage: experimental diff --git a/cups/rootfs/usr/share/avahi-daemon.conf.tempio b/cups/rootfs/etc/avahi/avahi-daemon.conf similarity index 92% rename from cups/rootfs/usr/share/avahi-daemon.conf.tempio rename to cups/rootfs/etc/avahi/avahi-daemon.conf index d668620..58b6729 100644 --- a/cups/rootfs/usr/share/avahi-daemon.conf.tempio +++ b/cups/rootfs/etc/avahi/avahi-daemon.conf @@ -19,7 +19,7 @@ # file! [server] -host-name={{.hostname}} +#host-name=foo #domain-name=local #browse-domains=0pointer.de, zeroconf.org use-ipv4=yes @@ -45,18 +45,19 @@ enable-wide-area=yes #disable-publishing=no #disable-user-service-publishing=no #add-service-cookie=no -publish-addresses=no +#publish-addresses=yes publish-hinfo=no publish-workstation=no -publish-domain=no +#publish-domain=yes #publish-dns-servers=192.168.50.1, 192.168.50.2 #publish-resolv-conf-dns-servers=yes #publish-aaaa-on-ipv4=yes #publish-a-on-ipv6=no [reflector] -#enable-reflector=no +enable-reflector=yes #reflect-ipv=no +#reflect-filters=_airplay._tcp.local,_raop._tcp.local [rlimits] #rlimit-as= diff --git a/cups/rootfs/etc/cont-init.d/dbus-setup b/cups/rootfs/etc/cont-init.d/dbus-setup deleted file mode 100644 index a706c93..0000000 --- a/cups/rootfs/etc/cont-init.d/dbus-setup +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -mkdir -p /var/run/dbus \ No newline at end of file diff --git a/cups/rootfs/usr/share/cupsd.conf.tempio b/cups/rootfs/etc/cups/cupsd.conf similarity index 61% rename from cups/rootfs/usr/share/cupsd.conf.tempio rename to cups/rootfs/etc/cups/cupsd.conf index c1aa4d1..fb8d207 100644 --- a/cups/rootfs/usr/share/cupsd.conf.tempio +++ b/cups/rootfs/etc/cups/cupsd.conf @@ -1,49 +1,46 @@ # -# -# Sample configuration file for the CUPS scheduler. See "man cupsd.conf" for a +# Configuration file for the CUPS scheduler. See "man cupsd.conf" for a # complete description of this file. # # Log general information in error_log - change "warn" to "debug" # for troubleshooting... LogLevel warn +PageLogFormat -# Deactivate CUPS' internal logrotating, as we provide a better one, especially -# LogLevel debug2 gets usable now +# Specifies the maximum size of the log files before they are rotated. The value "0" disables log rotation. MaxLogSize 0 -# Listen to all +# Default error policy for printers +ErrorPolicy retry-job + +# Only listen for connections from the local machine. Port 631 -Listen /var/run/cups/cups.sock +Listen /run/cups/cups.sock # Show shared printers on the local network. -Browsing On +Browsing Yes BrowseLocalProtocols all # Default authentication type, when authentication is required... DefaultAuthType Basic -DefaultEncryption Required - -# Host header validation - -ServerAlias {{.hostname}}.local {{.internal}} {{.external}} - -ServerName {{.hostname}} # Web interface setting... WebInterface Yes +# Timeout after cupsd exits if idle (applied only if cupsd runs on-demand - with -l) +IdleExitTimeout 60 + # Restrict access to the server... Order allow,deny - Allow all - Encryption {{if .require_ssl}}Required{{else}}IfRequested{{end}} + Allow @LOCAL # Restrict access to the admin pages... Order allow,deny - Allow all + Allow @LOCAL # Restrict access to configuration files... @@ -51,8 +48,13 @@ WebInterface Yes AuthType Default Require user @SYSTEM Order allow,deny - Allow 172.0.0.1 - Satisfy any + + +# Restrict access to log files... + + AuthType Default + Require user @SYSTEM + Order allow,deny # Set the default printer/job policies... @@ -70,35 +72,27 @@ WebInterface Yes Require user @OWNER @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # All administration operations require an administrator to authenticate... AuthType Default Require user @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # All printer operations require a printer operator to authenticate... AuthType Default Require user @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # Only the owner or an administrator can cancel or authenticate a job... Require user @OWNER @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow @@ -123,36 +117,74 @@ WebInterface Yes AuthType Default Require user @OWNER @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # All administration operations require an administrator to authenticate... AuthType Default Require user @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # All printer operations require a printer operator to authenticate... AuthType Default Require user @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow # Only the owner or an administrator can cancel or authenticate a job... AuthType Default Require user @OWNER @SYSTEM - Order allow,deny - Allow 172.0.0.1 - Satisfy any + Order deny,allow + + + + Order deny,allow + + + +# Set the kerberized printer/job policies... + + # Job/subscription privacy... + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + # Job-related operations must be done by the owner or an administrator... + + AuthType Negotiate + Order deny,allow + + + + AuthType Negotiate + Require user @OWNER @SYSTEM + Order deny,allow + + + # All administration operations require an administrator to authenticate... + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + # All printer operations require a printer operator to authenticate... + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + # Only the owner or an administrator can cancel or authenticate a job... + + AuthType Negotiate + Require user @OWNER @SYSTEM + Order deny,allow @@ -160,5 +192,3 @@ WebInterface Yes -# -# \ No newline at end of file diff --git a/cups/rootfs/etc/nginx/nginx.conf b/cups/rootfs/etc/nginx/nginx.conf deleted file mode 100644 index 71869c1..0000000 --- a/cups/rootfs/etc/nginx/nginx.conf +++ /dev/null @@ -1,19 +0,0 @@ -events { -} - -http { - - server { - listen 8099; - - location / { - proxy_pass https://localhost:631; - proxy_hide_header X-Frame-Options; - proxy_hide_header Content-Security-Policy; - add_header Content-Security-Policy "sandbox allow-forms allow-modals allow-popups allow-popups-to-escape-sandbox allow-scripts"; - sub_filter '"/' '"$http_x_ingress_path/'; - sub_filter "'/" "'$http_x_ingress_path/"; - sub_filter_once off; - } - } -} \ No newline at end of file diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/dependencies.d/dbus-daemon b/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/dependencies.d/dbus-daemon new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/run b/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/run new file mode 100644 index 0000000..8594ce5 --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/run @@ -0,0 +1,11 @@ +#!/usr/bin/with-contenv bashio + +ulimit -n 1048576 + +bashio::log.info "Starting Avahi daemon from S6" + +until [ -e /run/dbus/system_bus_socket ]; do + sleep 1s +done + +avahi-daemon diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/type b/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/avahi-daemon/type @@ -0,0 +1 @@ +longrun diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/dependencies.d/avahi-daemon b/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/dependencies.d/avahi-daemon new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/run b/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/run new file mode 100644 index 0000000..dc2dff1 --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/run @@ -0,0 +1,12 @@ +#!/usr/bin/with-contenv bashio + +ulimit -n 1048576 + +bashio::log.info "Starting CUPS server from S6" + +until [ -e /var/run/avahi-daemon/socket ]; do + sleep 1s +done + +cupsd -f + diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/type b/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/cups-server/type @@ -0,0 +1 @@ +longrun diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/dependencies.d/initialization b/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/dependencies.d/initialization new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/run b/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/run new file mode 100644 index 0000000..c970dc4 --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/run @@ -0,0 +1,7 @@ +#!/usr/bin/with-contenv bashio + +ulimit -n 1048576 + +bashio::log.info "Starting DBUS daemon from S6" + +dbus-daemon --system --nofork diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/type b/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/type new file mode 100644 index 0000000..5883cff --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/dbus-daemon/type @@ -0,0 +1 @@ +longrun diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/dependencies.d/base b/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/dependencies.d/base new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/type b/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/type new file mode 100644 index 0000000..bdd22a1 --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/type @@ -0,0 +1 @@ +oneshot diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/up b/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/up new file mode 100644 index 0000000..04b5638 --- /dev/null +++ b/cups/rootfs/etc/s6-overlay/s6-rc.d/initialization/up @@ -0,0 +1,4 @@ +#!/usr/bin/env bashio + +mkdir -p /var/run/dbus + diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/avahi-daemon b/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/avahi-daemon new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/dbus-daemon b/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/dbus-daemon new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/initialization b/cups/rootfs/etc/s6-overlay/s6-rc.d/user/contents.d/initialization new file mode 100644 index 0000000..e69de29 diff --git a/cups/rootfs/etc/services.d/avahi/run b/cups/rootfs/etc/services.d/avahi/run deleted file mode 100644 index 6178c3f..0000000 --- a/cups/rootfs/etc/services.d/avahi/run +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -ulimit -n 1048576 - -# Wait until D-Bus is up and the init script has mapped in the external hostname -until [ -e /var/run/dbus/system_bus_socket ] && [ -e /var/run/avahi_configured ]; do - sleep 1s -done - -avahi-daemon 2>&1 | mawk -W interactive '{printf "%c[34m[avahi]%c[0m %s\n", 27, 27, $0}' \ No newline at end of file diff --git a/cups/rootfs/etc/services.d/dbus/run b/cups/rootfs/etc/services.d/dbus/run deleted file mode 100644 index ebe2df6..0000000 --- a/cups/rootfs/etc/services.d/dbus/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -ulimit -n 1048576 - -dbus-daemon --system --nofork 2>&1 | mawk -W interactive '{printf "%c[31m[dbus]%c[0m %s\n", 27, 27, $0}' \ No newline at end of file diff --git a/cups/rootfs/etc/services.d/nginx/run b/cups/rootfs/etc/services.d/nginx/run deleted file mode 100644 index a8b07de..0000000 --- a/cups/rootfs/etc/services.d/nginx/run +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -ulimit -n 1048576 - -nginx -g "daemon off;" 2>&1 | mawk -W interactive '{printf "%c[35m[nginx]%c[0m %s\n", 27, 27, $0}' \ No newline at end of file diff --git a/cups/rootfs/run.sh b/cups/rootfs/run.sh index a971ebd..9d2c64e 100644 --- a/cups/rootfs/run.sh +++ b/cups/rootfs/run.sh @@ -1,57 +1,17 @@ #!/usr/bin/with-contenv bashio -# Create links for certificates with CUPS' expected filenames -bashio::config.require.ssl +ulimit -n 1048576 -keyfile=$(bashio::config keyfile) -certfile=$(bashio::config certfile) -cafile=$(bashio::config cafile) -hostname=$(bashio::info.hostname) -fqdn=$(hostname --fqdn) - -mkdir -p /data/ssl - -if [ $cafile != null ] && [ -e "/ssl/$cafile" ]; then - rm -f /data/ssl/site.crt - ln -s "/ssl/$cafile" /data/ssl/site.crt -fi - -if bashio::config.true ssl; then - rm -f "/data/ssl/$fqdn.key" - rm -f "/data/ssl/$fqdn.crt" - ln -s "/ssl/$keyfile" "/data/ssl/$fqdn.key" - ln -s "/ssl/$certfile" "/data/ssl/$fqdn.crt" -fi - -# Get all possible hostnames from configuration -result=$(bashio::api.supervisor GET /core/api/config true || true) -internal=$(bashio::jq "$result" '.internal_url' | cut -d'/' -f3 | cut -d':' -f1) -external=$(bashio::jq "$result" '.external_url' | cut -d'/' -f3 | cut -d':' -f1) - -# Fill config file templates with runtime data -config=$(jq --arg internal "$internal" --arg external "$external" --arg hostname "$hostname" \ - '{ssl: .ssl, require_ssl: .require_ssl, internal: $internal, external: $external, hostname: $hostname}' \ - /data/options.json) - -echo "$config" | tempio \ - -template /usr/share/cupsd.conf.tempio \ - -out /etc/cups/cupsd.conf - -echo "$config" | tempio \ - -template /usr/share/cups-files.conf.tempio \ - -out /etc/cups/cups-files.conf - -echo "$config" | tempio \ - -template /usr/share/avahi-daemon.conf.tempio \ - -out /etc/avahi/avahi-daemon.conf - -mkdir -p /data/cups - -# Start Avahi, wait for it to start up -touch /var/run/avahi_configured until [ -e /var/run/avahi-daemon/socket ]; do sleep 1s done -# Start CUPS -/usr/sbin/cupsd -f +bashio::log.info "Preparing directories" +cp -v -R /etc/cups /data +rm -v -fR /etc/cups + +ln -v -s /data/cups /etc/cups + +bashio::log.info "Starting CUPS server as CMD from S6" + +cupsd -f diff --git a/cups/rootfs/usr/share/cups-files.conf.tempio b/cups/rootfs/usr/share/cups-files.conf.tempio deleted file mode 100644 index ee04db8..0000000 --- a/cups/rootfs/usr/share/cups-files.conf.tempio +++ /dev/null @@ -1,3 +0,0 @@ -ServerRoot /data/cups -ServerKeychain /data/ssl -CreateSelfSignedCerts {{if .ssl}}no{{else}}yes{{end}} \ No newline at end of file