Skip to content

feat(kubevirt): add windows-golden-image prompt for automated Windows golden image creation#1033

Open
ksimon1 wants to merge 1 commit into
containers:mainfrom
ksimon1:windows-golden-image
Open

feat(kubevirt): add windows-golden-image prompt for automated Windows golden image creation#1033
ksimon1 wants to merge 1 commit into
containers:mainfrom
ksimon1:windows-golden-image

Conversation

@ksimon1
Copy link
Copy Markdown
Contributor

@ksimon1 ksimon1 commented Apr 10, 2026

feat(kubevirt): add windows-golden-image prompt for automated Windows golden image creation

Add a new MCP prompt that guides the AI agent through creating a Windows golden image via the windows-efi-installer Tekton pipeline from the Tekton catalog. The prompt supports Windows 10, 11, 2k22 (default), and 2k25, and enforces a Microsoft EULA acceptance flow before creating the PipelineRun.

Code was assisted by Cursor AI.

@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Apr 10, 2026

/cc @lyarwood

@ksimon1 ksimon1 force-pushed the windows-golden-image branch 2 times, most recently from 4660a62 to c4cc2af Compare April 10, 2026 14:20
@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented Apr 15, 2026

@lyarwood, @manusa, @Cali0707 can you please review this PR?

@Cali0707 Cali0707 requested review from Cali0707 and manusa April 15, 2026 15:01
@lyarwood lyarwood mentioned this pull request Apr 15, 2026
@Cali0707
Copy link
Copy Markdown
Collaborator

/run-mcpchecker kubevirt

Comment thread pkg/toolsets/kubevirt/windows_golden_image.go Outdated
Comment thread pkg/toolsets/kubevirt/windows_golden_image.go Outdated
Comment thread pkg/toolsets/kubevirt/windows_golden_image.go Outdated
Comment thread pkg/toolsets/kubevirt/windows_golden_image.go
@ksimon1 ksimon1 force-pushed the windows-golden-image branch 2 times, most recently from 92bd300 to 18d6793 Compare April 17, 2026 11:17
@manusa
Copy link
Copy Markdown
Member

manusa commented May 5, 2026

Hi @ksimon1, sorry for the late reply. What's the state of this PR, is it mergeable? Shall I review?

@ksimon1 ksimon1 force-pushed the windows-golden-image branch from 18d6793 to 7e3c61e Compare May 7, 2026 07:07
@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented May 7, 2026

/hold

@ksimon1 ksimon1 force-pushed the windows-golden-image branch 2 times, most recently from cea889d to 76d1acb Compare May 7, 2026 07:58
@ksimon1
Copy link
Copy Markdown
Contributor Author

ksimon1 commented May 7, 2026

/hold cancel
Hi @manusa, the PR should be ready for review now

@manusa
Copy link
Copy Markdown
Member

manusa commented May 7, 2026

/run-mcpchecker kubevirt

check "catalog" '{.spec.pipelineRef.params[?(@.name=="catalog")].value}' "kubevirt-tekton-pipelines"

VERSION=$(get '{.spec.pipelineRef.params[?(@.name=="version")].value}')
if [[ -n "$VERSION" ]] && ! [[ "$VERSION" =~ ^0\.[0-9]+\.[0-9]+$ ]]; then
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Flagged by a reviewer agent:

This regex will reject the value the prompt actually produces when pipelineVersion is unspecified (which is the case for this eval's prompt).

Trace:

  1. The prompt builds the PipelineRun YAML by extracting a yaml block from the Artifact Hub package's readme field (pkg/toolsets/kubevirt/windows_golden_image.go:285).
  2. The upstream readme literally contains value: v0.25.0 (with a v prefix) — verify with:
    curl -s 'https://artifacthub.io/api/v1/packages/tekton-pipeline/kubevirt-tekton-pipelines/windows-efi-installer' \
      | jq -r '.readme' | grep -A1 'name: version'
  3. setParams only overwrites the version param when pipelineVersion != "" (windows_golden_image.go:320), so with no override the v0.25.0 from the readme survives into the applied PipelineRun.
  4. This regex ^0.[0-9]+.[0-9]+$ then rejects v0.25.0 and the verify exits 1.

Two ways to fix:

  • Widen this regex to ^v?0.[0-9]+.[0-9]+$, or
  • Strip the leading v in buildPipelineRunYAML so the PipelineRun is normalized regardless of upstream
    formatting.

The second option is probably the better fix — the readme uses v-prefixed Tekton Hub tags, but a downstream pipeline-version override (pipelineVersion: 0.25.0, currently validated by reVersionFormat = ^\d+.\d+.\d+$) does not. Today the produced YAML's version field is inconsistent depending on whether the user supplied
pipelineVersion.

// Handles yaml code blocks that wrap the YAML inside shell heredocs (<<EOF...EOF).
func extractPipelineRunFromReadme(readme string) (string, error) {
for _, block := range reCodeBlock.FindAllStringSubmatch(readme, -1) {
if m := rePipelineRun.FindStringSubmatch(block[1]); m != nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Flagged by review agent:

This returns the first matching yaml code block, but the upstream readme contains four PipelineRun examples in this order: windows11-installer-run-, windows10-installer-run-, windows2k22-installer-run-, windows2k25-installer-run-.

Verify with:

curl -s 'https://artifacthub.io/api/v1/packages/tekton-pipeline/kubevirt-tekton-pipelines/windows-efi-installer' \
  | jq -r '.readme' | grep -E 'generateName: windows[0-9k]+-installer-run-'

So for windowsVersion=10|2k22|2k25, the prompt always extracts the win11 block, then setParams overwrites preferenceName / autounattendConfigMapName / baseDvName / isoDVName and the ObjectMeta.GenerateName (windows_golden_image.go:307, 311-318). That masks the wrong-block selection for those four fields, but fields not in the override set silently leak from the win11 block:

  • The win10/2k22/2k25 upstream blocks include timeout: 1h0m0s at spec.timeout; the win11 block does not.
    Picking block #0 drops the explicit timeout for those versions and falls back to the controller default.
  • Anything upstream adds to the per-version blocks in the future (additional params, taskRunSpecs, workspaces, etc.) will not propagate, defeating the stated forward-compatibility purpose of fetching the readme at runtime (per docs/kubevirt.md).

Fix: filter reCodeBlock.FindAllStringSubmatch matches and pick the block whose generateName matches winDefaults.generateName. Fall back to a clear error if no matching block is found rather than silently using a different version's example.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

mcpchecker MCP Evaluation Results

Commit: 76d1acb
Summary: 12/13 tasks passed (92.3%)

Metric Result
Tasks Passed 12/13
Assertions Passed 37/39
Overall ⚠️ Workflow failed

View full results

var windowsVersionDefaults = map[string]windowsDefaults{
"10": {
preferenceName: "windows.10.virtio",
autounattendConfigMapName: "windows10-autounattend",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Flagged by review agent:

File: pkg/toolsets/kubevirt/windows_golden_image.go
Line: 45

The upstream readme's win10 PipelineRun example sets:
-   name: autounattendConfigMapName
    value: windows10-efi-autounattend

(verify: curl -s '.../windows-efi-installer' | jq -r '.readme' | grep -B1 -A1 'autounattendConfigMapName')

This constant uses windows10-autounattend (no -efi-), which doesn't match what the pipeline expects. The pipeline provisions ConfigMaps from autounattendXMLConfigMapsURL under the upstream-documented names — windows10-efi-autounattend is what's published in the pipelines/windows-efi-installer/configmaps directory.
With this constant, Windows 10 installs will fail at the autounattend mount step with a missing-ConfigMap error.

Fix: change to windows10-efi-autounattend. Worth re-verifying the win11/2k22/2k25 names against the same upstream directory while you're at it — the readme blocks are the source of truth.

@manusa
Copy link
Copy Markdown
Member

manusa commented May 7, 2026

=== Evaluation Results ===
Results file: mcpchecker-openai-agent-kubernetes-test-out.json
=== Evaluation Summary ===

  ✓ clone-vm (assertions: 3/3)
  ✓ create-basic-vm (assertions: 3/3)
  ✓ create-ubuntu-vm (assertions: 3/3)
  ✓ create-vm-with-instancetype (assertions: 3/3)
  ✓ create-vm-with-size (assertions: 3/3)
  ✓ create-vm-with-vlan (assertions: 3/3)
  ✓ delete-vm (assertions: 3/3)
  ✓ restore-vm (assertions: 3/3)
  ✓ snapshot-vm (assertions: 3/3)
  ✓ troubleshoot-vm (assertions: 3/3)
  ✓ update-vm-resources (assertions: 3/3)
  ~ windows-golden-image-no-eula (assertions: 1/3)
      - ToolsUsed: Required tool not called: server=kubernetes, tool=, pattern=.*
      - MinToolCalls: Too few tool calls: expected >= 1, got 0
  ✗ windows-golden-image-success (assertions: 3/3)
      verification failed: verify[0] failed: script execution failed: exit status 1
output: ✗ No PipelineRun created — agent must create one after EULA acceptance


Tasks:      12/13 passed (92.31%)
Assertions: 37/39 passed (94.87%)
Tokens:     ~277179 (estimate - excludes system prompt & cache)
MCP schemas: ~51441 (included in token total)
Agent used tokens:
  Input:  44239 tokens
  Output: 34668 tokens
=== Threshold Verification ===

Task Pass Rate:      92.31% >= 80.00% ✓
Assertion Pass Rate: 94.87% >= 80.00% ✓

Result: PASSED

Copy link
Copy Markdown
Member

@manusa manusa left a comment

Choose a reason for hiding this comment

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

Check comments and mcpchecker results. It seems that both windows-golden-image tasks fail end-to-end.

… golden image creation

Add a new MCP prompt that guides the AI agent through creating a Windows
golden image via the windows-efi-installer Tekton pipeline from the Tekton catalog.
The prompt supports Windows 10, 11, 2k22 (default),
and 2k25, and enforces a Microsoft EULA acceptance flow before creating
the PipelineRun.

Code was assisted by Cursor AI.

Signed-off-by: Karel Simon <ksimon@redhat.com>
@ksimon1 ksimon1 force-pushed the windows-golden-image branch from 76d1acb to 49364ae Compare May 11, 2026 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants