Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Automate HPLIP driver and plugin installation #726

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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