Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for creating Windows scratch-equivalent baselayers #64

Merged
merged 5 commits into from
Oct 15, 2020

Conversation

micahyoung
Copy link
Member

@micahyoung micahyoung commented Oct 8, 2020

This allows FROM scratch-style Windows images (and buildpackages) to be stored on WCOW daemons (required for buildpacks/pack#840).

This is needed because imgutil in local scenarios requires all images to be stored on a Docker daemon. This works fine for Linux since the Docker daemon has pretty loose validation for Linux images (only requires the correct image metadata). But WCOW daemons, on the other hand, are most strict and require a specific baselayer as well. This difference is likely because there is no current FROM scratch use-case for Windows since it's not currently possible to statically compile a Windows binary with enough libraries to run in an empty container.

The smallest Microsoft-authored baselayer that can be stored on a daemon is from nanoserver, which is 100MB, has license restrictions for use, is a foreign layer that requires public internet access to pull, changes frequently due to patches, is coupled to the OS version (nanoserver:2004 images can't be pulled by Windows 1809), and currently has no long-term-supported version. For these reasons, it is unsuitable as a scratch-equivalent baselayer for something like buildpackages.

This implementation was derived from the files required by the moby and hcsshim codebases. It creates a layer with the 6 files necessary so an image that uses it can be stored on a daemon. There is no documented API contract for these files unfortunately which is a big downside. However the benefits in contrast to using nanoserver are that it can be generated on the fly on any OS, is created with OSS tools, has no distribution limitations, works with all current daemon versions, is only a few bytes, is trivial enough to hopefully not require regular patches, and if it does need to be patched, can be replaced with Image.Rebase(). The images with this layer can also be pulled and inspected with daemon-based tools like dive and presumably anything using the Docker API.

This implementation includes a new generator to create the imgutil source file with the encoded content of the most complex file - the baselayer's BCD hive file. This is needed only because the hivex C++ shared library is difficult to compile for OSes besides Linux and would introduce a surprising runtime requirement for consumers of imgutil on any OS.

I manually tested the layer against the main supported versions of Docker Desktop for Windows (1809, 2004) and Docker for Windows Server (1809, 2004). Additionally, a nearly identical layer has been used as an imgutil test fixture for the past several months without issue.

@micahyoung micahyoung force-pushed the windows-baselayer branch 6 times, most recently from aab7807 to 16d783a Compare October 12, 2020 13:43
@micahyoung micahyoung changed the title Prerequisites for package-buildpack on WCOW Adds support for creating Windows scratch-equivalent baselayers Oct 12, 2020
@micahyoung micahyoung force-pushed the windows-baselayer branch 2 times, most recently from e48fd21 to 4a5f630 Compare October 12, 2020 16:32
@micahyoung micahyoung marked this pull request as ready for review October 12, 2020 19:01
@micahyoung micahyoung requested a review from a team as a code owner October 12, 2020 19:01
@micahyoung
Copy link
Member Author

micahyoung commented Oct 13, 2020

I realize I focused mostly on importance of this scratch base layer for imgutil scenarios. But in fact, any Windows OCI image must have some base layer like this one to allow docker pull, docker load, ggcr daemon.Write() or anything else that writes and image to a WCOW daemon, even if the base layer is not runnable.

A user who is not interested in using imgutil.Images could still benefit from using layer.WindowsBaseLayer with something like ggcr mutate.AppendLayer(empty.Image, tarball.LayerFromReader(layer.WindowsBaseLayer()))

Or something similar with a Docekerfile is also possible:

FROM mcr.microsoft.com/windows/nanoserver:1809 --as builder

RUN echo "created in Windows" > c:\output.txt

FROM micahyoung/scratch-windows

COPY --from=builder c:\output.txt c:\output.txt

Copy link
Member

@ekcasey ekcasey left a comment

Choose a reason for hiding this comment

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

@micahyoung Thanks for all of your hard work here. I appreciate the effort that went into creating the nice go generate interface.

I left some comments the mostly boil down to:

  1. some very minor cleanup in the testhelpers
  2. can we make the Makefile target smart enough to avoid slow generation steps when possible? If not maybe we should pull it out of the test target it leave it to users who edit the bsdgen code to run manually when appropriate?

Makefile Outdated Show resolved Hide resolved
layer/windows_baselayer.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
tools/bcdhive_generator/Dockerfile Outdated Show resolved Hide resolved
Makefile Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
testhelpers/testhelpers.go Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
Micah Young added 5 commits October 15, 2020 12:46
Required for storing images without Microsoft baselayers on WCOW daemons (i.e. buildpackages)

Adds the bcdhive_gen generator for the creation of BCD file, which uses that hivex library which has tricky run-time dependencies on darwin

- Replaces testhelper with implementation

Signed-off-by: Micah Young <[email protected]>
- Build with current go version

Signed-off-by: Micah Young <[email protected]>
Signed-off-by: Micah Young <[email protected]>
@ekcasey ekcasey merged commit 6dd3ca3 into buildpacks:main Oct 15, 2020
@micahyoung micahyoung deleted the windows-baselayer branch October 16, 2020 14:52
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.

3 participants