PaperCut Blog

Tech & Dev

Automate your PaperCut MF upgrade review process

Automate your PaperCut MF upgrade review process

When you are a PaperCut MF or PaperCut NG administrator you need to make sure your software is up to date. Not only do your users crave the latest features, but you need to make sure you’ve got all the latest
security patches.

You can discover the latest release of PaperCut MF by looking at our Atom feed here:

https://www.papercut.com/products/mf/release-history.atom

If you have a feed reader installed (for example Feeder in Chrome), you can get a nice pretty display.

PaperCut latest build Atom feed

Screenshot of our releases feed, displayed in an appropriate reader

You can click the subscribe button and ask Feeder to send an email every time we release a new version. But that is so old school!

I am lazy, so let’s write a script that will create a job ticket when a new MF release is available and assign it to the appropriate person, so they get prompted to investigate.


Notes:

  • These notes talk about PaperCut MF, but it’s easy enough to adapt
    for PaperCut NG.
  • Iā€™ll be demonstrating scripts for POSIX
    style (Linux and macOS) shells and PowerShell,
    but you can use whatever scripting language you like (for example Python)

We need to do three things:

  1. Discover which version of PaperCut MF is currently running on our
    server
  2. Get the latest PaperCut MF release version from the PaperCut
    website
  3. If the version has changed since we last checked, then create a
    review ticket.

This splits what could be a long article up into three convenient standalone posts.

Warning: This article assumes moderately advanced script writing and PaperCut MF administration knowledge. You should test in your own environment before deploying to production.

Discover which version of PaperCut MF is currently running on our server

We can retrieve the PaperCut MF server version through the health API. But, for security reasons, in order to use the health API we need the health API key.

We can retrieve the health API key from the PaperCut MF server, either via the web services API, or via the server-commandutility.

Again for security reasons, the web services API also needs a separate security auth token to work. The auth token needs to be configured by the PaperCut administrator (by editing the advanced config key auth.webservices.auth-token).

I’ll provide examples for POSIX shells (specifically the Dash shell) and PowerShell.

Retrieve the health API key in a POSIX shell

Let’s assume we have the web services API auth token stored in a local file ~/.PAPERCUT_API_TOKEN, because it’s bad practice to embed secrets into script files.

Use this code to get the health API key key:

#!/bin/dash

# Use the Dash shell. It's smaller and faster

API_TOKEN="$(cat ~/.PAPERCUT_API_TOKEN)" # Don't hard code API tokens

MF_HOST="$(hostname).local" # Modify to suit

# We need the health API key. Get it via the web services API
# Config key is health.api.key
# Use XMLLint to parse XML-RPC output

HEALTH_API_KEY=$(curl -s -H "content-type:text/xml" --data @- \
  "http://${MF_HOST}:9191/rpc/api/xmlrpc"  <<EOF | \
  xmllint --xpath '//methodResponse/params/param/value/text()' -
<?xml version="1.0"?>
<methodCall>
<methodName>
api.getConfigValue
</methodName>
<params>
<param>
<value>
${API_TOKEN}
</value>
</param>
<param>
<value>
health.api.key
</value>
</param>
</params>
</methodCall>
EOF
)

echo $HEALTH_API_KEY

This code should echo a random string.

NOTE: You will need to make sure xmllint is installed (Tip: In Debian, that’s package libxml2-utils).

If your script is running on the PaperCut MF server, then you can make your life a lot easier by using the server-command utility instead of the web services API. Just make sure you are running as the PaperCut user on Linux.

For example use this code to get the API key, this will use server command, or the web services API if server-command does not work.

#!/bin/dash

MF_HOST="$(hostname).local" # Modify to suit

HEALTH_API_KEY=$($HOME/server/bin/linux-x64/server-command get-config health.api.key)

if [ -z "$HEALTH_API_KEY" ] ; then

  HEALTH_API_KEY=$(curl -s -H "content-type:text/xml" --data @- \
      "http://${MF_HOST}:9191/rpc/api/xmlrpc"  <<EOF | \
    xmllint --xpath '//methodResponse/params/param/value/text()' -
<?xml version="1.0"?>
<methodCall>
<methodName>
api.getConfigValue
</methodName>
<params>
<param>
<value>
$(cat ~/.PAPERCUT_API_TOKEN)
</value>
</param>
<param>
<value>
health.api.key
</value>
</param>
</params>
</methodCall>
EOF
)

fi

echo $HEALTH_API_KEY

Discover the server version in a POSIX shell

(these code fragments assume we still have the HEALTH_API_KEY and MF_HOST variables set from the previous section).

Now we have the correct health API key we can make calls to the health API to discover the server version. As an experiment, run the following from the Linux command line:

curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health" | head -10

The output is JSON, but if if we install the jq
JSON processor we can extract the version string

curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health"  |
    jq '.applicationServer.systemInfo.version'

Which displays something like 21.2.10 (Build 62186).
What we really need are the MAJOR, MINOR, PATCH values from the semantic version. In this example, they are 21, 2, and 10. This requires some string extraction and on POSIX I prefer to use the sed editor.

INSTALLED_RELEASE=$(curl -s -H "Authorization:$HEALTH_API_KEY" "http://${MF_HOST}:9191/api/health" |
    jq '.applicationServer.systemInfo.version' |
    sed -Ee 's/^"([0-9]+\.[0-9]+\.[0-9]+).+$/\1/')

echo $INSTALLED_RELEASE

Now we know which PaperCut MF release is running on our server.

Retrieve the health API key in modern PowerShell

Note: These examples were tested on PowerShell V 7.2

$MF_HOST = "$(hostname).local" # Modify to suit
$API_TOKEN = (Get-Content -raw ~/.PAPERCUT_API_TOKEN).trim()  # Don't hard code API tokens
$uri = [Uri] "http://${MF_HOST}:9191/rpc/api/xmlrpc"

$HEALTH_API_KEY = (@"
<?xml version="1.0"?>
<methodCall>                 
<methodName>api.getConfigValue</methodName>
<params> 
<param>      
<value>${API_TOKEN}</value>                                                                                        
</param>
<param>
<value>health.api.key</value>
</param>
</params>
</methodCall>
"@ | Invoke-RestMethod  -Method 'Post' -Uri $uri | Select-Xml -XPath "/methodResponse/params/param/value").toString()

Write-Output $HEALTH_API_KEY

Notice that PowerShell has build in support for XML so no need to install further packages.

If we assume that the script will run on the PaperCut MF server system them we can use server-command.exe to retrieve the health API key, instead of using web services API.

Note: On Windows PowerShell will need to be running with elevated privilege to execute server-command.exe.

$HEALTH_API_KEY = & "$((Get-ItemProperty `
    -Path 'HKLM:\HKEY_LOCAL_MACHINE\SOFTWARE\PaperCut MF').InstallPath)\server\bin\win\server-command.exe" `
    get-config health.api.key

Write-Output $HEALTH_API_KEY

(more information on how to locate the PaperCut MF installation in this note.)

Discover the server version in Modern PowerShell

These code fragments assume we still have the HEALTH_API_KEY and MF_HOST variables set from the previous section.

Now we have the correct health API key we can make calls to the health API to discover the server version. You may like to look at the POSIX example above to understand how to locate the correct information in the JSON response.

(Invoke-RestMethod -Uri "http://${MF_HOST}:9191/api/health" -Method Get `
    -Headers @{'Authorization' = $HEALTH_API_KEY}).applicationServer.systemInfo.Version

Notice that PowerShell has build in support for JSON so no need to install further packages like jq.

We get a string that looks like “21.2.10 (Build 62186)”. But what we really need are the MAJOR, MINOR, PATCH values from the semantic version. In my example they are 21, 2, and 10. PowerShell provides a
handy -replace operator and we can use a regex to extract the information we need:

$INSTALLED_RELEASE = (Invoke-RestMethod -Uri "http://${MF_HOST}:9191/api/health" -Method Get `
    -Headers @{'Authorization' = $HEALTH_API_KEY}).applicationServer.systemInfo.Version `
    -replace '^(\d+\.\d+\.\d+).+','$1'

Write-Output $INSTALLED_RELEASE 

Job done!

In the next installment, we’ll get the current PaperCut MF release version from the website Atom feed
at http://www.papercut.com/products/mf/release-history.atom

You can find more complete versions of these scripts in our GitHub repo:

Comments