# CLI reference

> All cobra commands (mount, unmount, stop, status, info, list, create, fork, migrate, test-connection, config, version), flags, and argument patterns.

- Repository: timescale/tigerfs
- GitHub: https://github.com/timescale/tigerfs
- Human docs: https://grok-wiki.com/public/docs/timescale-tigerfs-60719456a5c3
- Complete Markdown: https://grok-wiki.com/public/docs/timescale-tigerfs-60719456a5c3/llms-full.txt

## Source Files

- `internal/tigerfs/cmd/root.go`
- `internal/tigerfs/cmd/mount.go`
- `internal/tigerfs/cmd/migrate.go`
- `internal/tigerfs/cmd/config.go`
- `docs/spec.md`
- `internal/tigerfs/cmd/cmd_test.go`

---

---
title: "CLI reference"
description: "All cobra commands (mount, unmount, stop, status, info, list, create, fork, migrate, test-connection, config, version), flags, and argument patterns."
---

The `tigerfs` binary is a Cobra application rooted at `internal/tigerfs/cmd`: `cmd.Execute` builds `buildRootCmd`, runs `PersistentPreRunE` (logging + `config.Init`), then dispatches subcommands. Mount is a blocking long-lived process; `create` and `fork` optionally spawn a detached `tigerfs mount` child. Active mounts are recorded in a JSON registry (default `~/.config/tigerfs/mounts.json`) for `status`, `list`, `info`, `unmount`, and `stop`.

## Command tree

```text
tigerfs                          # root: persistent logging/config flags
├── mount [CONNECTION] [MOUNTPOINT]
├── unmount MOUNTPOINT
├── stop PID
├── status [MOUNTPOINT]
├── info [MOUNTPOINT]
├── list
├── create [BACKEND:]NAME [MOUNTPOINT]
├── fork SOURCE [DEST]
├── migrate [CONNECTION]
├── test-connection [CONNECTION]
├── config
│   ├── show
│   ├── validate
│   └── path
└── version
```

<Info>
`mount` is documented as the primary workflow, but the root command does not register a Cobra default command. Invoke `tigerfs mount …` explicitly (not `tigerfs /mnt/db` alone).
</Info>

## Global flags

Applied on every subcommand via root `PersistentPreRunE` (flags bind to Viper at run time).

| Flag | Default | Effect |
|------|---------|--------|
| `--config-dir` | `~/.config/tigerfs` (or `XDG_CONFIG_HOME` / `%APPDATA%`) | Config search path |
| `--log-level` | `warn` | `debug`, `info`, `warn`, `error` |
| `--log-file` | (empty → stderr) | Log file path |
| `--log-format` | `text` | `text` or `json` |
| `--log-sql-params` | `false` | Log SQL bind parameters (may leak secrets) |

Configuration merge order for runtime behavior: built-in defaults → `config.yaml` → `TIGERFS_*` and bound `PG*` / `TIGER_*` env vars → command-specific flag overrides in each command’s `RunE`.

## Connection argument patterns

Many commands accept an optional `CONNECTION` positional argument. Resolution rules differ by command.

### Prefix scheme (mount, migrate)

| Form | Meaning |
|------|---------|
| `tiger:ID` | Tiger Cloud service; CLI fetches `postgres://…` via backend |
| `ghost:ID` | Ghost database; same pattern |
| `postgres://…` | Direct URL (two-arg mount: connection + mountpoint) |
| (omitted) | See per-command resolution below |

`backend.Resolve` treats only `tiger:` and `ghost:` as cloud backends. A bare name (no prefix) is not a connection string; callers use `default_backend` in config (`create`, `fork`) or treat a single non-prefixed arg as a mountpoint path (`mount`).

### `db.ResolveConnectionString` (test-connection, migrate)

When `CONNECTION` is omitted:

1. Explicit argument if provided  
2. `tiger_service_id` / `TIGER_SERVICE_ID` in config  
3. `host` from config (including `PGHOST`)

`mount` does **not** call `ResolveConnectionString`. It resolves `tiger:` / `ghost:` via `backend.GetConnectionString` only when the connection arg is non-empty after `resolveMountArgs`.

## `mount`

**Use:** `tigerfs mount [CONNECTION] [MOUNTPOINT]`  
**Args:** `cobra.RangeArgs(1, 2)` — one or two positionals.

Blocks until SIGINT/SIGTERM (from `cmd/tigerfs/main.go` cancel) or external unmount. Registers the mount in the registry on success; unregisters on exit. Auto-creates missing mountpoint directories and removes them on unmount only when TigerFS created the directory.

### Argument resolution

| Args | `CONNECTION` | `MOUNTPOINT` |
|------|--------------|--------------|
| `CONN MNT` | First arg | Second arg |
| `tiger:ID` or `ghost:ID` | Prefix ref | `default_mount_dir/ID` (default `/tmp/ID`) |
| Single path or name | Empty | That arg (e.g. `/mnt/db`, `./db`) |

<Warning>
A single `postgres://…` positional is parsed as a **mountpoint**, not a connection. Use two args: `tigerfs mount postgres://user@host/db /mnt/db`.
</Warning>

### Mount flags (applied in `RunE`)

| Flag | Default | Maps to / behavior |
|------|---------|-------------------|
| `--schema` | `""` | `cfg.DefaultSchema` when set |
| `--no-filename-extensions` | `false` | `cfg.NoFilenameExtensions` |
| `--query-timeout` | `0` | `cfg.QueryTimeout` when &gt; 0 |
| `--dir-filter-limit` | `0` | `cfg.DirFilterLimit` when &gt; 0 |
| `--max-pipeline-depth` | `0` | `cfg.MaxPipelineDepth` only if flag changed |
| `--legacy-fuse` | `false` | Linux: legacy FUSE tree vs `fs.Operations` (default) |
| `--insecure-no-ssl` | `false` | `cfg.InsecureNoSSL` |
| `--user-id` | `""` | `cfg.UserID`, else `TIGERFS_USER_ID` |
| `--auto-savepoint-interval` | `0` | `cfg.AutoSavepointInterval` when non-zero; must be ≥ 0 |
| `--undo-list-limit` | `0` | `cfg.UndoListLimit` when &gt; 0 |

### Mount flags (registered, not wired in `RunE`)

These appear in `--help` but are not passed into `cfg` or the mount layer today:

| Flag | Default | Note |
|------|---------|------|
| `--read-only` | `false` | Logged only |
| `--max-ls-rows` | `10000` | Use `dir_listing_limit` in config (default 1000) |
| `--foreground` | `false` | Mount always blocks in the foreground process |

### Platform backends

| OS | Backend |
|----|---------|
| Linux | FUSE (`fuse.MountOps` default; `--legacy-fuse` → `fuse.Mount`) |
| macOS | In-process NFS (`nfs.Mount`) |

### Examples

```bash
# Cloud: auto mountpoint under /tmp
tigerfs mount tiger:abcde12345

# Cloud + explicit path
tigerfs mount ghost:fghij67890 /mnt/db

# Direct URL (two positionals required)
tigerfs mount postgres://user@host:5432/mydb /mnt/db

# Undo identity + debug logs
tigerfs mount --user-id agent-1 --log-level debug postgres://localhost/mydb /mnt/db
```

## `unmount`

**Use:** `tigerfs unmount MOUNTPOINT`  
**Args:** Exactly one mountpoint (resolved to absolute path).

| Flag | Shorthand | Default | Description |
|------|-----------|---------|-------------|
| `--force` | `-f` | `false` | Force unmount (`fusermount -uz` on Linux, `diskutil unmount force` on macOS) |
| `--timeout` | `-t` | `30` | Seconds to wait for graceful shutdown |

**Behavior:** Looks up registry → `SIGTERM` to registered PID → waits → falls back to OS unmount. Cleans registry entry and removes auto-created mountpoint dirs when applicable. Prints `Successfully unmounted <path>`.

## `stop`

**Use:** `tigerfs stop PID`  
**Args:** Positive integer PID.

| Flag | Shorthand | Default |
|------|-----------|---------|
| `--timeout` | `-t` | `30` |

Sends `SIGTERM`, waits for exit, cleans registry if the PID matches a registered mount. Equivalent to unmount when you have the PID from `status` instead of the path.

## `status`

**Use:** `tigerfs status [MOUNTPOINT]`  
**Args:** Zero or one.

| Mode | Output |
|------|--------|
| No args | Table: `MOUNTPOINT`, `DATABASE`, `PID`, `STATUS`, `UPTIME` for active mounts (stale entries cleaned first) |
| With mountpoint | Detail: mountpoint, database, backend, service ID, PID, status (`active` / `stale`), started time, uptime |

Empty registry: `No active TigerFS mounts`.

## `list`

**Use:** `tigerfs list`  
**Args:** None.

One mountpoint path per line (no header). Stale registry entries are cleaned before listing. Intended for scripting (`xargs`, loops).

## `info`

**Use:** `tigerfs info [MOUNTPOINT]`  
**Args:** Zero or one.

| Flag | Description |
|------|-------------|
| `--json` | JSON `backend.MountInfo` |

Without `MOUNTPOINT`: requires exactly one active mount; errors if zero or multiple (lists suggested commands). For cloud-backed mounts (`CLIBackend` + `ServiceID`), calls the backend CLI for live service metadata.

## `create`

**Use:** `tigerfs create [BACKEND:]NAME [MOUNTPOINT]`  
**Args:** `cobra.MaximumNArgs(2)`.

| Flag | Description |
|------|-------------|
| `--no-mount` | Create service only; print manual mount hint |
| `--json` | JSON result including `backend`, `no_mount` |

**Backend resolution:** `tiger:NAME`, `ghost:NAME`, or bare `NAME` with `default_backend` in config. Bare `tiger:` / `ghost:` auto-generates a service name.  
**Mount:** Unless `--no-mount`, runs detached `tigerfs mount <backend>:<serviceID> <mountpoint>`. Default mountpoint: `default_mount_dir/<name>` (often `/tmp/<name>`).

## `fork`

**Use:** `tigerfs fork SOURCE [DEST]`  
**Args:** One or two.

| Flag | Description |
|------|-------------|
| `--name` | Override fork service name |
| `--no-mount` | Fork only |
| `--json` | JSON fork result |

**SOURCE**

| Form | Resolution |
|------|------------|
| Path starting with `/` or `.` | Mount registry lookup (requires cloud-backed mount) |
| `tiger:ID`, `ghost:ID` | Backend + service ID |
| Bare name | `default_backend` |

**DEST** (optional): path → mount there (basename used as name unless `--name`); bare name → service name and mount at `baseDir/NAME` (`baseDir` is parent of source mountpoint when SOURCE was a path, else `default_mount_dir`).

## `migrate`

**Use:** `tigerfs migrate [CONNECTION]`  
**Args:** `cobra.MaximumNArgs(1)`. Uses `db.ResolveConnectionString`. 60s command timeout.

| Flag | Description |
|------|-------------|
| `--describe` | List pending migrations and items |
| `--dry-run` | Print SQL without executing |
| `--schema` | Schema to migrate (default: `current_schema()`) |
| `--insecure-no-ssl` | Disable TLS enforcement for remote hosts |

**Registered migrations (order fixed):**

| Name | Summary |
|------|---------|
| `move-backing-tables` | Move synth backing tables from `_name` in user schema to `tigerfs.name` |
| `relational-directories` | Add `parent_id` parent-pointer directory model |
| `parent-dir-mtime-trigger` | Parent directory `modified_at` trigger for NFS listings |

Default mode runs each pending migration in a transaction. Idempotent when nothing pending: `No pending migrations.`

## `test-connection`

**Use:** `tigerfs test-connection [CONNECTION]`  
**Args:** `cobra.MaximumNArgs(1)`. 30s timeout. Uses `db.ResolveConnectionString`.

**Output:** PostgreSQL version (trimmed), database, user, schema count, base table count (user schemas only).

## `config`

**Use:** `tigerfs config <subcommand>`

### `config show`

Merged effective config as YAML (passwords omitted). Sections: `connection`, `tiger_cloud`, `backend`, `filesystem`, `query`, `metadata`, `nfs`, `ddl`, `logging`, `advanced`.

### `config validate`

Reads `~/.config/tigerfs/config.yaml` (or `--config-dir`). Missing file is OK (“Using default configuration”). Validates YAML, unmarshaling, port/pool/dir limits, `default_format`, `binary_encoding`, `log_level`.

### `config path`

Prints config file path; notes if file does not exist.

## `version`

**Use:** `tigerfs version`

Prints: `Version`, `BuildTime`, `GitCommit` (ldflags in release builds; `dev` / `unknown` in dev), Go version, `GOOS`/`GOARCH`.

## Mount lifecycle

```mermaid
stateDiagram-v2
  [*] --> Starting: tigerfs mount
  Starting --> Registered: register mounts.json
  Registered --> Serving: fs.Serve blocks
  Serving --> Unregistering: SIGTERM or unmount
  Unregistering --> [*]: unregister + optional rmdir
```

## Operational commands (quick reference)

| Goal | Command |
|------|---------|
| Mount cloud DB | `tigerfs mount tiger:SERVICE_ID` |
| List mountpoints | `tigerfs list` |
| Inspect mounts | `tigerfs status` |
| Cloud service details | `tigerfs info --json /path` |
| Test credentials | `tigerfs test-connection postgres://…` |
| Graceful teardown | `tigerfs unmount /path` or `tigerfs stop PID` |
| Provision + mount | `tigerfs create tiger:my-db` |
| Clone + mount | `tigerfs fork /mnt/prod my-fork` |
| Schema upgrades | `tigerfs migrate postgres://… --dry-run` |

## Error and exit behavior

- Root and subcommands set `SilenceUsage: true` on failure (no usage spam; message on stderr via logging).
- Invalid args (bad PID, missing mount, multiple mounts for bare `info`) return descriptive errors from `RunE`.
- FUSE/NFS operational errors surface as POSIX errno to tools; detailed hints are written via `logging.Error` / `Warn` (see error-codes page).

<Note>
`cmd_test.go` verifies command names, help text, and core flag registration. When `--help` disagrees with runtime wiring, trust the `RunE` implementation in `internal/tigerfs/cmd/*.go`.
</Note>

## Related pages

<CardGroup>
  <Card title="Configuration reference" href="/configuration-reference">
    Config file fields, env vars, and precedence beyond CLI flags.
  </Card>
  <Card title="Connection reference" href="/connection-reference">
    postgres:// URIs, PG* env, TLS, passwords, and pool settings.
  </Card>
  <Card title="Cloud backends" href="/cloud-backends">
    tiger: and ghost: resolution, create/fork, and Tiger CLI auth.
  </Card>
  <Card title="Migrate workspaces" href="/page-migrate-workspaces">
    migrate --describe/--dry-run and history-format upgrade boundaries.
  </Card>
  <Card title="Troubleshooting" href="/troubleshooting">
    Stale mounts, force unmount, and --log-level debug.
  </Card>
</CardGroup>
