> For the complete documentation index, see [llms.txt](https://docs.nodeum.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nodeum.io/data-mover/nd-client.md).

# ND Client

`nd` is the Nodeum command-line client. Use it to create copy and move tasks, monitor executions, manage pools, and administer a Nodeum deployment.

This page describes the current `nd/` source, reviewed on **6 October 2026** (latest change under `nd/`: `4ae508939`). It is not tied to the old 2.0.13 release. Run `nd --version` to identify your installed build and `nd COMMAND --help` to check the options it supports.

### How it works

The client submits requests to the Nodeum management API. Nodeum services execute the transfer; the client displays progress and results. Files are transferred between storage systems accessible to Nodeum, rather than uploaded through the terminal running `nd`.

```mermaid
flowchart LR
    CLI[nd client] -->|Tasks, control, status| API[Nodeum management API]
    API --> D[Dispatcher]
    D --> M[Mover services]
    M <--> S[Source storage]
    M <--> T[Destination storage]
    CLI -.->|Optional local authentication and config sync| A[Linux nd auth service]
    A --> API
```

| Term            | Meaning                                                                                                                                                         |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Alias / cluster | A named connection containing a Nodeum URL, authentication settings, and optional defaults and selection weight. Selection messages also call this a **Mover**. |
| Pool            | A storage grouping configured in Nodeum. Primary pools can be addressed as `nod://POOL/path`.                                                                   |
| Task            | A saved transfer definition: sources, destination, options, metadata, and callbacks.                                                                            |
| Execution       | One run of a task. A task may have multiple executions.                                                                                                         |
| Deferred ID     | An identifier returned when a run is deferred, used to start it later.                                                                                          |

### Installation

#### Platforms and artifact names

The build configuration defines these targets. Replace `VERSION` with the version supplied for your deployment; the table describes build artifact names, not a guarantee that every artifact is published for every release.

| Platform / package | x86-64                          | ARM64                            |
| ------------------ | ------------------------------- | -------------------------------- |
| Linux binary       | `nd-VERSION-linux-x86_64`       | `nd-VERSION-linux-aarch64`       |
| macOS binary       | `nd-VERSION-darwin-x86_64`      | `nd-VERSION-darwin-aarch64`      |
| Windows binary     | `nd-VERSION-windows-x86_64.exe` | `nd-VERSION-windows-aarch64.exe` |
| RPM                | `nd-VERSION-1.x86_64.rpm`       | `nd-VERSION-1.aarch64.rpm`       |
| DEB                | `nd_VERSION-1_amd64.deb`        | `nd_VERSION-1_arm64.deb`         |

`amd64` and `x86_64` refer to the same CPU architecture; `arm64` and `aarch64` refer to the same CPU architecture. Use `uname -m` on Linux/macOS to check your machine.

#### Standalone binary

Obtain the matching binary from your Nodeum release distribution. On Linux or macOS, rename it to `nd`, make it executable, and add its directory to `PATH`:

```bash
mkdir -p "$HOME/nodeum-binaries"
cp ./nd-VERSION-linux-x86_64 "$HOME/nodeum-binaries/nd"
chmod +x "$HOME/nodeum-binaries/nd"
export PATH="$HOME/nodeum-binaries:$PATH"
nd --version
nd --help
```

For macOS, substitute the appropriate `darwin` filename. The `export` applies to the current shell; add it to your shell configuration for subsequent sessions.

On Windows, rename the downloaded binary to `nd.exe` and run it from PowerShell or Command Prompt. For example, in PowerShell:

```powershell
.\nd.exe --help
```

#### Linux packages

```bash
# RPM-based systems
sudo dnf install ./nd-VERSION-1.x86_64.rpm

# Debian-based systems
sudo apt install ./nd_VERSION-1_amd64.deb
```

Packages install `/usr/bin/nd`, the `nd(1)` manual, Bash completion, and `nd-auth-service.service`. Installation also creates the `nodeum_auth` system account and enables/restarts the authentication service. The service needs administrator-provided configuration; see Linux authentication service.

### Quickstart

If your administrator has configured the local authentication service, start with `nd config review`. Otherwise, use the interactive setup:

```bash
nd config configure
nd config show
nd config review
nd pool list
```

Copy a directory between two primary pools, substituting pool names from your deployment:

```bash
nd copy --recursive nod://source/project/ nod://destination/backup/
```

Copy and move commands run immediately and wait for progress by default. Use `--no-run` to save a task without starting it, or `--no-progress` to start it and return without waiting for completion.

```bash
nd copy --recursive --no-run nod://source/project/ nod://destination/backup/
nd task run TASKID
nd task status TASKID
nd task processed --id TASKID --status error
```

For several clusters, add `--alias CLUSTER` **before** the command when following up on an existing task:

```bash
nd --alias production task status TASKID
```

### Access to the interface

Run `nd` without arguments, or `nd --help`, to display the command overview and global options. This Linux example preserves the help-screen layout; `<installed-version>` stands for your build's version, and the configuration path depends on your account/platform. The descriptions and available options reflect the current source.

```
[nodeum01@ ~]$ nd
NAME:
   nd - Nodeum CLI

USAGE:
   nd [global options] command [command options] [arguments...]

VERSION:
   <installed-version>

DESCRIPTION:
   FLAG SYNTAX
     Value flags accept both forms:  --flag value  or  --flag=value
     Boolean flags:
       --flag          sets it to true
       --flag=false    sets it to false  (the = sign is required when making false)
       --no-flag       disables it where available (e.g. --no-progress)

COMMANDS:
   admin
   auth-service   Service that manages users based on Linux users
   config         configure the Nodeum Client
   copy, cp       create copy task
   move, mv       create move task
   pool           manage pools
   server-config
   settings       manage user preferences (synced with the web UI)
   task
   help, h        Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --json                          output as JSON (default: false)
   --debug                         enable verbose logging (default: false) [$ND_DEBUG]
   --insecure, -k                  skip TLS certificate verification (insecure) (default: false) [$ND_INSECURE]
   --config value                  path to configuration file (default: <config-dir>/config.json) [$ND_CONFIG]
   --config-dir value, -C value    path to configuration folder (default: "/home/nodeum01/.config/.nd") [$ND_CONFIG_DIR]
   --alias value                   alias in configuration file for authentication (default: "default") [$ND_ALIAS]
   --url value                     URL of Nodeum [$ND_URL]
   --auth-type value               Auth type (empty or ldap) [$ND_AUTH_TYPE]
   --access-token value            for API authentication (1st authentication method) [$ND_ACCESS_TOKEN]
   --refresh-token value           for API authentication (1st authentication method, not saved in config) [$ND_REFRESH_TOKEN]
   --authorization-endpoint value  for Device Authorization Flow (2nd authentication method)
   --token-endpoint value          for Device Authorization Flow (2nd authentication method)
   --client-id value               for Device Authorization Flow (2nd authentication method)
   --scopes value                  for Device Authorization Flow (2nd authentication method)
   --persist-session               persist Device Authorization session on disk for 1 hour (default: true)
   --persist-session-renew         if persist session is enabled, renew the token (default: false)
   --username value                for API authentication (3rd authentication method) [$ND_USERNAME]
   --password value                for API authentication (3rd authentication method) [$ND_PASSWORD]
   --anonymous                     no login (default: false)
   --help, -h                      show help
   --version, -v                   print the version

COPYRIGHT:
   nd is a property of Nodeum and its subsidiaries, if any. The intellectual and
   technical concepts contained herein are proprietary to Nodeum and its
   subsidiaries and may be covered by Belgium and Foreign Patents, patents in
   process, and are protected by trade secret or copyright law. Dissemination of
   this information or reproduction of this material is strictly forbidden unless
   prior written permission is obtained from Nodeum.
```

Use `nd --version` for the actual version. To inspect a command or subcommand, run:

```bash
nd copy --help
nd task --help
nd task processed --help
nd admin logs --help
```

The command and option tables below explain the same interface in more detail.

### Command syntax and global flags

```
nd [GLOBAL OPTIONS] COMMAND [SUBCOMMAND] [COMMAND OPTIONS] [ARGUMENTS...]
```

Place command options before positional arguments. In particular, copy/move reject flags placed after source or destination paths.

* Value flags accept `--flag value` and `--flag=value`.
* Boolean flags use `--flag` for true and `--flag=false` for false. Do not write `--flag false`.
* `--no-progress` is an explicit alternative to `--progress=false`; other `--no-*` forms exist only where documented.
* Quote paths containing spaces, URI query strings, regular expressions, and metadata values containing spaces.
* Use `nd help`, `nd COMMAND --help`, or `nd COMMAND SUBCOMMAND --help` for contextual help. `help` has alias `h`.

| Command            | Purpose                                                              |
| ------------------ | -------------------------------------------------------------------- |
| `copy`, `cp`       | Create and optionally run a copy task.                               |
| `move`, `mv`       | Create and optionally run a move task.                               |
| `task`             | List, run, inspect, pause, resume, and stop tasks/executions.        |
| `pool`             | List pools; create or destroy pools as an administrator.             |
| `config`           | Manage local connections, defaults, sessions, and cluster discovery. |
| `settings`         | Read/write user preferences shared with the web UI.                  |
| `admin`            | Service status, logs, license, and user management.                  |
| `server-config`    | Read/write the server's LDAP configuration.                          |
| `auth-service run` | Run the local Linux authentication service.                          |

#### Global options

Unless stated otherwise, booleans default to false and string values are unset.

| Option                         | Environment variable | Meaning / default                                                                                                               |
| ------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `--json`                       | —                    | Request JSON from supported output formatters. See the output notes below.                                                      |
| `--debug`                      | `ND_DEBUG`           | Enable verbose informational logging.                                                                                           |
| `--insecure`, `-k`             | `ND_INSECURE`        | Skip TLS certificate verification. Default: verification enabled.                                                               |
| `--config FILE`                | `ND_CONFIG`          | Configuration file; defaults to `<config-dir>/config.json`.                                                                     |
| `--config-dir DIR`, `-C DIR`   | `ND_CONFIG_DIR`      | Configuration directory; defaults to the platform's user configuration directory plus `.nd`.                                    |
| `--alias NAME`                 | `ND_ALIAS`           | Connection alias; default name is `default`. Copy/move may automatically select a cluster when this is not explicitly supplied. |
| `--url URL`                    | `ND_URL`             | Nodeum management API URL.                                                                                                      |
| `--auth-type TYPE`             | `ND_AUTH_TYPE`       | Empty for normal authentication, or `ldap`.                                                                                     |
| `--access-token TOKEN`         | `ND_ACCESS_TOKEN`    | API access token.                                                                                                               |
| `--refresh-token TOKEN`        | `ND_REFRESH_TOKEN`   | API refresh token; not saved in `config.json`.                                                                                  |
| `--authorization-endpoint URL` | —                    | Device Authorization Flow endpoint.                                                                                             |
| `--token-endpoint URL`         | —                    | Device Flow token endpoint.                                                                                                     |
| `--client-id ID`               | —                    | Device Flow client ID.                                                                                                          |
| `--scopes LIST`                | —                    | Device Flow scopes separated by spaces, commas, or `+`.                                                                         |
| `--persist-session`            | —                    | Persist the Device Flow session for one hour; default `true`.                                                                   |
| `--persist-session-renew`      | —                    | Renew a persisted session.                                                                                                      |
| `--username USER`              | `ND_USERNAME`        | API username.                                                                                                                   |
| `--password PASSWORD`          | `ND_PASSWORD`        | API password.                                                                                                                   |
| `--anonymous`                  | —                    | Skip login, for example when starting a deferred run.                                                                           |
| `--help`, `-h`                 | —                    | Show help.                                                                                                                      |
| `--version`, `-v`              | —                    | Show the client version.                                                                                                        |

### Configuration and authentication

#### Configuration locations

The default directory follows the operating system's user configuration directory:

| Platform | Default configuration file                                                                             |
| -------- | ------------------------------------------------------------------------------------------------------ |
| Linux    | `$XDG_CONFIG_HOME/.nd/config.json`, or `$HOME/.config/.nd/config.json` when `XDG_CONFIG_HOME` is unset |
| macOS    | `$HOME/Library/Application Support/.nd/config.json`                                                    |
| Windows  | `%AppData%\.nd\config.json`                                                                            |

`--config` selects a file; `--config-dir` / `-C` selects a directory. `-C` is **not** shorthand for `--config`.

Connection settings are grouped under named aliases. Credentials saved by the client are stored in the local configuration file, which is written with mode `0600` on systems supporting Unix file permissions. The storage discovery cache is stored separately as `storage_cache.json`, beside the selected configuration file. Legacy inline storage caches are migrated automatically by client commands.

#### Configure a connection

The interactive wizard is the simplest way to set up a connection:

```bash
nd config configure
```

For scripted setup, `config save` accepts the authentication/alias options listed above:

```bash
# Username/password connection; replace all example values
nd config save --alias production --url https://nodeum.example.com \
  --username alice --password 'PASSWORD'

# Token connection
nd config save --alias production --url https://nodeum.example.com \
  --access-token 'TOKEN'

# LDAP connection
nd config save --alias production --url https://nodeum.example.com \
  --auth-type ldap --username alice --password 'PASSWORD'

# OpenID Device Authorization Flow
nd config save --alias production --url https://nodeum.example.com \
  --authorization-endpoint https://idp.example.com/device \
  --token-endpoint https://idp.example.com/token \
  --client-id nodeum-cli --scopes 'openid,profile,offline_access,email'

nd --alias production config review
```

Device Flow prompts you to authorize with the identity provider. The local auth service can instead provision credentials using your Linux identity when deployed by an administrator. Explicit username/password or token flags select those credentials rather than requesting credentials from the service.

`config save` and `config copy` print configuration that can contain secrets. `config review` may print authentication tokens even without `--detail`. Use `config show` for a masked view when sharing diagnostic output.

#### Configuration commands

| Command                                      | Behavior                                                                                                                                              |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `config configure`                           | Interactive connection setup.                                                                                                                         |
| `config save [OPTIONS]`                      | Save connection options.                                                                                                                              |
| `config show`                                | Show configured aliases without testing API connectivity; mask secrets in text and omit them in JSON.                                                 |
| `config show --minimal`                      | Show alias names and URLs.                                                                                                                            |
| `config show --detail`                       | Include secrets.                                                                                                                                      |
| `config review [--detail]`                   | Authenticate/test connectivity and show the resolved configuration. Without an explicit alias, also attempt to refresh aliases from the auth service. |
| `config remove [ALIAS]`                      | Confirm removal of an alias and its storage cache. Without an argument, removes `default`, regardless of `--alias`.                                   |
| `config clear-session`                       | Clear the current alias's persisted Device Flow session.                                                                                              |
| `config copy`                                | Print the configuration as JSON for transfer. This command still exists.                                                                              |
| `config paste 'JSON'`                        | Write the supplied JSON argument to `<config-dir>/config.json`; replaces that file. It does not read stdin or use a custom `--config` filename.       |
| `config sync`                                | Check for published configuration updates from the local auth service.                                                                                |
| `config refresh-clusters`                    | Refresh storage discovery for configured clusters.                                                                                                    |
| `config set-weight ALIAS WEIGHT`             | Set a nonnegative cluster selection weight.                                                                                                           |
| `config unset-weight ALIAS`                  | Remove a local selection weight.                                                                                                                      |
| `config default-flags show [COMMAND]`        | Show stored defaults for one command or all commands.                                                                                                 |
| `config default-flags set COMMAND KEY VALUE` | Set one default; use the flag name without leading hyphens.                                                                                           |
| `config default-flags unset COMMAND [KEY]`   | Remove one default, or all defaults for a command.                                                                                                    |

**Example configuration output**

`nd config show` produces an alias summary such as this illustrative example. Stored secrets are masked; `--detail` reveals them.

```
production:
          URL: https://nodeum.example.com
     Username: alice
     Password: *****xyz
       Weight: 5
Default Flags: copy: {"recursive":true,"parallel":4}
```

`nd config show --minimal` provides a compact view:

```
      backup: https://backup.example.com
  production: https://nodeum.example.com
```

The current alias is marked with `*` when it refers to a configured entry. Exact spacing and alias ordering follow the formatter; aliases are sorted by name.

#### Default flags

Defaults are stored per alias. Use `global` for supported global defaults, and `copy` or `move` for transfer defaults. Explicit command-line/environment settings take precedence for ordinary flags. Metadata defaults are prepended to supplied entries, so a supplied value for the same key wins. Values are parsed as JSON when possible, allowing booleans, numbers, and arrays.

```bash
nd --alias production config default-flags set copy recursive true
nd --alias production config default-flags set copy parallel 4
nd --alias production config default-flags set copy include-ext '[".pdf",".txt"]'
nd --alias production config default-flags set global debug true
nd --alias production config default-flags show
nd --alias production config default-flags unset copy parallel
```

The storage command accepts arbitrary keys; it does not guarantee that a command consumes them. Global `json`, `debug`, and `insecure` and copy/move's configuration-backed flags are supported. Copy defaults do not automatically become move defaults. When a default-flags write has several possible aliases, the client prompts on a terminal or requires `--alias` in noninteractive use.

For aliases published by the auth service, URL, default flags, and weight are synchronized before commands when the published configuration version changes. Provisioning can also replace these defaults. Make lasting changes in the service configuration. Local aliases not published by the service are retained, including aliases removed from the service's published list. Configuration sync does not exchange credentials; a changed URL clears the stored access token for subsequent renewal.

#### TLS certificates

The client trusts system root certificates and can load additional PEM CA certificates:

* System directory: `/etc/nodeum/certs/CAs/`.
* User directory: `<OS user configuration directory>/.nd/certs/CAs/`.

For a selected alias such as `production`, place its CA in `production.crt`. The client first looks in the system directory, then the user directory. A valid alias-specific file is used alongside system roots. If no alias-specific CA is found, the legacy fallback loads the system CA directory, or the user CA directory if the system directory is missing/empty.

These certificate paths are independent of `--config` and `--config-dir`. Moving the configuration does not relocate CA discovery. `--insecure` disables certificate verification; installing the correct CA keeps verification enabled.

### Working with multiple clusters

#### Automatic selection for copy/move

An explicit `--alias NAME` or `ND_ALIAS` always selects the cluster. Without either:

1. If only one active alias exists, use it directly.
2. With several aliases, find clusters whose cached primary pools/NAS share paths cover **all** sources and the destination.
3. Exclude candidates with an explicit weight of `0`.
4. If the same pool name identifies different known storage across candidates, require `--alias`.
5. Otherwise choose the candidate with the highest weight. An unset weight ranks below a positive weight; a tie requires `--alias`.

The weight rules apply to selection among multiple configured aliases; the single-alias shortcut does not perform that comparison. Storage identity checks use the information the client can discover.

Automatic selection supports `nod://` pool paths and filesystem paths that match configured NAS shares. With several aliases, `nod-nas://` and `nod-cloud://` require an explicit alias. A single selected cluster must be able to resolve the entire operation; automatic selection does not arrange a transfer between two separate clusters.

```bash
nd config set-weight production 5
nd config set-weight backup 3
nd copy --recursive nod://source/project/ nod://destination/backup/

# Explicit choice overrides weights
nd --alias backup copy --recursive nod://source/project/ nod://destination/backup/
```

Discovery caches expire after 24 hours and are refreshed when missing/stale. A selection miss triggers one refresh/retry; an automatic selection that cannot resolve the endpoints also gets one refresh/reselection attempt. To refresh explicitly:

```bash
nd config refresh-clusters
nd copy --refresh-clusters nod://source/file.txt nod://destination/file.txt
```

#### Reading across clusters

`task list`, `pool list`, and `config review` can show one section per configured cluster when there is no configured `default` URL and no explicit alias, URL, credential override, or anonymous mode. Filters and pagination apply **per cluster**. One cluster's failure does not hide successful results from the others; the command fails overall only if none succeeds.

Commands that act on a task/execution ID do not search every cluster for that ID. Keep the cluster alias with the ID and pass it on subsequent commands. Task, execution, and deferred-run JSON includes a `cluster` object with `alias` and `url` where available. When an explicit URL overrides the alias URL, the output omits the alias because it would not return you to that same server.

### Copy and move

```
nd copy [OPTIONS] SOURCE [SOURCE...] DESTINATION
nd move [OPTIONS] SOURCE [SOURCE...] DESTINATION
```

`cp` and `mv` are aliases. The client requires at least two positional arguments, validates the source/destination combination, creates a task, and runs it unless `--no-run` is set. Multiple primary-pool sources must belong to the same pool. `move` requests removal of the source as part of the workflow.

#### Addressing storage

| Form                                        | Meaning                                                                                   |
| ------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `nod://POOL/path/to/item`                   | A primary pool and a path inside it.                                                      |
| `nod-cloud://CONNECTOR/BUCKET/path/to/item` | Direct cloud connector/bucket addressing.                                                 |
| `nod-nas://NAS/SHARE/path/to/item`          | Direct NAS/share addressing.                                                              |
| `/mounted/share/path`                       | Absolute filesystem path matched to a configured NAS share, then converted to a pool URI. |
| `./path` or `../path`                       | Path resolved against the current directory and matched to a NAS share.                   |

For filesystem-path resolution, the path seen by the client must match the NAS share path stored in Nodeum. For example, if the share is configured as `/p/projectspace`, using `/mnt/projectspace/file.txt` will not identify that share; use the matching mount path or an explicit `nod://POOL/file.txt` URI.

The longest matching share path wins. An absolute path that matches no configured NAS share fails; it is not an arbitrary local upload. Relative paths that do not match retain the legacy pool/path interpretation. Prefer explicit `nod://` URIs when the intent would otherwise be ambiguous. Keep a trailing `/` when a destination is intended as a directory.

The parser also accepts `?pool=ID-OR-NAME` for pool lookup, but the current `nod://` resolver subsequently sets the primary pool again. Do not rely on that suffix alone to select a secondary archive pool with `nod://` in this implementation.

```bash
# Copy a directory
nd copy -R nod://source/project/ nod://destination/backup/

# Copy several files
nd copy nod://source/a.txt nod://source/b.txt nod://destination/reports/

# Use configured NAS mount paths
nd copy -R /mnt/source/project/ /mnt/destination/backup/

# Address a cloud bucket directly
nd --alias production copy -R \
  nod://source/project/ nod-cloud://object-store/reports/backup/

# Move while keeping ownership
nd move -R --keep-file-ownership nod://source/project/ nod://destination/archive/
```

#### Working directory and destination layout

`--working-dir` / `--wd` determines how much of the source path is retained at the destination. It is a task option interpreted by the server, not a change to the terminal's current directory. A relative value such as `.` or `..` is resolved from the source path; trailing slashes on source and destination affect the result.

The following examples assume the source folder contains `FILE.txt`; use `--recursive` for folder transfers. These result tables match the server's current working-directory handling.

With `--wd=.`

| Source                         | Destination              | Result                                 |
| ------------------------------ | ------------------------ | -------------------------------------- |
| `nod://source/folder/FILE.txt` | `nod://dest/directory/`  | `nod://dest/directory/FILE.txt`        |
| `nod://source/folder/FILE.txt` | `nod://dest/RENAMED.txt` | `nod://dest/RENAMED.txt`               |
| `nod://source/folder/`         | `nod://dest/directory/`  | `nod://dest/directory/FILE.txt`        |
| `nod://source/folder/`         | `nod://dest/directory`   | `nod://dest/directory/FILE.txt`        |
| `nod://source/folder`          | `nod://dest/directory/`  | `nod://dest/directory/folder/FILE.txt` |
| `nod://source/folder`          | `nod://dest/directory`   | `nod://dest/directory/FILE.txt`        |

With `--wd=..`

| Source                         | Destination              | Result                                        |
| ------------------------------ | ------------------------ | --------------------------------------------- |
| `nod://source/folder/FILE.txt` | `nod://dest/directory/`  | `nod://dest/directory/folder/FILE.txt`        |
| `nod://source/folder/FILE.txt` | `nod://dest/RENAMED.txt` | `nod://dest/RENAMED.txt`                      |
| `nod://source/folder/`         | `nod://dest/directory/`  | `nod://dest/directory/folder/FILE.txt`        |
| `nod://source/folder/`         | `nod://dest/directory`   | `nod://dest/directory/FILE.txt`               |
| `nod://source/folder`          | `nod://dest/directory/`  | `nod://dest/directory/source/folder/FILE.txt` |
| `nod://source/folder`          | `nod://dest/directory`   | `nod://dest/directory/FILE.txt`               |

You can also specify an explicit source URI prefix as the working directory:

```bash
nd copy --recursive --working-dir nod://source/project/ \
  nod://source/project/reports/ nod://destination/backup/
```

This retains `reports/` under `backup/`. Source items outside the specified working directory are rejected by the server.

#### Copy and move between a filesystem and cloud storage

These examples use a primary filesystem pool named `posix_storage` and a configured cloud connector named `cloud_storage`. For Swift, the bucket component corresponds to the container name. Replace `production`, connector, pool, and bucket names with those configured at your site.

```bash
# Copy from a filesystem pool to cloud storage
nd --alias production copy --recursive --ignore-hidden \
  --working-dir nod://posix_storage/path/ \
  nod://posix_storage/path/subpath/ nod-cloud://cloud_storage/container/

# Copy from cloud storage to a filesystem pool
nd --alias production copy --recursive --ignore-hidden \
  --working-dir nod-cloud://cloud_storage/container/ \
  nod-cloud://cloud_storage/container/path/ nod://posix_storage/restore/

# Move from a filesystem pool to cloud storage
nd --alias production move --recursive --ignore-hidden \
  --working-dir nod://posix_storage/path/ \
  nod://posix_storage/path/subpath/ nod-cloud://cloud_storage/container/

# Move from cloud storage to a filesystem pool
nd --alias production move --recursive --ignore-hidden \
  --working-dir nod-cloud://cloud_storage/container/ \
  nod-cloud://cloud_storage/container/path/ nod://posix_storage/restore/
```

For deployments that require OpenStack project metadata, add the relevant `--md KEY=VALUE` options before the paths; see Metadata and callbacks.

#### Transfer options

Defaults below describe the client flags. Options not explicitly set can be left to the server; stored default flags can also change their effective values.

| Option                            | Meaning / default                                                                                                                                    |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--name NAME`, `-n NAME`          | Task name; generated from endpoints if omitted.                                                                                                      |
| `--comment TEXT`                  | Task comment; empty by default.                                                                                                                      |
| `--recursive`, `-R`               | Include subdirectories; default false.                                                                                                               |
| `--working-dir PATH`, `--wd PATH` | Set the task working directory used for destination path layout; unset by default.                                                                   |
| `--overwrite`                     | Overwrite existing entries; default false.                                                                                                           |
| `--ignore-hidden`                 | Ignore files/directories starting with a dot; default false.                                                                                         |
| `--priority NUMBER`               | Priority from `0` to `9`; `0` is highest. Displayed default: `0`.                                                                                    |
| `--parallel NUMBER`               | Maximum mover processes; help advertises default `1`. If unset, the client leaves the value to the server. There is no client-enforced `1–20` range. |
| `--keep-file-ownership`           | Preserve file ownership; default false.                                                                                                              |
| `--remove-root-folder`            | Remove the source root folder for a **move**; default false. Exposed for copy too, but only applied to move.                                         |
| `--no-run`                        | Create the task without running it; default false.                                                                                                   |
| `--refresh-clusters`              | Force discovery refresh for automatic cluster selection.                                                                                             |
| `--defer`                         | Request a deferred run ID instead of starting immediately.                                                                                           |
| `--progress`                      | Wait and display progress; default true for copy/move and `task run`.                                                                                |
| `--no-progress`                   | Return after submission/status retrieval without waiting; overrides `--progress`.                                                                    |
| `--processed-items MODE`          | Items shown while waiting: `none`, `error` (default), or `all`. Use an explicit value, such as `--processed-items=all`.                              |
| `--run-as-user USER`              | Run on behalf of another user; requires administrator privileges and an existing user.                                                               |

#### Metadata and callbacks

| Option                                     | Purpose                                                     |
| ------------------------------------------ | ----------------------------------------------------------- |
| `--trigger-md KEY=VALUE`, `--md KEY=VALUE` | Metadata for the run trigger; also available on `task run`. |
| `--task-md KEY=VALUE`                      | Metadata attached to the task.                              |
| `--files-md KEY=VALUE`                     | Metadata attached to files.                                 |
| `--callback TYPE:FILE`                     | Upload a local callback script as part of the task.         |

Repeat a metadata flag for multiple entries. The first `=` separates the key and value, so a key cannot contain `=`. OpenStack-related metadata such as `project_name`, `project_domain_name`, `user_domain_name`, and `region_name` is deployment-specific; it is not a universal requirement for OpenID authentication.

Callbacks execute as **JavaScript** (`.js` or `.cjs`) in the server's callbacks plugin. Although the client still recognizes `.py`, the current plugin does not execute Python callbacks; it skips them and logs a warning at task start. Rewrite existing Python callbacks in JavaScript.

| Callback type           | Exported function                         | When it runs                                                                                     |
| ----------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `filter`                | `function(request, { logger })`           | Before request dispatch; a falsy result filters out the request. Scan requests are not filtered. |
| `before_task_executed`  | `function(task, metadata, { logger })`    | Before task execution.                                                                           |
| `after_result_received` | `function(result, execution, { logger })` | After receiving a result.                                                                        |
| `after_task_executed`   | `function(execution, { logger })`         | After task execution.                                                                            |

Only the specified file's contents are uploaded; imported files are not bundled. Repeat `--callback` to add callbacks. Scripts must export a function through `module.exports`. They run in an embedded JavaScript engine, not Node.js: `fs`, `child_process`, `process`, and `fetch` are unavailable. Built-in helpers include `require('./utils')` and logging; outbound HTTP requires administrator configuration of the plugin's allowed destinations.

For example, save this as `after-task.js` to write the task name to the execution log:

```javascript
module.exports = function(execution, { logger }) {
  logger.info('Task finished: %s', execution.getTask().getName())
}
```

Attach it when creating the task:

```bash
nd copy -R --files-md project=research \
  --trigger-md project_name=research \
  --callback after_task_executed:./after-task.js \
  nod://source/project/ nod://destination/backup/
```

#### Filters

Filters become a JavaScript callback evaluated by the dispatcher's callbacks plugin before request dispatch. Includes for the same subject are combined with **OR**; different subjects and all exclusions are combined with **AND**. This applies to all metadata includes together, even when they use different keys. It also means that two size bounds, or two bounds on the same timestamp, are OR'd rather than forming an interval. Use a custom filter callback when you need an AND condition within one subject.

| Criteria          | Flags                                                                           | Value                                                                                                             |
| ----------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Full path         | `--include-path`, `--exclude-path`                                              | Regular expression; repeatable.                                                                                   |
| Filename          | `--include-filename`, `--exclude-filename`                                      | Regular expression; repeatable.                                                                                   |
| Extension         | `--include-ext`, `--exclude-ext`                                                | Exact extension, e.g. `.pdf`; repeatable.                                                                         |
| Metadata          | `--include-metadata`, `--exclude-metadata`                                      | `KEY=REGEXP`; repeatable. Linux `user.*` xattrs are supported; `user.tag` and `tag` refer to the same key.        |
| Size              | `--size-more-than`, `--size-less-than`                                          | Strict lower/upper bound. Decimal units `KB` through `PB`; binary units `KiB` through `PiB`; no unit means bytes. |
| Modification time | `--mtime-older-than`, `--mtime-earlier-than`, `--mtime-before`, `--mtime-after` | Relative duration or absolute date.                                                                               |
| Change time       | `--ctime-older-than`, `--ctime-earlier-than`, `--ctime-before`, `--ctime-after` | Relative duration or absolute date.                                                                               |
| Access time       | `--atime-older-than`, `--atime-earlier-than`, `--atime-before`, `--atime-after` | Relative duration or absolute date.                                                                               |

For relative times, `older-than 7d` means more than seven days old; `earlier-than 7d` means **less** than seven days old despite the flag's name. Units include `h` / hour, `d` / day, `w` / week, `M` / month, and `Y` / year. Use whole-number durations. Absolute dates accept `YYYY-MM-DD` and ISO 8601 timestamps; these transfer filters do not use the natural-language parser of task listing/log commands.

Use valid size/date/duration formats: the current filter builder silently omits values it cannot parse. Metadata filter entries without `=` are also ignored.

```bash
# PDFs larger than 10 MB and modified more than 30 days ago
nd copy -R --include-ext .pdf --size-more-than 10MB \
  --mtime-older-than 30d nod://source/reports/ nod://destination/archive/

# JPEG or PNG images modified within the last week, excluding draft paths
nd copy -R --include-ext .jpg --include-ext .png \
  --mtime-earlier-than 1w --exclude-path '.*draft.*' \
  nod://source/images/ nod://destination/images/

# Exclude temporary files and logs
nd copy -R --exclude-ext .tmp --exclude-ext .log \
  nod://source/project/ nod://destination/backup/
```

### Task monitoring and control

A **TASKID** identifies the saved definition; an **EXECUTIONID** identifies a particular run. When status/control/processed commands receive a task ID, they resolve its **last execution**. A task created with `--no-run` has no execution until started.

#### List tasks

```bash
nd task list
nd task list --contains backup --limit 25 --sort-by updated_at:desc
nd task list --created-from '1 week ago' --created-to yesterday
nd task list --limit 0
```

| Option                                  | Meaning / default                                                                                                                                                         |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--limit`, `-l`                         | Page size; default `10`, maximum `100`; `0` disables the client pagination limit.                                                                                         |
| `--offset`, `-o`                        | Number of tasks to skip; default `0`.                                                                                                                                     |
| `--sort-by`, `-s`                       | Repeatable sort field: `id` or `updated_at`, with `:asc` or `:desc`. Default `updated_at:desc`.                                                                           |
| `--id`                                  | Filter by task ID.                                                                                                                                                        |
| `--name`, `-n`                          | Exact task name.                                                                                                                                                          |
| `--contains`, `-c`                      | Name pattern/containing text; takes precedence over `--name` when both are supplied.                                                                                      |
| `--workflow-type`, `-w`                 | `active_archive`, `offline_archive`, `data_exchange`, `data_migration`, `maintenance`, or `data_enrichment`.                                                              |
| `--workflow-action`                     | `copy`, `move`, `erase`, `scan`, `rehydratation`, `format`, `check_consistency`, or `duplication`. These filter server tasks; they are not all top-level client commands. |
| `--sources-type`, `--destinations-type` | `primary_nas`, `secondary_nas`, `primary_cloud`, or `secondary_cloud`.                                                                                                    |
| `--created-from`, `--created-to`        | Creation date bounds.                                                                                                                                                     |
| `--updated-from`, `--updated-to`        | Update date bounds.                                                                                                                                                       |
| `--extended`, `-e`                      | Include dispatcher and mover columns.                                                                                                                                     |
| `--all`, `-a`                           | Administrator-only all-task request; supported but hidden from help.                                                                                                      |

Date bounds accept explicit dates and natural-language expressions such as `yesterday` or `1 week ago`.

**Example task list output**

Illustrative single-cluster output, with locale `en-GB`. The table includes **Created At**; `--extended` adds dispatcher and mover columns.

```
╭──────────────────────────┬────────────────┬─────────┬──────────────────┬────────────┬───────────────────────╮
│ TASK ID                  │ TASK NAME      │ COMMENT │ CREATED AT       │ CREATED BY │ LAST EXECUTION STATUS │
├──────────────────────────┼────────────────┼─────────┼──────────────────┼────────────┼───────────────────────┤
│ 633ecc74a91db0f38f7abc2e │ Project backup │         │ 06/10/2022 12:39 │ alice      │ done                  │
├──────────────────────────┼────────────────┼─────────┼──────────────────┼────────────┼───────────────────────┤
│ NUMBER OF TASK(S)        │ 1              │         │                  │            │                       │
╰──────────────────────────┴────────────────┴─────────┴──────────────────┴────────────┴───────────────────────╯
1 – 1 of 1
```

#### Execution history, status, and control

| Command                           | Behavior / options                                                                                                                                                                            |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `task list-exec --task-id TASKID` | List runs of one task. `--task-id` / `-t` can also be replaced by a positional task ID. `--limit` / `-l` defaults to `10`; `0` removes the client limit. `--offset` / `-o` defaults to `0`.   |
| `task run TASKID`                 | Start another execution. Supports `--defer`, `--progress`, `--no-progress`, `--processed-items`, `--run-as-user`, and `--trigger-md` / `--md`.                                                |
| `task status ID`                  | Show a snapshot; `--progress` follows live progress, `--no-progress` disables following, `--processed-items` chooses `none`, `error` (default), or `all`. Default progress is **false** here. |
| `task pause ID`                   | Pause an execution.                                                                                                                                                                           |
| `task resume ID`                  | Resume a paused execution.                                                                                                                                                                    |
| `task stop ID`                    | Stop an execution. `--force` / `-f` requests a force stop.                                                                                                                                    |

```bash
nd --alias production task list-exec --task-id TASKID --limit 20
nd --alias production task status --progress --processed-items=error TASKID
nd --alias production task pause EXECUTIONID
nd --alias production task resume EXECUTIONID
nd --alias production task stop --force EXECUTIONID
```

Status/results show execution and task identifiers, counts, transferred size, state, and available execution details. Disabling progress does not stop the server-side task. A command returning successfully after submission does not mean the transfer has finished; inspect its execution status.

**Example task status output**

Illustrative completed execution (IDs and values are examples):

```
         ID: 633ecc74975854bbc799a424
    Task ID: 633ecc74a91db0f38f7abc2e
       Name: Project backup
    Comment:
 Created by: alice
Last Status: done
      Items: 471 / 471
       Size: 8.17 MB / 8.17 MB
     Status: done
```

`Last Status` describes the task's latest execution, when included in the returned task; `Status` describes the execution being inspected. These may differ when inspecting an older execution.

Displayed states include `not_activated`, `calculating`, `in progress`, `finalizing`, `paused`, `done`, `done with warnings`, `finished with error`, `error`, `stopped_by_system`, and `stopped_by_user`. Inspect processed items for the file-level details behind warnings/errors.

**Example execution history output**

`task list-exec` displays one row per run. The following illustrative excerpt uses locale `en-GB`:

```
╭──────────────────────────┬──────────────────┬──────────────────┬───────────┬───────────────────┬────────╮
│ ID                       │ STARTED AT       │ FINISHED AT      │ ITEMS     │ SIZE              │ STATUS │
├──────────────────────────┼──────────────────┼──────────────────┼───────────┼───────────────────┼────────┤
│ 633ecc74975854bbc799a424 │ 06/10/2022 12:39 │ 06/10/2022 12:40 │ 471 / 471 │ 8.17 MB / 8.17 MB │ done   │
╰──────────────────────────┴──────────────────┴──────────────────┴───────────┴───────────────────┴────────╯
```

#### Deferred runs

```bash
nd --alias production copy --defer \
  nod://source/file.txt nod://destination/file.txt

# Use the returned DEFERID on the same server
nd --alias production --anonymous task run DEFERID
```

`--no-run` saves a definition without requesting a run. `--defer` requests a deferred run identifier; if both flags are set, `--no-run` prevents the run/defer request.

#### Processed items and CSV export

```bash
nd task processed --id TASKID
nd task processed --id TASKID --status error
nd task processed --id EXECUTIONID --status copied --offset 50
nd task processed --id EXECUTIONID --path '~%.txt%'
```

| Option           | Meaning / default                                                                                                                                                                    |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--id`, `-i`     | Required task or execution ID; a positional ID is also accepted.                                                                                                                     |
| `--status`       | `all` (default) means all **non-pending** items; `error` selects failed items. Raw states include `pending`, `progress`, `finalizing`, `copied`, `moved`, `removed`, and `filtered`. |
| `--limit`, `-l`  | Default `50`; `0` removes the client pagination limit.                                                                                                                               |
| `--offset`, `-o` | Items to skip; default `0`.                                                                                                                                                          |
| `--path`, `-p`   | Path filter; supports server pattern syntax such as `~%.txt%`.                                                                                                                       |
| `--csv`          | Stream matching items from the server's CSV endpoint into a file.                                                                                                                    |
| `--output`, `-O` | With `--csv`, output filename, or `-` for stdout. Default: `processed-EXECUTIONID.csv`.                                                                                              |

`task processed` uses `--status`, **not** `--processed-items`. That latter flag belongs to the progress display for copy/move/run/status.

CSV exports include all matching items unless `--limit` or `--offset` is explicitly supplied; the normal 50-item default is not applied. CSV and global `--json` cannot be combined. An existing output file is replaced only after the export has been written successfully.

```bash
nd --alias production task processed --id TASKID --status error \
  --csv --output errors.csv

nd --alias production task processed --id EXECUTIONID \
  --csv --output - > processed.csv
```

**Example processed-item output**

For `nd task processed --id EXECUTIONID`, an illustrative successful item looks like this (locale `en-GB`):

```
╭────────┬──────────────────────────────┬─────────┬─────────────────────┬───────────────┬──────────┬─────────╮
│ STATUS │ PATH                         │ SIZE    │ TIME                │ DISPATCHER    │ MOVER    │ WARNING │
├────────┼──────────────────────────────┼─────────┼─────────────────────┼───────────────┼──────────┼─────────┤
│ copied │ nod://destination/report.pdf │ 1.00 MB │ 06/10/2026 10:15:00 │ dispatcher-01 │ mover-01 │         │
╰────────┴──────────────────────────────┴─────────┴─────────────────────┴───────────────┴──────────┴─────────╯
```

```
1 – 1 of 1
```

The path is the destination path when available, otherwise the source path. The current text table has a **Warning** column, but no separate **Error** column. JSON output retains the returned node fields; the final progress-aware JSON result can also include each item's error and warning.

After a successful CSV export to a file, stderr reports the exported count and destination, for example:

```
Exported 12 item(s) to errors.csv
```

#### JSON output

Use `--json` before the command. Progress-aware JSON runs return the result document after waiting; when `--processed-items` is `error` or `all`, the result can include a `processed` object with the total matching count and up to **100** items. Export CSV for a complete matching item report.

```bash
nd --json --alias production copy --processed-items=error \
  nod://source/file.txt nod://destination/file.txt
nd --json --alias production task status EXECUTIONID
```

JSON support is formatter-based, not a promise that every command emits one JSON-only stdout document. Some listing commands still print pagination or empty-result text; multi-cluster output emits separate alias-tagged results/errors. Use an explicit alias and check the output shape when integrating a command into a script.

### Pools

`pool list` defaults to **primary** pools. It does not require the client's administrator gate used for create/destroy; server permissions still apply.

```bash
nd pool list
nd pool list --content nas
nd pool list --type offline_archive
nd --alias production pool list --name source
```

List filters are `--content`, `--type`, `--name`, `--comment`, and `--id`. Common content types are `nas`, `cloud`, and `tape`. Results include pool identity, type/content, and available NAS path information.

**Example pool list output**

Illustrative primary NAS pools; IDs and paths depend on the deployment. An empty storage ID means the response did not supply one. The formatter currently leaves **Write Protect** cells empty, so they should not be interpreted as a protection setting.

```
╭───────────────────┬─────────────┬──────────────┬─────────┬─────────┬──────────────────┬────────────┬───────────────╮
│ POOL ID           │ NAME        │ COMMENT      │ TYPE    │ CONTENT │ PATH             │ STORAGE ID │ WRITE PROTECT │
├───────────────────┼─────────────┼──────────────┼─────────┼─────────┼──────────────────┼────────────┼───────────────┤
│ 7                 │ source      │ Source files │ primary │ nas     │ /mnt/source      │            │               │
│ 8                 │ destination │ Backup files │ primary │ nas     │ /mnt/destination │            │               │
├───────────────────┼─────────────┼──────────────┼─────────┼─────────┼──────────────────┼────────────┼───────────────┤
│ NUMBER OF POOL(S) │ 2           │              │         │         │                  │            │               │
╰───────────────────┴─────────────┴──────────────┴─────────┴─────────┴──────────────────┴────────────┴───────────────╯
```

Administrators can create a NAS or cloud pool using the interactive wizard, which selects available shares/buckets and reviews the configuration before creation:

```bash
nd --alias production pool create
nd --alias production pool destroy --id POOLID
```

`pool create` does not register noninteractive creation flags; use the wizard. `pool destroy` requires `--id` and sends the deletion request without a local confirmation prompt.

### User preferences

The supported setting is `locale`, shared with the web UI and cached locally after an update:

```bash
nd --alias production settings get locale
nd --alias production settings set locale en-GB
```

Accepted values are `en`, `en-GB`, and `de`. `en` uses US-style dates; `en-GB` and `de` use day/month ordering. There is no registered global `--date-format` flag.

### Administration

The `admin` commands require a Nodeum administrator account. Select the intended cluster explicitly when managing several deployments.

#### Services and license

```bash
nd --alias production admin status
nd --alias production admin license
nd --alias production admin license --file ./license.key
```

`admin status` lists service states. `admin license` shows the license unless `--file` / `-f` is supplied, in which case it uploads that license file.

**Reading service status**

The current table includes a **Service ID** column in addition to name, version, address, uptime, and memory. Each reported service node has its own row. For Nodeum IDs, the service-name prefix is removed, leaving the node identifier (for example, `10.2.2.84-a1b2`).

* `●` (green in a color terminal): the node reports `STATUS_ALIVE`.
* `○` (red): the reported status is not `STATUS_ALIVE`, or the client has added a missing required service.
* `N/A`: the corresponding uptime or memory statistic is unavailable. This does **not** by itself mean the service is down.

The examples below are illustrative excerpts based on the current formatter, with invented IDs/statistics and `BUILD` standing for the reported version. They are not observations from a live cluster. Colors are omitted.

**Output where all shown services are reachable**

```
╭───┬───────────────────┬────────────────┬─────────┬─────────────────┬───────────┬──────────╮
│   │ NAME              │ SERVICE ID     │ VERSION │ ADDRESS         │ UPTIME    │ MEMORY   │
├───┼───────────────────┼────────────────┼─────────┼─────────────────┼───────────┼──────────┤
│ ● │ nodeum.dispatcher │ 10.2.2.84-a1b2 │ BUILD   │ 10.2.2.84:50010 │ 172h11m8s │ 34.92 MB │
│ ● │ nodeum.mover      │ 10.2.2.84-c3d4 │ BUILD   │ 10.2.2.84:50020 │ 172h4m48s │ 25.23 MB │
│ ● │ nodeum.mover      │ 10.2.2.85-e5f6 │ BUILD   │ 10.2.2.85:50020 │ 172h4m48s │ 25.63 MB │
│ ● │ etcd              │ etcd-1         │ BUILD   │ 10.2.2.83:2379  │ N/A       │ N/A      │
╰───┴───────────────────┴────────────────┴─────────┴─────────────────┴───────────┴──────────╯
```

**Output where some services are not available**

A reported node can be unavailable while another node of the same service is alive:

```
╭───┬───────────────────┬────────────────┬─────────┬─────────────────┬───────────┬──────────╮
│   │ NAME              │ SERVICE ID     │ VERSION │ ADDRESS         │ UPTIME    │ MEMORY   │
├───┼───────────────────┼────────────────┼─────────┼─────────────────┼───────────┼──────────┤
│ ● │ nodeum.dispatcher │ 10.2.2.84-a1b2 │ BUILD   │ 10.2.2.84:50010 │ 172h11m8s │ 34.92 MB │
│ ● │ nodeum.mover      │ 10.2.2.84-c3d4 │ BUILD   │ 10.2.2.84:50020 │ 172h4m48s │ 25.23 MB │
│ ○ │ nodeum.mover      │ 10.2.2.85-e5f6 │ BUILD   │ 10.2.2.85:50020 │ N/A       │ N/A      │
│ ○ │ nodeum.scheduler  │                │         │                 │ N/A       │ N/A      │
╰───┴───────────────────┴────────────────┴─────────┴─────────────────┴───────────┴──────────╯
```

Here one mover is alive, another is unavailable, and the scheduler is absent from the API response. The client adds the scheduler row with blank identity/version/address and `N/A` statistics.

The client checks for these required service names: `etcd`, `redis`, `mysql`, `mongo`, `nodeum.front`, `nodeum.scheduler`, `nodeum.monitoring`, `nodeum.dispatcher`, and `nodeum.mover`. If a name is entirely absent, it appends one unavailable row. It does not infer how many replicas should exist: a missing mover replica is not synthesized if another `nodeum.mover` entry is present. Other services returned by the server are displayed too.

`admin status` currently supports text output only; its JSON formatter is not implemented.

#### Application logs

**Command help**

The current help includes pagination options as well as time, tag, and level filters:

```
[nodeum01@ ~]$ nd admin logs --help
NAME:
   nd admin logs - display application logs

USAGE:
   nd admin logs [command options] [arguments...]

OPTIONS:
   --since value, -S value                       show logs since this date. Examples: '2025-01-15 14:30:00', '-1h', yesterday, '5 minutes ago', 'in 2 hours', 'last monday', 'yesterday at 10am'. See man page for full list
   --until value, -U value                       show logs until this date. Same formats as --since
   --tag value, -u value [ --tag value, -u value ]  filter by tags
   --level value                                minimum level of logs, one of [trace debug info warn error fatal]
   --limit value, -l value                       number of log entries to display (max: 100, 0 = no limit) (default: 50)
   --offset value, -o value                      number of log entries to skip for pagination (default: 0)
   --help, -h                                    show help
```

**Query logs**

```bash
nd --alias production admin logs --since '1 hour ago' --level error --limit 50
```

| Option           | Meaning                                                               |
| ---------------- | --------------------------------------------------------------------- |
| `--since`, `-S`  | Start time.                                                           |
| `--until`, `-U`  | End time.                                                             |
| `--tag`, `-u`    | Repeatable tag filter.                                                |
| `--level`        | Minimum level: `trace`, `debug`, `info`, `warn`, `error`, or `fatal`. |
| `--limit`, `-l`  | Default `50`, maximum `100`; `0` removes the client limit.            |
| `--offset`, `-o` | Entries to skip; default `0`.                                         |

Times accept explicit timestamps, relative durations such as `-1h`, and natural-language expressions such as `yesterday`, `5 minutes ago`, or `last monday`.

**Example log output and export**

Illustrative text output with locale `en-GB`:

```
06/10/2026 10:15:00 ERROR mover-01 nodeum.mover: Unable to read source file
1 – 1 of 1
```

Each log line contains the time, level, hostname, tag, and message. Redirect output to save a report:

```bash
nd --alias production admin logs --since '1 hour ago' --level error > errors.log
nd --json --alias production admin logs --since '1 hour ago' --limit 0 > logs.json
```

The JSON formatter emits one JSON object per entry, rather than a single JSON array. With a nonzero limit or offset, pagination text is also printed. `--limit 0` with no offset avoids that pagination footer.

#### Users

```bash
nd --alias production admin user list --limit 50
nd --alias production admin user create --uid 1500 --gid 1500 alice
nd --alias production admin user create --if-not-exists alice
nd --alias production admin user delete alice
```

| Command                                      | Options / behavior                                                                                                 |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `admin user list`                            | `--limit` / `-l`: default `50`, range `0–100`, with `0` removing the client limit. `--offset` / `-o`: default `0`. |
| `admin user create [OPTIONS] USERNAME`       | Create a user with a generated password, printed in the result.                                                    |
| `admin user delete [OPTIONS] ID-OR-USERNAME` | Resolve the user and ask for confirmation. `--yes` / `-y` skips confirmation.                                      |

Creation options:

| Option                     | Meaning                                                                                                                                                 |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--type`, `--source`, `-t` | `cli_linux_multi_user` (default), `cli_ldap`, or `web_app`.                                                                                             |
| `--uid`, `--gid`           | Explicit Linux user/group IDs. These are user-creation flags, not transfer flags.                                                                       |
| `--lookup`                 | Require a matching local account through `getent` for IDs not explicitly supplied. Without it, a missing local account only warns.                      |
| `--admin`                  | Grant administrator rights.                                                                                                                             |
| `--if-not-exists`          | Succeed without changes if the username already exists; no new password is generated. A different existing source type is reported rather than changed. |

**Example user output**

Illustrative `admin user list` output; absent optional fields are blank. This table formats dates as `YYYY-MM-DD HH:MM:SS`.

```
╭───────────────────┬──────────┬───────┬──────────────────────┬──────┬──────┬───────┬─────────────────────┬─────────────────────╮
│ ID                │ USERNAME │ ADMIN │ TYPE                 │ UID  │ GID  │ EMAIL │ CREATED AT          │ UPDATED AT          │
├───────────────────┼──────────┼───────┼──────────────────────┼──────┼──────┼───────┼─────────────────────┼─────────────────────┤
│ 12                │ alice    │       │ cli_linux_multi_user │ 1500 │ 1500 │       │ 2026-10-06 10:00:00 │ 2026-10-06 10:00:00 │
├───────────────────┼──────────┼───────┼──────────────────────┼──────┼──────┼───────┼─────────────────────┼─────────────────────┤
│ NUMBER OF USER(S) │ 1        │       │                      │      │      │       │                     │                     │
╰───────────────────┴──────────┴───────┴──────────────────────┴──────┴──────┴───────┴─────────────────────┴─────────────────────╯
```

Creating a user prints the generated password once in the result. This example substitutes a placeholder:

```
      ID: 12
Username: alice
Password: <generated-password>
    Type: cli_linux_multi_user
   Admin: false
     UID: 1500
     GID: 1500
```

If `--if-not-exists` finds the existing username, the output instead reads:

```
User "alice" already exists (ID 12, type cli_linux_multi_user); not changed
```

#### Server LDAP configuration

These commands read or update server configuration, separate from setting the client's `--auth-type ldap`:

```bash
nd --alias production server-config ldap get
nd --alias production server-config ldap set \
  --host ldap.example.com --port 389 \
  --admin-path 'cn=admin,dc=example,dc=com' \
  --admin-password 'PASSWORD' \
  --user-base-path 'ou=people,dc=example,dc=com' \
  --user-filter-template 'DEPLOYMENT_USER_FILTER'
```

The set options are `--host`, `--port`, `--admin-path`, `--admin-password`, `--user-base-path`, and `--user-filter-template`. Supply the complete intended configuration: the handler sends all fields, including empty/zero values for omitted options. Use your deployment's filter template and server-authorized account.

### Linux authentication service

The optional `nd auth-service run` daemon maps connecting Linux users to Nodeum users and provisions credentials. It also publishes non-secret cluster URLs, default flags, and weights for client configuration sync.

Communication uses the Linux abstract Unix socket `nd-auth-server.sock` (displayed with an `@` prefix by socket tools). It is not a filesystem socket to create or chmod. The service identifies clients using operating-system peer credentials; clients verify that the server runs as root or the fixed `nodeum_auth` service account. This local Linux mechanism is separate from standalone CLI access on macOS/Windows.

The packaged systemd service runs as `nodeum_auth`, with `ND_CONFIG_DIR=/etc/nodeum/config` and `ExecStart=/usr/bin/nd auth-service run`. Administrators must provision that directory and configuration for the service account: directory ownership `nodeum_auth`, mode `0750`, and configuration files mode `0600`, with credentials authorized to manage the relevant Nodeum users. The package creates the directory but leaves site-specific configuration/ownership provisioning to deployment management.

```bash
sudo systemctl status nd-auth-service
sudo journalctl -u nd-auth-service -f

# Client-side verification after service configuration
nd config sync
nd config review
nd config show --minimal
```

The daemon watches its configuration for updates. Clients synchronize published settings on subsequent commands; an unavailable or incompatible service leaves their existing local configuration intact. `config sync` is a settings check, while `config review` tests actual API authentication/connectivity.

### Troubleshooting

When updating older scripts, replace `config list` with `config show --minimal` and `task processed --processed-items=error` with `task processed --status error`. Transfer flags `--context-uid` / `--uid` and `--context-gid` / `--gid` are no longer registered; use the authenticated identity or the administrator-only `--run-as-user` option as appropriate. The `--uid` and `--gid` options documented above belong only to `admin user create`.

| Symptom                                   | What to check                                                                                                                  |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| Unknown flag or command                   | Check `nd --version` and that command's `--help`; installed releases may predate this source reference.                        |
| A flag is treated as a path/argument      | Put options before positional paths/IDs; use `--flag=false` for booleans and `--processed-items=all` for item display.         |
| No default alias / several clusters match | Run `nd config show --minimal`, then pass `--alias NAME`. Use selection weights for otherwise equivalent copy/move candidates. |
| Storage is missing after a pool change    | Run `nd config refresh-clusters` or use copy/move's `--refresh-clusters`.                                                      |
| Filesystem path matches no share          | Verify the path against NAS shares configured in Nodeum; use an explicit `nod://POOL/path` if appropriate.                     |
| A task ID is not found                    | Select the cluster that created the task; IDs are not automatically searched across clusters.                                  |
| Task has no last execution                | Start the saved definition with `nd task run TASKID`.                                                                          |
| No failed items appear                    | Use `task processed --status error`; `--processed-items` is a progress option.                                                 |
| Pool is absent from the default list      | `pool list` defaults to primary pools; specify the required `--type`.                                                          |
| TLS verification fails                    | Check the URL hostname and CA files, including `<alias>.crt`; custom config directories do not change certificate lookup.      |
| Local defaults/weight revert              | For service-published aliases, update the auth service's configuration rather than relying on a local override.                |
| Auth service cannot read configuration    | Check `nodeum_auth` ownership/access under `/etc/nodeum/config` and inspect its journal.                                       |

For connection diagnostics, use `nd --debug --alias NAME config review`. Its output may include tokens; remove credentials before sharing it.

> **Copyright**
>
> `nd` is a property of Nodeum and its subsidiaries, if any. The intellectual and technical concepts contained herein are proprietary to Nodeum and its subsidiaries and may be covered by Belgium and Foreign Patents, patents in process, and are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is strictly forbidden unless prior written permission is obtained from Nodeum.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.nodeum.io/data-mover/nd-client.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
