Skip to content

Add TrueNAS Storage Driver#2157

Closed
mrstux wants to merge 232 commits intolxc:mainfrom
truenas:truenas-storage-driver
Closed

Add TrueNAS Storage Driver#2157
mrstux wants to merge 232 commits intolxc:mainfrom
truenas:truenas-storage-driver

Conversation

@mrstux
Copy link
Copy Markdown

@mrstux mrstux commented May 29, 2025

The TrueNAS Storage driver allows an Incus node to utilise a remote TrueNAS storage server to host one or more incus storage pools.

When the node is in a cluster, then all members of the cluster can use the storage pool simultaneously. This works well , for example, when live migrating a VM from one Incus node to another.

The driver is block-based, ie all Incus volumes are created as zvols on the remote server, and the zvol block devices are accessed on the local incus node via iscsi

The driver is modelled after the existing ZFS driver, and supports most existing ZFS functionality, but on a remote TrueNAS server.

For example, a local VM can be snapshotted and then cloned. The snapshot and cloning will be performed on the remote server after synchronizing the local filesystem, and the clone will then be activated via iSCSI as necessary.

The driver uses the truenas_incus_ctl tool, which provides a simple CLI interface to the TrueNAS API to effect changes on the remote server. Additionally, the tool can also activate/deactivate remote zvols using open-iscsi.

If the tool is not found, then the driver is disabled.

The latest version of the truenas tool can be obtained from : https://github.com/truenas/truenas_incus_ctl, and must be installed in the PATH supplied to incusd (v0.7.2+ is required)

open-iscsi can be installed with apt install open-iscsi

To login to the remote TrueNAS host first run the command:

sudo truenas_incus_ctl config login

Example:

$ sudo truenas_incus_ctl config login
[sudo] password for user: 
Enter a name for this connection: example
Enter the TrueNAS hostname or IP address: server.example.com
Setting up connection to TrueNAS host: server.example.com
Choose authentication method (1 for API Key, 2 for Username/Password): 2
Testing connection to wss://server.example.com/api/current...
Enter your TrueNAS username: truenas_admin
Enter your TrueNAS password: 
Generating API key...
API key successfully generated
Successfully connected to wss://server.example.com/api/current
Configuration for 'example' (connecting to server.example.com) saved to /root/.truenas_incus_ctl/config.json

After logging in, ensure iSCSI is configured and working with the following command:

sudo truenas_incus_ctl share iscsi setup --test

As an example of the functionality of the TrueNAS tool, this command can be used to list all datasets on the remote server

sudo truenas_incus_ctl dataset ls

Once logged in and iSCSI has been configured, the following command can be used to create a remote storage pool

incus storage create <poolname> truenas source=[host:]<pool>/<dataset>/[remote-poolname]

source is used to describe the location where the storage pool will be created on the remote TrueNAS host
host is optional, and remote-poolname will be set to poolname if not supplied.

truenas.config can be used to specify a specific login config
truenas.host can be used to specify a specific host, which the tool will lookup in the config.json

Running Tests

There are a number of INCUS_TRUENAS_ environment variables that can be used to configure the remote TrueNAS that will be used by the driver during the test. The only environment variable that is required is INCUS_TRUENAS_DATASET

I use the following commands in a script called start-tests.sh to run the suite using the default host configured in truenas_incus_ctl config file

sudo -E env PATH=$PATH INCUS_BACKEND=truenas INCUS_TRUENAS_DATASET=tank/se/incus-tests ./main-tn.sh $1

Alternatively, I specify a config for a different host. Hosts and API keys can also be specified manually to avoid the use of a config file. Alternate config files can be specified.

sudo -E env PATH=$PATH INCUS_VERBOSE=0 INCUS_TMPFS=0 INCUS_BACKEND=truenas INCUS_TRUENAS_DATASET=puddle/se/incus-tests INCUS_TRUENAS_CONFIG=goldeye2 ./main-tn.sh $1

I run the standalone tests using ./start-tests standalone, as the cluster tests require net ns support from truenas_incus_ctl which is not implemented.

main-tn.sh is the same as main.sh, except some tests which are problematic on my testing hosts are disabled.

main-tn.sh should probably be deleted once the ./main.sh standalone tests are verified

When running the test truenas_incus_ctl will be launched in daemon mode. It can be useful to prelaunch the daemon to view its console as the test suite runs.

for example:
sudo /home/<user>/go/bin/truenas_incus_ctl daemon /home/<user>/tncdaemon.sock

Incus CI Integration

I would suggest that a VM with a "golden" image of GoldEye with the middleware defer patch is used as a target. The truenas_incus_ctl tool should be built from master and the standalone tests used. A preconfigured config.json for the tool could be used to provide the host/api-key to use for the tests. A container dataset should be created and removed after the test suite is run.

Known Issues

@github-actions github-actions bot added Documentation Documentation needs updating API Changes to the REST API labels May 29, 2025
@mrstux mrstux force-pushed the truenas-storage-driver branch from 0f4c846 to a9a6817 Compare May 30, 2025 04:31
@william-gr
Copy link
Copy Markdown

Launching a new instance with a TrueNAS without iSCSI configure says:

Launching u1
Error: Failed instance creation: Failed creating instance from image: Failed to run: truenas_incus_ctl --host 192.168.1.10 share iscsi create tank/incusstorage/images/eb7ec38152a187619b1004f15f922a44cbbc11e46c6443bd119a6bd74854877f_ext4 --target-prefix=incus: exit status 1 (Error: 
No iSCSI portal was found for this host. Use:
<truenas_incus_ctl> share iscsi portal create --ip <IP address> --port <port number>
To create one.

<truenas_incus_ctl> share iscsi portal create --ip --port
suggestions seems wrong as that command is not valid.

@william-gr
Copy link
Copy Markdown

Logging in using the truenas incus ctl does not seem to work without a SSL certificate:

~/go/bin/truenas_incus_ctl config login --allow-insecure
Enter a name for this connection: test
Enter the TrueNAS hostname or IP address: 192.168.1.10
Setting up connection to TrueNAS host: 192.168.1.10
Choose authentication method (1 for API Key, 2 for Username/Password): 2
Testing connection to wss://192.168.1.10/api/current...
Error: Failed to create connection to wss://192.168.1.10/api/current: failed to connect: tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.10 because it doesn't contain any IP SANs
Usage:
  truenas_incus_ctl config login [flags]

@william-gr
Copy link
Copy Markdown

william-gr commented May 30, 2025

After manually creating the portal:

william@thinkpad[~]: ~/go/bin/incus launch -s tnpool images:debian/12 u1
Launching u1
Error: Failed instance creation: Failed creating instance from image: No path for activated TrueNAS volume: tank/incusstorage/images/eb7ec38152a187619b1004f15f922a44cbbc11e46c6443bd119a6bd74854877f_ext4

I had to manually start iSCSI service, a hint would have been great.

After that:

Error: Failed instance creation: Failed creating instance from image: Failed to run: truenas_incus_ctl --host 192.168.1.10 share iscsi create tank/incusstorage/images/eb7ec38152a187619b1004f15f922a44cbbc11e46c6443bd119a6bd74854877f_ext4 --target-prefix=incus: exit status 1 (Error: 

Error -32602
Invalid params
[EINVAL] iscsi_target_create.groups.0.initiator: 1 Initiator not found in database)

I tried creating initiator group but got same error.

It seems truenas_incus_ctl is hard-coding initiator id 1.

@mrstux
Copy link
Copy Markdown
Author

mrstux commented Jun 2, 2025

Logging in using the truenas incus ctl does not seem to work without a SSL certificate:

~/go/bin/truenas_incus_ctl config login --allow-insecure
Enter a name for this connection: test
Enter the TrueNAS hostname or IP address: 192.168.1.10
Setting up connection to TrueNAS host: 192.168.1.10
Choose authentication method (1 for API Key, 2 for Username/Password): 2
Testing connection to wss://192.168.1.10/api/current...
Error: Failed to create connection to wss://192.168.1.10/api/current: failed to connect: tls: failed to verify certificate: x509: cannot validate certificate for 192.168.1.10 because it doesn't contain any IP SANs
Usage:
  truenas_incus_ctl config login [flags]

This bug has been fixed in truenas_incus_ctl now

https://github.com/truenas/truenas_incus_ctl/pull/40/commits

@mrstux
Copy link
Copy Markdown
Author

mrstux commented Jun 2, 2025

After manually creating the portal:

william@thinkpad[~]: ~/go/bin/incus launch -s tnpool images:debian/12 u1
Launching u1
Error: Failed instance creation: Failed creating instance from image: No path for activated TrueNAS volume: tank/incusstorage/images/eb7ec38152a187619b1004f15f922a44cbbc11e46c6443bd119a6bd74854877f_ext4

I had to manually start iSCSI service, a hint would have been great.

I've added a hint to the instructions at the top of this post, and there is an issue to add iscsi service control support to the tool. Once that's added I'll include the exact incantation to ensure the iscsi service is created.

After that:

Error: Failed instance creation: Failed creating instance from image: Failed to run: truenas_incus_ctl --host 192.168.1.10 share iscsi create tank/incusstorage/images/eb7ec38152a187619b1004f15f922a44cbbc11e46c6443bd119a6bd74854877f_ext4 --target-prefix=incus: exit status 1 (Error: 

Error -32602
Invalid params
[EINVAL] iscsi_target_create.groups.0.initiator: 1 Initiator not found in database)

I tried creating initiator group but got same error.

It seems truenas_incus_ctl is hard-coding initiator id 1.

Enhanced Portal + Initiator support is being implemented in the Tool.

Once this is implemented, portal+initiator creation/usage should be automatic, but the driver has properties that will allow overriding the automatic selections (tool support is required)

@jbendtsen
Copy link
Copy Markdown

The issues described in this thread should all be fixed, but more testing will be conducted to confirm.

@mrstux mrstux force-pushed the truenas-storage-driver branch from c1ff8a9 to cc5588d Compare June 4, 2025 06:38
@mrstux mrstux force-pushed the truenas-storage-driver branch 9 times, most recently from e49e5a0 to 1f37754 Compare June 12, 2025 22:34
@mrstux
Copy link
Copy Markdown
Author

mrstux commented Jun 12, 2025

./start-test standalone

...

==> Test result: success

@mrstux mrstux marked this pull request as ready for review June 12, 2025 22:59
@mrstux mrstux requested a review from stgraber as a code owner June 12, 2025 22:59
@mrstux
Copy link
Copy Markdown
Author

mrstux commented Jun 16, 2025

@stgraber I don’t believe the Linstor failure is related to this PR

@stgraber
Copy link
Copy Markdown
Member

Yeah, it's not, we're seeing it everywhere now, something must have changed in Linstor.

@mrstux mrstux force-pushed the truenas-storage-driver branch from 1f37754 to 9b68c3d Compare June 25, 2025 08:09
Stuart Espey added 24 commits August 12, 2025 07:20
The TrueNAS storage driver uses open-iscsi, which is incompatible with net-ns, which is used by the cluster tests
This file was used during the development of the driver, but should not be needed anymore.
The loop was problematic, it took a long time, and was sensitive to drivers which require
longer to re-activate after a kill

The core issue was that if we use >4s then we get good reliability, but we can exceed the
60s timeout window, and thus fail the loop

The solution is to try to wait for the PID to be available, rather than hoping it it is available
after we wait for a fixed time.

This actually results in faster testing, and should be more reliable
The `:` characters in IPv6 IP address was resulting in improper host:dataset splitting when parsing source property
…reate activate failure

When locate --create is called, and create succeeds, but discovery fails, the tool may not return an error, and skip activation. In this case we return an obtuse error about unable to find path.

The error has been fixed in the tool, but as belt+braces, more explici handling has been added to the driver to suggest a possible communications issue

Also, the generic error has been improved.
@mrstux mrstux force-pushed the truenas-storage-driver branch from da773ff to f27d435 Compare August 12, 2025 07:21
@mrstux
Copy link
Copy Markdown
Author

mrstux commented Aug 12, 2025

And, I applied the EnsureMountPath changes. The neat thing is that the driver and the zfs driver are very similar... so easy to apply the change based on the zfs driver's changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API Changes to the REST API Documentation Documentation needs updating

Development

Successfully merging this pull request may close these issues.

5 participants