Skip to content

Commit

Permalink
feat: Automate HPLIP driver and plugin installation
Browse files Browse the repository at this point in the history
* Removes HPLIP docker stage in favor of installation at run time based on ENV (HP_AIO)
* Automates downloading and installing matching HPLIP binary plugin based on libsane-hpaio installed version using ENV (HP_PLUGIN)

sbs20#701 sbs20#724
  • Loading branch information
FoxxMD committed Apr 29, 2024
1 parent 8d0588f commit 6f3e6e5
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 12 deletions.
16 changes: 4 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ COPY entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
ENTRYPOINT [ "/entrypoint.sh" ]

# Copy scripts for additional driver/dep setup
RUN mkdir /scripts
COPY scripts/*.sh /scripts/

# Copy the code and install
COPY --from=scanservjs-build "/app/debian/scanservjs_*.deb" "/"
RUN apt-get install ./scanservjs_*.deb \
Expand Down Expand Up @@ -112,18 +116,6 @@ USER $UNAME
# default build
FROM scanservjs-core

# hplip image
#
# This image adds the HP scanner libs to the image. This target is not built by
# default - you will need to specifically target it.
# ==============================================================================
FROM scanservjs-core AS scanservjs-hplip
RUN apt-get update \
&& apt-get install -yq libsane-hpaio \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& echo hpaio >> /etc/sane.d/dll.conf

# brscan4 image
#
# This image includes the brscan4 driver which is needed for some Brother
Expand Down
8 changes: 8 additions & 0 deletions docs/02-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,14 @@ RUN apt install -yq "$APP_DIR/brscan4-0.4.10-1.amd64.deb" \
&& brsaneconfig4 -a name=ADS-2600W model=ADS-2600W nodename=10.0.100.30
```

### HP Printers

Many HP printers require installing [an additional driver and plugin](sane.md#hp-printers) that can be automated during docker installation.

* Include env `HP_AIO=true` to install the `libsane-hpaio` driver
* Include env `HP_PLUGIN=true` to install the driver and automatically detect/install the required plugin binary
* NOTE: This binary is closed-source and requries accepting a license which is printed to docker logs on installation. You should read the license after installation.

Note: The addition of more backends to the docker container is not planned
since it would mostly add cruft for most users who don't need it.

Expand Down
8 changes: 8 additions & 0 deletions docs/03-sane.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ Please follow the manufacturer's instructions for setting up such scanners.
Once a scanner is listed in `scanimage -L`, it should be ready to use with
scanservjs.

### HP Printers

To use most HP printers the [HP Linux Imaging and Printing software] (HPLIP) driver is required. For debian based systems this driver can be installed with `apt get install libsane-hpaio`.

Additionally, some scanners/printers may require a [closed-source plugin binary](https://developers.hp.com/hp-linux-imaging-and-printing/binary_plugin.html). Installation of this plugin can be automated using the included script [`hplip.sh`](/scripts/docs/hplip.sh). Driver and plugin installation can also be specified in the [docker installation.](docker.md#hp-printers)

NOTE: `hplip.sh` automates accepting the license included with the binary plugin installation. You should read it after installation.

## SANE Airscan

[sane-airscan](https://github.com/alexpevzner/sane-airscan) is useful for
Expand Down
2 changes: 2 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ fi
unset IFS
set +f

/scripts/hpaio.sh || true

node ./server/server.js
34 changes: 34 additions & 0 deletions scripts/hpaio.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh
set -e

HP_AIO="${HP_AIO:=false}"
HP_PLUGIN="${HP_PLUGIN:=false}"

if [ "$HP_AIO" = "true" ] || [ "$HP_PLUGIN" != "false" ];
then
if [ $(dpkg-query -W -f='${Status}' libsane-hpaio 2>/dev/null | grep -c "ok installed") -eq 0 ];
then

if [ "$HP_AIO" = "true" ];
then
echo "HP_AIO is true and libsane-hpaio is not installed. Installing now."
else
echo "HP_PLUGIN is not false and libsane-hpaio is not installed. Installing now."
fi

apt-get -qq update > /dev/null \
&& apt-get install -yq libsane-hpaio > /dev/null \
&& apt-get -q clean > /dev/null \
&& rm -rf /var/lib/apt/lists/*

echo "libsane-hpaio installed!"
else
echo "libsane-hpaio is already installed"
fi
fi

# only install plugin if user specifies (assuming coming from docker)
if [ "$HP_PLUGIN" != "false" ];
then
/scripts/hplip.sh || true
fi
62 changes: 62 additions & 0 deletions scripts/hplip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/sh
set -e

# if coming from docker user needs to set HP_PLUGIN to true
# otherwise if running manually (local install) assume if user tries to run script it should try to install plugin (duh)
HP_PLUGIN="${HP_PLUGIN:=true}"
if [ "$PLUGIN" != "false" ]; then

# if variable is true then try to determine plugin version automatically
if [ "$HP_PLUGIN" = "true" ]; then

echo "Trying to determine HPLIP plugin version from 'hp-plugin' command..."
set +e
# determine installed HPLIP version
RE="HP Linux Imaging and Printing System \(ver\. (.+?)\)"
#cmd_output=$(hp-plugin --help 2>&1)$?
cmd_output=$(hp-plugin --help 2>&1)
cmd_exit=$?
set -e
if [ "$cmd_exit" != "0" ];
then
echo "'hp-plugin' command does not seem to be installed! Cannot determine plugin version automatically so will skip plugin installation."
echo "'hp-plugin' command output: $cmd_output"
exit 1
fi
#https://stackoverflow.com/a/2778096
RAW_VERSION="$(echo "$cmd_output" | sed -rn "s/$RE/\1/p")"
# Remove ansi coloring so its just a raw string
#https://stackoverflow.com/a/51141872
HPLIP_VERSION=$(echo "$RAW_VERSION" | sed 's/\x1B\[[0-9;]\{1,\}[A-Za-z]//g')
printf 'HPLIP Version: %s\n' "$HPLIP_VERSION"

# check if plugin is already installed
# files installed to these locations https://wiki.gentoo.org/wiki/HPLIP#Binary_plugins
if [ -d /usr/share/hplip/data/firmware ]; then
printf 'A plugin is already installed. To force (re)install specify version in ENV like HP_PLUGIN=%s\n' "$HPLIP_VERSION"
else
INSTALL_PLUGIN_VERSION=$HPLIP_VERSION
fi
else
INSTALL_PLUGIN_VERSION=$HPLIP_VERSION
fi
else
echo "To install HPLIP plugin the env HP_PLUGIN must be either 'true' or specify a version"
exit 1
fi

if [ ! -z "$INSTALL_PLUGIN_VERSION" ]; then
printf 'Attempting to install HPLIP plugin version %s\n' "$INSTALL_PLUGIN_VERSION"
PLUGIN_FILE="/tmp/hplip-$INSTALL_PLUGIN_VERSION-plugin.run"

if [ ! -f "$PLUGIN_FILE" ]; then
echo 'Plugin does not already existing, downloading...'
wget --backups 0 -q -P /tmp "https://developers.hp.com/sites/default/files/hplip-$INSTALL_PLUGIN_VERSION-plugin.run" || true
fi
echo "Making plugin runnable..."
chmod +x "$PLUGIN_FILE"
echo "Starting plugin install..."
# has to run as root in order to prevent erroneous invisible password prompt after license accept
su root -c "yes y | $PLUGIN_FILE --noprogress --accept --nox11 -- -i"
echo "HPLIP plugin installed!"
fi

0 comments on commit 6f3e6e5

Please sign in to comment.