Skip to content

Conversation

@sebsoto
Copy link

@sebsoto sebsoto commented Dec 10, 2025

What type of PR is this?

/kind feature

What this PR does / why we need it:

Add basic functionality to build Windows images

Enables committing a Windows base image as the final layer.
This gives the possibility of building a Windows container image on a
Linux build system. Only COPY and ADD are in scope. This allows the
workflow of cross compiling Windows binaries on Linux, and copying them
into a Windows container image for use on Windows systems.

How to verify it

Which issue(s) this PR fixes:

Fixes #4010

Special notes for your reviewer:

Does this PR introduce a user-facing change?


@openshift-ci openshift-ci bot added do-not-merge/work-in-progress kind/feature Categorizes issue or PR as related to a new feature. labels Dec 10, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 10, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sebsoto
Once this PR has been reviewed and has the lgtm label, please assign mtrmac for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sebsoto sebsoto force-pushed the windowsWork branch 6 times, most recently from 0d130f7 to 40ef079 Compare December 13, 2025 22:54
@github-actions
Copy link

A friendly reminder that this PR had no activity for 30 days.

@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jan 13, 2026
@packit-as-a-service
Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

@sebsoto sebsoto force-pushed the windowsWork branch 3 times, most recently from b880025 to 2077e66 Compare January 13, 2026 19:20
Copy link
Member

@nalind nalind left a comment

Choose a reason for hiding this comment

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

I usually don't look at draft and WIPs, but since you asked.

tests/bud.bats Outdated
# Get the last layer digest from the manifest (the layer we just created)
run jq -r '.layers[-1].digest' ${manifest_file}
local layer_digest=${output#sha256:}
local layer_file=${ocidir}/blobs/sha256/${layer_digest}
Copy link
Member

Choose a reason for hiding this comment

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

There's a oci_image_last_diff() helper function which will probably save a bit of time here.

image.go Outdated
return <-w.done
}

func newWindowsMutator(outStream io.WriteCloser) *winMutator {
Copy link
Member

Choose a reason for hiding this comment

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

This duplicates a lot of what makeFilteredLayerWriteCloser() is already doing to create a tar filterer through which the layer diff will be passed. Adding these changes to it will save us the trouble of passing the layer over another pipe.

image.go Outdated
}

if !h.ModTime.IsZero() {
h.PAXRecords[keyCreationTime] = fmt.Sprintf("%d.%d", h.ModTime.Unix(), h.ModTime.Nanosecond())
Copy link
Member

Choose a reason for hiding this comment

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

The timestamp needs to be clamped as we do elsewhere when the build is meant to be reproducible. The nanosecond value is not zero-padded.

@github-actions github-actions bot removed the stale-pr label Jan 14, 2026
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Jan 16, 2026
@sebsoto sebsoto changed the title [WIP] Enable building Windows container images Enable building Windows container images Jan 16, 2026
@sebsoto
Copy link
Author

sebsoto commented Jan 16, 2026

Thanks @nalind
I addressed your comments and took the PR out of WIP.

Copy link
Member

@nalind nalind left a comment

Choose a reason for hiding this comment

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

I think that dropping the layerWriter refactor would make this PR considerably smaller, and would hopefully avoid the copy-pasting of functions from elsewhere.

Having the tar filter adjust everything that passes through it (i.e., setting the PAX records and header format) , and having makeFilteredLayerWriteCloser() write the initial Hives/ and Files/ entries through the new WriteCloser before returning it (much as newLayerWriter() would have) would reduce the number of locations where the header changes needed to be made and the desired ModTime determined.

image.go Outdated
if windows {
hdr.Name = filepath.Join("Files", hdr.Name)
if hdr.Linkname != "" {
hdr.Linkname = filepath.Join("Files", hdr.Linkname)
Copy link
Member

Choose a reason for hiding this comment

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

These need to be path.Join(), in case this code is ever natively built for Windows.

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jan 28, 2026
@sebsoto sebsoto force-pushed the windowsWork branch 2 times, most recently from b905676 to 25a54a5 Compare January 28, 2026 19:55
Enables committing a Windows base image as the final layer.
This gives the possibility of building a Windows container image on a
Linux build system. Only COPY and ADD are in scope. This allows the
workflow of cross compiling Windows binaries on Linux, and copying them
into a Windows container image for use on Windows systems.

Signed-off-by: Sebastian Soto <ssoto@redhat.com>
@sebsoto
Copy link
Author

sebsoto commented Jan 28, 2026

@nalind

having makeFilteredLayerWriteCloser() write the initial Hives/ and Files/ entries through the new WriteCloser before returning it (much as newLayerWriter() would have) would reduce the number of locations where the header changes needed to be made and the desired ModTime determined.

Finding a clean way to do this has been difficult, as the directories passed through the writer would end up being Files/Files and Files/Hives. So while not doing this exactly, I did reduce the scope as requested, and removed duplicate code where possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

do-not-merge/work-in-progress kind/feature Categorizes issue or PR as related to a new feature. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Building Windows container images

2 participants