Skip to content

Fix custom image deployment via SimpleStreams (3.7) - #576

Open
jlboostrun wants to merge 1 commit into
canonical:3.7from
jlboostrun:SRE-31-custom-simplestreams-patches
Open

Fix custom image deployment via SimpleStreams (3.7)#576
jlboostrun wants to merge 1 commit into
canonical:3.7from
jlboostrun:SRE-31-custom-simplestreams-patches

Conversation

@jlboostrun

@jlboostrun jlboostrun commented Aug 25, 2026

Copy link
Copy Markdown

Problem

Custom images synced from a SimpleStreams boot source cannot be deployed. The deploy fails with:

Failed to retrieve curtin config: 'custom'

Launchpad bug: https://bugs.launchpad.net/maas/+bug/2164564

Root Cause

When custom images are synced from a SimpleStreams source, the importer stores them with a custom/ name prefix (e.g. custom/br-ubuntu-24.04) and rtype=SYNCED. However, all resource lookups for the custom osystem query with the bare series name and only match UPLOADED resources:

  1. preseed.py:get_base_osystem_seriesBootResource.objects.get(name=release, ...) never matches custom/{release}
  2. bootresource.py:get_resource_forname=series + rtype=(UPLOADED,) categorically excludes synced resources
  3. rpc/boot.py:get_boot_config_for_machine — same name=final_series bare lookup in the xinstall path
  4. rpc/boot.py:_get_files_map — same bare lookup for PXE kernel/initrd retrieval

This makes the custom osystem + SimpleStreams combination entirely undeployable. Only manually uploaded custom images (bare name, rtype=UPLOADED) work.

Fix

All four lookups now use name__in=[series, f"custom/{series}"] to match both naming conventions, and get_resource_for includes SYNCED in the rtype filter for custom osystem.

The change is backward-compatible: uploaded custom resources (bare name, UPLOADED) still match via the bare name in the name__in list.

Testing

  • Existing tests pass (they use UPLOADED + bare names, still matched)
  • New tests added:
    • test_get_resource_for_returns_synced_custom_resource — SYNCED resource with custom/ prefix found via bare series
    • test_get_boot_config_for_machine_synced_custom_image — full boot config lookup for SYNCED custom resource

Verification

Verified end-to-end on MAAS 3.7.2 (snap rev 41649): custom Ubuntu 24.04 image published to a SimpleStreams stream, synced to a MAAS controller, and deployed to a UEFI VM. Machine reached Deployed state with cloud-init complete.

The bind-mounted hot-fixes on the test controller used exactly these name lookups; this PR makes them persistent in the codebase.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[maas-code-reviewer review]

LLM-generated review from https://github.com/canonical/maas-code-reviewer.
Intended to assist a human reviewer, not replace one — suggestions may be
incorrect, please verify before acting.

This change correctly identifies and fixes a bug where SYNCED custom images could not be deployed because the lookup logic only matched UPLOADED images with the bare series name.

However, I spotted a couple of issues:

  1. A test class definition (TestGetAvailableCommissioningResources) was accidentally removed during the test additions, which messes up the test suite structure and causes unintended setUp overwrites.
  2. In rpc/boot.py, replacing name=final_series with name__in=[...] introduces the possibility of BootResource.objects.get() throwing a MultipleObjectsReturned exception if a user happens to have both an uploaded and a synced custom image with the same series name. This exception currently goes unhandled.

Please see the inline comments for more details.

Comment thread src/maasserver/models/tests/test_bootresource.py
Comment thread src/maasserver/rpc/boot.py
Comment thread src/maasserver/rpc/boot.py
Comment thread src/maasserver/rpc/boot.py
Comment thread src/maasserver/rpc/tests/test_boot.py Outdated
@jlboostrun
jlboostrun force-pushed the SRE-31-custom-simplestreams-patches branch from 57f82dc to 97ae731 Compare August 25, 2026 19:37
Custom images synced from a SimpleStreams source are stored with a
'custom/' name prefix (e.g. 'custom/br-ubuntu-24.04') and rtype=SYNCED.
However, all name lookups for custom osystem used the bare series name
and only matched UPLOADED resources, making custom-via-SimpleStreams
undeployable.

Three code paths fixed:
- preseed.py get_base_osystem_series: name=release → name__in=[release, f"custom/{release}"]
- bootresource.py get_resource_for: name=series + rtype=(UPLOADED,) → name__in=[series, f"custom/{series}"] + rtype=(SYNCED, UPLOADED)
- rpc/boot.py get_boot_config_for_machine + _get_files_map: same name__in fix

Tests added for SYNCED custom resources with custom/ prefix in both
bootresource and rpc/boot code paths.
@jlboostrun
jlboostrun force-pushed the SRE-31-custom-simplestreams-patches branch from 97ae731 to f1e6a62 Compare August 25, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant