Gunnar

nordisk/Skidbladnir

.nornir/airgap-for-idiots.md

# Airgap (Skíðblaðnir) — for idiots

> **Class:** `idiot`. Every step, nothing assumed. Goal: from a **cold shell**, seal nornir + one product on a connected computer, carry it across an air gap, and get nornir **running on a computer with no internet**. If you already know your way around a terminal, read [`airgap-guide.md`](airgap-guide.md) instead — this one spells out every keystroke. The *why* is in [`airgap-reasoning.md`](airgap-reasoning.md).

## What you need first

- **Two computers.** Call them **BUILD** (has internet) and **TARGET** (no internet — the air-gapped one).
- A **USB stick** (or any way to copy a file from BUILD to TARGET).
- A terminal on each (the black window where you type commands). You press **Enter** after every command.
- `nornir` installed on BUILD. Check it — type and press **Enter**:
  ```
  nornir --version
  ```
  If that prints a version, you are good. TARGET does **not** need internet, but it does need the `nornir` binary — you will carry that over too (it can ride inside the bundle).

---

# PART A — on BUILD (the computer with internet)

## Step 1 — open a shell and make a workspace folder

Type each line, pressing **Enter** after each:
```
cd ~
mkdir -p airgap-demo
cd airgap-demo
```

## Step 2 — lay out the "staging tree"

The staging tree is just a folder whose shape becomes the bundle. Make the folders:
```
mkdir -p stage/linux-x86_64
mkdir -p stage/manifests
```

Now copy the program(s) you want to ship into `stage/linux-x86_64/`. For example, if your built `nornir-server` binary is at `target/release/nornir-server`:
```
cp target/release/nornir-server stage/linux-x86_64/nornir-server
```
Copy any other product the same way (e.g. `holger`). One file per program. If you do not have a real binary yet, make a fake one just to see the flow:
```
echo "pretend-binary" > stage/linux-x86_64/nornir-server
```

## Step 3 — seal it into ONE bundle file

Type and press **Enter** (pick today's date as the version, 8 digits `YYYYMMDD`):
```
nornir airgap pack ./stage --out lake-20250505.tar.zst --version 20250505
```
You should see a line like:
```
✓ packed 1 entries → lake-20250505.tar.zst (root sha256 abc123… , VERSION beside)
```
That created **three** things in the folder:
- `lake-20250505.tar.zst` — the sealed bundle (this is the important one).
- `lake-20250505.tar.zst.manifest.json` — its "packing list" with a hash of every file.
- `VERSION` — a tiny text file with `20250505` in it.

**Write down the `root sha256` value it printed** (the first 16 characters are fine) on a sticky note. You will check it on the other side.

## Step 4 — copy the bundle onto the USB stick

Plug in the USB stick. Find where it mounted (often under `/media/<you>/...` or `/run/media/<you>/...`). Copy **both** the bundle and its manifest:
```
cp lake-20250505.tar.zst          /run/media/$USER/USB/
cp lake-20250505.tar.zst.manifest.json /run/media/$USER/USB/
```
Then eject it safely (use your file manager's eject button), unplug it, and walk it over to TARGET.

---

# PART B — on TARGET (the air-gapped computer, no internet)

## Step 5 — plug in the USB and copy the bundle onto TARGET

Open a terminal on TARGET. Make a folder and copy both files off the USB stick:
```
cd ~
mkdir -p airgap-in
cd airgap-in
cp /run/media/$USER/USB/lake-20250505.tar.zst          .
cp /run/media/$USER/USB/lake-20250505.tar.zst.manifest.json .
```

## Step 6 — VERIFY the bundle before trusting it

This checks that nothing got corrupted or tampered with on the way over. Type and press **Enter** (paste the full sha you wrote down after `--sha256`, or leave that part off to just check the internal packing list):
```
nornir airgap fetch lake-20250505.tar.zst
```
- **Green / "ok"** → good, keep going.
- **Red / a non-zero error** → STOP. The file is broken or was changed. Re-copy it from BUILD and try again. nornir will refuse to install a bad bundle on purpose.

## Step 7 — install a component (this needs admin/root)

Installing creates a system user, writes a service, and unpacks the program. That needs `sudo` (admin). Type and press **Enter**:
```
sudo nornir airgap component add nornir-server --bundle lake-20250505.tar.zst
```
Not sure what the name should be? Ask nornir to list what it knows:
```
nornir airgap component status
```
That prints the components it can install (like `nornir-server`, `holger`, `tunnr`). Use one of those names.

**Want to see what it WOULD do without touching anything?** Add `--dry-run` (no `sudo` needed):
```
nornir airgap component add nornir-server --bundle lake-20250505.tar.zst --dry-run
```
That just prints the service file it would write.

## Step 8 — start everything in the right order

If you shipped more than one product, they might depend on each other. Make a small `lake.json` describing them (copy the example from [`airgap-guide.md`](airgap-guide.md) and edit the names), then type and press **Enter**:
```
nornir airgap start lake.json
```
It prints the "waves" — which product starts first, which waits for it — and records what happened. Read the record back any time:
```
nornir airgap events
```

## Step 9 — check it is actually running

Ask nornir whether the service is up:
```
nornir airgap component status nornir-server
```
An **active** service means you did it: nornir is running on a computer with **no internet**, installed entirely from the one file you carried over.

---

## If something goes wrong

- **"verify FAILED" on Step 6** → the copy got corrupted. Re-copy the bundle from BUILD. Do not force past it.
- **"needs root" / "permission denied" on Step 7** → you forgot `sudo`. Put `sudo` at the front.
- **"unknown component"** → run `nornir airgap component status` and use exactly one of the names it lists.
- **You have no internet on TARGET and something tries to download** → it should not. The whole point is that everything is inside the bundle. If nornir asks for the network on TARGET, you are missing a file from the bundle — go back to BUILD and add it to the staging tree in Step 2, then repack.

That is the whole journey: **seal one file on BUILD → carry it → verify → install → start on TARGET.** No internet on the far side, ever.