Skip to content
Open
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
145 changes: 145 additions & 0 deletions docs/ignition-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
```mermaid
flowchart TB
%% ===== IGNITION BOOT FLOW =====

%% --- Early Boot ---
boot["Boot"] --> setup_pre["ignition-setup-pre.service"]
setup_pre --> setup["ignition-setup.service"]
setup --> fetch_offline["ignition-fetch-offline.service"]

%% --- Fetch Offline Details ---
subgraph FETCH_OFFLINE ["Ignition Fetch Offline"]
direction TB
offline_detect_platform["Detect platform"]
offline_check_configs["Check configs at:"]
offline_base_dir["/usr/lib/ignition/base.d"]
offline_platform_dir["/usr/lib/ignition/base.platform.d/{platform}"]
offline_detect_platform --> offline_check_configs
offline_check_configs --> offline_base_dir
offline_check_configs --> offline_platform_dir
offline_check_user_ign{"/usr/lib/ignition/user.ign exists?"}
offline_base_dir --> offline_check_user_ign
offline_platform_dir --> offline_check_user_ign
offline_check_user_ign -->|Yes| offline_copy_user_ign["Write to /run/ignition.json"]
offline_check_user_ign -->|No| offline_done["Done"]
offline_copy_user_ign --> offline_done
end
fetch_offline --> FETCH_OFFLINE

FETCH_OFFLINE --> fetch_check{"/run/ignition.json exists?"}
fetch_check -->|Yes, skip ignition-fetch.service| kargs_service
fetch_check -->|No| fetch_service["ignition-fetch.service"]

%% --- Fetch Service Details ---
subgraph FETCH_ONLINE ["Ignition Fetch"]
direction TB
online_detect_platform["Detect platform"]
online_check_configs["Check configs at:"]
online_base_dir["/usr/lib/ignition/base.d"]
online_platform_dir["/usr/lib/ignition/base.platform.d/{platform}"]
online_detect_platform --> online_check_configs
online_check_configs --> online_base_dir
online_check_configs --> online_platform_dir
online_fetch_provider["Fetch provider-specific configs (see Provider Specific Behavior - Config Fetch below)"]
online_check_user_ign{"/usr/lib/ignition/user.ign exists?"}
online_base_dir --> online_check_user_ign
online_platform_dir --> online_check_user_ign
online_check_user_ign -->|Yes| online_copy_user_ign["Write config to /run/ignition.json"]
online_check_user_ign -->|No| online_fetch_provider
online_copy_user_ign --> online_done["Done"]
online_fetch_provider -->|Config found| online_write_provider["Write config to /run/ignition.json"]
online_write_provider --> online_done
online_fetch_provider -->|No config| online_done
end
fetch_service --> FETCH_ONLINE

%% --- Network Stack ---
subgraph NETWORK ["Network Stack"]
direction TB
networkd_service["systemd-networkd.service"]
network_config["systemd-networkd.service - Network Configuration"]
network_target["network.target reached"]
networkd_service --> network_config --> network_target
end
setup --> NETWORK
NETWORK --> FETCH_ONLINE
NETWORK --> get_dhcp_address["Get DHCP address"]
get_dhcp_address --> online_fetch_provider

%% --- Disk & Mount Services ---
FETCH_ONLINE --> kargs_service["ignition-kargs.service"]
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could mention that a reboot might occur here (and we restart the flow from the beginning) - if a kernel argument is added / removed from the kernel command line.

Copy link
Author

Choose a reason for hiding this comment

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

I updated the flowchart to include the reboot section!

kargs_service -->|kargs changed| reboot_kargs["Reboot & restart from top"]

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_detect_platform["Detect platform"]
files_check_configs["Check configs at:"]
files_base_dir["/usr/lib/ignition/base.d"]
files_platform_dir["/usr/lib/ignition/base.platform.d/{platform}"]
files_detect_platform --> files_check_configs
files_check_configs --> files_base_dir
files_check_configs --> files_platform_dir
files_base_dir --> files_check_run_json
files_platform_dir --> files_check_run_json
files_check_run_json{"/run/ignition.json exists?"}
files_check_run_json -->|Yes| files_merge_all["Merge all detected configs and apply"]
files_merge_all --> files_done["Done"]
files_check_run_json -->|No| files_error["Error"]
end
files_service --> FILES

FILES --> quench_service["ignition-quench.service"]
quench_service --> initrd_setup_root["initrd-setup-root-after-ignition.service"]
quench_service --> complete_target["ignition-complete.target"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Ignition has a ignition-delete-config.service that takes care of deleting the user-data configuration from the cloud provider (only supported for VMWare at this moment, but I'd started a discussion a while ago for Azure to investigate on a similar feature and/or protect user-data access)

Copy link
Author

Choose a reason for hiding this comment

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

This is great to know about! I had not encountered this as I am primarily running on Azure.

From what I am reading, ignition-delete-config.service seems to be a bit disconnected from the flow of the rest of Ignition. It seems to operate before sysinit.target, but I do not find any other references to sysinit.target in the codebase. Since these two are disjointed, do you have any recommendation on how to include it in the flowchart? I could put it in its own subgraph, but am not sure where to link it. Thanks!


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

class setup_pre,setup,fetch_offline,fetch_service,kargs_service,disks_service,mount_service,files_service,quench_service,initrd_setup_root,network_config,networkd_service,afterburn_hostname_service service
class diskful_target,complete_target,network_target,initrd_root_fs_target target

```

## 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
```
Loading