# `Hyper.Img.OciLoader`
[🔗](https://github.com/harmont-dev/hyper/blob/main/lib/hyper/img/oci_loader.ex#L1)

Builds an ext4 rootfs from an OCI image and hands it to `Hyper.Img.create/2`.

`load/1` takes a registry reference (e.g. `"docker.io/library/alpine:3.19"`)
and:

  1. **pulls** it with `skopeo`, selecting the manifest entry matching this node's
     architecture, into a local OCI layout.
  2. **flattens** it with `umoci unpack`, which applies OCI whiteouts/opaque dirs correctly,
     yielding a merged rootfs directory.
  3. **builds** an ext4 image of that rootfs with `mke2fs -d`.
  4. hands the ext4 file to `Hyper.Img.create/2`, which content-addresses it,
     publishes it into the media store, and records it as a base image --
     returning the `img_id`.

This module owns only the OCI-to-ext4 conversion; ingesting a prepared image
file into the store and database is `Hyper.Img`'s job.

# `load`

```elixir
@spec load(String.t()) :: {:ok, Hyper.Img.id()} | {:error, term()}
```

Load `ref` into the store and DB. See the module doc. Label defaults to `ref`.

# `load`

```elixir
@spec load(
  String.t(),
  keyword()
) :: {:ok, Hyper.Img.id()} | {:error, term()}
```

Load `ref`. `opts[:label]` sets the human-readable `images.label` (defaults to
`ref`).

Returns `{:error, {:missing_tools, names}}` when the node lacks a required
external tool (`skopeo`/`umoci`/`mke2fs`); the check runs up front so the load
fails fast before the multi-minute pull.

# `test_system`

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

Verify the external tools the loader needs (`skopeo`, `umoci`, `mke2fs`) are
resolvable on this host. Returns `{:error, {:missing_tools, names}}` listing
any that are absent.

---

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