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

Ensure support for building base images via Dockerfile #4688

Open
cgwalters opened this issue Nov 6, 2023 · 11 comments
Open

Ensure support for building base images via Dockerfile #4688

cgwalters opened this issue Nov 6, 2023 · 11 comments

Comments

@cgwalters
Copy link
Member

It'd be nice if something like this worked:

FROM quay.io/centos-boot/builder as builder
RUN --mount=type=bind,rw=true,src=.,dst=/buildcontext,bind-propagation=shared rpm-ostree compose image --format=ociarchive --initialize manifest.yaml test.ociarchive
FROM oci-archive:/test.ociarchive

There's hints it is supposed to per https://github.com/openshift/os/blob/master/docs/rhcos-oci-braindump.md but I'm not seeing anything show up in the build context, the build fails very quickly on a nonexistent dir.

Now obviously we can break this into multiple containers per that doc, but that means the build is no longer just podman build.

@cgwalters
Copy link
Member Author

Note that rpm-ostree constructs the full OCI structure including layers on its own, that's the reason we want it to stay in control here.

@nalind
Copy link

nalind commented Nov 6, 2023

Can you be more specific about which part breaks or is a hypothetical? Is it a privilege limitation, or that the second stage is attempting to use, as its base, an archive file from an earlier stage, or something else I'm not spotting?

@cgwalters
Copy link
Member Author

or that the second stage is attempting to use, as its base, an archive file from an earlier stage

This.

@nalind
Copy link

nalind commented Nov 7, 2023

I don't think that's something the Dockerfile syntax really provides a way to express, but we treat the FROM argument loosely enough that, using RUN --mount to force the first stage to be built before the second when when it would otherwise be skipped or not necessarily be built in the desired order, you could get most of the way there:

ARG BUILDCONTEXT=.
FROM quay.io/centos-boot/builder as builder
RUN --mount=type=bind,rw=true,src=.,dst=/buildcontext,bind-propagation=shared rpm-ostree compose image --format=ociarchive --initialize manifest.yaml /buildcontext/test.ociarchive
FROM oci-archive:${BUILDCONTEXT}/test.ociarchive
RUN --mount=type=bind,from=builder,src=.,target=/var/tmp :

You'd have to build with --build-arg BUILDCONTEXT=... if you didn't start the build from the context directory, and I expect docker build would reject it, but it appears to succeed with the podman and buildah we have now.

@jlebon
Copy link
Member

jlebon commented Nov 7, 2023

This is super interesting and has ramifications beyond wrapping rpm-ostree base image building. It means we could provide alternative ways to build container images while still being compatible with the builders out there that support this by using a Dockerfile stub behind-the-scenes. So then we could have the concept of "builder images" similar in some ways to Buildpack (or OpenShift's S2I).

Would it make sense to formalize it a bit so you don't have to play tricks to force ordering or require a --build-arg? I can file a buildah RFE if so.

For direct CLI usage, we could have a UX like

podman build --builder quay.io/centos-boot/builder /my/context/dir

where it would pass the place to output the OCI archive to the builder image via a build arg.

@nalind
Copy link

nalind commented Nov 8, 2023

I think I need to stress the "off the beaten path" nature of this. Adding affordances for it would imply a certain level of encouragement, and I'm not sure we want to sign up for that when the standard advice for jobs that can't be done with a Dockerfile is to use buildah's other commands.

@cgwalters
Copy link
Member Author

@nalind Yes. However one problem this solves is basically that saying "use buildah" opens up the big question of "which buildah from where" - Dockerfile is already a language to define that.

Obviously one can encode tooling using buildah in things like Github Actions, Tekton pipelines etc. etc. But I can't podman build a Github action YAML natively. This is basically about defining ways to build base images in that way.

@cgwalters
Copy link
Member Author

So @nalind I was playing around with this again, trying to minimize your example to e.g.:

ARG BUILDCONTEXT=.
FROM quay.io/centos-bootc/bootc-image-builder:latest as builder
COPY . /src
WORKDIR /src
RUN --mount=type=bind,rw=true,src=.,dst=/buildcontext,bind-propagation=shared skopeo copy docker://quay.io/fedora/fedora:39 oci-archive:/buildcontext/dest.ociarchive
FROM oci-archive:${BUILDCONTEXT}/dest.ociarchive
RUN --mount=type=bind,from=builder,src=.,target=/var/tmp :

Trying to build that I hit:

time="2024-03-22T20:52:07Z" level=fatal msg="committing the finished image: creating tar file \"/buildcontext/dest.ociarchive\": open /buildcontext/dest.ociarchive: permission denied"
Error: building at STEP "RUN --mount=type=bind,rw=true,src=.,dst=/buildcontext,bind-propagation=shared skopeo copy docker://quay.io/fedora/fedora:39 oci-archive:/buildcontext/dest.ociarchive": while running runtime: exit status 1

And yeah, it works with podman build --security-opt label=disable. With that I get:

 podman build -t localhost/test-container -f Containerfile .                                                                                                                                   125 03/22/24 16:51:55 PM
[1/2] STEP 1/4: FROM quay.io/centos-bootc/bootc-image-builder:latest AS builder
[1/2] STEP 2/4: COPY . /src
--> Using cache 9e814a42078b662af51fcaa3a23fc86d3f5a1dae346331e18ebdc9eb88bd747a
--> 9e814a42078b
[1/2] STEP 3/4: WORKDIR /src
--> Using cache 9ac9b60aca5dbc01fb7956226a821dd7b4372071e119097ba19201aef846a584
--> 9ac9b60aca5d
[1/2] STEP 4/4: RUN --mount=type=bind,rw=true,src=.,dst=/buildcontext,bind-propagation=shared skopeo copy docker://quay.io/fedora/fedora:39 oci-archive:/buildcontext/dest.ociarchive
--> Using cache 6342d0ee63592dfbd26e840b10c9d5da5d4d45faffad033fac0f2effb49fbc17
--> 6342d0ee6359
[2/2] STEP 1/2: FROM oci-archive:./dest.ociarchive
Error: creating build container: creating temp directory: archive file not found: "/dest.ociarchive"

So there must be some magic missing.

cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 23, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  At a high level, the build process
outputs a "nested container" - a container image with a
`/nested.ociarchive` at the top level.

Higher level build processes need not be aware of exactly
how that `.ociarchive` is constructed (as it will definitely
change in the future).

In an ideal world of course we wouldn't need this "wrapped image"
as it runs the ergonomics.  See discussion in e.g.
coreos/rpm-ostree#4688
for that.

Signed-off-by: Colin Walters <[email protected]>
cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 23, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  At a high level, the build process
outputs a "nested container" - a container image with a
`/nested.ociarchive` at the top level.

Higher level build processes need not be aware of exactly
how that `.ociarchive` is constructed (as it will definitely
change in the future).

In an ideal world of course we wouldn't need this "wrapped image"
as it runs the ergonomics.  See discussion in e.g.
coreos/rpm-ostree#4688
for that.

Signed-off-by: Colin Walters <[email protected]>
cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 23, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  At a high level, the build process
outputs a "nested container" - a container image with a
`/nested.ociarchive` at the top level.

Higher level build processes need not be aware of exactly
how that `.ociarchive` is constructed (as it will definitely
change in the future).

In an ideal world of course we wouldn't need this "wrapped image"
as it runs the ergonomics.  See discussion in e.g.
coreos/rpm-ostree#4688
for that.

Signed-off-by: Colin Walters <[email protected]>
cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 24, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  At a high level, the build process
outputs a "nested container" - a container image with a
`/nested.ociarchive` at the top level.

Higher level build processes need not be aware of exactly
how that `.ociarchive` is constructed (as it will definitely
change in the future).

In an ideal world of course we wouldn't need this "wrapped image"
as it runs the ergonomics.  See discussion in e.g.
coreos/rpm-ostree#4688
for that.

Signed-off-by: Colin Walters <[email protected]>
cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 24, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  At a high level, the build process
outputs a "nested container" - a container image with a
`/nested.ociarchive` at the top level.

Higher level build processes need not be aware of exactly
how that `.ociarchive` is constructed (as it will definitely
change in the future).

In an ideal world of course we wouldn't need this "wrapped image"
as it runs the ergonomics.  See discussion in e.g.
coreos/rpm-ostree#4688
for that.

Signed-off-by: Colin Walters <[email protected]>
cgwalters added a commit to cgwalters/centos-bootc that referenced this issue Mar 25, 2024
This is a small but notable step towards making the build
process more container native.  The rpm-ostree bits
are hidden much more.  We use a special trick
specific to podman/buildah to do `FROM oci-archive`
on an oci-archive that was built in a previous image
stage.

This lets us do things not possible in a Containerfile
that is basically about total control over the image
layers:

 - Output content-addressed reproducible "chunked" layers
 - Choose whether or not to use zstd for layers

See discussion in e.g.
coreos/rpm-ostree#4688

Signed-off-by: Colin Walters <[email protected]>
@nalind
Copy link

nalind commented Mar 25, 2024

So there must be some magic missing.

A z or Z option for the --mount flag. I have no idea why it's documented for the equivalent CLI flag for buildah run but not for the file.

@cgwalters
Copy link
Member Author

Hmm, actually the problem seems to be that this flow doesn't work with podman-remote (which isn't surprising I guess given the subtleties). I was trying those original commands on MacOS.

OK so...as you say, it seems like this support is not really documented really other than implicitly/indirectly via this statement in the buildah changelog:

  • The buildah from command now supports pulling images using the following three transports: docker-archive, oci-archive, and dir, as well as normal container registries and the docker daemon.

I'm not finding many tests for it either. So...I guess we're looping back to

Adding affordances for it would imply a certain level of encouragement, and I'm not sure we want to sign up for that when the standard advice for jobs that can't be done with a Dockerfile is to use buildah's other commands.

But the problem is there's just so much code that expects, processes, and operates on Containerfile. Would you be OK with patches adding some docs and tests for this and hence committing to supporting it?

@nalind
Copy link

nalind commented Mar 26, 2024

But the problem is there's just so much code that expects, processes, and operates on Containerfile. Would you be OK with patches adding some docs and tests for this and hence committing to supporting it?

That'd ensure that breaking those use cases would be intentional rather than accidental, which I'm on board with. Keep in mind that I don't expect other tools that accept Dockerfiles to support this sort of thing -- we get it for relatively little work by having containers/image do most of the heavy lifting.

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

No branches or pull requests

3 participants