|
| 1 | +```mermaid |
| 2 | +flowchart TB |
| 3 | + %% ===== IGNITION BOOT FLOW ===== |
| 4 | +
|
| 5 | + %% --- GRUB Firstboot Detection --- |
| 6 | + boot["Boot"] --> grub["GRUB bootloader"] |
| 7 | +
|
| 8 | + subgraph GRUB_FIRSTBOOT ["GRUB Firstboot Detection"] |
| 9 | + direction TB |
| 10 | + grub_check{"/ignition.firstboot |
| 11 | + stamp file on bootfs?"} |
| 12 | + grub_check -->|Yes| grub_source["Source /ignition.firstboot |
| 13 | + (may set ignition_network_kcmdline)"] |
| 14 | + grub_source --> grub_append["Append to kernel cmdline: |
| 15 | + ignition.firstboot $ignition_network_kcmdline"] |
| 16 | + grub_check -->|No| grub_no_flag["No ignition.firstboot on cmdline"] |
| 17 | + end |
| 18 | + grub --> GRUB_FIRSTBOOT |
| 19 | +
|
| 20 | + %% --- Initramfs Generator --- |
| 21 | + GRUB_FIRSTBOOT --> generator["ignition-generator |
| 22 | + (reads /proc/cmdline)"] |
| 23 | + generator --> firstboot_check{"ignition.firstboot |
| 24 | + on kernel cmdline?"} |
| 25 | +
|
| 26 | + %% --- Subsequent Boot Path --- |
| 27 | + firstboot_check -->|No| subsequent_target["ignition-subsequent.target"] |
| 28 | + subsequent_target --> subsequent_diskful["ignition-diskful-subsequent.target"] |
| 29 | + subsequent_diskful --> subsequent_done["Ignition services do not run. |
| 30 | + Boot continues normally."] |
| 31 | +
|
| 32 | + %% --- Firstboot Path --- |
| 33 | + firstboot_check -->|Yes| complete_gate["ignition-complete.target activated"] |
| 34 | + complete_gate --> fetch_offline["ignition-fetch-offline.service"] |
| 35 | +
|
| 36 | + %% --- Fetch Offline Details --- |
| 37 | + subgraph FETCH_OFFLINE ["Ignition Fetch Offline"] |
| 38 | + direction TB |
| 39 | + offline_check_cmdline{"Config provided |
| 40 | + via kernel cmdline?"} |
| 41 | + offline_check_user_ign{"/usr/lib/ignition/user.ign |
| 42 | + exists?"} |
| 43 | + offline_try_platform["Try platform provider"] |
| 44 | + offline_write_cache["Write config to /run/ignition.json"] |
| 45 | + offline_needs_net{"Config needs |
| 46 | + network resources?"} |
| 47 | + offline_signal_neednet["Signal neednet"] |
| 48 | + offline_done["Done"] |
| 49 | + offline_check_cmdline -->|Yes| offline_write_cache |
| 50 | + offline_check_cmdline -->|No| offline_check_user_ign |
| 51 | + offline_check_user_ign -->|Yes| offline_write_cache |
| 52 | + offline_check_user_ign -->|No| offline_try_platform |
| 53 | + offline_try_platform -->|Config found| offline_write_cache |
| 54 | + offline_try_platform -->|Needs network| offline_signal_neednet |
| 55 | + offline_write_cache --> offline_needs_net |
| 56 | + offline_needs_net -->|Yes| offline_signal_neednet |
| 57 | + offline_needs_net -->|No| offline_done |
| 58 | + end |
| 59 | + fetch_offline --> FETCH_OFFLINE |
| 60 | + |
| 61 | + FETCH_OFFLINE -.-> distro_network["Distro-managed network bring-up"] |
| 62 | + FETCH_OFFLINE --> fetch_check{"/run/ignition.json exists?"} |
| 63 | + fetch_check -->|Yes, skip ignition-fetch.service| kargs_service |
| 64 | + fetch_check -->|No| neednet_check{"/run/ignition/neednet exists?"} |
| 65 | + neednet_check -->|No| kargs_service |
| 66 | + distro_network --> network_target["network.target reached"] |
| 67 | + neednet_check --> |Yes| fetch_service["ignition-fetch.service"] |
| 68 | + network_target --> fetch_service |
| 69 | + |
| 70 | + %% --- Fetch Service Details --- |
| 71 | + subgraph FETCH_ONLINE ["Ignition Fetch"] |
| 72 | + direction TB |
| 73 | + online_check_cmdline{"Config provided |
| 74 | + via kernel cmdline?"} |
| 75 | + online_check_user_ign{"/usr/lib/ignition/user.ign |
| 76 | + exists?"} |
| 77 | + online_fetch_provider["Fetch from platform provider |
| 78 | + (see Provider Specific Behavior - Config Fetch below)"] |
| 79 | + online_write_config["Write config to /run/ignition.json"] |
| 80 | + online_done["Done"] |
| 81 | + online_check_cmdline -->|Yes| online_write_config |
| 82 | + online_check_cmdline -->|No| online_check_user_ign |
| 83 | + online_check_user_ign -->|Yes| online_write_config |
| 84 | + online_check_user_ign -->|No| online_fetch_provider |
| 85 | + online_fetch_provider -->|Config found| online_write_config |
| 86 | + online_fetch_provider -->|No config| online_done |
| 87 | + online_write_config --> online_done |
| 88 | + end |
| 89 | + fetch_service --> FETCH_ONLINE |
| 90 | + |
| 91 | + %% --- Disk & Mount Services --- |
| 92 | + FETCH_ONLINE --> kargs_service["ignition-kargs.service"] |
| 93 | + kargs_service -->|kargs changed| reboot_kargs["Reboot & restart from top"] |
| 94 | + |
| 95 | + kargs_service -->|no changes| disks_service["ignition-disks.service"] |
| 96 | + disks_service --> diskful_target["ignition-diskful.target reached"] |
| 97 | + diskful_target --> mount_service["ignition-mount.service"] |
| 98 | + |
| 99 | + %% --- Files --- |
| 100 | + mount_service --> files_service["ignition-files.service"] |
| 101 | + initrd_root_fs_target["initrd-root-fs.target"] --> afterburn_hostname_service["afterburn-hostname.service"] |
| 102 | + afterburn_hostname_service -.-> files_service |
| 103 | + |
| 104 | + %% --- Files Service Details --- |
| 105 | + subgraph FILES ["Ignition Files"] |
| 106 | + direction TB |
| 107 | + files_read_cache["Read cached config |
| 108 | + from /run/ignition.json"] |
| 109 | + files_apply["Merge with base configs and apply"] |
| 110 | + files_done["Done"] |
| 111 | + files_read_cache --> files_apply |
| 112 | + files_apply --> files_done |
| 113 | + end |
| 114 | + files_service --> FILES |
| 115 | + |
| 116 | + FILES --> complete_target["ignition-complete.target reached"] |
| 117 | + |
| 118 | + complete_target --> pivot_root["Pivot to real root"] |
| 119 | + pivot_root --> firstboot_delete_check{"Is this the first boot?"} |
| 120 | + firstboot_delete_check -->|Yes| delete_config["ignition-delete-config.service"] |
| 121 | + firstboot_delete_check -->|No| skip_delete["Skip config deletion"] |
| 122 | + |
| 123 | + %% ===== STYLING ===== |
| 124 | + classDef service fill:#42a5f5,stroke:#1565c0,stroke-width:2px,color:#000 |
| 125 | + classDef target fill:#ffa726,stroke:#e65100,stroke-width:2px,color:#000 |
| 126 | + |
| 127 | + class fetch_offline,fetch_service,kargs_service,disks_service,mount_service,files_service,afterburn_hostname_service,delete_config service |
| 128 | + class diskful_target,complete_target,complete_gate,network_target,initrd_root_fs_target,subsequent_target,subsequent_diskful target |
| 129 | + classDef distro fill:#66bb6a,stroke:#2e7d32,stroke-width:2px,color:#000 |
| 130 | + class distro_network distro |
| 131 | +
|
| 132 | +``` |
| 133 | + |
| 134 | +## Provider Specific Behavior |
| 135 | +### Config Fetch |
| 136 | +#### Azure |
| 137 | +```mermaid |
| 138 | +flowchart TB |
| 139 | + %% ===== AZURE PROVIDER-SPECIFIC CONFIG FETCH ===== |
| 140 | +
|
| 141 | + start["Fetch provider-specific config"] --> imds_request["HTTP GET to Azure IMDS |
| 142 | + http://169.254.169.254/metadata/instance/compute/userData |
| 143 | + ?api-version=2021-01-01&format=text |
| 144 | + Header - Metadata: true"] |
| 145 | +
|
| 146 | + imds_request --> imds_retry{"Response code?"} |
| 147 | + imds_retry -->|"404, 410, 429, or 5xx |
| 148 | + Retry with exponential backoff |
| 149 | + (200ms initial, 5s max)"| imds_request |
| 150 | + imds_retry -->|"Network Unreachable |
| 151 | + (DHCP has not completed)"| imds_request |
| 152 | + imds_retry -->|200, empty body| fallback_ovf |
| 153 | + imds_retry -->|200, has body| write_config["Write decoded config to /run/ignition.json"] |
| 154 | + imds_retry -->|Other error| error["Error"] |
| 155 | + write_config --> done["Done"] |
| 156 | +
|
| 157 | + fallback_ovf["Fallback: read OVF custom data from CD-ROM device"] |
| 158 | + fallback_ovf --> scan["Scan for UDF CD-ROM (often /dev/sr0)"] |
| 159 | + scan --> mount["Mount device"] |
| 160 | + mount --> read["Read for ovf-env.xml and CustomData.bin"] |
| 161 | + read --> available{"Config available?"} |
| 162 | + available -->|Yes| write_device["Write config to /run/ignition.json"] |
| 163 | + write_device --> done |
| 164 | + available -->|No| wait["Wait 1s"] --> scan |
| 165 | +``` |
0 commit comments