-
Notifications
You must be signed in to change notification settings - Fork 258
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
Is it possible to create an empty scratch layer? #853
Comments
So I've just noticed So I guess this question can be treated as a feature-request to complete this support for ltsc2019 (assuming that's feasible... I'm testing on Windows 10 2004, so it's possible I'm already using too-new features) and either expose the functionality, or make it work for |
I decided I'd have an explore myself. It looks like I'm guessing this means there's no way to actually do what I want to do here with the current API. I'm not clear if that's something that can be fixed, or perhaps there is some other path I'm overlooking for creating an empty sandbox, mount it for filesystem operations (BuildKit's use-case for dockerfiles is this much), and export it as an layer, so that more layers can be build upon it, e.g. a Dockerfile like |
Hmm. I just saw #407. That has some other likely-looking functions exposed from computestorage.dll. A lot of them look like things that already have implementations in Go, so I suspect the same limitations will apply. |
For tracking purposes, it seems that the k8s implementation of privileged containers on Windows may require or produce a "slim base image" which could be used as Or even just filling in the missing details needed to create a parentless/empty scratch layer. |
TODO: Look closely at #881 (replaced #407, but without a couple of legacywriteablelayer functions), the newly-exposed APIs there might help with this, although I suspect this might be LTSC 2019 (RS5) or newer, and per #556 (comment) LTSC 2016 (RS1) and even non-LTSC releases are still out there are potentially relevant. |
I had a quick experiment replacing
(Being an exception, this bypasses the deferred I don't see any existing uses of |
Hey @TBBle. I stumbled across your comment and I'm not sure if it's helpful but we did manage to create a WCOW https://github.com/buildpacks/imgutil/blob/main/layer/windows_baselayer.go The only complex file in there is https://github.com/buildpacks/imgutil/blob/main/tools/bcdhive_generator/bcdhive_hivex.go Both Here's an image of containing solely one of these layers, if you want to play around:
|
Oh, that's brilliant timing. I had just worked out part of this in containerd/containerd#4419 (comment) using Since I don't want to create containers from this, (it's mostly used for storage, e.g. BuildKit for build contexts, and #750 above) it seems in brief testing I can just create dummy files in Windows\System32\Config, as that's what copied to the Hives folder (as _...Base) by And having looked at all that, I realise that internal/wclayer/baselayer.go is the implementation of the code that receives the tarball you're generating in your script, and it just extracts it in-place and calls Interestingly, the parent export failed, I'm not sure if that's the missing UtilityVM data or something else. It might be that I suspect that could be added to hcsshim the way base-layer import is handled, just directly walking the three relevant directories. That would also be easy to test in hcsshim, as it should be able to round-trip a WCOW parent layer, and get the exact same thing back the second time. Edit: Missing BCD did not affect me because it looks like the UtilityVM is only used during the stream-from-tar-to-backup-and-write-to-disk stage, which I don't have when creating a new base layer from on-disk files. It might matter once I am able to export and reimport such layers. Edit for the above: After implementing #901, I realise that the reason I wasn't noticing lack of BCD was that I wasn't calling |
A quick status update: #901 is ready for final review, I think, which will give us base-layer creation for "scratch" (i.e. not bootable!) WCOW layers on RS5 (Windows Server 2019). However, Windows 20H2 (and presumably back to some earlier version after RS5) will refuse to import layers that depend on so-created base layers. That will be fixed in a follow-up PR based on @micahyoung's #853 (comment); minimal testing has been done on a hack version of this fix, see #901 (comment). |
@TBBle When you say "not bootable", what do you mean here? I'd expect a scratch image to be usable in Windows Server Container (Argon) scenarios. Is that not the case here? |
I mean "not bootable" in that it won't contain an OS so you can't use it as-is with, e.g., License restrictions means it won't be practical for anyone to provide their own OS from Windows. I guess in-theory, one could provider their own-developed OS layer that can talk to the WCOW components, but I honestly have no idea how complex that would be -- I assume "very" -- and it's probably not documented anywhere public. I'd have to check, it might also be against MS licensing to do that, but I'm not sure if they have anything that restricts what can be inside a WCOW container... So the use-cases are for data distribution, e.g. #750, and creating layer-based snapshots for attaching to containers, i.e. the way BuildKit uses Containerd's snapshotter to capture and manage the Dockerfile and image build context. |
@TBBle I have a feeling this case is not possible, having a image from scratch and then your application but using |
See the last paragraph of my previous comment for use-cases for non-bootable container images. It's definitely possible to create a container image "from scratch" and then add files to make it bootable as a WCOW container. That's actually how all containers work (there's no difference in a "base" layer structurally), it's just that the code to do so for Windows Server containers is not public, and it's probably not allowed for anyone except MS to do it under the Windows EULA. So while possible, I'd say it's not usefully feasible, and hence why I'm keeping it out-of-scope for this work. |
@TBBle Thanks for your detailed answer. I am just reading your comments everywhere seems they are the most documentation I can get on everything. Obviously a stupid question, but is it possible for example in Windows Server 2019 Host, have a minimal non-bootable image (with some of those magic, or UtilityVM) but with mapping of container's C:\Windows\System32 to host? Why that route was not taken to minimize size of Windows Server images at least on Windows Server hosts? |
Generally, container images should be as self-contained as possible, and not depend on the userspace of the host. It would be similarly unexpected if a Linux base layer worked by mapping There's not actually a way in the OCI standard for container images for a layer to rely on host files, only the end-user can do that by mapping the host filesystem into a container at run-time. |
@TBBle any progress on this by chance? Finding the need to have a @micahyoung tried using your
testempty.Dockerfile:
|
The error you're seeing from For my own status, #901 is pending some rework from me, mostly unit tests and reimplementing the "hives" feature due to silent changes in Go module tooling (and also just to be less-awful); however, I'm in the middle of moving countries so I don't expect to have any time to put into this until late October at best. After #901 is done, then the containerd side of this work can be completed, and then we can finish teaching BuildKit about native WCOW container builds. And then we can teach BuildKit to understand Right now, you could use my branch's Perhaps That said, you might find that BuildKit's cross-build support can do |
#1637 (successor for #901 mentioned earlier) has merged, so the hcsshim-side of this feature is complete, and we can now create Base layers (i.e. with no parents) from arbitrary files (including no files, although you end up with registry hives no matter what due to image format requirements) and use them as the base for further layers. To actually use this functionality outside the |
It seems that
hcsshim.CreateScratchLayer(.., someDir, "<unused>", [])
simply creates the directory, but does not set up asandbox.vhdx
or similar. I tested this with a slightly-modifiedwclayer
to make the parents list forwclayer create
optional.Is there any way to create a functional scratch layer without needing to base it on an existing image? This appears to be a blocker for #750, and the lack of it creates complications in containerd WCOW support since I cannot just treat every snapshot as a WCOW layer, but must juggle plain directories and WCOW layers with sandbox.vhdx and WCOW layers without sandbox.vhdx.
The ability to create an empty scratch layer would simplify this, by letting me use WCOW layers for all use-cases, and never needing to symlink anything, resolving an open question on containerd/containerd#2366
Also, it seems
hcsshim.CreateLayer
always seems to just create an empty directory no matter what I pass it. I assume that if it was doing anything behind-the-scenes, it would be safe to import layer data from an OCI tarball into the resulting directory.I did a quick test, and
hcsshim.CreateLayer
even with a parents list does not seem to result in something suitable for the parents list ofPrepareLayer
, so I guess you must import a tarball into that directory?The text was updated successfully, but these errors were encountered: