Description
Summary
Adopt the ORAS project located at deislabs/oras.
Overview
ORAS is a CLI that can publish arbitrary content to an OCI registry, with special features for setting mediatypes on manifest configs and on content.
Note: the manifest mediatype itself is always application/vnd.oci.image.manifest.v1+json
.
Example - uploading rockets, a brand new type of package:
# Create a thing
printf '🚀' > rocket.txt
# Create a manifest config
printf '{"RocketVersion":"v0.1.0"}' > rocket-config.json
# Upload your thing with a custom mediatype
oras push localhost:5000/mystuff/myrocket:v0.1.0 rocket.txt:text/plain \
--manifest-config rocket-config.json:application/vnd.acme.rocket.config.v1+json
See manifest created:
$ curl -s -H 'Accept: application/vnd.oci.image.manifest.v1+json' \
http://localhost:5000/v2/mystuff/myrocket/manifests/v0.1.0 | jq
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.acme.rocket.config.v1+json",
"digest": "sha256:310175f34d2d4d5cba3418be06ddd1ef948147d729516d78318ec7f5c2d83d49",
"size": 26
},
"layers": [
{
"mediaType": "text/plain",
"digest": "sha256:ebbc0b2870eb323f2b6cffa5c493ceef81ae7eb36afc73d4e0367301631daec5",
"size": 4,
"annotations": {
"org.opencontainers.image.title": "rocket.txt"
}
}
]
}
Get that thing:
$ curl -s http://localhost:5000/v2/mystuff/myrocket/blobs/sha256:ebbc0b2870eb323f2b6cffa5c493ceef81ae7eb36afc73d4e0367301631daec5
🚀
Additional Usage
ORAS is built primarily on top of Go packages provided by containerd, but it also imports packages from the docker/cli, which enables "docker-style" auth login:
oras login -u username -p password localhost:5000 -c rocket-creds.json
There are also public Go packages available to build on top of ORAS. The following is the equivalent of the rocket example with the CLI above, but in Go:
package main
import (
"context"
"fmt"
"github.com/containerd/containerd/remotes/docker"
"github.com/deislabs/oras/pkg/content"
"github.com/deislabs/oras/pkg/oras"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
func main() {
ctx := context.Background()
resolver := docker.NewResolver(docker.ResolverOptions{})
store := content.NewMemoryStore()
registryRootURL := "localhost:5000"
registryNamespace := "mystuff/myrocket"
rocketVersion := "v0.1.0"
rocketFileName := "rocket.txt"
rocketMediaType := "text/plain"
rocketContent := []byte("🚀")
rocketDescriptor := store.Add(rocketFileName, rocketMediaType, rocketContent)
rocketConfigMediaType := "application/vnd.acme.rocket.config.v1+json"
rocketConfigContent := []byte(fmt.Sprintf("{\"RocketVersion\":\"%s\"}", rocketVersion))
rocketConfigDescriptor := store.Add("", rocketConfigMediaType, rocketConfigContent)
ref := fmt.Sprintf("%s/%s:%s", registryRootURL, registryNamespace, rocketVersion)
_, err := oras.Push(ctx, resolver, ref, store, []ocispec.Descriptor{rocketDescriptor},
oras.WithConfig(rocketConfigDescriptor))
if err != nil {
panic(err)
}
fmt.Println("Pushed to", ref)
fmt.Printf("\nTry:\n\ncurl -s -H 'Accept: application/vnd.oci.image.manifest.v1+json' \\\n" +
" %s/v2/%s/manifests/%s | jq\n", registryRootURL, registryNamespace, rocketVersion)
}
You can see all features in the project README.
Adoption
The following projects are already successfully using ORAS to work with custom artifacts:
Why move it into opencontainers?
For a few reasons:
- Provide end users a method to publish and retrieve any type of content to/from an OCI registry
- Provide a reference implementation for the in-progress artifacts spec
- Expand awareness of the project to a broader audience
- Encourage more community contributions