Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions docs/ignition-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
```mermaid
flowchart TB
%% ===== IGNITION BOOT FLOW =====

%% --- GRUB Firstboot Detection ---
boot["Boot"] --> grub["GRUB bootloader"]

subgraph GRUB_FIRSTBOOT ["GRUB Firstboot Detection"]
direction TB
grub_check{"/ignition.firstboot
stamp file on bootfs?"}
grub_check -->|Yes| grub_source["Source /ignition.firstboot
(may set ignition_network_kcmdline)"]
grub_source --> grub_append["Append to kernel cmdline:
ignition.firstboot $ignition_network_kcmdline"]
grub_check -->|No| grub_no_flag["No ignition.firstboot on cmdline"]
end
grub --> GRUB_FIRSTBOOT

%% --- Initramfs Generator ---
GRUB_FIRSTBOOT --> generator["ignition-generator
(reads /proc/cmdline)"]
generator --> firstboot_check{"ignition.firstboot
on kernel cmdline?"}

%% --- Subsequent Boot Path ---
firstboot_check -->|No| subsequent_target["ignition-subsequent.target"]
subsequent_target --> subsequent_diskful["ignition-diskful-subsequent.target"]
subsequent_diskful --> subsequent_done["Ignition services do not run.
Boot continues normally."]

%% --- Firstboot Path ---
firstboot_check -->|Yes| complete_gate["ignition-complete.target activated"]
complete_gate --> fetch_offline["ignition-fetch-offline.service"]

%% --- Fetch Offline Details ---
subgraph FETCH_OFFLINE ["Ignition Fetch Offline"]

@prestist prestist Apr 1, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a really good attempt but there are a few things that are a little misleading here.

In reality, this is done by the engine (internal/exec/engine.go), not by the individual stages. For example, fetch-offline's Run() method only checks whether the already-acquired config requires networking and creates the neednet flag if so.

The way these stages are currently represented it looks like a lot of extra work. It gets the point across but is not correct from a code perspective. The reality is that each of Fetch_offline, fetch_online, Files, all have the results of this work from the engine.go.

Also the detect platform is not something any of this code does, its taking the platforom id which is an external input passed from --platfrom on the clia from the env var. It feels a little missleading in its current representation im not sure what the correct way to express that would be tho.

direction TB
offline_check_cmdline{"Config provided
via kernel cmdline?"}
offline_check_user_ign{"/usr/lib/ignition/user.ign
exists?"}
offline_try_platform["Try platform provider"]
offline_write_cache["Write config to /run/ignition.json"]
offline_needs_net{"Config needs
network resources?"}
offline_signal_neednet["Signal neednet"]
offline_done["Done"]
offline_check_cmdline -->|Yes| offline_write_cache
offline_check_cmdline -->|No| offline_check_user_ign
offline_check_user_ign -->|Yes| offline_write_cache
offline_check_user_ign -->|No| offline_try_platform
offline_try_platform -->|Config found| offline_write_cache
offline_try_platform -->|Needs network| offline_signal_neednet
offline_write_cache --> offline_needs_net
offline_needs_net -->|Yes| offline_signal_neednet
offline_needs_net -->|No| offline_done
end
fetch_offline --> FETCH_OFFLINE

FETCH_OFFLINE -.-> distro_network["Distro-managed network bring-up"]
FETCH_OFFLINE --> fetch_check{"/run/ignition.json exists?"}
fetch_check -->|Yes, skip ignition-fetch.service| kargs_service
fetch_check -->|No| neednet_check{"/run/ignition/neednet exists?"}
neednet_check -->|No| kargs_service
distro_network --> network_target["network.target reached"]
neednet_check --> |Yes| fetch_service["ignition-fetch.service"]
network_target --> fetch_service

%% --- Fetch Service Details ---
subgraph FETCH_ONLINE ["Ignition Fetch"]
direction TB
online_check_cmdline{"Config provided
via kernel cmdline?"}
online_check_user_ign{"/usr/lib/ignition/user.ign
exists?"}
online_fetch_provider["Fetch from platform provider
(see Provider Specific Behavior - Config Fetch below)"]
online_write_config["Write config to /run/ignition.json"]
online_done["Done"]
online_check_cmdline -->|Yes| online_write_config
online_check_cmdline -->|No| online_check_user_ign
online_check_user_ign -->|Yes| online_write_config
online_check_user_ign -->|No| online_fetch_provider
online_fetch_provider -->|Config found| online_write_config
online_fetch_provider -->|No config| online_done
online_write_config --> online_done
end
fetch_service --> FETCH_ONLINE

%% --- Disk & Mount Services ---
FETCH_ONLINE --> kargs_service["ignition-kargs.service"]
Comment thread
cadejacobson marked this conversation as resolved.
kargs_service -->|kargs changed| reboot_kargs["Reboot & restart from top"]
Comment thread
cadejacobson marked this conversation as resolved.

kargs_service -->|no changes| disks_service["ignition-disks.service"]
disks_service --> diskful_target["ignition-diskful.target reached"]
diskful_target --> mount_service["ignition-mount.service"]

%% --- Files ---
mount_service --> files_service["ignition-files.service"]
initrd_root_fs_target["initrd-root-fs.target"] --> afterburn_hostname_service["afterburn-hostname.service"]
afterburn_hostname_service -.-> files_service

%% --- Files Service Details ---
subgraph FILES ["Ignition Files"]
direction TB
files_read_cache["Read cached config
from /run/ignition.json"]
files_apply["Merge with base configs and apply"]
files_done["Done"]
files_read_cache --> files_apply
files_apply --> files_done
end
files_service --> FILES

FILES --> complete_target["ignition-complete.target reached"]

complete_target --> pivot_root["Pivot to real root"]
pivot_root --> firstboot_delete_check{"Is this the first boot?"}
firstboot_delete_check -->|Yes| delete_config["ignition-delete-config.service"]
firstboot_delete_check -->|No| skip_delete["Skip config deletion"]

%% ===== STYLING =====
classDef service fill:#42a5f5,stroke:#1565c0,stroke-width:2px,color:#000
classDef target fill:#ffa726,stroke:#e65100,stroke-width:2px,color:#000

class fetch_offline,fetch_service,kargs_service,disks_service,mount_service,files_service,afterburn_hostname_service,delete_config service
class diskful_target,complete_target,complete_gate,network_target,initrd_root_fs_target,subsequent_target,subsequent_diskful target
classDef distro fill:#66bb6a,stroke:#2e7d32,stroke-width:2px,color:#000
class distro_network distro

```

## Provider Specific Behavior
### Config Fetch
#### Azure
```mermaid
flowchart TB
%% ===== AZURE PROVIDER-SPECIFIC CONFIG FETCH =====

start["Fetch provider-specific config"] --> imds_request["HTTP GET to Azure IMDS
http://169.254.169.254/metadata/instance/compute/userData
?api-version=2021-01-01&format=text
Header - Metadata: true"]

imds_request --> imds_retry{"Response code?"}
imds_retry -->|"404, 410, 429, or 5xx
Retry with exponential backoff
(200ms initial, 5s max)"| imds_request
imds_retry -->|"Network Unreachable
(DHCP has not completed)"| imds_request
imds_retry -->|200, empty body| fallback_ovf
imds_retry -->|200, has body| write_config["Write decoded config to /run/ignition.json"]
imds_retry -->|Other error| error["Error"]
write_config --> done["Done"]

fallback_ovf["Fallback: read OVF custom data from CD-ROM device"]
fallback_ovf --> scan["Scan for UDF CD-ROM (often /dev/sr0)"]
scan --> mount["Mount device"]
mount --> read["Read for ovf-env.xml and CustomData.bin"]
read --> available{"Config available?"}
available -->|Yes| write_device["Write config to /run/ignition.json"]
write_device --> done
available -->|No| wait["Wait 1s"] --> scan
```
1 change: 1 addition & 0 deletions docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ nav_order: 9
### Changes

- Fix test script compatibility with Go 1.26 which removed the `-go` flag from `go tool fix`
- Improved documentation for the flow of Ignition across clouds.

### Bug fixes

Expand Down
Loading