Fully automated customization of EmComm Tools Community (ETC) ISO images using xorriso/squashfs. No GUI required.
Upstream Project: EmComm Tools Community
Documentation: community.emcommtools.com
ETC already includes all ham radio tools (Winlink, VARA, JS8Call, fldigi, etc.). This customizer adds:
- β Pre-configured WiFi networks (auto-connect on boot)
- β
Personal callsign and grid square (pre-populated for
et-user) - β
Hostname set to
ETC-{CALLSIGN} - β Desktop preferences (dark mode, scaling, accessibility)
- β Display & screen management (brightness, dimming, blank timeout)
- β Power management (sleep behavior, power profiles, idle actions)
- β System timezone configuration
- β Additional development packages (VS Code, Node.js, npm, git)
- β
VARA FM/HF license
.regfiles + import script (run post-install after VARA installation) - β APRS configuration (iGate, beaconing with symbol/comment)
- β Git configuration
- β
Embedded cache files for faster rebuilds (use
-mfor minimal)
This customizer respects upstream ETC architecture. We:
- Keep ETC's runtime template system (et-direwolf, et-yaac, etc.)
- Modify templates in-place, keeping
{{ET_*}}placeholders - Don't change package selections or install additional software
- Don't pre-install VARA or Wine prefix (these require a desktop session post-install)
ETC Architecture: ETC uses runtime template processing. When you run et-direwolf, et-yaac, or et-winlink, these wrapper scripts read from ~/.config/emcomm-tools/user.json and generate configs dynamically. We pre-populate user.json so you skip the et-user prompt on first boot.
APRS Customization: We modify ETC's direwolf template at /opt/emcomm-tools/conf/template.d/packet/direwolf.aprs-digipeater.conf to add iGate and beacon settings while preserving the {{ET_CALLSIGN}} and {{ET_AUDIO_DEVICE}} placeholders that ETC substitutes at runtime.
- Build process: Fully automated ETC ISO customization via xorriso/squashfs
- WiFi configuration: Networks are pre-configured in NetworkManager
- APRS setup: direwolf iGate/beacon templates customized and ready for runtime use
- User config:
~/.config/emcomm-tools/user.jsonpre-populated with callsign, grid, Winlink password - Desktop settings: Dark mode, scaling, accessibility, display, power management, timezone all applied
- Git config: User name/email configured
- VARA license setup:
.regfiles and import script created for post-install use - Additional packages: Development tools (git, nodejs, npm, uv) installable via configuration
- Cache system: Downloaded ISOs cached for faster rebuilds
Hostname & User Account - Currently BYPASSED due to Ubuntu installer behavior:
- The Ubuntu 22.10 installer runs after ISO boot and prompts for hostname/username
- Our pre-build customizations are overwritten during this interactive setup phase
- Users must manually enter values during Ubuntu installer (not automated)
Workaround (Current): Users must:
- Boot the custom ISO
- Go through Ubuntu installer (set hostname and username manually)
- All other customizations (WiFi, APRS, desktop settings, etc.) apply automatically
Priority Fix: See GitHub Issues for tracking.
All planned features for future releases are tracked as GitHub Issues:
- #8 - [HIGH PRIORITY] Preseed file for automated Ubuntu installer
- #7 - Build log preservation and embedding
- #6 - Anytone D578UV CAT control integration
- #5 - GPS auto-detection for grid square calculation
- #4 - USB radio auto-detection for CAT control setup
- #3 - WiFi network connection validation and troubleshooting
- #2 - Post-install script for first-boot customizations
View all work: GitHub Issues
Each issue includes:
- Problem statement and proposed solution
- Acceptance criteria (checklist)
- Estimated effort
- Prerequisites and dependencies
emcomm-tools-customizer/
βββ build-etc-iso.sh # Main build script (fully automated)
βββ secrets.env.template # Configuration template
βββ secrets.env # Your configuration (gitignored)
βββ cache/ # Downloaded files (persistent)
β βββ ubuntu-22.10-desktop-amd64.iso # β Drop your ISO here!
βββ output/ # Generated custom ISOs
βββ logs/ # Build logs
βββ post-install/ # Scripts for after ISO installation
Ubuntu 22.10 reached end-of-life, so you must first update apt sources:
# Fix apt sources for EOL Ubuntu 22.10
sudo sed -i 's/archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
sudo sed -i 's/security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
sudo apt update
# Install build dependencies
sudo apt install -y xorriso squashfs-tools wget curl jq# Clone repository
git clone https://github.com/AlwaysLearningTech/emcomm-tools-customizer.git
cd emcomm-tools-customizer
# Create configuration
cp secrets.env.template secrets.env
nano secrets.env # Fill in your values
# Build from stable release (downloads ETC + Ubuntu ISO automatically)
sudo ./build-etc-iso.sh -r stable
# Output: output/<release-tag>-custom.isoTo avoid downloading the 3.6GB Ubuntu ISO each time:
# Create cache directory and copy your ISO there
mkdir -p cache
cp ~/Downloads/ubuntu-22.10-desktop-amd64.iso cache/
# Now build - ISO download will be skipped!
sudo ./build-etc-iso.sh -r stableThe script checks cache/ubuntu-22.10-desktop-amd64.iso before downloading.
# List available releases and tags from GitHub
./build-etc-iso.sh -l
# Build from stable release (recommended for most users)
sudo ./build-etc-iso.sh -r stable
# Build from latest development tag (bleeding edge)
sudo ./build-etc-iso.sh -r latest
# Build a specific tag by name
sudo ./build-etc-iso.sh -r tag -t emcomm-tools-os-community-20251113-r5-build17
# Minimal build (smaller ISO, no embedded cache files)
sudo ./build-etc-iso.sh -r stable -m
# Debug mode (show detailed DEBUG log messages)
sudo ./build-etc-iso.sh -r stable -d
# Verbose mode for maximum debugging (bash -x)
sudo ./build-etc-iso.sh -r stable -v| Option | Description |
|---|---|
-r <stable|latest|tag> |
Release mode |
-t <tag> |
Specific tag name (required with -r tag) |
-l |
List available releases and tags |
-m |
Minimal build (exclude cache files, saves ~4GB) |
-d |
Debug mode (show DEBUG log messages) |
-v |
Verbose mode (bash -x tracing) |
-h |
Show help |
| Mode | Description | Source |
|---|---|---|
stable |
Latest GitHub Release (production-ready) | Releases |
latest |
Most recent git tag (development) | Tags |
tag |
Specific tag by name | Use with -t |
By default, cache files (Ubuntu ISO, ETC tarballs) are embedded in /opt/emcomm-customizer-cache/
so they're available for the next build on the installed system. This is useful when building
on the same machine you install to.
Use -m for a minimal build that excludes these files (saves ~4GB).
# === User Identity (REQUIRED) ===
CALLSIGN="N0CALL" # Your amateur radio callsign
USER_FULLNAME="Your Name" # Full name for git commits
USER_EMAIL="[email protected]" # Email for git commits
GRID_SQUARE="CN87" # Maidenhead grid locator
# === User Account ===
USER_USERNAME="" # Linux username (defaults to lowercase CALLSIGN)
USER_PASSWORD="" # Password (leave blank to keep ETC default)
ENABLE_AUTOLOGIN="no" # "yes" or "no" - default is NO (password prompt)
# === System ===
MACHINE_NAME="" # Hostname (defaults to ETC-{CALLSIGN})
TIMEZONE="America/Denver" # System timezone (Linux format, see /usr/share/zoneinfo/)
# === Desktop Preferences ===
DESKTOP_COLOR_SCHEME="prefer-dark" # prefer-dark or prefer-light
DESKTOP_SCALING_FACTOR="1.0" # 1.0, 1.25, 1.5, or 2.0
DISABLE_ACCESSIBILITY="yes" # yes = disable screen reader, on-screen keyboard
# === Display & Screen Management ===
AUTOMATIC_SCREEN_BRIGHTNESS="false" # true = adaptive brightness, false = manual
DIM_SCREEN="true" # true = dim screen during idle
SCREEN_BLANK="true" # true = blank screen after idle timeout
SCREEN_BLANK_TIMEOUT="300" # Seconds before screen blanks (300=5min)
# === Power Management ===
POWER_MODE="balanced" # balanced, performance, or power-saver
POWER_LID_CLOSE_AC="suspend" # AC lid close: nothing, suspend, hibernate, logout
POWER_LID_CLOSE_BATTERY="suspend" # Battery lid close: nothing, suspend, hibernate, logout
POWER_BUTTON_ACTION="interactive" # Power button: nothing, suspend, hibernate, interactive
POWER_IDLE_AC="nothing" # AC idle action: nothing, suspend, hibernate
POWER_IDLE_BATTERY="suspend" # Battery idle action: nothing, suspend, hibernate
POWER_IDLE_TIMEOUT="900" # Seconds before idle action (900=15min)
AUTOMATIC_POWER_SAVER="true" # true = enable power saver on battery
AUTOMATIC_SUSPEND="true" # true = enable automatic suspend
# === Additional System Packages ===
ADDITIONAL_PACKAGES="code git nodejs npm" # Space-separated apt packages to install
# === WiFi Networks ===
WIFI_SSID_HOME="YourHomeNetwork"
WIFI_PASSWORD_HOME="YourHomePassword"
WIFI_AUTOCONNECT_HOME="yes"
WIFI_SSID_MOBILE="YourHotspot"
WIFI_PASSWORD_MOBILE="HotspotPassword"
WIFI_AUTOCONNECT_MOBILE="yes"
# === Winlink ===
WINLINK_PASSWORD="" # Your Winlink password
# === APRS Configuration ===
APRS_SSID="10" # SSID (0-15, 10=iGate)APRS_PASSCODE="-1" # APRS-IS passcode (-1=RX only) APRS_SYMBOL="/r" # Symbol: table+code (/r=antenna) APRS_COMMENT="EmComm iGate" # Beacon comment
ENABLE_APRS_BEACON="no" # Enable position beaconing APRS_BEACON_INTERVAL="300" # Seconds between beacons APRS_BEACON_VIA="WIDE1-1" # Digipeater path APRS_BEACON_POWER="10" # PHG: Power in watts APRS_BEACON_HEIGHT="20" # PHG: Antenna height (feet) APRS_BEACON_GAIN="3" # PHG: Antenna gain (dBi)
ENABLE_APRS_IGATE="yes" # Enable iGate APRS_SERVER="noam.aprs2.net" # APRS-IS server
DIREWOLF_ADEVICE="plughw:1,0" # Audio device (Digirig) DIREWOLF_PTT="CM108" # PTT method
VARA_FM_CALLSIGN="" # Callsign registered with VARA FM license
VARA_FM_LICENSE_KEY="" # Your VARA FM license key
VARA_HF_CALLSIGN="" # Callsign registered with VARA HF license
VARA_HF_LICENSE_KEY="" # Your VARA HF license key
PAT_EMCOMM_ALIAS="yes" # Create "emcomm" quick-connect alias PAT_EMCOMM_GATEWAY="" # Gateway callsign (e.g., "W7ACS-10")
POWER_LID_CLOSE_AC="suspend" # Lid close on AC power POWER_LID_CLOSE_BATTERY="suspend" # Lid close on battery POWER_BUTTON_ACTION="interactive" # Power button action POWER_IDLE_AC="nothing" # Idle action on AC POWER_IDLE_BATTERY="suspend" # Idle action on battery POWER_IDLE_TIMEOUT="900" # Idle timeout (seconds)
### About VARA Licenses
VARA is commercial software with **two separate products**:
| Product | Cost | Use Case |
|---------|------|----------|
| **VARA FM** | ~$69 | VHF/UHF Winlink via FM repeaters |
| **VARA HF** | ~$69 | HF Winlink for long-distance |
Purchase at [rosmodem.wordpress.com](https://rosmodem.wordpress.com/)
**Important:** VARA licenses are applied **after** VARA installation, not during ISO build:
1. **Install VARA** (post-install, requires desktop session):
```bash
cd ~/add-ons/wine
./01-install-wine-deps.sh
./02-install-vara-hf.sh # If you use HF
./03-install-vara-fm.sh # If you use FM
- Import license keys (if configured in secrets.env):
./99-import-vara-licenses.sh
The build script creates .reg files and an import script in ~/add-ons/wine/. This is because Wine's prefix (~/.wine32) doesn't exist until you run the VARA installers.
Pat is the Winlink client on ETC. The emcomm alias adds a quick-connect shortcut to your standard Pat config:
pat connect emcomm # Quick connect to your configured gatewayAfter first boot, run ~/.config/pat/add-emcomm-alias.sh to add the alias to your Pat config.
| Setting | Options | Description |
|---|---|---|
| Lid Close | nothing, suspend, hibernate, logout |
What happens when laptop lid closes |
| Power Button | interactive, suspend, hibernate, poweroff |
Power button behavior |
| Idle Action | nothing, suspend, hibernate |
Action after idle timeout |
| Idle Timeout | Seconds (e.g., 900 = 15 min) |
Time before idle action triggers |
These variables control ETC's optional features and map downloads during the ISO build.
Interactive vs Automated Builds:
- Variables configured β Downloads happen automatically, no prompts
- Variables blank β Original ETC dialog prompts appear during build
- This ensures future ETC versions with new dialogs still work interactively
| Variable | Options | Description |
|---|---|---|
OSM_MAP_STATE |
US state name (lowercase) | OpenStreetMap data for offline Navit navigation |
ET_MAP_REGION |
us, ca, world |
Pre-rendered raster tiles for YAAC and other apps |
ET_EXPERT |
yes or blank |
Enables Wikipedia download (ETC internal variable) |
WIKIPEDIA_SECTIONS |
Comma-separated list | Offline Wikipedia sections (requires ET_EXPERT=yes) |
Note about ET_EXPERT: This is an undocumented ETC variable. When set, it:
- Enables the Wikipedia download dialog during install
- Shows a Wine info textbox during wine installation
Leave blank unless you want Wikipedia offline content.
OSM State Names: Use lowercase state names from Geofabrik US:
alabama, alaska, arizona, arkansas, california, colorado, connecticut, delaware, district-of-columbia, florida, georgia, hawaii, idaho, illinois, indiana, iowa, kansas, kentucky, louisiana, maine, maryland, massachusetts, michigan, minnesota, mississippi, missouri, montana, nebraska, nevada, new-hampshire, new-jersey, new-mexico, new-york, north-carolina, north-dakota, ohio, oklahoma, oregon, pennsylvania, rhode-island, south-carolina, south-dakota, tennessee, texas, utah, vermont, virginia, washington, west-virginia, wisconsin, wyoming
ET Map Regions:
| Region | File Size | Coverage |
|---|---|---|
us |
~2.5 GB | United States, zoom 0-11 |
ca |
~1.5 GB | Canada, zoom 0-10 |
world |
~500 MB | Global, zoom 0-7 |
Wikipedia Sections: Available sections for offline Wikipedia:
computer, history, mathematics, medicine, simple
Examples:
# Fully automated build (no Wikipedia)
OSM_MAP_STATE="washington"
ET_MAP_REGION="us"
ET_EXPERT=""
WIKIPEDIA_SECTIONS=""
# Fully automated with Wikipedia
OSM_MAP_STATE="washington"
ET_MAP_REGION="us"
ET_EXPERT="yes"
WIKIPEDIA_SECTIONS="computer,medicine"
# Semi-automated - let dialog prompt for maps you're unsure about
OSM_MAP_STATE="" # Will show dialog to pick state
ET_MAP_REGION="us" # Auto-download US tilesThere are two ways to get offline Wikipedia content on ETC:
Set ET_EXPERT="yes" and WIKIPEDIA_SECTIONS="computer,medicine" to download pre-built .zim files from Kiwix during the build. These are large files (100-500MB each) covering entire topic areas.
This customizer includes a script to create a small, targeted .zim file with just the Wikipedia articles relevant to ham radio operators.
Configuration:
# In secrets.env - specify individual articles (pipe-separated)
WIKIPEDIA_ARTICLES="2-meter_band|70-centimeter_band|General_Mobile_Radio_Service|Family_Radio_Service"Default articles include:
- Band information: 2-meter band, 70-centimeter band, HF/VHF/UHF
- Radio services: GMRS, FRS, MURS, Citizens Band
- Digital modes: APRS, Winlink, DMR, D-STAR, System Fusion
- Emergency comms: Amateur radio emergency communications
- General ham radio topics: Repeaters, simplex, antennas, propagation
Post-Install Usage: After first boot, run the Wikipedia ZIM creator:
cd ~/add-ons/wikipedia
./create-my-wikipedia.shThis downloads your configured articles and creates a .zim file in ~/wikipedia/ that you can view with Kiwix:
# Start local server
kiwix-serve --port=8080 ~/wikipedia/ham-radio-wikipedia_*.zim
# Open http://localhost:8080 in browserNote: The custom .zim creator is a post-install script because it requires network access and takes a few minutes to run. It's NOT embedded in the ISO build.
| SSID | Usage |
|---|---|
| 0 | Primary station (home, fixed) |
| 1 | Digipeater, fill-in digi |
| 2 | Digipeater (alternate) |
| 3 | Portable station |
| 4 | HF to VHF gateway |
| 5 | Smartphone, mobile app |
| 6 | Satellite ops, special |
| 7 | Handheld, walkie-talkie |
| 8 | Boat, maritime mobile |
| 9 | Mobile (car, truck, RV) |
| 10 | Internet, APRS-IS only |
| 11 | Balloon, aircraft, spacecraft |
| 12 | APRStt, DTMF, touchstone |
| 13 | Weather station |
| 14 | Trucking |
| 15 | Generic, other |
Symbols are specified with a two-character code: table + symbol.
Primary Table Symbols (table = /)
| Symbol Code | Icon | Description |
|---|---|---|
/> |
π | Car |
/y |
π | House with antenna |
/[ |
πΆ | Jogger/Walker (portable) |
/_ |
π€οΈ | Weather station |
/! |
π | Police station |
/# |
π | Digipeater |
/$ |
π | Phone |
/- |
π | House (QTH) |
/. |
β | X / Unknown |
// |
π΄ | Red Dot |
/? |
β | Question mark |
/K |
π« | School |
/R |
π½οΈ | Restaurant |
/Y |
β΅ | Yacht/Sailboat |
/^ |
Large aircraft | |
/a |
π | Ambulance |
/b |
π² | Bicycle |
/f |
π | Fire truck |
/k |
π | Truck |
/n |
π‘ | Node (packet) |
/r |
π» | Antenna/Portable |
/s |
π’ | Ship (power) |
/u |
π | Bus |
/v |
π | Van |
Alternate Table Symbols (table = \)
| Symbol Code | Icon | Description |
|---|---|---|
\> |
π | Car (overlay capable) |
\a |
πͺ | ARES/RACES |
\# |
π | Digipeater (overlay) |
\& |
π· | Diamond (overlay) |
\- |
π | House (HF) |
\0 |
β | Circle (numbered) |
\K |
π | Helicopter |
\^ |
Small aircraft | |
\j |
ποΈ | Camping |
\k |
ποΈ | ATV/Motorcycle |
\n |
πΊ | Triangle (overlay) |
\s |
π₯οΈ | Small boat |
\v |
πΊ | ATV (overlay) |
Full table: APRS Symbol Codes
The cache/ directory stores downloaded files to speed up rebuilds:
cache/
βββ ubuntu-22.10-desktop-amd64.iso # Ubuntu base ISO (3.6 GB)
βββ emcomm-tools-os-*.tar.gz # ETC installer tarballs
To skip downloads:
- Create
cache/directory - Copy
ubuntu-22.10-desktop-amd64.isointo it - Run build - download will be skipped
ETC tarballs are also cached automatically after first download.
Generated ISOs are placed in output/:
output/
βββ emcomm-tools-os-community-20251128-r5-final-5.0.0-custom.iso
Copy to Ventoy USB:
cp output/*.iso /media/$USER/Ventoy/
syncSymptom: The built ISO boots into a standard Ubuntu installer asking you to create a user, with none of the ETC tools installed.
Cause: The ETC installer (install.sh) failed silently during the chroot phase.
Fixes (as of v1.1.0):
- Build now verifies the ETC tarball extraction was successful
- Build now verifies ETC installation by checking for
/opt/emcomm-toolsandet-user - Build now properly captures the chroot exit code
If you still encounter this, run with -d flag for debug output and check the log file in logs/.
Symptom: After installing the ISO on a dual-boot system (especially Panasonic Toughbook FZ-G1), screen brightness controls no longer work in either Windows or Ubuntu.
Causes: The Intel graphics backlight controller can get confused by ACPI/UEFI state changes during OS installation.
Fixes:
-
Try BIOS reset: Power off completely, enter BIOS setup, and load "Setup Defaults" then save and exit.
-
Windows Device Manager: Device Manager β Display Adapters β Intel HD Graphics β Update/Rollback Driver
-
Ubuntu kernel parameters: Edit
/etc/default/grub, find theGRUB_CMDLINE_LINUX_DEFAULTline and add one of:acpi_backlight=vendor acpi_backlight=video acpi_backlight=nativeThen run
sudo update-gruband reboot. -
Intel xbacklight: Install
xbacklightand use it directly:sudo apt install xbacklight xbacklight -set 50 # Set to 50% -
Direct sysfs control (last resort):
# Find the backlight device ls /sys/class/backlight/ # Typically intel_backlight or acpi_video0 # Read max brightness cat /sys/class/backlight/intel_backlight/max_brightness # Set brightness (example: 500) echo 500 | sudo tee /sys/class/backlight/intel_backlight/brightness
Run with sudo:
sudo ./build-etc-iso.sh -r stableInstall prerequisites (after fixing apt sources for Ubuntu 22.10):
sudo apt install -y xorriso squashfs-tools wget curl jqPre-download and cache:
mkdir -p cache
wget -O cache/ubuntu-22.10-desktop-amd64.iso \
https://old-releases.ubuntu.com/releases/kinetic/ubuntu-22.10-desktop-amd64.iso- Ensure you have 15+ GB free disk space
- The squashfs step takes 10-20 minutes on typical hardware
- Download: Fetches Ubuntu 22.10 ISO and ETC installer tarball (cached in
cache/) - Extract: Uses xorriso to extract ISO, unsquashfs for filesystem
- Install ETC: Runs ETC's install.sh in chroot to install all ham radio tools
- Verify: Confirms ETC installed correctly by checking for key files
- Customize: Modifies
/etc/skel/and system configs with your settings - Rebuild: Creates new squashfs and ISO with xorriso
All customizations go into /etc/skel/ so they apply to new users automatically.
MIT License - See LICENSE file
- EmComm Tools Community: thetechprepper
- Customizer: KD7DGF
73 de KD7DGF π»