Repository navigation
API Reference
All endpoints are served at http://<host>:8080. The API is JSON-over-HTTP; all request and response bodies are application/json.
| Method | Path | Description |
|---|---|---|
| GET | /api/sysinfo |
Host and process info |
| GET | /api/network |
Network interfaces (name, state, MAC, MTU, IPs, speed, RX/TX) |
| GET | /api/version |
OpenZFS version string |
| GET | /api/pools |
List all pools with usage stats |
| GET | /api/poolstatus |
Detailed pool status with vdev tree |
| GET | /api/datasets |
List all datasets and volumes |
| GET | /api/dataset-props/{name} |
Editable properties for a dataset |
| GET | /api/snapshots |
List all snapshots |
| GET | /api/snapshots/diff |
Files changed between snapshots (zfs diff) |
| GET | /api/iostat |
Pool I/O statistics (1-second sample) |
| GET | /api/smart |
S.M.A.R.T. health per disk |
| GET | /api/events |
Server-Sent Events stream |
| GET | /metrics |
Prometheus text exposition |
| GET | /api/schema |
Dataset property definitions and system metadata for the current OS |
| POST | /api/datasets |
Create a dataset or volume |
| PATCH | /api/datasets/{name} |
Update dataset properties |
| DELETE | /api/datasets/{name} |
Destroy a dataset or volume |
| POST | /api/datasets/rename |
Rename a dataset or volume ({"name","new_name"}, same parent) |
| POST | /api/rewrite/{name} |
Rewrite existing blocks (zfs rewrite, background job) |
| GET | /api/userspace/{name} |
Per-user/group space usage (?kind=user|group) |
| POST | /api/userquota/{name} |
Set or remove a per-user/group quota |
| POST | /api/snapshots |
Create a snapshot |
| POST | /api/snapshots/clone |
Clone a snapshot to a new dataset |
| POST | /api/snapshots/send |
Send a snapshot to a target dataset (local or remote SSH) |
| POST | /api/snapshots/delete-batch |
Destroy several snapshots ({"snapshots":[...]}) |
| DELETE | /api/snapshots/{name} |
Destroy a snapshot |
| GET | /api/users |
List local users |
| POST | /api/users |
Create a local user |
| PUT | /api/users/{name} |
Edit user (shell, groups, password) |
| DELETE | /api/users/{name} |
Delete user and home directory |
| GET | /api/users/{name}/sshkeys |
List a user's SSH authorized keys |
| POST | /api/users/{name}/sshkeys |
Add an SSH authorized key |
| DELETE | /api/users/{name}/sshkeys |
Remove an SSH authorized key ({"key":"ssh-ed25519 …"}) |
| GET | /api/groups |
List local groups |
| POST | /api/groups |
Create a local group |
| PUT | /api/groups/{name} |
Edit group (name, GID, members) |
| DELETE | /api/groups/{name} |
Delete a local group |
| GET | /api/chown/{dataset} |
Get mountpoint owner and group |
| POST | /api/chown/{dataset} |
Set mountpoint owner and/or group |
| GET | /api/acl-status |
ACL presence map (dataset → bool) |
| GET | /api/acl/{dataset} |
Get ACL entries for a dataset |
| POST | /api/acl/{dataset} |
Add or modify an ACL entry |
| DELETE | /api/acl/{dataset} |
Remove an ACL entry |
| GET | /api/smb-shares |
List active Samba usershares |
| POST | /api/smb-share/{dataset} |
Create or update a Samba usershare |
| DELETE | /api/smb-share/{dataset} |
Remove a Samba usershare |
| GET | /api/smb-users |
List users registered in smbpasswd |
| POST | /api/smb-users/{name} |
Add a user to smbpasswd |
| DELETE | /api/smb-users/{name} |
Remove a user from smbpasswd |
| GET | /api/smb/status |
Samba init state, conf path, OS, wsdd status |
| POST | /api/smb/init |
Initialise Samba (back up existing config, render smb.conf) |
| POST | /api/smb/wsdd |
Render wsdd options from smb.conf (take over wsdd) |
| GET | /api/smb/homes |
Get current SMB [homes] config |
| POST | /api/smb/homes |
Enable/update SMB [homes] section |
| DELETE | /api/smb/homes |
Disable/remove SMB [homes] section |
| GET | /api/smb/timemachine |
List all Time Machine shares |
| POST | /api/smb/timemachine |
Create/update a Time Machine share |
| DELETE | /api/smb/timemachine/{name} |
Remove a Time Machine share |
| GET | /api/devices |
List physical block devices (vdev candidates, in-use flag) |
| POST | /api/pools |
Create a pool (zpool create) |
| GET | /api/pools/importable |
List pools available for import |
| POST | /api/pools/import |
Import a pool (zpool import [-f]) |
| POST | /api/pools/{pool}/export |
Export a pool (zpool export) |
| POST | /api/pools/{pool}/vdevs |
Add a data vdev (zpool add) |
| POST | /api/pools/{pool}/cache |
Add an L2ARC cache device |
| POST | /api/pools/{pool}/log |
Add a SLOG log device (optionally mirrored) |
| POST | /api/pools/{pool}/spare |
Add a hot spare |
| DELETE | /api/pools/{pool}/devices/{device} |
Remove a cache/log/spare device (zpool remove) |
| POST | /api/pools/{pool}/replace |
Replace a pool device (starts resilver) |
| POST | /api/pools/{pool}/offline |
Take a pool device offline |
| POST | /api/pools/{pool}/online |
Bring a pool device online |
| POST | /api/scrub/{pool} |
Start a pool scrub |
| DELETE | /api/scrub/{pool} |
Cancel a running pool scrub |
| GET | /api/scrub-schedules |
List periodic scrub schedule config |
| PUT | /api/scrub-schedule/{pool} |
Add pool to periodic scrub schedule |
| DELETE | /api/scrub-schedule/{pool} |
Remove pool from periodic scrub schedule |
| GET | /api/auto-snapshot/{dataset} |
Get auto-snapshot property values for a dataset |
| PUT | /api/auto-snapshot/{dataset} |
Set auto-snapshot properties for a dataset |
| GET | /api/auto-snapshot/status |
Auto-snapshot ownership (OS daemon vs dumpstore) |
| POST | /api/auto-snapshot/takeover |
Disable the OS daemon and run snapshots from dumpstore |
| POST | /api/auto-snapshot/release |
Re-enable the OS daemon and stop dumpstore's scheduler |
| GET | /api/auto-snapshot-schedules |
Auto-snapshot properties for all datasets |
| GET | /api/iscsi-targets |
List all iSCSI targets |
| POST | /api/iscsi-targets |
Create an iSCSI target for a zvol |
| DELETE | /api/iscsi-targets |
Remove an iSCSI target |
| GET | /api/services |
List status of all managed services |
| POST | /api/services/{name}/{action} |
Control a service (start/stop/restart/enable/disable) |
| GET | /api/replication |
List scheduled replication tasks |
| POST | /api/replication |
Create a replication task |
| PATCH | /api/replication/{id} |
Update a replication task |
| DELETE | /api/replication/{id} |
Delete a replication task |
| POST | /api/replication/{id}/run |
Fire a replication task immediately (returns 202 + job_id) |
| GET | /api/replication/{id}/history |
Recent run records for a task |
| GET | /api/jobs |
List background jobs |
| GET | /api/jobs/{id} |
Single job status |
| POST | /api/jobs/{id}/cancel |
Cancel a running job (SIGTERM, then SIGKILL) |
| DELETE | /api/jobs/{id} |
Remove a finished job record |
| GET | /api/tls/status |
TLS configuration and certificate metadata |
| POST | /api/tls/gencert |
Generate a self-signed certificate |
| PATCH | /api/tls/config |
Use an existing certificate + key from disk |
| POST | /api/tls/acme/issue |
Issue a certificate via ACME (lego) |
| POST | /api/tls/acme/renew |
Renew the ACME certificate |
| GET | /login |
Login page |
| POST | /auth/login |
Log in (form: username, password); sets the session cookie |
| POST | /auth/logout |
Log out |
| GET | /api/whoami |
Current identity (session or trusted-proxy X-Remote-User) |
| GET | /api/auth/config |
Configured username and session TTL |
| POST | /api/auth/change-password |
Change the login password |
| POST | /api/auth/change-username |
Change the login username |
Create a filesystem or volume.
{
"name": "tank/data",
"type": "filesystem",
"compression": "lz4",
"quota": "50G",
"mountpoint": "/mnt/data",
"recordsize": "128K",
"atime": "off",
"exec": "on",
"sync": "standard",
"dedup": "off",
"copies": "1",
"xattr": "sa"
}For volumes, use "type": "volume" and add "volsize": "10G". Optional: "volblocksize", "sparse": true.
Update dataset properties. Any subset of editable properties may be sent. An empty string value resets the property to inherited; a non-empty value sets it explicitly. Unknown properties are ignored.
{
"compression": "zstd",
"quota": "",
"readonly": "on"
}Editable properties: compression, quota, mountpoint, recordsize, atime, exec, sync, dedup, copies, xattr, readonly, acltype, sharenfs, sharesmb.
Rewrite the existing blocks of a mounted filesystem via zfs rewrite so that updated properties (compression, checksum, dedup, copies) apply to already-stored data. Runs as a background job — returns 202 Accepted with a job_id; progress and output appear in the Jobs tab (GET /api/jobs).
{
"recursive": true,
"skip_snapshot_shared": true,
"skip_clone_shared": false
}-
recursive→-r(recurse into directories; crosses into child dataset mountpoints) -
skip_snapshot_shared→-S(don't duplicate blocks shared with snapshots) -
skip_clone_shared→-C(don't duplicate blocks shared via block cloning)
Caveats: recordsize changes are not applied by rewrite; rewriting blocks shared with snapshots/clones duplicates them (pool usage can increase) unless skipped; rewritten blocks appear as modified in incremental send streams. Volumes are rejected with 400 — rewrite operates through the mounted filesystem. Requires OpenZFS with zfs rewrite support (2.3+).
Per-user or per-group space consumption and quotas for a dataset, via zfs userspace -Hp / zfs groupspace -Hp. Query parameter kind is user (default) or group.
{
"dataset": "tank/data",
"kind": "user",
"rows": [
{ "name": "alice", "used": 1073741824, "quota": 10737418240 },
{ "name": "root", "used": 53248, "quota": 0 }
]
}quota: 0 means no quota is set.
Set or remove a per-user/per-group quota (userquota@<principal> / groupquota@<principal>).
{ "kind": "user", "principal": "alice", "quota": "10G" }"quota": "none" removes the limit. Returns Ansible task steps.
Destroy a dataset or volume. Append ?recursive=true to also destroy all child datasets and snapshots.
Pool roots (e.g. tank) cannot be deleted via this endpoint — use zpool destroy.
{
"dataset": "tank/data",
"snapname": "2024-01-15_backup",
"recursive": false
}Dispatch zfs send | zfs recv as a background job. Returns 202 Accepted immediately with the job metadata; live status is published on the jobs.update SSE topic and visible in the Jobs tab. Local target:
{
"snapshot": "tank/data@2026-05-06",
"target": "backup/data",
"incremental_from": "tank/data@2026-05-05",
"raw": false
}Add "remote": "user@host" to receive over SSH (ssh -o BatchMode=yes); the dumpstore service account must have SSH keys pre-configured for host. incremental_from and raw are optional. Response shape:
{
"job_id": "8f3c…",
"type": "snapshot.send",
"started_at": "2026-05-06T15:21:33Z",
"snapshot": "tank/data@2026-05-06",
"target": "user@host:backup/data"
}Use GET /api/jobs/{id} to poll status, or subscribe to the jobs.update SSE topic.
Show files changed between two snapshots, or between a snapshot and the live dataset, via zfs diff -H.
Query parameters:
-
from(required) — the older snapshot (dataset@label) -
to(optional) — a later snapshot of the same dataset; omit to diff against the current filesystem state
{
"from": "tank/data@before",
"to": "tank/data@after",
"truncated": false,
"entries": [
{ "change": "+", "path": "/tank/data/new.txt" },
{ "change": "-", "path": "/tank/data/gone.txt" },
{ "change": "M", "path": "/tank/data/report.pdf" },
{ "change": "R", "path": "/tank/data/old.txt", "new_path": "/tank/data/renamed.txt" }
]
}Entries are capped at 10 000 (truncated: true when more changed). The dataset must be mounted for zfs diff to work.
Long-running data-plane operations (currently snapshot send/receive) run as direct child processes outside Ansible, since they may run for hours. Each job has a status (running, success, failed, cancelled, interrupted), the captured argv, bounded stdout/stderr tails (last 64 KiB each), and timestamps. Records are persisted to disk so status survives a restart; any job left in running at shutdown is rewritten to interrupted on next boot.
Returns the list of known jobs, newest first.
Returns a single job's full record (including stdout/stderr tail).
Sends SIGTERM to the job's process group, escalating to SIGKILL after a 10 s grace. Returns 204 No Content on success, 400 if the job is already terminal.
Removes a terminal job from the manager and deletes its on-disk record. Returns 204 No Content on success, 400 if the job is still running (cancel it first).
Cron-scheduled replication tasks. Each fire creates a dumpstore-repl-<UTC> snapshot on the source, holds it for the duration of the transfer, picks the most recent common dumpstore-repl-* snapshot for an incremental send, dispatches the pipeline through the jobs runner, releases the hold, and prunes destination replication snapshots beyond the retention count.
Returns all replication tasks (without last_runs). Use /history to retrieve run records.
Create a task. enabled and retention_count default to true and 7 respectively.
{
"name": "nightly-backup",
"source": "tank/data",
"target": "backup/data",
"remote": "user@host",
"schedule": "0 3 * * *",
"retention_count": 7,
"raw": false,
"recursive": false,
"enabled": true
}schedule is a standard 5-field cron expression (minute, hour, day-of-month, month, day-of-week) with 1-minute resolution and no catch-up on missed firings. remote is optional; when empty the task replicates between local pools.
Partial update; any subset of the above fields is accepted. Re-registers the task with the scheduler.
Unregister and remove the task. Replicated snapshots on the destination, and dumpstore-repl-* snapshots on the source, are not deleted.
Fire the task immediately, off-schedule. Returns 202 Accepted with the job_id of the dispatched send/recv pipeline. The body of the running task continues asynchronously; subscribe to jobs.update for completion.
Returns the recent RunRecord list (capped at 20):
[
{
"job_id": "8f3c…",
"snapshot": "tank/data@dumpstore-repl-20260524T030000Z",
"started_at": "2026-05-24T03:00:00Z",
"finished_at": "2026-05-24T03:11:42Z",
"status": "success"
}
]Append ?recursive=true to also destroy clones.
Create a new pool via zpool create. Destroys all existing data on the selected devices — the UI gates this behind confirm-by-typing.
{
"name": "tank",
"vdev_type": "mirror",
"devices": ["/dev/sdb", "/dev/sdc"],
"ashift": "12",
"compression": "zstd"
}vdev_type: single (stripe, no redundancy keyword), mirror, raidz1, raidz2, raidz3, draid, draid2, draid3. Minimum device counts are enforced (mirror ≥ 2, raidzN ≥ N+1, draidN ≥ N+1). ashift (9–16) and compression are optional. Returns 409 if a pool with that name already exists. Returns Ansible task steps.
Scans with zpool import (no pool name) and returns pools available for import.
[
{ "name": "tank", "id": "11536261005894085344", "state": "ONLINE" },
{ "name": "backup", "id": "9183745610293847561", "state": "DEGRADED", "status": "One or more devices are missing from the system." }
]{ "pool": "tank", "force": false }force: true passes -f — needed for pools that were not cleanly exported or belonged to another system. Returns Ansible task steps.
Export the pool via zpool export. Fails when the pool is busy (open files, active shares, running jobs) — the error is surfaced in the op-log. Returns Ansible task steps.
Add a data vdev via zpool add. Irreversible on most pool layouts — the UI gates this behind confirm-by-typing.
{ "vdev_type": "mirror", "devices": ["/dev/sdd", "/dev/sde"] }vdev_type: single, mirror, raidz1, raidz2, raidz3 (minimum device counts enforced). Returns Ansible task steps.
Add auxiliary devices: L2ARC cache, SLOG log, or hot spare.
{ "devices": ["/dev/nvme0n1"] }For /log, an optional "mirror": true mirrors the log devices (requires ≥ 2). Returns Ansible task steps.
Remove a cache, log, or spare device via zpool remove. zpool itself rejects removals that aren't legal for the given vdev. Returns Ansible task steps.
Returns the physical block devices on the host (Linux: /sys/block, skipping loop/ram/zvol/dm pseudo-devices; FreeBSD: geom disk list). in_use_by carries the pool name when the device currently backs a vdev (best-effort matching: by-id/by-path symlinks resolved, partition suffixes stripped).
[
{ "name": "sdb", "path": "/dev/sdb", "size_bytes": 4000787030016, "model": "WDC WD40EFRX", "in_use_by": "tank" },
{ "name": "sdc", "path": "/dev/sdc", "size_bytes": 4000787030016, "model": "WDC WD40EFRX", "in_use_by": "" }
]Replace a vdev with a new device via zpool replace. A resilver onto the new device starts automatically; progress is visible in the pool's scan field (GET /api/poolstatus, poolstatus SSE topic).
{ "old_device": "sdb", "new_device": "/dev/sdc" }old_device accepts a device name, path, or the numeric guid zpool status prints for missing devices. Returns Ansible task steps.
Take a device offline for maintenance via zpool offline. Body: { "device": "sdb" }. Returns Ansible task steps.
Bring an offlined device back via zpool online. Body: { "device": "sdb" }. Returns Ansible task steps.
Start a scrub on the named pool. Returns Ansible task steps.
Cancel a running scrub on the named pool. Returns Ansible task steps.
Returns the current periodic scrub configuration for all pools.
{
"mode": "zfsutils",
"schedules": [
{ "pool": "tank" }
]
}mode is "zfsutils" on Linux (managed via ZFS_SCRUB_POOLS in /etc/default/zfs) or "periodic" on FreeBSD (managed via daily_scrub_zfs_pools in /etc/periodic.conf). On FreeBSD, threshold_days is also returned (default 35). An empty schedules array means all pools are scrubbed by the platform default.
Add a pool to the periodic scrub schedule. On FreeBSD, an optional threshold_days body field sets how many days must elapse before a scrub is triggered.
{ "threshold_days": 35 }Returns Ansible task steps.
Remove a pool from the periodic scrub schedule. Returns Ansible task steps.
Manages com.sun:auto-snapshot* ZFS user properties per dataset. These properties are consumed by zfs-auto-snapshot (Linux) or zfstools (FreeBSD) to automatically create and rotate snapshots. dumpstore sets/clears the properties; the external daemon handles snapshot creation.
zfs-auto-snapshot uses an opt-out model: any dataset where com.sun:auto-snapshot is not explicitly set is snapshotted by default. Setting the property to false is how you exclude a dataset.
The recommended pattern for snapshotting only specific datasets:
# 1. Opt the entire pool out
zfs set com.sun:auto-snapshot=false tank
# 2. Opt specific datasets back in
zfs set com.sun:auto-snapshot=true tank/data
zfs set com.sun:auto-snapshot=true tank/home# All datasets, all 6 properties
zfs get com.sun:auto-snapshot,com.sun:auto-snapshot:frequent,com.sun:auto-snapshot:hourly,com.sun:auto-snapshot:daily,com.sun:auto-snapshot:weekly,com.sun:auto-snapshot:monthly -t filesystem,volume
# Recursively from a pool root
zfs get -r com.sun:auto-snapshot tank
# Only locally-set values (excludes inherited/default)
zfs get -r -s local com.sun:auto-snapshot tankReturns the current com.sun:auto-snapshot* property values and their source (local/inherited/default) for the given dataset.
{
"com.sun:auto-snapshot": { "value": "true", "source": "local" },
"com.sun:auto-snapshot:frequent": { "value": "4", "source": "local" },
"com.sun:auto-snapshot:hourly": { "value": "24", "source": "local" },
"com.sun:auto-snapshot:daily": { "value": "7", "source": "local" },
"com.sun:auto-snapshot:weekly": { "value": "4", "source": "local" },
"com.sun:auto-snapshot:monthly": { "value": "-", "source": "default" }
}A value of "-" with source of "default" means the property is not set (inherits system default).
Set or clear com.sun:auto-snapshot* properties on a dataset. Returns Ansible task steps.
Request body — any combination of these keys; omitted keys are left unchanged:
| Key | Values |
|---|---|
com.sun:auto-snapshot |
"true", "false", or "" (inherit) |
com.sun:auto-snapshot:frequent |
integer 1–9999, or "" (inherit) |
com.sun:auto-snapshot:hourly |
integer 1–9999, or "" (inherit) |
com.sun:auto-snapshot:daily |
integer 1–9999, or "" (inherit) |
com.sun:auto-snapshot:weekly |
integer 1–9999, or "" (inherit) |
com.sun:auto-snapshot:monthly |
integer 1–9999, or "" (inherit) |
Empty string ("") triggers zfs inherit on the property (clears the local value).
{
"com.sun:auto-snapshot": "true",
"com.sun:auto-snapshot:daily": "7",
"com.sun:auto-snapshot:monthly": "3"
}Expose ZFS volumes as iSCSI targets. Uses targetcli/LIO on Linux or ctld on FreeBSD. Endpoints return 501 if no backend is detected.
List all iSCSI targets backed by ZFS volumes.
[
{
"iqn": "iqn.2024-03.io.dumpstore:tank-vms-win11",
"zvol_name": "tank/vms/win11",
"zvol_device": "/dev/zvol/tank/vms/win11",
"lun": 0,
"portals": ["0.0.0.0:3260"],
"auth_mode": "none",
"initiators": []
}
]Create an iSCSI target for a ZFS volume.
{
"zvol": "tank/vms/win11",
"iqn": "iqn.2024-03.io.dumpstore:tank-vms-win11",
"portal_ip": "0.0.0.0",
"portal_port": "3260",
"auth_mode": "none",
"chap_user": "",
"chap_password": "",
"initiators": []
}| Field | Required | Description |
|---|---|---|
zvol |
yes | ZFS volume name, must contain /
|
iqn |
yes | RFC 3720 iSCSI Qualified Name (iqn.YYYY-MM.domain:name) |
portal_ip |
no | Listen IP, defaults to 0.0.0.0
|
portal_port |
no | Listen port, defaults to 3260
|
auth_mode |
yes |
"none" or "chap"
|
chap_user |
when chap | CHAP username |
chap_password |
when chap | CHAP password |
initiators |
no | Array of allowed initiator IQNs; empty = allow all |
Returns Ansible task steps.
Remove an iSCSI target and its backstore. Both query parameters are required.
Returns Ansible task steps.
Manage the sharing daemons dumpstore controls (Samba, NFS, iSCSI). Status reads happen directly via systemctl/service — no Ansible overhead. Mutations (start/stop/restart/enable/disable) go through playbooks with op-log.
Logical service names: samba, nfs, iscsi, wsdd.
Returns the status of all managed services.
[
{
"name": "samba",
"display_name": "Samba (SMB)",
"unit_name": "smbd",
"active": true,
"enabled": true,
"state": "active",
"installed": true
}
]state values: active, inactive, failed, unknown. installed is false when the unit file (Linux) or rc.d script (FreeBSD) is absent — unit_name is then the preferred candidate name.
Control a service. Valid actions: start, stop, restart, enable, disable.
Returns Ansible task steps. 409 if the service is not installed on this host.
Returns the ACL type and entries for the dataset's mountpoint.
{
"dataset": "tank/data",
"mountpoint": "/mnt/data",
"acl_type": "posix",
"entries": [
{ "tag": "user", "qualifier": "", "perms": "rwx", "default": false },
{ "tag": "user", "qualifier": "alice", "perms": "r-x", "default": false },
{ "tag": "group", "qualifier": "", "perms": "r-x", "default": false },
{ "tag": "mask", "qualifier": "", "perms": "rwx", "default": false },
{ "tag": "other", "qualifier": "", "perms": "---", "default": false }
]
}acl_type is one of "posix", "nfsv4", or "off".
For NFSv4 datasets each entry has the form:
{ "tag": "A", "flags": "fd", "qualifier": "OWNER@", "perms": "rwaDxtTnNcCoy" }Add or modify an ACL entry. The ace string format depends on the dataset's acltype:
-
POSIX:
setfacl -mspec —"user:alice:rwx","group:storage:r-x","default:user:alice:rwx" -
NFSv4: full ACE string —
"A::alice@localdomain:rwaDxtTnNcCoy"
{ "ace": "user:alice:rwx", "recursive": false }recursive (POSIX only) applies setfacl -R to all files inside the mountpoint.
Remove an ACL entry. The entry query parameter:
-
POSIX:
user:alice,default:group:storage - NFSv4: full ACE string to match
Append &recursive=true (POSIX only) to remove recursively.
Manage the Samba [homes] section in smb.conf. When enabled, each authenticated user automatically gets a personal share mapped to a subdirectory under the configured base path.
Returns the current [homes] configuration. If the section is not present, enabled is false and all fields are empty.
{
"enabled": true,
"path": "/tank/homes/%S",
"browseable": "yes",
"read_only": "no",
"create_mask": "0644",
"directory_mask": "0755"
}Enable or update the [homes] section. Returns Ansible task steps.
{
"path": "/tank/homes/%S",
"dataset": "tank/homes",
"browseable": "yes",
"read_only": "no",
"create_mask": "0644",
"directory_mask": "0755"
}| Field | Required | Description |
|---|---|---|
path |
yes | Base path for home directories (may include %S for username substitution) |
dataset |
no | ZFS dataset to use as base path (alternative to specifying path directly) |
browseable |
yes |
"yes" or "no" — whether the share is visible in browse lists |
read_only |
yes |
"yes" or "no"
|
create_mask |
no | File creation mask (default "0644") |
directory_mask |
no | Directory creation mask (default "0755") |
Remove the [homes] section from smb.conf. Returns Ansible task steps.
wsdd announces the host in the Windows Network view. It advertises only the host and its workgroup, so dumpstore derives everything from smb.conf — there are no separate settings. GET /api/smb/status carries a wsdd object:
| Field | Description |
|---|---|
installed |
wsdd unit (Linux) / rc.d script (FreeBSD) present |
install_hint |
Distro install command (only when not installed) |
unit, state, active, enabled
|
Service status (wsdd-server on Debian/Ubuntu, else wsdd) |
conf_path |
Options file dumpstore renders — the unit's EnvironmentFile; "" on FreeBSD |
manageable |
Linux: the unit expands $WSDD_PARAMS; always true on FreeBSD |
managed |
Options file carries dumpstore's header (FreeBSD: always true — rc.d reads smb4.conf) |
workgroup |
Workgroup announced ("" → wsdd's default WORKGROUP; names with spaces/shell characters are not passed) |
On Linux every Samba config write (smb_apply.yml) also renders the options file and restarts wsdd only if it was running and the file changed.
Re-applies the current Samba config so the wsdd options file is rendered — for hosts where wsdd was installed after Samba was initialised. Returns Ansible task steps. 409 if Samba is not initialised, or wsdd is not installed / its unit does not read $WSDD_PARAMS.
Manage Samba shares configured as macOS Time Machine backup targets using vfs_fruit with catia and streams_xattr VFS modules.
List all Time Machine shares. Parses smb.conf for sections with fruit:time machine = yes.
[
{
"sharename": "timemachine",
"path": "/tank/backups/timemachine",
"max_size": "1T",
"valid_users": "alice bob"
}
]Create or update a Time Machine share. Returns Ansible task steps.
{
"sharename": "timemachine",
"dataset": "tank/backups",
"path": "/tank/backups/timemachine",
"max_size": "1T",
"valid_users": "alice bob"
}| Field | Required | Description |
|---|---|---|
sharename |
yes | Samba share name |
dataset |
no | ZFS dataset (alternative to specifying path directly) |
path |
yes | Filesystem path for the share |
max_size |
no | Maximum size quota for Time Machine backups |
valid_users |
no | Space-separated list of allowed users |
Remove a Time Machine share from smb.conf. Returns Ansible task steps.
Subscribe to live data updates. The server pushes named events whenever data changes.
Query parameter: topics — comma-separated list of topics to subscribe to.
Available topics:
| Topic | Data | Cadence |
|---|---|---|
pool.query |
Same JSON as GET /api/pools
|
Every 10 s on change |
poolstatus |
Same JSON as GET /api/poolstatus
|
Every 10 s on change |
dataset.query |
Same JSON as GET /api/datasets
|
Every 10 s on change |
snapshot.query |
Same JSON as GET /api/snapshots
|
Every 10 s on change |
autosnapshot.query |
Same JSON as GET /api/auto-snapshot-schedules
|
Every 10 s on change |
iostat |
Same JSON as GET /api/iostat
|
Every 10 s |
user.query |
Same JSON as GET /api/users
|
Every 10 s on change + after writes |
group.query |
Same JSON as GET /api/groups
|
Every 10 s on change + after writes |
service.query |
Same JSON as GET /api/services
|
Every 10 s on change |
jobs.update |
Single job object (as GET /api/jobs/{id}) |
On every job state change |
replication.update |
Same JSON as GET /api/replication
|
On task create/update/delete + after each scheduled run |
autosnap.status |
Same JSON as GET /api/auto-snapshot/status
|
After takeover / release |
ansible.progress |
Single TaskStep object |
Streamed during every write (Ansible and ops lanes) |
Unknown topic names are ignored. The browser UI subscribes to all of them and falls back to 30 s REST polling (retrying SSE after 5 s) if the stream drops.
event: pool.query
data: [{"name":"tank","health":"ONLINE",...}]
event: iostat
data: [{"pool":"tank","read_ops":0,"write_ops":443,...}]
Example — watch pool health and I/O live:
curl -N 'http://localhost:8080/api/events?topics=pool.query,iostat'Non-2xx responses return:
{
"error": "human-readable message",
"tasks": [ ... ]
}tasks is populated for Ansible-backed operations and contains the step results up to the point of failure.