# IncusOS ISO Download & Customization Methods

> **Note:** This document was the original research note that started this repository.
> For the actual automation scripts, see [`../incusos/README.md`](../incusos/README.md).

---

To automate the generation and download of customized IncusOS ISO files, you have two technical paths: using the official **flasher-tool** (the recommended CLI method for automation) or scripting the **REST API** used by the web customizer.

### Method 1: The flasher-tool (Recommended for Scripts)

The Incus team provides a dedicated command-line utility specifically for automated image generation. It connects to the Linux Containers CDN to fetch the latest builds and applies your customizations locally.

**Installation:**

```bash
go install github.com/lxc/incus-os/incus-osd/cmd/flasher-tool@latest
```

**Sample Automation Script:**

This script generates a customized ISO for an x86_64 cluster node with your local client certificate already trusted.

```bash
#!/bin/bash
# automated-incusos-build.sh

# 1. Fetch your local Incus client certificate
CLIENT_CERT=$(incus remote get-client-certificate)

# 2. Define your customized seed in JSON format
# This example preps a node to join a cluster (apply_defaults: false)
cat <<EOF > cluster-node-seed.json
{
  "apply_defaults": false,
  "preseed": {
    "certificates": []
  }
}
EOF

# 3. Run the flasher tool to build the ISO
# -f: format (iso or img)
# -s: path to your seed file
# -o: output filename
flasher-tool -f iso -s cluster-node-seed.json -o my-custom-node.iso
```

### Method 2: Scripting the Web Customizer API

If you prefer to use the web backend directly via curl, you must POST a configuration payload to the generator endpoint. The web customizer is an SPA that communicates with a backend to stream a compressed image.

**Technical Logic:**

The backend accepts a JSON object that mimics the "Seed" structures. One critical detail is that the web customizer streams **gzipped** data which the browser typically decompresses on the fly; when using curl, you must ensure you handle the output stream correctly.

**Sample curl Download Script:**

```bash
#!/bin/bash

# Configuration
ARCH="x86_64"           # x86_64 or aarch64
APP="incus"             # incus, operations-center, or migration-manager
USAGE="install"         # install (on disk) or live (run from media)
CERT=$(incus remote get-client-certificate | sed ':a;N;$!ba;s/\n/\\n/g')

# Generate the JSON payload for the web customizer
PAYLOAD=$(cat <<EOF
{
  "format": "iso",
  "architecture": "$ARCH",
  "usage": "$USAGE",
  "applications": ["$APP"],
  "incus": {
    "apply_defaults": true,
    "preseed": {
      "certificates": []
    }
  }
}
EOF
)

# POST to the customizer backend (Note: The URL may vary by build/release)
curl -X POST https://incusos-customizer.linuxcontainers.org/api/generate \
     -H "Content-Type: application/json" \
     -d "$PAYLOAD" \
     --output incus-os-latest.iso
```

### Key Reference for Customization Settings

When scripting either tool, use these field values to generate the "flavors" you need for your lab:

| Selection          | Value Options                                | Description                                        |
|--------------------|----------------------------------------------|----------------------------------------------------|
| **Architecture**   | x86_64, aarch64                              | Target CPU type.                                   |
| **Applications**   | incus, operations-center, migration-manager  | Can be an array for multiple apps.                 |
| **Defaults**       | true or false                                | Set to false for cluster nodes to avoid conflicts. |
| **Security**       | missing_tpm: true                            | Use if hardware/VM lacks a TPM 2.0 module.         |

### Advanced Automation Tip: Using a "Pristine" Image

If you find downloading multiple 500MB+ files is too slow, you can download one **Pristine ISO** (unconfigured) from the image server and provide the unique configuration via a small external partition labeled **SEED_DATA**.

- Download the base image once.
- Create a tiny (10MB) FAT image.
- Label that tiny image `SEED_DATA` and place your unique `incus.yaml` and `network.yaml` inside it.
- Mount both the ISO and the SEED_DATA disk to your VM. IncusOS will automatically merge them at boot.
