fix(cloudinit): merge cloud-config documents before the seed is written - #97
Conversation
stoat handed cloud-init a cloud-config-archive and let it merge the documents. An archive is a top-level YAML list, and cloud-init 24.4 on AlmaLinux 9 and Rocky 9 reads user-data with .get() before it checks the type, so init-local fails and cloud-init status reports error for the life of the VM. #91 avoided the archive for a one-document seed, which left any guest with a recipe still broken there. mergeDocs folds the documents into one mapping: a list appends, a mapping merges key by key, and anything else takes the later value. Those are the rules the merge_how directive used to ask cloud-init for. The seed no longer depends on the guest's cloud-init version. The rendered YAML differs from the template: yaml.Marshal sorts keys, drops comments, and emits the sudo rule as a plain scalar. The parsed values are the same, and the tests now assert those. Signed-off-by: NovusEdge <novusedge0@gmail.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Team Run ID: 📒 Files selected for processing (5)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughThe change replaces cloud-config archives with one merged ChangesCloud-config merge
Estimated code review effort: 3 (Moderate) | ~25 minutes Merge Risk: ⚪ Minimal · up to Cloud-config seeds are now emitted as one mapping, avoiding the archive-list parsing failure while retaining account settings, packages, commands, and recipe content. The covered behavior is ready to merge. Sequence Diagram(s)sequenceDiagram
participant SeedBuilder
participant mergeDocs
participant CloudInit
SeedBuilder->>mergeDocs: pass base and recipe documents
mergeDocs->>mergeDocs: merge mappings and append lists
mergeDocs-->>SeedBuilder: return one `#cloud-config` mapping
SeedBuilder->>CloudInit: provide merged user-data document
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Live evidenceMerged-seed candidate
The three recipe rows are the multi-document path: the base account block, the guest's own extra packages, the 9p mounts document where the guest takes one, and two recipe fragments, all folded into one mapping. Each row checks that both recipes report healthy, that the declared outputs resolve in the guest, and that cloud-init finishes with no hard errors. AlmaLinux with a recipe stays unproven on hardware, because no recipe declares AlmaLinux yet. That is #85. This change is what unblocks it. |
Closes #93. Unblocks #85 for AlmaLinux and Rocky.
stoat handed cloud-init a cloud-config-archive and let it merge the documents.
An archive is a top-level YAML list, and cloud-init 24.4 on AlmaLinux 9 and
Rocky 9 reads user-data with
.get()before it checks the type:#91 avoided the archive when the seed held one document, which covered a guest
with no recipes. A guest with a recipe still produced two or more documents and
still failed.
mergeDocsfolds them into one mapping before the seed is written: a listappends to the list already there, a mapping merges key by key, and anything
else takes the later value. Those are the rules the
merge_howdirective usedto ask cloud-init for. The seed no longer depends on the guest's cloud-init
version, and
merge_how,withMergeHow,archiveDocandbuildArchivearegone.
What the rendered seed looks like now
yaml.Marshalsorts keys, drops comments, and emits the sudo rule as a plainscalar. The parsed values are unchanged. Ubuntu with one recipe:
The package header says to re-verify the seed on hardware before changing its
shape, so the tests that pinned the file's bytes now pin the parsed values, and
this PR carries live evidence.
Tests
merge_test.gocovers the merge rules directly: lists append in documentorder, mappings recurse, a later scalar wins,
write_filesentries accumulate,a document that is not a mapping fails, and the error names which document
failed.
The seed tests assert parsed values instead of rendered bytes.
TestSeedIsAlwaysAMappingruns six guests with and without a recipe.TestSeedCarriesRecipesOnAlmaLinuxis the case #93 is about.Live evidence
Filled in below as the gates finish.
Summary by CodeRabbit
#cloud-configdocument.