Gardenhouse Installer
Zero-touch deployment tool for Gardenhouse images.
Delivery Modes
- USB: Create bootable USB drives for simple deployment
- ISO: Generate ISO images for redistribution
- PXE: Set up iPXE-based network boot
- Factory: Build raw disk images ready for cloning onto hard drives
Options
-
--target-profile: Target OS profile name (required) -
--target-version: Target OS version -
--profiles-dir: Directory containing Florist profile outputs -
--preset-values: Path to preset values file -
--output: Block device path (required) -
--force: Skip confirmation prompt
Boot Flow
-
UEFI firmware loads
BOOTX64.EFIfrom the ESP -
The stem UKI boots with
root=stem -
Dracut mounts a tmpfs on
/sysrootand runsstem-install -
stem-installfinds theSTEMINSTlabeled partition, locates the images, and installs to the target disk - System reboots into the newly installed OS
ISO Image
Generates a UEFI-bootable ISO image.
Command
$ gardenhouse-installer usb iso \
--target-profile bamboo \
--preset-values ./presets.txt \
--output ./installer.iso
Boot Flow
Identical to USB mode, except the ISO filesystem itself carries the STEMINST label. The stem-install.sh dracut hook mounts the ISO device directly to find the images.
PXE Network Boot
Sets up files for iPXE-based network boot. UEFI PXE chainloading works as follows:
-
UEFI firmware downloads
ipxe.efivia PXE -
iPXE loads
boot.ipxe -
boot.ipxefetches the stem UKI (stem-uki.efi) and boots it withstem.url=<server>/images/<profile>/ - The stem initramfs brings up networking and downloads images from the URL
Setup Server Files
# gardenhouse-installer pxe setup \
--target-profile bamboo \
--preset-url http://config.example.com/presets/ \
--output /var/www/html/ipxe/ \
--generate-dhcp-config
This produces:
/var/www/html/ipxe/
├── ipxe.efi # iPXE EFI binary
├── rootloaderx64.efi # Rootloader (if available)
├── stem-uki.efi # Stem UKI
├── boot.ipxe # Main iPXE boot script
├── dhcpd.conf # Sample DHCP config (optional)
└── images/
└── bamboo/
├── gardenhouse-root_*.img
├── gardenhouse-root_*.verity
├── gardenhouse-efi_*.efi
├── manifest
└── disk_layout.cfg
Generate Per-Device Scripts
$ gardenhouse-installer pxe generate-script \
--mac 00:11:22:33:44:55 \
--profile bamboo \
--preset-url http://config.example.com/presets/ \
--server-url http://pxe.example.com/ipxe \
--output ./device-01.ipxe
iPXE Kernel Command Line
The generated scripts automatically include:
root=stem rd.neednet=1 ip=dhcp stem.profile=bamboo stem.url=http://pxe.example.com/ipxe/images/bamboo/
If you need static IPs instead of DHCP, pass a standard dracut ip= string on the kernel command line.
Factory Disk Image
Creates a complete raw disk image that can be flashed directly onto target devices. The image contains the full partition table, all partitions formatted, and all data written.
Command
# gardenhouse-installer factory image \
--target-profile bamboo \
--preset-values ./factory.txt \
--output ./factory.img \
--compress zstd \
--level 19
Options
-
--layout: Customdisk_layout.cfgfile -
--compress:zstd,gzip, orxz -
--level: Compression level -
--split: Split output into chunks (e.g.,1G)
Media Verification
The verify command checks that installation media (USB directory, ISO file, factory image, or raw block device) matches the manifest.
# gardenhouse-installer verify --media /dev/sdX1
# gardenhouse-installer verify --media ./installer.iso --ignore-missing
It validates checksums for all files listed in the manifest and reports any mismatches.
Preset Values
Preset values allow zero-touch configuration of the target system. They are rendered at install time and written to the USERDATA partition as /preset_values. On first boot, the firstboot script reads this file and applies the settings.
Template Variables
The installer supports automatic substitution of these placeholders when creating installation media:
-
{{MAC}}: First Ethernet MAC address detected during installation -
{{SERIAL}}: System serial number fromdmidecode -
{{UUID}}: Random UUID (v4) -
{{RANDOM}}: 8-character alphanumeric random string -
{{TIMESTAMP}}: UTC timestamp inYYYYMMDDHHMMSSformat -
{{FACTORY_PASSWORD_HASH}}: Optional hash passed via--factory-password-hashCLI flag -
{{GENERATE}}Auto-generatedsha512cryptpassword hash
Generating a Password Hash Manually
If you prefer not to use {{GENERATE}}, generate your own hash:
$ openssl passwd -6 "your_password"
Example Preset File
See examples/preset_values for a fully documented template. A minimal configuration looks like this:
FIRSTBOOT_UNATTENDED=yes
HOSTNAME=gh-{{RANDOM}}
MACHINE_ID={{UUID}}
TIMEZONE=UTC
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH={{GENERATE}}
HOMECRYPT=no
ROOT_DISABLED=yes
SSH_AUTHORIZED_KEYS=""
FIRST_BOOT_SCRIPT=""
Required Fields for Zero-Touch
When FIRSTBOOT_UNATTENDED=yes, the firstboot script runs without prompting. These fields must be populated:
-
ADMIN_USERNAME -
ADMIN_PASSWORD_HASH -
HOSTNAME -
TIMEZONE
If any required field is missing, firstboot exits with an error.
Preset File Format
Preset files are plain text with KEY=value pairs. Lines starting with # are treated as comments. Values can contain template variables which are replaced at install time.
# This is a comment
HOSTNAME=server-{{SERIAL}}
ADMIN_USERNAME=admin
ADMIN_PASSWORD_HASH=$6$rounds=5000$...
Multi-line values (like SSH_AUTHORIZED_KEYS) should use quoted strings:
SSH_AUTHORIZED_KEYS="ssh-ed25519 AAAAC3NzaC... user@example.com
ssh-rsa AAAAB3NzaC... backup@example.com"
Firstboot Behavior
The firstboot OpenRC service runs once on the target system's initial boot. It performs the following actions:
-
Load presets from
/user/preset_values -
Create the admin user (
ADMIN_USERNAME) - Set passwords
-
Admin password via
ADMIN_PASSWORD_HASH(hash or plaintext) -
Root password via
ROOT_PASSWORD_HASH, or lock root ifROOT_DISABLED=yes
-
Set hostname (
HOSTNAME) -
Set timezone (
TIMEZONE) -
Write machine ID (
MACHINE_ID, or auto-generate) -
Install SSH authorized keys (
SSH_AUTHORIZED_KEYS) -
Run first-boot script (
FIRST_BOOT_SCRIPT) if set -
Mark completion by touching
/user/.firstboot_completed
Password Hash Detection
firstboot automatically detects password hashes:
-
Values starting with
$(e.g.,$6$rounds=5000$...) are applied withusermod -p -
Plaintext values are applied with
chpasswd
First-Boot Script
FIRST_BOOT_SCRIPT can be:
-
A local path:
/lib/stem/post-install.sh -
An HTTP(S) URL:
https://config.example.com/scripts/post-install.sh
For URLs, the script is downloaded to /tmp/firstboot-script and executed with bash.
CLI Usage
Pass presets to any installer mode:
# gardenhouse-installer usb create \
--target-profile bamboo \
--preset-values ./my_presets \
--output /dev/sdX
Source
Gardenhouse Installer can be downloaded from https://git.pinkro.se/Rose/gardenhouse/gardenhouse-installer.git/about/
It is also mirrored at Codeberg where issues are tracked.