From 18ae34e1b6c6ae87ed130eca2d3d396d805432cb Mon Sep 17 00:00:00 2001 From: Blake Haug Date: Mon, 13 Jul 2026 16:56:40 -0700 Subject: [PATCH] new printhost docs --- .../infrastructure/printing/maintenance.md | 50 +++--- .../infrastructure/printing/printhost.md | 145 +++++++++++------- .../printing/printing-pipeline.svg | 2 + 3 files changed, 110 insertions(+), 87 deletions(-) create mode 100644 docs/staff-docs/infrastructure/printing/printing-pipeline.svg diff --git a/docs/staff-docs/infrastructure/printing/maintenance.md b/docs/staff-docs/infrastructure/printing/maintenance.md index e0d6e8b..0f2b601 100644 --- a/docs/staff-docs/infrastructure/printing/maintenance.md +++ b/docs/staff-docs/infrastructure/printing/maintenance.md @@ -4,37 +4,31 @@ title: Printing Maintenance ## Removing printers from service -Ideally, printers shouldn't ever be turned off. Instead, they should be removed -from the CUPS classes: +Ideally, printers shouldn't ever be turned off. Instead, they should be paused +in the CUPS web interface: 1. Go to https://printhost.ocf.berkeley.edu/ (works only in lab) -2. Go to Classes > `double` > Modify Class -3. Remove the offending printer from the list of selected printers -4. GOTO 2, repeat for the `single` class +2. Go to Printers > `printer` > Maintenance > Pause Printer -Alternatively, this can be done using the `utils` command `mod-printer` with proper authentication. +The `printer` is the name of the physical printer (currently: `logjam`, +`papercut`, `pagefault`, or `OCF-Color (fishpaper)`). This will prompt you to enter your password. - mod-printer remove [printer] +## Restoring printer service -The `printer` is the name of the physical printer (currently: `logjam`, -`papercut`, or `pagefault`). This will prompt you to enter your password -twice, once for `single` and again for `double`. +Go to Printers > `printer` > Maintenance > Resume Printer -**Note**: this command must be used from [`whiteout`](https://www.ocf.berkeley.edu/docs/staff/backend/servers/#whiteout). -(In theory pausing printers should have the same effect, but the current CUPS -version still queues jobs for them for some unknown reason, causing half of -user jobs to not print.) +## Stats -## Restoring printer service + * [Printer status Grafana dashboard (ocf.io/printers)][printer-dashboard] + * Toner and Maintenance Kit [status][printer-summary] + * [How many pages has each printer printed][pages-printed]? (expressed as total + pages printed over time) -Perform the reverse of the above (add the printers back to the classes), then -double-check that the printers are not paused. This can also be done by -replacing `remove` in the above `mod-printer` command with `add` (again only if called from `whiteout`). -Even if staff don't pause them, -CUPS will pause them automatically if they fail. -## Replacing toner +## History + +### Replacing toner (pre-2020's) Toner replacement takes only a few seconds. Don't bother recording toner replacement, there is no point. @@ -57,7 +51,7 @@ between the ASUC and the University. The LEAD center has requested we keep our use of the passthrough account to a miminum, so we've agreed to buy toner in annual intervals. -## Recycling used toner +### Recycling used toner (pre-2020's) OCF goes through toners quite fast, due to the heavy volume of printing from our users. In the past, we've let it accumulate inside the storage room which @@ -67,7 +61,7 @@ to recycle the toners in hope of encouraging rapid removal of the toners from OC OCF staffers should keep an eye out for the accumulation of the toners, and proactively recycle the used toners as soon as possible. -### Options to dispose the toners +#### Options to dispose the toners * We can dispose the toners by returning them to [Staples](https://www.staples.com/sbd/cre/marketing/sustainability-center/recycling- @@ -83,7 +77,7 @@ building - would accept our toners that are individually sealed in a garbage bag l?mode=recycling&XOGlang=en_US&referer=xrx) toner return box kit with a free return label. Once the kit arrives, put the used toners in the box and schedule a UPS pick up. -## Performing maintenance on the printers +### Performing maintenance on the printers (pre-2020's) Our contract with PMP entitles us to free service for our printers, with a short turn-around time. As a result, we should not longer attempt maintenance @@ -102,14 +96,6 @@ The following is a list of our printers and their IDs, from left to right: | logjam | 1786 | | pagefault | 1781 | -## Stats - - * [Printer status Grafana dashboard (ocf.io/printers)][printer-dashboard] - * Toner and Maintenance Kit [status][printer-summary] - * [How many pages has each printer printed][pages-printed]? (expressed as total - pages printed over time) - - [toner]: https://www.staples.com/HP-64X-Black-Toner-Cartridge-CC364XD-High-Yield-Twin-Pack/product_821762 [pmp]: https://campuslifeservices.ucsf.edu/documentsmedia/services/print_management [printer-dashboard]: https://ocf.io/printers diff --git a/docs/staff-docs/infrastructure/printing/printhost.md b/docs/staff-docs/infrastructure/printing/printhost.md index 8d8a1af..1ff4235 100644 --- a/docs/staff-docs/infrastructure/printing/printhost.md +++ b/docs/staff-docs/infrastructure/printing/printhost.md @@ -9,55 +9,25 @@ standard UNIX print server, and a custom print accounting system contained in the ocflib API. CUPS is responsible for receiving print jobs over the network, converting documents to a printer-friendly format, and delivering processed jobs to one of the available printers. The OCF's print accounting system, -nicknamed enforcer after one of the scripts, plugs into CUPS as a hook that -looks at jobs before and after going to the printer. It records jobs in a +nicknamed enforcer after one of the scripts, plugs into CUPS as a driver that +intercepts jobs before and after going to the printer. It records jobs in a database that keeps track of how many pages each user has printed, rejecting jobs that go over quota. The high level flow of data through the print system looks like this: -``` - [Application] - + - | PDF or PS document - v -[Print spool (CUPS)] - + - | Raw document - v -[Filter(s) (ocfps)] - + - | Converted PS document - v -[Backend (Tea4CUPS)] - + - | Accept or reject - +<------------------+[Page counter (enforcer)] - | ^ - v | - [Printer] | Remaining quota - + +-------+/ \<---------------+/ \ - | Status/completion time |ocflib| |Jobs database| - v +------->\ /+--------------->\ / - [Backend] | Job table entry - + | - | + - +---------------------->[Enforcer (again)] - | Log success/failure - v -[Print spool logger] -``` +## Printing Pipeline +![Printing Pipeline](printing-pipeline.svg) -[cups]: https://www.cups.org/documentation.html +[cups]: https://openprinting.github.io/cups/ ## CUPS pipeline overview The first stage of printing is handled by the application that sends the print -job, such as Evince. The application opens up a system print dialog, which gets -a list of available printers and options from the local CUPS client, which in -turn gets it from the printhost. The application renders the desired pages to a -PostScript, PDF, or other CUPS-compatible format, then sends it to the -printhost. +job, such as Firefox. The application opens up a system print dialog, which gets +a list of available printers and options from printhost. The application renders +the desired pages to a PostScript, PDF, or other CUPS-compatible format, then sends +it to the printhost. The CUPS server on the printhost receives the job and print options and queues the job for printing. The actual document, plus metadata including user-set @@ -91,29 +61,94 @@ duplexing, then, finally, a device-specific filter such as `hpcups`. Each filter is associated with an internal "cost", and CUPS picks the path with the least total cost to print the document. -At the OCF, print jobs are all processed by a single filter, [ocfps][ocfps], -which converts raw PDFs to rasterized, printable PostScript. It calls on a -command-line converter to render the PDF as pixels (rasterization), then passes -the result and the rest of the arguments to standard CUPS filters. So far, this -has given us the fewest headaches in terms of malformatted output and printer -errors. - -[ocfps]: https://github.com/ocf/puppet/blob/master/modules/ocf_printhost/files/ocfps +We used to use ocfps as the filter for all documents. We use the stock +HP PPD drivers which use a combo of multiple filters, such as `hpps` and `pdftops`. ### Drivers In order to know what job options are available for a particular printer and how to convert documents to a printable format, CUPS requires large config -files called PostScript Printer Drivers (PPDs). The OCF uses a modified HP PPD -for the [M806][m806]. There are two versions of it: one which only allows -double-sided printing and one which only allows single-sided. This is how we -implement the "double" and "single" classes. The PPDs tell CUPS to use `ocfps` -to convert documents to PostScript, plus they turn on economode so we can -afford the toner. +files called PostScript Printer Drivers (PPDs). The OCF uses the stock HP PPD's +for our printers and we have the user select double/single-sided on the client +print dialog. (as opposed to the double/single classes we used to have) + + +## Print accounting + +The OCF used to use a virtual CUPS printer backend called [Tea4CUPS][Tea4CUPS] to +install a page accounting hook that runs before and after each job is actually +sent to the printer. Tea4CUPS is no longer maintained so we wrote a script that +implements the same api called [ocf-cups-backend][ocf-cups-backend]. The +[enforcer][enforcer] script actually holds the pre and post-hook logic, as well +as in the [ocflib printing package][ocflib.printing]. All jobs +are logged in the `ocfprinting` SQL database, including the username, print +queue, and number of pages. Several views count up the number of pages printed +by each user per day and per semester. Sensitive data like document titles are +removed from the database after 2 weeks. (see [enforcer][enforcer] for more details) + +Page counting is actually done when the document is converted to PostScript, +since CUPS-processed PostScript includes the page count as a comment near the +top or bottom of the file. When enforcer receives a job that would put the user +over daily or semesterly quota, it emails the user and returns an error code +that cancels the job. Otherwise, it logs successful print jobs in the database +and emails users in the case a job fails. + +[Tea4CUPS]: https://wiki.debian.org/Tea4CUPS +[enforcer]: https://github.com/ocf/nix/blob/main/modules/printhost/scripts/enforcer.py +[ocflib.printing]: https://github.com/ocf/ocflib/tree/master/ocflib/printing +[ocf-cups-backend]: https://github.com/ocf/nix/blob/main/modules/printhost/scripts/ocf-cups-backend + + +### Desktop notifications + +After printing a document from a desktop, lab visitors are notified when their +print is sent to a printer (and which printer it was sent to) by a desktop +notification. The enforcer script sends a request for [wayout][wayout] to +notify the user. + +[wayout]: https://github.com/ocf/wayout + +## More Details -[m806]: https://github.com/ocf/puppet/blob/master/modules/ocf_printhost/templates/cups/ppd/m806.ppd.epp +Please see the [printhost migration PR][printhost-pr] for more details on this new printing system. +[printhost-pr]: https://github.com/ocf/nix/pull/240 + +## History + +### Old Pipeline +``` + [Application] + + + | PDF or PS document + v +[Print spool (CUPS)] + + + | Raw document + v +[Filter(s) (ocfps)] + + + | Converted PS document + v +[Backend (Tea4CUPS)] + + + | Accept or reject + +<------------------+[Page counter (enforcer)] + | ^ + v | + [Printer] | Remaining quota + + +-------+/ \<---------------+/ \ + | Status/completion time |ocflib| |Jobs database| + v +------->\ /+--------------->\ / + [Backend] | Job table entry + + | + | + + +---------------------->[Enforcer (again)] + | Log success/failure + v +[Print spool logger] +``` ## Print accounting @@ -160,7 +195,7 @@ current user. ## See also - [Printing maintenance](../procedures/printing.md) -- The [ocf\_printhost][ocf_printhost] Puppet class +- The [ocf\_printhost][ocf_printhost] Puppet class # TODO update - The [paper](../scripts/paper.md) command - [CUPS documentation at Samba][cups-samba] (for Windows users, but has general CUPS info as well) diff --git a/docs/staff-docs/infrastructure/printing/printing-pipeline.svg b/docs/staff-docs/infrastructure/printing/printing-pipeline.svg new file mode 100644 index 0000000..51f72d4 --- /dev/null +++ b/docs/staff-docs/infrastructure/printing/printing-pipeline.svg @@ -0,0 +1,2 @@ +Clientlpoptions...Server (tule.ocf.berkeley.edu)OCF-BW(virtual printer)PPD: HP M806...OCF-BW-Group(class, load balances)Public: YesPublic: NoMembers: logjam, papercut, ...HP PPD Filters(PDF -> PostScript)OCF Enforcer (pre-hook)(checks page quotaand sends wayout)logjamPPD: raw (no ppd, no filters)(physical printer)OCF Enforcer (post-hook)(adds job to DB) \ No newline at end of file