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¶
drpclion yourPATH(DRP v4.17 or later — thecontent_archivescommand with--compressand--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:
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:
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:
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¶
raid-toolsis the target; the tool always writesraid-tools.drpca. The.drpcaextension is appended if you leave it off and never stripped, so a versioned target likev1.0.0becomesv1.0.0.drpca.--content content.yamlsupplies the name, version, and any automation.--files filesincludes the payload directory.--filesdefaults tofiles/, 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.--compresswrites 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:
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:
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
sourceis where the build fetches the payload from —http(s)://,s3://,file://, or a local path.sha256is verified at build time, so a corrupted or swapped-out source fails the build instead of shipping silently. Use it wheneversourceis a URL.installactions map to the same behaviors as the conventional directories —expose(serve in place),mount(browsable image),extract(copy to disk),link(alias). Add atargetto 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¶
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:
Step 7 — Validate¶
Confirm the endpoint installed the archive and serves the payload without exploding it:
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):
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:
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¶
- Content Archives — the architecture: how archives mount and serve.
- Install and Use a Content Archive — installing and using an archive as an operator.
- Contents Layout — authoring the content pack that goes inside.
- Content Archives API — doing all of this programmatically.