I’m running TrueNAS Scale on an offsite server to backup my data and I’m using the native encryption of ZFS to securely store it at rest.

To periodically backup my data to the offsite server with an automated script, I needed to find a way how to unlock the ZFS datasets from the command line, while not messing with the way TrueNAS Scale manages the storage.

Enter midclt, a tool to access the TrueNAS Scale REST API from the command line. With midclt call you can call all of the described API endpoints, without creating an API token or the need to call the API externally.

After discovering midclt and the API reference, I needed to figure out how this works. I couldn’t find any docs on the topic, but eventually, I was able to make it work.

How midclt works

The first argument to midclt call will be the name of the endpoint, for example pool.dataset.unlock.

Many API endpoints take an id, which will be the second argument to midclt call.

If the endpoint takes additional options, those can be supplied as a JSON string as the third argument to midclt call, like so:

{
  "datasets": [
    {
      "name": "mydataset",
      "passphrase": "mypassphrase"
    }
  ]
}

This is the unlock_options dict of pool.dataset.unlock taken from the API reference.

Putting it all together

Unlocking a dataset with pool.dataset.unlock:

DATASET=mydataset
PASSPHRASE=mypassphrase

midclt call pool.dataset.unlock "${DATASET}" "{\"datasets\": [{\"name\": \"${DATASET}\",\"passphrase\": \"${PASSPHRASE}\"}]}"

Locking a dataset with pool.dataset.lock:

DATASET=mydataset

midclt call pool.dataset.lock "${DATASET}"

Easy, isn’t it?