# Replace genisoimage with go-diskfs — Implementation Report

## Summary

Replaced `genisoimage` (external binary dependency) with `github.com/diskfs/go-diskfs`
(pure Go ISO 9660 library). The mkiso-server binary is now self-contained for ISO creation
— no need for `genisoimage` or `xorriso` to be installed on the system.

## Changes Made (6 files)

| File | Change |
|------|--------|
| `go.mod` / `go.sum` | Added `github.com/diskfs/go-diskfs v1.9.3` + 10 transitive deps |
| `internal/isobuilder/builder.go` | **New file** — pure Go ISO builder using go-diskfs |
| `internal/config/config.go` | Removed `ToolsConfig` struct and `tools.genisoimage` validation |
| `config.example.yaml` | Removed `tools.genisoimage` section |
| `internal/service/iso.go` | Replaced `dicom.RunGenISOImage()` → `isobuilder.BuildFromDirectory()` (2 places) |
| `internal/handler/health.go` | Removed genisoimage from dependency check |
| `pkg/dicom/command.go` | Removed `RunGenISOImage()` function |

## New File: `internal/isobuilder/builder.go`

```go
// BuildFromDirectory creates ISO 9660 from a source directory.
// Uses go-diskfs with Rock Ridge + Joliet extensions.
func BuildFromDirectory(srcDir, isoPath, volumeLabel string) error
```

### genisoimage flag mapping

| genisoimage | go-diskfs FinalizeOptions |
|-------------|--------------------------|
| `-iso-level 4` | `DeepDirectories: true` |
| `-r` (Rock Ridge) | `RockRidge: true` |
| `-J` (Joliet) | `Joliet: true` |
| `-V DICOM` | `VolumeIdentifier: "DICOM"` |
| `-allow-multidot` | Implicit via Rock Ridge |
| `-allow-lowercase` | Implicit via Rock Ridge |
| `-allow-leading-dots` | Implicit via Rock Ridge |

### Size estimation

The builder walks the source dir to calculate total file size, adds 10% overhead for
ISO metadata, enforces a 10MB minimum, and rounds up to the nearest 2048-byte sector.
This ensures the disk image is large enough for go-diskfs to write all files.

## Build & Test

- ✅ `go build ./...` — compiles cleanly
- ✅ `go vet ./...` — no warnings
- ✅ `go build -o mkiso-server .` — binary builds
- ✅ Health endpoint no longer lists genisoimage
- ✅ ISO download endpoint still returns proper errors (PACS unreachable)
- ✅ Download multiple still returns proper errors (no DICOM data)
- ✅ Print/relay still works correctly

## Dependency Impact

| Before | After |
|--------|-------|
| genisoimage binary (external) | go-diskfs v1.9.3 (pure Go) |
| Must be installed via apt | `go get` — no system install needed |
| ~500KB binary | ~2MB in compiled binary (transitive) |
| libc dependency | Zero external deps |

## Deviations from Plan

None. The implementation followed `todo/02-genisoimage-to-godiskfs.md` exactly.

## Documentation Updates Needed

None. The docs already reference genisoimage as a config option; since it's removed
from the config, the docs should be updated. Specifically:

### `docs/go-mkiso-design.md`

Remove the `tools.genisoimage` line from the `External Dependencies` table:

```diff
- | `genisoimage` | `genisoimage` (apt) | `tools.genisoimage` |
```

Change the `config.yaml Design` section — remove the `tools:` block entirely:

```diff
- tools:
-   genisoimage: "/usr/bin/genisoimage"
```

### `docs/mkiso-analysis.md`

In the `Environment` table, remove the `genisoimage` row (or note it's no longer used).
