Using the FreeNAS v2.0 API

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Hello,

I'm posting to this thread mainly because I couldn't identify a section more precisely dedicated to the matter of programming with the FreeNAS API, hope this won't be problematic. And, since my specific interest is using the API to manage various aspects of the sharing functions offered by FreeNAS, it seemed to make sense to post here. I hope this is appropriate.

I've been trying to get started with the new websocket interface but with little luck as I already explained in a previous post which, up to now, has received zero answer which is not really encouraging :'(

I hope that this one will receive a little more answer ;-)

I'm currently writing some Bash scripts that intend to interact with FreeNAS through its API using curl and jq.
They use the v2.0 API which documentation, although interestingly available through a Swagger (OpenAPI) model that offers a wealth of documentation possibilities, is currently particularly minimal. Except for the endpoints nomenclature and JSON models, it provides absolutely no additional indication regarding the effective usage of the API. We, as developers, are thus left to our own to try and discover what works and what doesn't, what values will be accepted or rejected, which ones are required or optional and so on...

Enough with the whining, I'm here to ask for serious indications whether it is worth to hope for a real possibility of developing solutions using the FreeNAS API.

As said earlier I'm mainly interested in managing ISCSI extents and SAMBA shares and here are a few of the main problems I'm facing at the moment.
The system is quite sturdy and I'd be surprised that the situation would result from a lack of resources...

System configuration:
SuperMicro X9DRD-7LN4F JBOD - Dual Xeon E-2620 @2.10GHz (12 cores / 24 threads) - 192 GB ECC RAM - 36 HDD (+/- 100TB)

1. Gateway Timeouts
When accessing the sharing/smb endpoint with a payload of type:
Code:
{ "path": "/mnt/Pool1/Test", "home": false, "name": "Test", "comment": "", "ro": false, "browsable": true, "recyclebin": false, "showhiddenfiles": false, "guestok": true, "guestonly": false, "abe": false, "auxsmbconf": "follow symlinks = yes%x0Awide links = yes", "default_permissions": false }

I each time receive the following: HTTP ERROR STATUS 504 : Gateway Timeout
Nonetheless the share gets effectively created and is available even though the reported error, the problem is that it makes things difficult to manage since the script's error management is not supposed to know that the intended action was successful when it receives an error.

My guess is that the uwsgi configuration is set in such a way that it gives up waiting for a script answer before it is returned. Could anyone indicate me whether this can be the cause of the problem, and if it is, how to possibly fix it?

2. Limitations of the sharing/iscsi endpoint
Although it is possible, through the FreeNAS interface, to create ISCSI extents with a blocksize of 4096K, submitting the following payload to the v2.0 API returns a blocking message:
Code:
'{ name: "01.TEST", disk: "zvol/Pool1/Test/01.TEST/VHD", type: "DISK", blocksize: 4096, pblocksize: true, insecure_tpc: true, xen: false, rpm: "SSD", ro: false, legacy: false }'

Returns:
Code:
{ "blocksize": [ { "message": "Invalid choice: 4096", "errno": 22 } ] }

Is there anything I can do to "allow" this value of 4096?
Could someone indicate me what scripts are getting executed with those API calls in order to adapt them manually maybe as a temporary workaround?

Any useful information regarding those problems would be greatly appreciated.
Thank you!
 
Last edited:

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
A quick and dirty workaround to the API blocksize setting problem

As I wasn't able to find a way to set the ISCSI Extent blocksize using the v2.0 API, I implemented a quick (and dirty) workaround.

First it is important to note that FreeNAS "extents" can be considered as ISCSI LUN descriptors. What that means is that, contrarily to setting a new SAMBA share for example, which, on top of storing data to the FreeNAS database, immediately launches a series of subsequent processes, like smb4.conf file reconstruction and samba_server service reload, defining an ISCSI "extent" simply stores a LUN description in the FreeNAS database. It is only when the extent is linked to a target that this information gets used to rebuild the ctl.conf file before reloading the ctld service.

It is thus reasonable to modify entries from the services_iscsitargetextent table in the FreeNAS database, before they are associated with a target. Which is obviously the case when the modification takes place right after the extent creation...

Thus, to workaround the API limitation, the code skips the blocksize value in the initial API call (setting the default value of 512). Then it recovers the id of the newly (API) created extent, which is returned in the response body of the API call, and issues an sqlite command to directly modify its iscsi_target_extent_blocksize column. Here is a sample of what the code looks like in a bash script using curl, sqlite and the fantastic jq library which greatly simplifies JSON data manipulations:
Code:
payload='{ name: "01.EXTENT-TEST", disk: "zvol/Pool1/Test/zvolume", type: "DISK", pblocksize: true, insecure_tpc: true, xen: false, rpm: "SSD", ro: false, legacy: false }'
response=$(curl --silent -X "POST" -d "$payload"  --header "Content-Type: application/json" --user "root:freenaspass" "my.free.nas.ip:port/iscsi/extent")
extentid=$(echo "$response" | jq -r ".id")
sqlite3 /data/freenas-v1.db "UPDATE services_iscsitargetextent SET iscsi_target_extent_blocksize=4096 WHERE id=$extentid"

Note that, as written above, the bash script has to be executed as root (or with sudo privileges) on the FreeNAS server itself...
 
D

dlavigne

Guest
If you believe there is a limitation in the API, please create a report at bugs.ixsystems.com and post the issue number here.
 
Top