# Archiso — Custom Live Installer

The archiso build system produces a bootable Arch Linux ISO pre-loaded with the M-Archy installer scripts. Optionally, an answerfile can be embedded so the entire install — base OS + dotfiles — runs with zero user interaction.

---

## Prerequisites

```bash
sudo pacman -S archiso jq
```

---

## Building the ISO

```bash
# Basic build — interactive installer, no answerfile
bash setup/tools/build.sh

# Specify output directory
bash setup/tools/build.sh /path/to/output

# Embed an answerfile for automated deployment
bash setup/tools/build.sh --preconf

# Embed a specific answerfile
bash setup/tools/build.sh --preconf ~/my-server.json

# Both flags together
bash setup/tools/build.sh --preconf ~/my-server.json /media/usb/output
```

| Flag | Effect |
|------|--------|
| _(none)_ | Clean ISO, no answerfile |
| `--preconf` | Embed `~/answerfile.json` at `/answerfile.json` in the ISO |
| `--preconf FILE` | Embed the specified file instead |

Build artefacts land in `~/m-archy-out/` by default. Override with the `OUT_DIR` environment variable or by passing a path argument.

### Environment Variables

| Variable | Default | Purpose |
|----------|---------|---------|
| `WORK_DIR` | `~/m-archy-build` | Scratch space for mkarchiso |
| `OUT_DIR` | `~/m-archy-out` | ISO output directory |

---

## What the Build Does

1. Copies the upstream `releng` Arch base profile
2. Applies the M-Archy overlay (`setup/archiso/overlay/`)
3. Replaces `profiledef.sh` with the M-Archy version
4. Adds extra packages from `packages.extra`
5. Embeds both installer scripts (`arch-autoinstall.sh`, `archbaseos-guided-install.sh`) into `/root/installer/`
6. If `--preconf`: copies the answerfile to `/answerfile.json` in the ISO's airootfs
7. Runs `mkarchiso` to produce the final `.iso`

---

## Extra Packages on the Live System

Defined in `setup/archiso/overlay/packages.extra`:

```
git
jq
pam-u2f
btop
fastfetch
openssh
libfido2
```

`libfido2` is included to support FIDO2 / token-based LUKS unlock in the system reset mode (see below).

These are added on top of the standard Arch `releng` package set.

---

## Live System Entry Points

Once booted from the ISO, the following are available:

### `install-arch`

A command placed in `/usr/local/bin/`:

```bash
install-arch           # guided mode (default)
install-arch guided    # guided interactive install
install-arch auto      # automated mode (reads /answerfile.json)
```

### `/root/launch.sh`

Internal dispatcher used by `install-arch`. After keymap selection, it prompts for one of two actions:

- **Install** — runs the normal guided or automated installer.
- **Reset** — runs `setup/reset-arch.sh` (see [System Reset Mode](#system-reset-mode)).

### `/answerfile.json`

Only present when built with `--preconf`. Both installer scripts check for this file on startup. If found, all prompts are answered from it — the only interaction required is the disk-encryption password (passwords are never stored in answerfiles).

---

## System Reset Mode

`setup/reset-arch.sh` performs a non-destructive system reinstall from the live environment, keeping user home data and authentication keys intact.

### What it does

1. Detects LUKS2 encryption on the selected partition and unlocks it:
   - **Option 1** (recommended): tries the enrolled FIDO2/TPM2 token first, falls back to passphrase.
   - **Option 2**: passphrase only.
   - **Option 3**: enrolled token only.
2. Snapshots `/etc` credentials and config from the existing `@` subvolume.
3. Wipes `~/.config` from `@home` for all users, **preserving** `~/.config/Yubico/` so FIDO2 PAM login continues to work after reset.
4. Deletes and recreates the `@` (root) Btrfs subvolume.
5. Reinstalls base system packages via `pacstrap`.
6. Restores `passwd`, `shadow`, `pam.d`, `sudoers`, `fstab`, `mkinitcpio.conf`, and GRUB config from the snapshot.
7. Regenerates initramfs and GRUB menu from chroot.

### How to run it

Boot from the ISO. At the action prompt, select **Reset**.

The reset mode is also available standalone on any live Arch environment:

```bash
bash /path/to/setup/reset-arch.sh
```

### What is preserved

| Data | Preserved |
|------|-----------|
| User home directories (`/home/*`) | Yes |
| User passwords (`/etc/shadow`) | Yes |
| FIDO2 keys (`~/.config/Yubico/`) | Yes |
| PAM configuration | Yes |
| sudoers rules | Yes |
| fstab, mkinitcpio config | Yes |
| App configs (`~/.config/*`) | **No** (wiped except Yubico) |
| Installed packages | **No** (reinstalled from base) |

---

## Automated Deployment Workflow

```
┌─────────────────────────────────────┐
│  Developer machine                  │
│                                     │
│  1. generate-answerfile.sh          │
│     → ~/answerfile.json             │
│                                     │
│  2. build.sh --preconf              │
│     → ~/m-archy-out/m-archy.iso     │
│                                     │
│  3. dd if=m-archy.iso of=/dev/sdX   │
└──────────────┬──────────────────────┘
               │ USB
               ▼
┌─────────────────────────────────────┐
│  Target machine (boots from USB)    │
│                                     │
│  4. install-arch auto               │
│     reads /answerfile.json          │
│     installs base OS                │
│     runs tui-install.sh in chroot   │
│     installs dotfiles & apps        │
│                                     │
│  5. Reboot → ready system           │
└─────────────────────────────────────┘
```

For multi-machine deployments, the `hostname` field in the answerfile is combined with the machine's MAC address, so each system gets a unique hostname even though they share the same answerfile.

---

## Overlay Structure

```
setup/archiso/overlay/
├── airootfs/
│   ├── etc/motd                          # Welcome message
│   ├── root/
│   │   └── launch.sh                     # Installer entry point
│   └── usr/local/bin/
│       └── install-arch                  # User-facing CLI command
├── packages.extra                        # Additional live-system packages
└── profiledef.sh                         # M-Archy ISO profile definition
```

The `build.sh` script also adds at build time:
```
airootfs/root/installer/
├── arch-autoinstall.sh
└── archbaseos-guided-install.sh
```

---

## Writing the ISO to USB

```bash
# Find the USB drive
lsblk

# Write (replace /dev/sdX with your drive — ALL DATA WILL BE ERASED)
sudo dd if=~/m-archy-out/m-archy-*.iso of=/dev/sdX bs=4M status=progress oflag=sync
```

Or use `ventoy` / `balenaEtcher` as alternatives.

---

## PXE Boot / netboot.xyz

Every build also produces a `*-netboot-*.tar.gz` artifact alongside the ISO. This tarball contains the kernel, initrd, and squashfs image laid out for HTTP-based PXE booting. The live initramfs already includes the `archiso_pxe_http` hook, so no extra packages or custom kernel parameters beyond the ones below are required.

### 1. Build with a netboot URL

```bash
bash setup/tools/build.sh --netboot-url http://your-server/m-archy
# or combined with an answerfile:
bash setup/tools/build.sh --preconf --netboot-url http://your-server/m-archy
```

This generates `~/m-archy-out/m-archy-netboot.ipxe` alongside the netboot tarball.

### 2. Serve the artifacts

Extract the netboot tarball so that its contents are reachable at the base URL you provided:

```bash
# On your web server
mkdir -p /srv/http/m-archy
tar -xzf ~/m-archy-out/*-netboot-*.tar.gz -C /srv/http/m-archy
cp ~/m-archy-out/m-archy-netboot.ipxe /srv/http/m-archy/
```

The server must expose at minimum:

```
http://your-server/m-archy/arch/boot/x86_64/vmlinuz-linux
http://your-server/m-archy/arch/boot/x86_64/initramfs-linux.img
http://your-server/m-archy/arch/x86_64/airootfs.sfs
http://your-server/m-archy/m-archy-netboot.ipxe
```

### 3. Add to netboot.xyz

In your netboot.xyz configuration (or the **Custom iPXE** option in the netboot.xyz menu), chainload the generated script:

```
chain http://your-server/m-archy/m-archy-netboot.ipxe
```

Or add a named menu item:

```
item m-archy  M-Archy Arch Linux Installer
...
:m-archy
chain http://your-server/m-archy/m-archy-netboot.ipxe
```

### Manual iPXE parameters

If you prefer to write the boot stanza by hand (e.g. for a self-hosted netboot.xyz with YAML menus):

```
kernel http://your-server/m-archy/arch/boot/x86_64/vmlinuz-linux \
    archiso_http_srv=http://your-server/m-archy/ \
    archisobasedir=arch \
    ip=dhcp
initrd http://your-server/m-archy/arch/boot/x86_64/initramfs-linux.img
boot
```

| Kernel parameter | Purpose |
|-----------------|---------|
| `archiso_http_srv=<url>/` | Base URL the initramfs fetches the squashfs from (trailing slash required) |
| `archisobasedir=arch` | Subdirectory prefix — matches `install_dir` in `profiledef.sh` |
| `ip=dhcp` | Acquire an IP before the HTTP fetch |
