OS Image Composer CLI Specification#
Table of Contents#
Overview#
os-image-composer is a command-line tool for generating custom images for
different operating systems, including
Azure Linux,
Wind River eLxr, and
Edge Microvisor Toolkit.
The tool provides a flexible approach to creating and configuring
production-ready OS images with precise customization.
OS Image Composer uses a single CLI with subcommands to deliver a consistent user experience while maintaining flexibility. The tool’s architecture is built around the following files:
A global configuration file that defines system-wide settings like cache locations and provider configurations
Image template files in YAML format that define per-image build requirements
The tool follows a staged build process to support package caching, image caching, and various customization options that speed up development cycles and ensure reproducible builds.
CLI Flow#
The following diagram illustrates the high-level flow of the OS Image Composer
CLI, the commands of which begin with os-image-composer:
flowchart TD
Start([os-image-composer]) --> Config[Load Configuration]
Config --> Commands{Commands}
Commands -->|build| Build[Build OS Image]
Build --> ReadTemplate[Read YAML Template]
ReadTemplate --> BuildProcess[Run Build Pipeline]
BuildProcess --> SaveImage[Save Output Image]
Commands -->|validate| Validate[Validate Template File]
Commands -->|config| ConfigCmd[Manage Configuration]
ConfigCmd --> ConfigOps[init/show]
Commands -->|cache| Cache[Manage Cache]
Cache --> CacheOps[Clean Cache]
Commands -->|version| Version[Show Version Info]
Commands -->|install-completion| Completion[Install Shell Completion]
%% Styling
classDef command fill:#b5e2fa,stroke:#0077b6,stroke-width:2px;
classDef process fill:#f8edeb,stroke:#333,stroke-width:1px;
class Start command;
class Build,Validate,ConfigCmd,Cache,Version,Completion command;
class ReadTemplate,BuildProcess,SaveImage,ConfigOps,CacheOps process;
The primary workflow is through the build command, which reads an image
template file and runs the build pipeline to create a new image.
See also:
Build Stages for the stages of the build pipeline
Usage#
os-image-composer [global options] command [command options] [arguments...]
Global Options#
The OS Image Composer command-line utility uses a layered configuration approach, with command-line options taking priority over the configuration file settings:
Option |
Description |
|---|---|
|
Global configuration file. This file contains system-wide settings that apply to all image builds. If not specified, the tool searches for configuration files in standard locations. |
|
Log level: debug, info, warn, error (overrides config). Use debug for troubleshooting build issues. |
|
Tee logs to a specific file path (overrides |
|
Show help for any command or subcommand. |
|
Show |
Commands#
Build Command#
Build an OS image from an image template file. This is the primary command for creating custom OS images according to your requirements.
os-image-composer build [flags] TEMPLATE_FILE
Arguments:
TEMPLATE_FILE- Path to the YAML image template file (required)
Flags:
Flag |
Description |
|---|---|
|
Number of concurrent download workers (overrides config). |
|
Package cache directory (overrides config). Proper caching significantly improves build times. |
|
Working directory for builds (overrides config). This directory is where images are constructed before being finalized. |
|
Enable verbose output (equivalent to –log-level debug). Displays detailed information about each step of the build process. |
|
Generate a dot file for the merged template dependency graph (user + defaults with resolved packages). Nodes are color-coded: essentials (pale yellow), template packages (green), kernel (blue), bootloader (orange). |
|
When paired with |
Example:
# Build an image with default settings
sudo -E os-image-composer build my-image-template.yml
# Build with custom workers and cache directory
sudo -E os-image-composer build --workers 16 --cache-dir /tmp/cache my-image-template.yml
# Build with verbose output
sudo -E os-image-composer build --verbose my-image-template.yml
# Build and generate dependency graphs
sudo -E os-image-composer build --dotfile deps.dot my-image-template.yml
# Limit the graph to SystemConfig.Packages roots
sudo -E os-image-composer build --dotfile system.dot --system-packages-only my-image-template.yml
Note: The build command typically requires sudo privileges for operations like creating loopback devices and mounting filesystems.
See also:
Build Stages in Detail for information about each build stage
Build Performance Optimization for tips to improve build speed
Validate Command#
Validate an image template file without building it. This allows checking for errors in your template before committing to a full build process.
os-image-composer validate TEMPLATE_FILE
Arguments:
TEMPLATE_FILE- Path to the YAML image template file to validate (required)
Description:
The validate command performs the following checks:
YAML syntax validation
Schema validation against the image template JSON schema
Required fields verification
Type checking for all fields
Example:
# Validate a template file
os-image-composer validate my-image-template.yml
# Validate with verbose output
os-image-composer --log-level debug validate my-image-template.yml
See also:
Validate Stage for details on the validation process
Inspect Command#
Inspects a raw image and outputs comprehensive details about the image including partition table layout, partition identity and attributes, filesystem information, bootloader details, and layout diagnostics.
os-image-composer inspect [flags] IMAGE_FILE
Arguments:
IMAGE_FILE- Path to the RAW image file to inspect (required)
Flags:
Flag |
Description |
|---|---|
|
Output format: |
|
Pretty-print JSON output (only for |
Description:
The inspect command extracts and analyzes the following from a disk image:
Partition Table:
Type (GPT/MBR) and sector sizes
For GPT: disk GUID and protective MBR status
Layout diagnostics: largest unallocated free span and misaligned partitions (detected against physical sector size and 1 MiB alignment)
Partitions:
Index, name, type/GUID, start/end LBA, and size
For GPT: partition GUID and decoded attribute bits (required, legacy BIOS bootable, read-only)
Filesystem type, label, and UUID
EFI/UKI evidence (if present on ESP/VFAT partitions)
Bootloader & Secure Boot:
EFI binaries: kind, architecture, signature status, SBAT
UKI payloads: kernel/initrd/OS-release hashes and metadata
Output Formats:
text: Human-readable summary with tables and structured sectionsjson: Complete structured data suitable for automation and comparisonyaml: YAML representation of the image summary
Example:
# Inspect a raw image and output text (default)
os-image-composer inspect my-image.raw
# Inspect and output pretty JSON
os-image-composer inspect --format=json --pretty my-image.raw
# Inspect and output YAML
os-image-composer inspect --format=yaml my-image.raw
Compare Command#
Compares two disk images and outputs detailed differences in partition layout, filesystems, bootloaders, and EFI/UKI payloads.
os-image-composer compare [flags] IMAGE_FILE1 IMAGE_FILE2
Arguments:
IMAGE_FILE1- Path to the first RAW image file (required)IMAGE_FILE2- Path to the second RAW image file (required)
Flags:
Flag |
Description |
|---|---|
|
Output format: |
|
Compare mode: |
|
Pretty-print JSON output (only for |
|
Perform image hashing for verifying binary identical image (default |
Description:
The compare command performs a deep structural comparison of two images and reports:
Partition Table Changes:
Disk GUID changes (GPT)
Partition table type or sector size changes
Free space layout changes (largest unallocated extent)
Misaligned partition detection changes
Partition Changes:
Added/removed partitions (detected by GUID for GPT, by LBA range for MBR)
Modified partitions: changes to name, GUID, LBA range, size, or GPT attribute bits
Filesystem changes: type, label, UUID modifications
Per-partition EFI binary changes (path, kind, architecture, signature status)
Global EFI/UKI Changes:
Added/removed EFI binaries across all partitions
Modified EFI binaries: SHA256, signature status, bootloader kind
UKI payload changes: kernel, initrd, OS-release, and section SHA256s
Compare Modes:
diff: Detailed changes (partitions, filesystems, EFI binaries)summary: High-level counts (added, removed, modified counts)full: Complete image metadata plus all diffs
Output:
Text format provides human-readable sections with tables and field-by-field diffs
JSON format includes complete structured data for scripting and tooling
Exit code is 0 if images are equal, 1 if differences found
Example:
# Compare two images and show detailed text diff
os-image-composer compare image-v1.raw image-v2.raw
# Show only a summary of changes
os-image-composer compare --mode=summary image-v1.raw image-v2.raw
# Compare and output pretty JSON with full metadata
os-image-composer compare --format=json --mode=full --pretty image-v1.raw image-v2.raw
# Compact JSON diff suitable for CI/CD automation
os-image-composer compare --format=json --mode=diff image-v1.raw image-v2.raw
# Perform comparison with image hashing enabled with details text diff
os-image-composer compare --hash-images=true image-v1.raw image-v2.raw
Cache Command#
Manage cached artifacts created during the build process.
os-image-composer cache SUBCOMMAND
cache clean#
Remove cached packages or workspace chroot data.
os-image-composer cache clean [flags]
Flags:
Flag |
Description |
|---|---|
|
Remove cached packages (default when no scope flags are provided). |
|
Remove cached chroot environments and chroot tarballs under the workspace directory. |
|
Enable both package and workspace cleanup in a single invocation. |
|
Restrict cleanup to a specific provider (format: |
|
Show what would be removed without deleting anything. |
Examples:
# Remove all cached packages
os-image-composer cache clean
# Remove chroot caches for a single provider
os-image-composer cache clean --workspace --provider-id azure-linux-azl3-x86_64
# Preview everything that would be deleted
os-image-composer cache clean --all --dry-run
When no scope flag is supplied, the command defaults to --packages.
Config Command#
Manage the global configuration file. The config command provides subcommands for initializing and viewing configuration.
os-image-composer config SUBCOMMAND
Subcommands:
config init#
Initialize a new configuration file with default values.
os-image-composer config init [CONFIG_FILE]
Arguments:
CONFIG_FILE- Path where the configuration file should be created (optional). If not specified, creates the configuration in a standard location.
Example:
# Initialize configuration in current directory
os-image-composer config init os-image-composer.yml
# Initialize in default location
os-image-composer config init
config show#
Show the current configuration settings.
os-image-composer config show
Example:
# Show current configuration
os-image-composer config show
# Show configuration from specific file
os-image-composer --config /path/to/config.yml config show
Version Command#
Display the tool’s version information, including build date, Git commit SHA, and organization.
os-image-composer version
Example:
os-image-composer version
Output includes:
Version number
Build date
Git commit SHA
Organization
Install-Completion Command#
Install shell completion for the os-image-composer command. Supports bash, zsh, fish, and PowerShell.
os-image-composer install-completion [flags]
Flags:
Flag |
Description |
|---|---|
|
Shell type (bash, zsh, fish, powershell). If not specified, auto-detects current shell. |
|
Force overwrite existing completion files. |
Example:
# Auto-detect shell and install completion
os-image-composer install-completion
# Install completion for specific shell
os-image-composer install-completion --shell bash
# Force reinstall
os-image-composer install-completion --force
Post-Installation Steps:
After installing completion, you need to reload your shell configuration:
Bash:
echo "source ~/.bash_completion.d/os-image-composer.bash" >> ~/.bashrc
source ~/.bashrc
Zsh:
echo 'fpath=(~/.zsh/completion $fpath)' >> ~/.zshrc
source ~/.zshrc
Fish: Fish automatically loads completions from the standard location. Just restart your terminal.
PowerShell:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
. $PROFILE
Examples#
Building an Image#
# Build an image with default settings
sudo -E os-image-composer build image-templates/azl3-x86_64-edge-raw.yml
# Build with custom configuration
sudo -E os-image-composer --config=/path/to/config.yaml build image-templates/azl3-x86_64-edge-raw.yml
# Build with custom workers and cache
sudo -E os-image-composer build --workers 12 --cache-dir ./package-cache image-templates/azl3-x86_64-edge-raw.yml
# Build with debug logging
sudo -E os-image-composer --log-level debug build image-templates/azl3-x86_64-edge-raw.yml
Managing Configuration#
# Initialize a new configuration file
os-image-composer config init my-config.yml
# Show current configuration
os-image-composer config show
# Use a specific configuration file
os-image-composer --config /etc/os-image-composer/config.yml build template.yml
Managing Cache#
# Remove all cached packages
os-image-composer cache clean
# Remove workspace chroot caches for a specific provider
os-image-composer cache clean --workspace --provider-id azure-linux-azl3-x86_64
# Preview both package and workspace cleanup without deleting files
os-image-composer cache clean --all --dry-run
Inspecting and Comparing Images#
# Inspect an image in text format
os-image-composer inspect my-image.raw
# Inspect and output JSON (suitable for tooling/CI)
os-image-composer inspect --format=json --pretty my-image.raw
# Compare two images with detailed diff
os-image-composer compare image-v1.raw image-v2.raw
# Compare with JSON output for parsing
os-image-composer compare --format=json --mode=diff image-v1.raw image-v2.raw
Validating Templates#
# Validate a template
os-image-composer validate image-templates/azl3-x86_64-edge-raw.yml
# Validate with debug output
os-image-composer --log-level debug validate image-templates/azl3-x86_64-edge-raw.yml
Configuration Files#
Global Configuration File#
The global configuration file (YAML format) defines system-wide settings that apply to all image builds. The tool searches for configuration files in the following locations (in order):
Path specified with
--configflagos-image-composer.ymlin current directory.os-image-composer.ymlin current directoryos-image-composer.yamlin current directory.os-image-composer.yamlin current directory~/.os-image-composer/config.yml~/.os-image-composer/config.yaml~/.config/os-image-composer/config.yml~/.config/os-image-composer/config.yaml/etc/os-image-composer/config.yml/etc/os-image-composer/config.yaml
Example Configuration:
# Number of concurrent workers for package downloads
workers: 8
# Directory for caching downloaded packages
cache_dir: "./cache"
# Working directory for build process
work_dir: "./workspace"
# Configuration files directory
config_dir: "./config"
# Temporary directory
temp_dir: "/tmp"
# Logging configuration
logging:
level: "info" # debug, info, warn, error
Configuration Fields:
Field |
Type |
Description |
|---|---|---|
|
integer |
Number of concurrent download workers (1-100). Default: 8 |
|
string |
Directory for package cache. Default: “./cache” |
|
string |
Working directory for builds. Default: “./workspace” |
|
string |
Directory for configuration files. Default: “./config” |
|
string |
Temporary directory. Default: system temp directory |
|
string |
Log level (debug/info/warn/error). Default: “info” |
Image Template File#
The image template file (YAML format) defines the specifications for a single image build. With this file, you can define exactly what goes into your custom OS image, including packages, configurations, and customizations.
Example Template:
image:
# Basic image identification
name: edge-device-image # Name of the resulting image
version: "1.2.0" # Version for tracking and naming
target:
# Target OS and image configuration
os: azure-linux # Base operating system
dist: azl3 # Distribution identifier
arch: x86_64 # Target architecture
imageType: raw # Output format (supported: raw, iso only)
systemConfig:
# System configuration
name: edge # Configuration name
description: Edge device image with Microvisor support
# Package configuration
packages: # Packages to install
- openssh-server
- docker-ce
- vim
- curl
- wget
# Kernel configuration
kernel:
version: "6.12" # Kernel version to include
cmdline: "quiet splash" # Additional kernel command-line parameters
See also:
Common Build Patterns for example image templates
Template Structure for detailed template documentation
Exit Codes#
The tool provides consistent exit codes that can be used in scripting and automation:
Code |
Description |
|---|---|
0 |
Success: The command completed successfully. |
1 |
General error: An unspecified error occurred during execution. |
Troubleshooting#
Common Issues#
Disk Space: Building images requires significant temporary disk space.
# Check free space in workspace directory df -h ./workspace # Check free space in cache directory df -h ./cache
Permissions: The build command requires sudo privileges.
# Run with sudo and preserve environment sudo -E os-image-composer build template.yml
Configuration Issues: Verify configuration is valid.
# Show current configuration os-image-composer config show # Initialize with defaults os-image-composer config init
Template Validation Errors: Validate templates before building.
# Validate template os-image-composer validate template.yml
Logging#
Use the --log-level flag or --verbose flag to get more detailed output:
# Debug logging
os-image-composer --log-level debug build template.yml
# Verbose output (same as debug)
os-image-composer build --verbose template.yml
# Error logging only
os-image-composer --log-level error build template.yml