Skip to content

Build a Content Archive

Your RAID and firmware tooling ships today as a loose .tgz that every endpoint downloads and explodes onto disk — keeping both the compressed archive and its expanded copy. In an air-gapped bundle that hurts the most: the payload is stored twice inside the one image you have to carry across the boundary. Packaging the tooling as a content archive (.drpca) fixes both halves at once — the payload lives once inside the archive and is served in place (nothing is exploded), and the archive is still a single file you can redistribute downstream. You no longer have to choose between a ready-to-serve layout and keeping the original bundle.

You will author a small content pack, add the tool payload, build a .drpca, inspect it, and upload it to an endpoint. The example uses stand-in files so you can follow along without the real (licensed) vendor binaries — swap them in at the end.

For the concepts behind archives — how they mount and serve — see Content Archives in the Architect guide.

Prerequisites

  • drpcli on your PATH (DRP v4.17 or later — the content_archives command with --compress and --docs).
  • The payload you want to package. This tutorial fabricates a stand-in.
  • A running DRP endpoint you can reach — needed only for the upload and validation steps.

What you will build

An archive is assembled from a content definition plus one or more conventional payload directories. You will end up with this layout:

Text Only
raid-tools/
├── content.yaml          the content pack (metadata, plus any tasks/params)
└── files/                payload served in place under tftpboot/files
    └── raid-tools/
        ├── storcli       (stand-in for the real vendor binary)
        └── firmware.bin  (stand-in firmware blob)

The files/ directory is the important choice — see Where the payload goes.

Step 1 — Create the payload

Make the working directory and drop in stand-in payload. In a real archive these are the vendor tools and firmware:

Bash
mkdir -p raid-tools/files/raid-tools
cd raid-tools
printf '#!/bin/sh\necho "storcli stand-in"\n' > files/raid-tools/storcli
head -c 1048576 /dev/urandom > files/raid-tools/firmware.bin   # 1 MiB stand-in blob
chmod +x files/raid-tools/storcli

Anything under files/ is served by the endpoint at the matching path under tftpboot/files — for example files/raid-tools/storcli is fetchable at /files/raid-tools/storcli.

Step 2 — Define the content

The archive carries a content definition so it has a name, a version, and any automation that uses the payload. Create a minimal content.yaml:

YAML
meta:
  Name: raid-tools
  Version: v1.0.0
  Description: RAID and firmware tooling, packaged as a content archive
  Author: you@example.com

Tip

In a real project you author content in a content/ directory (tasks, templates, params) and bundle it with drpcli contents bundle. See Contents Layout for the full content layout. Here we hand-write a minimal bundle so the tutorial stays focused on the archive.

If you omit --content entirely, the build synthesizes a minimal content layer named after the target at version v0.0.0. That is almost never what you want — always pass --content with a real name and version for anything you intend to keep or distribute.

Step 3 — Build the archive

Bash
drpcli content_archives build raid-tools --content content.yaml --files files --compress
  • raid-tools is the target; the tool always writes raid-tools.drpca. The .drpca extension is appended if you leave it off and never stripped, so a versioned target like v1.0.0 becomes v1.0.0.drpca.
  • --content content.yaml supplies the name, version, and any automation.
  • --files files includes the payload directory. --files defaults to files/, so you could omit it here — being explicit is just clearer. The same pattern applies to --isos, --extracts, and --docs, each defaulting to a directory of that name.
  • --compress writes the archive as a seekable zstd stream. It is off by default; turn it on for large payloads so the archive ships small. Readers detect compression automatically, so a compressed archive needs nothing special to install or serve.

The build writes to a temporary file and renames it on success, so a failed build never clobbers an existing archive.

Step 4 — Inspect it

Confirm the payload landed where you expect:

Bash
drpcli content_archives inspect raid-tools.drpca

You should see your content metadata and the files/raid-tools/... entries. This is the moment to check that the payload is under files/ — served in place — and not somewhere that gets copied to disk.

Where the payload goes: files/ vs extracts/

This is the decision that determines whether you actually solve the duplication problem.

Directory What the endpoint does with it Disk cost
files/ Serves the file in place, straight from the mounted archive Stored once, inside the archive
isos/ Serves the image in place and makes its contents browsable Stored once, inside the archive
extracts/ Copies the file out onto the endpoint's disk Stored in the archive and on disk

Put payload that only needs to be served — tools, firmware, images — in files/ or isos/. Reserve extracts/ for the rare artifact that some process needs as a real on-disk file. Putting the RAID tooling in extracts/ would recreate exactly the "stored twice" problem you set out to fix: once compressed in the archive, once expanded on disk.

Warning

Extraction is idempotent — the endpoint skips the copy when the on-disk file already matches by checksum, so extracts/ no longer blindly overwrites on every install — but it still costs a second on-disk copy. Use it only when a real file is genuinely required.

Plugin-provider archives

A .drpca can also package a plugin provider instead of a content pack. Build it with --providers (mutually exclusive with --content), pointing at a directory of arch/os/<name> binaries. Inside the archive these live under a plugin/ namespace; on install the endpoint extracts the binary for its own platform and registers it as a plugin provider. Everything else in this tutorial — versioning, upload, catalog install — works the same way.

Step 5 — Pull payload from a source with artifacts (optional)

The conventional directories cover most needs. When you want to fetch payload from a URL or another location, or place it at a path that does not match the directory layout, declare it in an artifacts: section inside your --content file. Each entry names a source and, optionally, an integrity checksum and how to install it:

YAML
meta:
  Name: raid-tools
  Version: v1.0.0
artifacts:
  files/raid-tools:
    source: https://artifacts.example.com/raid-tools-v1.0.0.tgz
    sha256: 9f2b...   # full 64-character hex digest
    install:
      - action: expose
  • source is where the build fetches the payload from — http(s)://, s3://, file://, or a local path.
  • sha256 is verified at build time, so a corrupted or swapped-out source fails the build instead of shipping silently. Use it whenever source is a URL.
  • install actions map to the same behaviors as the conventional directories — expose (serve in place), mount (browsable image), extract (copy to disk), link (alias). Add a target to an action to override the destination path.
  • An artifact entry wins over the flag-directory contents at the same path, so you can override a single file without restructuring your tree.

Note

content_archives build reads artifacts only from the artifacts: key of the file you pass to --content. If you author content in a content/ directory instead, put the same entries in content/artifacts.yaml and run drpcli contents bundle first — bundling folds them into the content file that build then reads. A bare content/artifacts.yaml handed to a build that never bundles is silently ignored.

Tip

Set DRP_CONTENT_ARCHIVES_CACHE to a directory to cache fetched artifacts between builds. Without it, every build with an artifacts: block re-downloads its sources and warns that it is doing so.

Step 6 — Upload to an endpoint

Bash
drpcli content_archives upload raid-tools.drpca

The upload is atomic: the endpoint stages the archive, applies the content model and mounts the payload together, and commits — or rolls back cleanly on failure. To replace an older archive in the same operation, name it with --remove:

Bash
drpcli content_archives upload raid-tools.drpca --remove old-raid-tools-name

Step 7 — Validate

Confirm the endpoint installed the archive and serves the payload without exploding it:

Bash
drpcli content_archives list          # the archive is listed as installed

Fetch a payload file over the static file server to confirm it is served straight from the archive (HTTP on port 8091, HTTPS on 8090):

Bash
curl -sS -o /dev/null -w '%{http_code}\n' \
  http://<endpoint>:8091/files/raid-tools/storcli

A 200 means the file is being served from the mounted archive. The endpoint now holds one copy — inside the archive — instead of the old compressed-plus-exploded pair.

Versioning

The archive's identity is the Name and Version from its content metadata. To cut a new release, bump Version in content.yaml and rebuild. Multiple versions coexist in a catalog as <name>/<version>.drpca, and an endpoint runs one at a time (selected by its version sets). For a versioned target, name the build after the version:

Bash
drpcli content_archives build v1.1.0 --content content.yaml --files files --compress
# writes v1.1.0.drpca

Troubleshooting

File location files is not a directory / cannot be used (the prefix is Image/Assets/Docs for --isos/--extracts/--docs). You pointed the flag at something that is not a directory, or at a path that does not exist. Point it at a real directory, or drop the flag to accept the default.

The payload shows up on the endpoint's disk. It is in extracts/, or an artifacts.yaml entry uses the extract action. Move it to files/ (or use expose) if it only needs to be served — see Where the payload goes.

Version is v0.0.0. You built without --content, so the content was synthesized. Provide a content.yaml with a real Name and Version.

References