# `Hyper.SuidHelper`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/hyper/suid_helper.ex#L1)

Interface to the setuid-root device helper (`hyper-suidhelper`), split by tool:

  * `Hyper.SuidHelper.Losetup`    - loop devices
  * `Hyper.SuidHelper.Dmsetup`    - device-mapper (snapshot / thin)
  * `Hyper.SuidHelper.Blockdev`   - block-device queries
  * `Hyper.SuidHelper.ChrootJail` - chroot lifecycle (prepare / remove)

Elixir runs unprivileged; these submodules are the only path to the privileged operations. Each
builds the argv for one operation and shells the helper through `exec/1`, which decodes the
JSON the helper prints on success. The helper validates every argument before briefly
escalating to root (see `native/suidhelper`).

`test_system/0` aggregates each tool's own presence check; `sys_test/0` runs the helper's
self-test and reports the base path it was compiled against.

# `err`

```elixir
@type err() :: {non_neg_integer(), String.t()}
```

Error tuple: exit code + trimmed stderr/stdout from the helper.

# `sys_test`

```elixir
@spec sys_test() :: {:ok, Path.t()} | {:error, err()}
```

Run the helper's `sys-test` subcommand (proves it can promote to root). Returns
`{:ok, hyper_base}` where `hyper_base` is the work-dir the helper was compiled
against.

# `test_system`

```elixir
@spec test_system() :: :ok | {:error, term()}
```

Check that the setuid helper is usable on this machine: the helper binary is
present, is the build this release expects (`verify_version/0`), and the kernel
exposes the device-mapper targets we need (`Dmsetup.test_system/0`, which also
exercises the helper's configured `dmsetup` binary).

The `losetup`/`blockdev` binaries are validated by the helper the first time
each is used; their paths live in the helper's own config, not here.

# `verify_version`

```elixir
@spec verify_version() :: :ok | {:error, :version_mismatch | err()}
```

Check the deployed helper is the one this build produced: its `version` output
must match `Hyper.SuidHelper.Expected` (the identity captured from the stamped
binary at compile time). Catches a stale or wrong binary at the configured path.

This compares the helper's *self-reported* identity, so it is a build-provenance
check, not an adversarial tamper proof -- a malicious binary could report any
value.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
