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

support for oras-like sugar #5091

Open
cgwalters opened this issue Oct 16, 2023 · 21 comments
Open

support for oras-like sugar #5091

cgwalters opened this issue Oct 16, 2023 · 21 comments
Labels
kind/feature Categorizes issue or PR as related to a new feature.

Comments

@cgwalters
Copy link

As far as I can tell, generally the core skopeo copy workflow is functional when using OCI artifacts. However, operating on artifacts is clunky; the most ergonomic way is to fetch into an oci directory and then parse the content (and if you just wanted the data, delete the temporary oci dir). For uploads it requires e.g. creating content in a local oci directory e.g. and then pushing to a registry.

The ORAS project has much nicer higher level sugar; especially things like oras push:

oras push --artifact-type application/vnd.me.config localhost:5000/hello:v1 hi.txt

is quite nice.

WDYT about adding some commands like this to skopeo?

@cgwalters cgwalters added the kind/feature Categorizes issue or PR as related to a new feature. label Oct 16, 2023
@vrothberg
Copy link
Member

Just came out of a call with @baude working in this area. In general, I think it would be great to provide means to create OCI artifacts more easily.

I am under the impression that you're looking more into creating artifacts (since copying them is already supported by Skopeo). In that case, I think that Buildah is probably a better home for that functionality. Or even extending umoci?

@vrothberg
Copy link
Member

@nalind is also looking into SBOMs and artifacts at the moment AFAIR.

@cgwalters
Copy link
Author

In that case, I think that Buildah is probably a better home for that functionality. Or even extending umoci?

Not opposed to buildah for this functionality; feels like it can go either way? In theory skopeo is more about inspection/copying, but OTOH this desired functionality is very close to "copying" too. There's no "containerization" involved here (namespaces, cgroups, overlayfs, etc etc.), it's just wrapping files in JSON.

Restating the above, one dividing line here is that IMO at a technical level this does not involve containers/storage and eventually I think it could make sense to drop the vendored copy of containers/storage out of skopeo and have it defer to the installed buildah/podman binary for that.

As far as umoci, today it's not shipped in RHEL and I'd definitely like something that is for this.

@mtrmac
Copy link
Contributor

mtrmac commented Oct 16, 2023

For me, the primary boundary is: Skopeo should not be in the business of editing blob contents. That’s clearly what Buildah is, for container layers.
Secondarily, I’d be wary of any kind of concept of “staging/WIP” and edit commands, even with whole blobs; that suggests that some kind of artifact-type-specific tool would be a better fit, possibly calling c/image to do the registry operations.

In that sense, a “push an artifact with these raw blobs” (creating just a manifest) is close but probably on the “reasonable to include” side. (It’s not that easy as the example shows… At least every blob needs a MIME type specified.)

Apart from skopeo sync, Skopeo is a very simple/dumb wrapper around c/image, with little UI design and quite little required maintenance. And, past experience is skopeo sync is, sadly, not getting the attention it probably deserves. There’s the chicken-and-egg problem of a very small project with little attention required vs. a very small project with little spare capacity available. Solvable, of course, but needs to be considered as something to solve if the feature set were to grow significantly, beyond that one example (which would be an one-off thing, and certainly manageable).

Now, Buildah is designed around c/storage and storing data in layers there; storing other arbitrary large blobs in c/storage is possible but I’m not sure it’s wanted; there’s not that much obvious benefit and the locking required by c/storage might mean that dealing with large artifacts could slow down otherwise unrelated pulls/pushes/container starts in the same store. So I can vaguely imagine that Buildah, as it exists right now, might not actually be the best answer either, and maybe Skopeo could be the place.


eventually I think it could make sense to drop the vendored copy of containers/storage out of skopeo

c/storage in Skopeo is one of those things that is useless and inconvenient 99% of the time (notably its dependencies are one of the stronger reasons we can’t provide a single static Skopeo binary that runs on all distributions, something a class of users wants) — and then very useful in rare support cases.

My wish is that every single caller of alltransports.ParseImageName accepts the same transports with the same syntax, with docker:// and dir: and …. and, yes, containers-storage:. (In many cases, the right call is not to call alltransports.ParseImageName in the first place!). In that sense, it Would Look Bad™️ if Skopeo, the poster child of c/image, did not do that. Now, of course, that “wish” is an architecture astronaut thing with not that much relevance to end users.

@cgwalters
Copy link
Author

In that sense, a “push an artifact with these raw blobs” (creating just a manifest) is close but probably on the “reasonable to include” side. (It’s not that easy as the example shows… At least every blob needs a MIME type specified.)

Right, that was my sense too.

Syntax

I guess regardless of whether it goes in skopeo or buildah (mostly) - any opinions on syntax?
I think my bikeshed here would be:

Pushing

skopeo ociartifact push (--export-manifest manifest.json) [IMAGE] [FILENAME]:[MIMETYPE]...
e.g.:

skopeo ociartifact push quay.io/example/configmap:latest foo.json:application/vnd.containers.configmap+json bar.json:application/vnd.containers.configmap+json

and
skopeo ociartifact push quay.io/example/diskimage:latest fedora-coreos.qcow2:application/vnd.coreos.disk+qcow2

Unlike oras we make the mime type required, because skopeo already has commands for pushing OCI images.

Pulling

skopeo copy quay.io/example/configmap:latest oci:myartifact

No new command! This already exists and works.

skopeo ociartifact extract quay.io/example/configmap:latest foo.json

This will write the contents of foo.json to stdout. Handy for streaming to other tools, etc.

skopeo ociartifact extract --single quay.io/example/configmap:latest

Assuming that there is only one referenced blob, extract it to stdout.

Both of these commands would take --export-manifest to also save the manifest (e.g. one may want version metadata e.g.)

Now, Buildah is designed around c/storage and storing data in layers there; storing other arbitrary large blobs in c/storage is possible but I’m not sure it’s wanted;

It's definitely unwanted; use cases here include e.g. storing .qcow2 images directly as an artifact in a registry, and we want to go directly from .qcow-in-filesystem to registry, not indirect through c/storage. That said, just because something is in buildah doesn't mean that it has to indirect through c/storage of course.

@mtrmac
Copy link
Contributor

mtrmac commented Oct 16, 2023

I guess regardless of whether it goes in skopeo or buildah (mostly) - any opinions on syntax?

  • Separate CLI arguments for MIME type and file paths, please. We already painted ourselves into that corner with oci-archive:path:tag making it impossible to podman load archive-path:with-colon.tar.
  • I think the destination should be a transport:name, not registry-specific. (I don’t quite feel strongly enough to call it a blocker, but it’s close.)
  • The OCI image format actually strongly differentiates between config (almost, but not quite, mandatory) and layers. It would probably be convenient to make “the first” argument the config, and the rest layers, I just want to be an intentional decision.

Maybe something like

skopeo oci-artifact push docker://quay.io/… {-c|--config-mime-type}application/foo.metadata foo.json{-m|--mime-type}application/foo.data blob1.bin[{-m|--mime-type} application/foo.extra] blob2.bin

with -m mandatory before the first blob but optional for the following ones (continuing to use the previous value)?

  • The extract part might not be necessary (inspect --config --raw), or alternatively needs some more mechanisms for dealing with config vs. one of the potentially many layers.
  • Unsure: I’m not sure that --export-manifest is necessary as such; what is the consumer going to do with the raw bytes? skopeo copy has --digestfile, is that roughly the idea?

@mtrmac
Copy link
Contributor

mtrmac commented Oct 16, 2023

Also Cc: @flouthoc @nalind — I’m not sure whether these or similar, conversations, have been happening elsewhere as well.

@cgwalters
Copy link
Author

We already painted ourselves into that corner with oci-archive:path:tag making it impossible to podman load archive-path:with-colon.tar.

Yeah, true. Agree it's unclean. Has it been a problem in practice though?

Maybe something like

My main concern with this is that usually arguments aren't positionally sensitive, it should be equivalent to specify them as FLAGS ARGS where FLAGS are things that start with - and ARGS don't (except for a flag that binds to an argument of course).

Dunno. Probably not a big deal.

Hmm, I think a , can't appear in a media type (since it's in tspecials here right?), so another alternative is to reverse things and do skopeo oci-artifact push [IMAGE] [MEDIATYPE],[FILE]

skopeo oci-artifact push quay.io/example/diskimage:latest application/vnd.coreos.disk+qcow2,fedora-coreos.qcow2

hmm, in the general case we may want support for accepting separate local filenames and remote org.opencontainers.image.title names...messy. I don't think oras supports this.

I'm OK with having separate arguments; visually noisier but in the end I expect most usage of this is from scripts or at worst humans copy/pasting instructions.

(Also the use cases I primarily care about have exactly one layer, in which case the argument ordering doesn't matter)

Unsure: I’m not sure that --export-manifest is necessary as such; what is the consumer going to do with the raw bytes? skopeo copy has --digestfile, is that roughly the idea?

Key metadata in the manifest: version aka org.opencontainers.image.version, timestamp aka org.opencontainers.image.created - plus digest of the whole manifest.

@mtrmac
Copy link
Contributor

mtrmac commented Oct 17, 2023

We already painted ourselves into that corner with oci-archive:path:tag making it impossible to podman load archive-path:with-colon.tar.

Yeah, true. Agree it's unclean. Has it been a problem in practice though?

containers/podman#489 (internal) containers/podman#18673 (external reporter), at least.

My main concern with this is that usually arguments aren't positionally sensitive, it should be equivalent to specify them as FLAGS ARGS

Yes. I don’t know that there is another trivial ergonomic solution… eventually we might end up accepting a JSON input, which clearly works but also takes a lot of pleasure out of using the tool. …

Hmm, I think a , can't appear in a media type (since it's in tspecials here right?), so another alternative is to reverse things and do skopeo oci-artifact push [IMAGE] [MEDIATYPE],[FILE]

… oh, look a non-trivial solution :) That looks promising. The trivial version would require specifying the MIME type on every argument, but special-casing ,file or something like that would work, even if inelegantly.


hmm, in the general case we may want support for accepting separate local filenames and remote org.opencontainers.image.title names...messy. I don't think oras supports this.

I’m not sure what you mean. Should this create a side image using the OCI referrers mechanism? (That, to me feels like a separate subcommand, and anyway c/image can’t currently do that.) Or is it just an annotation string?


Unsure: I’m not sure that --export-manifest is necessary as such; what is the consumer going to do with the raw bytes? skopeo copy has --digestfile, is that roughly the idea?

Key metadata in the manifest: version aka org.opencontainers.image.version, timestamp aka org.opencontainers.image.created - plus digest of the whole manifest.

At least for …image.version, that seems backwards to me: When creating the artifact, Skopeo itself has no idea what the value should be, it would have to come from the caller as an option.

I feel very weakly about .created — it could, plausibly, be automatically set, but for symmetry that might be an incoming option as well. Or just let the caller set arbitrary annotations [… on which of the many fields? All of them?] and be done with it.

@vrothberg
Copy link
Member

Buildah has already a hidden set of commands (see buildah source) to create a "source image" OCI artifact. I don't think we'll need that anymore but there is a precedent in Buildah that shows how artifacts can be build. It doesn't use c/storage at all for that but operates exclusively with the docker: and oci: transport. I am sure we can generalize that code fairly easily into a generic artifact building tool. I am sure @baude and @rhatdan will be supportive of such efforts - the timing seems right.

But I'd prefer to move the details of the design into a separate design doc/proposal/pr. May that be an .md or a Google Doc or something else - but something that allows for an easy iterative review.

@rhatdan
Copy link
Member

rhatdan commented Oct 17, 2023

That makes sense to me, I don't see us having to lock everything into containers/storage for buildah. Creating and assembling manifests and pushing them to a container/registry seems like a legitimate use case.

@cgwalters
Copy link
Author

That makes sense to me,

That = carrying this in buildah or carrying it in skopeo?

When creating the artifact, Skopeo itself has no idea what the value should be, it would have to come from the caller as an option. ... . Or just let the caller set arbitrary annotations

Yes, oras has -a, --annotation stringArray, so a full invocation might look like e.g.:
skopeo oci-artifact push -a 'org.opencontainers.image.version=38.20231011.7' quay.io/example/diskimage:latest application/vnd.coreos.disk+qcow2,fedora-coreos.qcow2

I feel very weakly about .created — it could, plausibly, be automatically set,

oras does this by default; I think it makes sense, but clearly needs to be overridable too.

@rhatdan
Copy link
Member

rhatdan commented Oct 17, 2023

buildah support.

I think skopeo might changing what the tool does.

@cgwalters cgwalters transferred this issue from containers/skopeo Oct 18, 2023
@cgwalters
Copy link
Author

(transferred this issue to buildah)

@flouthoc
Copy link
Collaborator

FWIW ( not directly related ) better support to push OCI artifacts is also needed so its easier to ship WASM modules ( for which podman is currently using scratch based OCI images ) if it becomes easier to work with artifacts, I think podman should switch to artifacts to ship wasm modules as well like other tools in the ecosystem.

Copy link

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

@cgwalters
Copy link
Author

xref CentOS/centos-bootc-layered#21 (comment)

One thing that got slightly lost here is that even if we choose buildah to build, we still probably want skopeo and podman to support fetching.

@rhatdan
Copy link
Member

rhatdan commented Dec 22, 2023

Not sure podman has any better support for fetching the buildah pull, but definitely better for running containers.

@arewm
Copy link

arewm commented Apr 2, 2024

I ran across buildah source recently but functionality isn't there for me to be able to depend on it for my use cases (i.e. #5399). I wanted to change from our current default of oras, but regctl also looked like it had a nice interface.

@flouthoc
Copy link
Collaborator

flouthoc commented Apr 2, 2024

I ran across buildah source recently but functionality isn't there for me to be able to depend on it for my use cases (i.e. #5399). I wanted to change from our current default of oras, but regctl also looked like it had a nice interface.

@arewm Created a PR for this: #5454

@cgwalters
Copy link
Author

I recently came across https://github.com/carvel-dev/imgpkg - definitely related and interesting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

No branches or pull requests

6 participants