commit d64b0c7ea468658d6f12b4fd59e743b1b4bab165 Author: Robert Kaussow Date: Fri Oct 25 19:27:47 2024 +0200 initial commit diff --git a/.dictionary b/.dictionary new file mode 100644 index 0000000..06b2e0b --- /dev/null +++ b/.dictionary @@ -0,0 +1,2 @@ +CUPS +cups diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b763b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +CHANGELOG.md diff --git a/.gitsv/config.yml b/.gitsv/config.yml new file mode 100644 index 0000000..acaf506 --- /dev/null +++ b/.gitsv/config.yml @@ -0,0 +1,47 @@ +--- +version: "1.1" + +versioning: + update-major: [] + update-minor: [feat] + update-patch: [fix, perf, refactor, chore, test, ci, docs] + +tag: + pattern: "v%d.%d.%d" + +release-notes: + sections: + - name: Features + commit-types: [feat] + section-type: commits + - name: Bug Fixes + commit-types: [fix] + section-type: commits + - name: Performance Improvements + commit-types: [perf] + section-type: commits + - name: Code Refactoring + commit-types: [refactor] + section-type: commits + - name: Others + commit-types: [chore] + section-type: commits + - name: Testing + commit-types: [test] + section-type: commits + - name: CI Pipeline + commit-types: [ci] + section-type: commits + - name: Documentation + commit-types: [docs] + section-type: commits + - name: BREAKING CHANGES + section-type: breaking-changes + +commit-message: + footer: + issue: + key: issue + add-value-prefix: "#" + issue: + regex: "#?[0-9]+" diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 0000000..b59a114 --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,6 @@ +--- +default: True +MD013: False +MD041: False +MD004: + style: dash diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..135c35d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +*.tpl.md +LICENSE diff --git a/.woodpecker/build-container.yml b/.woodpecker/build-container.yml new file mode 100644 index 0000000..2d55377 --- /dev/null +++ b/.woodpecker/build-container.yml @@ -0,0 +1,69 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: security-build + image: quay.io/thegeeklab/wp-docker-buildx:5 + settings: + containerfile: Containerfile.multiarch + output: type=oci,dest=oci/${CI_REPO_NAME},tar=false + repo: thegeeklab/${CI_REPO_NAME} + + - name: security-scan + image: ghcr.io/aquasecurity/trivy + commands: + - trivy -v + - trivy image --input oci/${CI_REPO_NAME} + environment: + TRIVY_EXIT_CODE: "1" + TRIVY_IGNORE_UNFIXED: "true" + TRIVY_NO_PROGRESS: "true" + TRIVY_SEVERITY: HIGH,CRITICAL + TRIVY_TIMEOUT: 1m + + - name: publish-dockerhub + image: quay.io/thegeeklab/wp-docker-buildx:5 + group: container + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: docker_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + repo: thegeeklab/${CI_REPO_NAME} + username: + from_secret: docker_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + + - name: publish-quay + image: quay.io/thegeeklab/wp-docker-buildx:5 + group: container + settings: + auto_tag: true + containerfile: Containerfile.multiarch + password: + from_secret: quay_password + platforms: + - linux/amd64 + - linux/arm64 + provenance: false + registry: quay.io + repo: quay.io/thegeeklab/${CI_REPO_NAME} + username: + from_secret: quay_username + when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} diff --git a/.woodpecker/build-package.yml b/.woodpecker/build-package.yml new file mode 100644 index 0000000..44951b2 --- /dev/null +++ b/.woodpecker/build-package.yml @@ -0,0 +1,25 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: changelog + image: quay.io/thegeeklab/git-sv + commands: + - git sv current-version + - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md + - cat CHANGELOG.md + + - name: publish-gitea + image: quay.io/thegeeklab/wp-gitea-release + settings: + api_key: + from_secret: gitea_token + base_url: https://gitea.rknet.org + note: CHANGELOG.md + title: ${CI_COMMIT_TAG} + when: + - event: [tag] diff --git a/.woodpecker/docs.yml b/.woodpecker/docs.yml new file mode 100644 index 0000000..7cb883d --- /dev/null +++ b/.woodpecker/docs.yml @@ -0,0 +1,60 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: markdownlint + image: quay.io/thegeeklab/markdownlint-cli + group: test + commands: + - markdownlint 'README.md' + + - name: spellcheck + image: quay.io/thegeeklab/alpine-tools + group: test + commands: + - spellchecker --files '_docs/**/*.md' 'README.md' -d .dictionary -p spell indefinite-article syntax-urls + environment: + FORCE_COLOR: "true" + + - name: link-validation + image: docker.io/lycheeverse/lychee + group: test + commands: + - lychee --no-progress --format detailed README.md + + - name: pushrm-dockerhub + image: docker.io/chko/docker-pushrm:1 + environment: + DOCKER_USER: + from_secret: docker_username + DOCKER_PASS: + from_secret: docker_password + PUSHRM_FILE: README.md + PUSHRM_SHORT: Ansible developer tools collection + PUSHRM_TARGET: thegeeklab/${CI_REPO_NAME} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + + - name: pushrm-quay + image: docker.io/chko/docker-pushrm:1 + environment: + APIKEY__QUAY_IO: + from_secret: quay_token + PUSHRM_FILE: README.md + PUSHRM_TARGET: quay.io/thegeeklab/${CI_REPO_NAME} + when: + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + status: [success] + +depends_on: + - build-package + - build-container diff --git a/.woodpecker/notify.yml b/.woodpecker/notify.yml new file mode 100644 index 0000000..374a96a --- /dev/null +++ b/.woodpecker/notify.yml @@ -0,0 +1,26 @@ +--- +when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +runs_on: [success, failure] + +steps: + - name: matrix + image: quay.io/thegeeklab/wp-matrix + settings: + homeserver: + from_secret: matrix_homeserver + room_id: + from_secret: matrix_room_id + user_id: + from_secret: matrix_user_id + access_token: + from_secret: matrix_access_token + when: + - status: [success, failure] + +depends_on: + - docs diff --git a/Containerfile.multiarch b/Containerfile.multiarch new file mode 100644 index 0000000..8888e02 --- /dev/null +++ b/Containerfile.multiarch @@ -0,0 +1,41 @@ +FROM docker.io/alpine:3.20@sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d + +LABEL maintainer="Robert Kaussow " +LABEL org.opencontainers.image.authors="Robert Kaussow " +LABEL org.opencontainers.image.title="cups" +LABEL org.opencontainers.image.url="https://gitea.rknet.org/container/cups" +LABEL org.opencontainers.image.source="https://gitea.rknet.org/container/cups" +LABEL org.opencontainers.image.documentation="https://gitea.rknet.org/container/cups" + +ARG TARGETOS +ARG TARGETARCH +ARG TARGETVARIANT + +ARG CONTAINER_LIBRARY + +# renovate: datasource=repology depName=alpine_edge/cups versioning=loose +ENV CUPS_VERSION=2.4.11-r0 +# renovate: datasource=repology depName=alpine_edge/cups-filters versioning=loose +ENV CUPS_FILTERS_VERSION=1.28.17-r6 + +RUN apk --update --no-cache add libcap && \ + apk --update --no-cache add cups=${CUPS_VERSION} cups-filters=${CUPS_FILTERS_VERSION} --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main && \ + mkdir -p /run/cups && \ + setcap 'cap_net_bind_service=+ep' /usr/sbin/cupsd && \ + rm -rf /var/cache/apk/* && \ + rm -rf /tmp/* + +ADD overlay/ / + +RUN chown -R root:lp /var/log/cups && \ + chown -R root:lp /var/spool/cups && \ + chown -R root:lp /var/cache/cups && \ + chown -R root:lp /run/cups && \ + chown -R root:lp /etc/cups + +EXPOSE 631 + +STOPSIGNAL SIGTERM + +ENTRYPOINT ["/usr/local/bin/entrypoint"] +CMD [] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3812eb4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Robert Kaussow + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..02bef6b --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# cups + +Custom image for OpenPrinting CUPS + + + +[![Build Status](https://ci.rknet.org/api/badges/container/cups/status.svg)](https://ci.rknet.org/repos/container/cups) +[![Docker Hub](https://img.shields.io/badge/dockerhub-latest-blue.svg?logo=docker&logoColor=white)](https://hub.docker.com/r/thegeeklab/cups) +[![Quay.io](https://img.shields.io/badge/quay-latest-blue.svg?logo=docker&logoColor=white)](https://quay.io/repository/thegeeklab/cups) +[![Source: Gitea](https://img.shields.io/badge/source-gitea-blue.svg?logo=gitea&logoColor=white)](https://gitea.rknet.org/container/cups) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://gitea.rknet.org/container/cups/src/branch/main/LICENSE) + + + +Custom container image for [OpenPrinting CUPS](https://github.com/OpenPrinting/cups) open source printing system. + +## License + +This project is licensed under the MIT License - see the [LICENSE](https://gitea.rknet.org/container/molecule/src/branch/main/LICENSE) file for details. diff --git a/overlay/.keep b/overlay/.keep new file mode 100644 index 0000000..e69de29 diff --git a/overlay/etc/cups/cups-files.conf b/overlay/etc/cups/cups-files.conf new file mode 100644 index 0000000..47d2f67 --- /dev/null +++ b/overlay/etc/cups/cups-files.conf @@ -0,0 +1,87 @@ +# +# File/directory/user/group configuration file for the CUPS scheduler. +# See "man cups-files.conf" for a complete description of this file. +# + +# List of events that are considered fatal errors for the scheduler... +#FatalErrors config + +# Strip domain in local username? +#StripUserDomain No + +# Do we call fsync() after writing configuration or status files? +#SyncOnClose No + +# Default user and group for filters/backends/helper programs; this cannot be +# any user or group that resolves to ID 0 for security reasons... +#User lp +#Group lp + +# Administrator user group, used to match @SYSTEM in cupsd.conf policy rules... +# This cannot contain the Group value for security reasons... +SystemGroup lpadmin + + +# User that is substituted for unauthenticated (remote) root accesses... +#RemoteRoot remroot + +# Do we allow file: device URIs other than to /dev/null? +#FileDevice No + +# Permissions for configuration and log files... +#ConfigFilePerm 0640 +#LogFilePerm 0644 + +# Location of the file logging all access to the scheduler; may be the name +# "syslog". If not an absolute path, the value of ServerRoot is used as the +# root directory. Also see the "AccessLogLevel" directive in cupsd.conf. +AccessLog stderr + +# Location of cache files used by the scheduler... +#CacheDir /var/cache/cups + +# Location of data files used by the scheduler... +#DataDir /usr/share/cups + +# Location of the static web content served by the scheduler... +#DocumentRoot /usr/share/cups + +# Location of the file logging all messages produced by the scheduler and any +# helper programs; may be the name "syslog". If not an absolute path, the value +# of ServerRoot is used as the root directory. Also see the "LogLevel" +# directive in cupsd.conf. +ErrorLog stderr + +# Location of the file logging all pages printed by the scheduler and any +# helper programs; may be the name "syslog". If not an absolute path, the value +# of ServerRoot is used as the root directory. Also see the "PageLogFormat" +# directive in cupsd.conf. +PageLog stderr + +# Location of the file listing all of the local printers... +#Printcap /etc/printcap + +# Format of the Printcap file... +#PrintcapFormat bsd +#PrintcapFormat plist +#PrintcapFormat solaris + +# Location of all spool files... +#RequestRoot /var/spool/cups + +# Location of helper programs... +#ServerBin /usr/lib/cups + +# SSL/TLS keychain for the scheduler... +#ServerKeychain ssl + +# Location of other configuration files... +#ServerRoot /etc/cups + +# Location of scheduler state files... +#StateDir /run/cups + +# Location of scheduler/helper temporary files. This directory is emptied on +# scheduler startup and cannot be one of the standard (public) temporary +# directory locations for security reasons... +#TempDir /var/spool/cups/tmp diff --git a/overlay/etc/cups/cupsd.conf b/overlay/etc/cups/cupsd.conf new file mode 100644 index 0000000..a700fde --- /dev/null +++ b/overlay/etc/cups/cupsd.conf @@ -0,0 +1,207 @@ +# +# 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 info +PageLogFormat + +# Specifies the maximum size of the log files before they are rotated. The value "0" disables log rotation. +MaxLogSize 1m + +# Default error policy for printers +ErrorPolicy stop-printer + +# Allow remote access +Listen *:631 +ServerAlias * + +# Disable tls +DefaultEncryption Never + +# Show shared printers on the local network. +Browsing No + +# Default authentication type, when authentication is required... +DefaultAuthType Basic + +# Web interface setting... +WebInterface Yes + +# Restrict access to the server... + + Allow All + Order allow,deny + + +# Restrict access to the admin pages... + + Allow All + AuthType Default + Require user @SYSTEM + Order allow,deny + + +# Restrict access to configuration files... + + Allow All + AuthType Default + Require user @SYSTEM + Order allow,deny + + +# Restrict access to log files... + + AuthType Default + Require user @SYSTEM + Order allow,deny + + +# Set the default 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... + + Order deny,allow + + + + Require user @OWNER @SYSTEM + Order deny,allow + + + + AuthType Default + 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... + + Require user @OWNER @SYSTEM + Order deny,allow + + + + AuthType Default + Require user @OWNER @SYSTEM + Order deny,allow + + + + Order deny,allow + + + +# Set the authenticated 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 Default + Order deny,allow + + + + AuthType Default + 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 Default + Require user @OWNER @SYSTEM + 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 Default + Order deny,allow + + + + AuthType Default + 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 Default + Require user @OWNER @SYSTEM + Order deny,allow + + + + Order deny,allow + + diff --git a/overlay/usr/local/bin/entrypoint b/overlay/usr/local/bin/entrypoint new file mode 100755 index 0000000..9e08849 --- /dev/null +++ b/overlay/usr/local/bin/entrypoint @@ -0,0 +1,30 @@ +#!/usr/bin/env sh + +# shellcheck disable=SC3040 + +set -eo pipefail + +# Function to handle SIGTERM +terminate() { + echo "Received SIGTERM, shutting down CUPS..." + kill -TERM "$child" 2>/dev/null + wait "$child" + exit 0 +} + +# Set up SIGTERM trap +trap terminate TERM + +if [ -n "$CUPS_ADMIN_USERNAME" ] && [ -n "$CUPS_ADMIN_PASSWORD" ]; then + if ! id -u "$CUPS_ADMIN_USERNAME" >/dev/null 2>&1; then + adduser -S -H -G lpadmin "$CUPS_ADMIN_USERNAME" + echo "$CUPS_ADMIN_USERNAME:$CUPS_ADMIN_PASSWORD" | chpasswd 2>/dev/null + fi +fi + +# Start CUPS in the background and get its PID +/usr/sbin/cupsd -f & +child=$! + +# Wait for the CUPS process +wait "$child" diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..5f02575 --- /dev/null +++ b/renovate.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["github>thegeeklab/renovate-presets:docker"] +} diff --git a/trivy-secret.yaml b/trivy-secret.yaml new file mode 100644 index 0000000..abca175 --- /dev/null +++ b/trivy-secret.yaml @@ -0,0 +1,6 @@ +--- +allow-rules: + - id: private-key + path: .*/ansible/.*/site-packages/ansible_collections/(community|google|netapp)/.*\.py + - id: aws-secret-access-key + path: .*/ansible/.*/site-packages/ansible_collections/amazon/.*\.py diff --git a/trivy.yaml b/trivy.yaml new file mode 100644 index 0000000..e74b43b --- /dev/null +++ b/trivy.yaml @@ -0,0 +1,4 @@ +--- +scan: + skip-files: + - /usr/local/bin/gomplate