Skip to content

gayanch/cloudinit-seedgen

Repository files navigation

Cloud-Init NoCloud Seed ISO Generator

Small Flask app that generates a cloud-init NoCloud seed ISO (cidata) from validated inputs.

Web UI screenshot

Features

  • Parameterized cloud-init meta-data + user-data
  • Strict input validation (allow-lists)
  • Per-request temp directories with TTL cleanup
  • Minimal HTMX form UI
  • Download token endpoint

Requirements

  • Python 3.10+
  • genisoimage available on the host
    • macOS: brew install cdrtools
    • Ubuntu/Debian: sudo apt-get install genisoimage

Setup

Create and use the virtual environment:

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Run

Development:

.venv/bin/python app.py

Production (WSGI):

.venv/bin/gunicorn -w 2 -b 0.0.0.0:5000 wsgi:app

Open http://localhost:5000 and submit the form.

Docker

Build:

docker build -t cloudinit-generator .

Run:

docker run --rm -p 5000:5000 cloudinit-generator

Override worker count:

docker run --rm -e WSGI_PROCESSES=2 -p 5000:5000 cloudinit-generator

Defaults in cloud-init

  • Users: appadmin (sudo + SSH keys), appuser
  • Directory: /opt/apps owned by appuser

API

  • GET / - HTML form
  • POST /generate - validate input and generate ISO (HTMX response)
  • GET /download/<token> - download generated ISO

Input validation summary

  • Image name: ^[a-zA-Z0-9._-]{1,64}$
  • Id: ^[a-zA-Z0-9_-]{1,32}$
  • Hostname: RFC 1123 lowercase
  • SSH keys:
    • One per line, no tabs/control chars
    • Types: ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256/384/521
    • Max 50 keys, max 4096 chars per line

Cleanup behavior

Generated files live in a per-request temp directory under the OS temp folder and are cleaned after roughly 60 minutes on subsequent requests.

About

Self hosted cloud-init NoCloud Seed ISO Generator

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published