Documentation
¶
Overview ¶
Example (AttachBlobToRemoteRepository) ¶
ExampleAttachBlobToRemoteRepository gives an example of attaching a blob to an existing artifact in a remote repository. The blob is packed as a manifest whose subject is the existing artifact.
package main
import (
"context"
"fmt"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
oras "github.com/oras-project/oras-go/v3"
"github.com/oras-project/oras-go/v3/registry/remote"
"github.com/oras-project/oras-go/v3/registry/remote/auth"
"github.com/oras-project/oras-go/v3/registry/remote/retry"
)
func main() {
// 0. Connect to a remote repository with basic authentication
registry := "myregistry.example.com"
repository := "myrepo"
repo, err := remote.NewRepository(fmt.Sprintf("%s/%s", registry, repository))
if err != nil {
panic(err)
}
// Note: The below code can be omitted if authentication is not required.
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: auth.StaticCredential(registry, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 1. Resolve the subject descriptor
ctx := context.Background()
subjectDescriptor, err := repo.Resolve(ctx, "sha256:f3a0356fe9f82b925c2f15106d3932252f36c1c56fd35be6c369d274f433d177")
if err != nil {
panic(err)
}
// 2. Prepare the blob to be attached
blob := []byte("example blob")
// 3. Push the blob to the repository
blobDescriptor, err := oras.PushBytes(ctx, repo, v1.MediaTypeImageLayer, blob)
if err != nil {
panic(err)
}
fmt.Println("pushed the blob to the repository")
// 4. Pack the blob as a manifest with version v1.1 and push it to the repository
packOpts := oras.PackManifestOptions{
Layers: []v1.Descriptor{blobDescriptor},
Subject: &subjectDescriptor,
}
artifactType := "application/vnd.example+type"
referrerDescriptor, err := oras.PackManifest(ctx, repo, oras.PackManifestVersion1_1, artifactType, packOpts)
if err != nil {
panic(err)
}
fmt.Printf("attached %s to %s\n", referrerDescriptor.Digest, subjectDescriptor.Digest)
}
Example (CopyArtifactFromRepository) ¶
ExampleCopyArtifactFromRepository gives an example of copying an artifact from a remote repository into memory.
// 0. Connect to a remote repository
repositoryName := "source"
src, err := remote.NewRepository(fmt.Sprintf("%s/%s", remoteHost, repositoryName))
if err != nil {
panic(err)
}
// 1. Create a memory store
dst := memory.New()
ctx := context.Background()
// 2. Resolve the descriptor of the artifact from the digest
exampleDigest := "sha256:70c29a81e235dda5c2cebb8ec06eafd3cca346cbd91f15ac74cefd98681c5b3d"
descriptor, err := src.Resolve(ctx, exampleDigest)
if err != nil {
panic(err)
}
// 3. Copy the artifact from the remote repository
err = oras.CopyGraph(ctx, src, dst, descriptor, oras.DefaultCopyGraphOptions)
if err != nil {
panic(err)
}
// 4. Verify that the artifact manifest described by the descriptor exists in dst
contentExists, err := dst.Exists(ctx, descriptor)
if err != nil {
panic(err)
}
fmt.Println(contentExists)
Output: true
Example (ExtendedCopyArtifactAndReferrersFromRepository) ¶
ExampleExtendedCopyArtifactAndReferrersFromRepository gives an example of copying an artifact along with its referrers from a remote repository into memory.
// 0. Connect to a remote repository
repositoryName := "source"
src, err := remote.NewRepository(fmt.Sprintf("%s/%s", remoteHost, repositoryName))
if err != nil {
panic(err)
}
// 1. Create a memory store
dst := memory.New()
ctx := context.Background()
// 2. Copy the artifact and its referrers from the remote repository
tagName := "latest"
// ExtendedCopy will copy the artifact tagged by "latest" along with all of its
// referrers from src to dst.
desc, err := oras.ExtendedCopy(ctx, src, tagName, dst, tagName, oras.DefaultExtendedCopyOptions)
if err != nil {
panic(err)
}
fmt.Println(desc.Digest)
Output: sha256:f396bc4d300934a39ca28ab0d5ac8a3573336d7d63c654d783a68cd1e2057662
Example (ExtendedCopyArtifactAndReferrersToRepository) ¶
ExampleExtendedCopyArtifactAndReferrersToRepository is an example of pushing an artifact and its referrer to a remote repository.
// 0. Assemble the referenced manifest in memory with tag "v1"
ctx := context.Background()
src := memory.New()
manifestDescriptor, err := oras.PackManifest(ctx, src, oras.PackManifestVersion1_1, "application/vnd.example+type", oras.PackManifestOptions{})
if err != nil {
panic(err)
}
fmt.Println("created manifest: ", manifestDescriptor)
tag := "v1"
err = src.Tag(ctx, manifestDescriptor, tag)
if err != nil {
panic(err)
}
fmt.Println("tagged manifest: ", manifestDescriptor.Digest)
// 1. Assemble the referrer manifest in memory
referrerPackOpts := oras.PackManifestOptions{
Subject: &manifestDescriptor,
}
referrerDescriptor, err := oras.PackManifest(ctx, src, oras.PackManifestVersion1_1, "sbom/example", referrerPackOpts)
if err != nil {
panic(err)
}
fmt.Println("created referrer: ", referrerDescriptor)
// 2. Connect to a remote repository with basic authentication
registry := "myregistry.example.com"
repository := "myrepo"
repo, err := remote.NewRepository(fmt.Sprintf("%s/%s", registry, repository))
if err != nil {
panic(err)
}
// Note: The below code can be omitted if authentication is not required.
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: auth.StaticCredential(registry, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 3. Push the manifest and its referrer to the remote repository
desc, err := oras.ExtendedCopy(ctx, src, tag, repo, "", oras.DefaultExtendedCopyOptions)
if err != nil {
panic(err)
}
fmt.Println("pushed: ", desc.Digest)
Example (PullFilesFromRemoteRepository) ¶
ExamplePullFilesFromRemoteRepository gives an example of pulling files from a remote repository to the local file system.
package main
import (
"context"
"fmt"
oras "github.com/oras-project/oras-go/v3"
"github.com/oras-project/oras-go/v3/content/file"
"github.com/oras-project/oras-go/v3/registry/remote"
"github.com/oras-project/oras-go/v3/registry/remote/auth"
"github.com/oras-project/oras-go/v3/registry/remote/retry"
)
func main() {
// 0. Create a file store
fs, err := file.New("/tmp/")
if err != nil {
panic(err)
}
defer fs.Close()
// 1. Connect to a remote repository
ctx := context.Background()
reg := "myregistry.example.com"
repo, err := remote.NewRepository(reg + "/myrepo")
if err != nil {
panic(err)
}
// Note: The below code can be omitted if authentication is not required
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: auth.StaticCredential(reg, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 2. Copy from the remote repository to the file store
tag := "latest"
manifestDescriptor, err := oras.Copy(ctx, repo, tag, fs, tag, oras.DefaultCopyOptions)
if err != nil {
panic(err)
}
fmt.Println("manifest descriptor:", manifestDescriptor)
}
Example (PullImageFromRemoteRepository) ¶
ExamplePullImageFromRemoteRepository gives an example of pulling an image from a remote repository to an OCI Image layout folder.
package main
import (
"context"
"fmt"
oras "github.com/oras-project/oras-go/v3"
"github.com/oras-project/oras-go/v3/content/oci"
"github.com/oras-project/oras-go/v3/registry/remote"
"github.com/oras-project/oras-go/v3/registry/remote/auth"
"github.com/oras-project/oras-go/v3/registry/remote/retry"
)
func main() {
// 0. Create an OCI layout store
store, err := oci.New("/tmp/oci-layout-root")
if err != nil {
panic(err)
}
// 1. Connect to a remote repository
ctx := context.Background()
reg := "myregistry.example.com"
repo, err := remote.NewRepository(reg + "/myrepo")
if err != nil {
panic(err)
}
// Note: The below code can be omitted if authentication is not required
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: auth.StaticCredential(reg, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 2. Copy from the remote repository to the OCI layout store
tag := "latest"
manifestDescriptor, err := oras.Copy(ctx, repo, tag, store, tag, oras.DefaultCopyOptions)
if err != nil {
panic(err)
}
fmt.Println("manifest descriptor:", manifestDescriptor)
}
Example (PullImageUsingDockerCredentials) ¶
ExamplePullImageUsingDockerCredentials gives an example of pulling an image from a remote repository to an OCI Image layout folder using Docker credentials.
package main
import (
"context"
"fmt"
oras "github.com/oras-project/oras-go/v3"
"github.com/oras-project/oras-go/v3/content/oci"
"github.com/oras-project/oras-go/v3/registry/remote"
"github.com/oras-project/oras-go/v3/registry/remote/auth"
"github.com/oras-project/oras-go/v3/registry/remote/credentials"
"github.com/oras-project/oras-go/v3/registry/remote/retry"
)
func main() {
// 0. Create an OCI layout store
store, err := oci.New("/tmp/oci-layout-root")
if err != nil {
panic(err)
}
// 1. Connect to a remote repository
ctx := context.Background()
reg := "docker.io"
repo, err := remote.NewRepository(reg + "/user/my-repo")
if err != nil {
panic(err)
}
// prepare authentication using Docker credentials
storeOpts := credentials.StoreOptions{}
credStore, err := credentials.NewStoreFromDocker(storeOpts)
if err != nil {
panic(err)
}
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: credentials.Credential(credStore), // Use the credentials store
}
// 2. Copy from the remote repository to the OCI layout store
tag := "latest"
manifestDescriptor, err := oras.Copy(ctx, repo, tag, store, tag, oras.DefaultCopyOptions)
if err != nil {
panic(err)
}
fmt.Println("manifest pulled:", manifestDescriptor.Digest, manifestDescriptor.MediaType)
}
Example (PushFilesToRemoteRepository) ¶
ExamplePushFilesToRemoteRepository gives an example of pushing local files to a remote repository.
package main
import (
"context"
"fmt"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
oras "github.com/oras-project/oras-go/v3"
"github.com/oras-project/oras-go/v3/content/file"
"github.com/oras-project/oras-go/v3/registry/remote"
"github.com/oras-project/oras-go/v3/registry/remote/auth"
"github.com/oras-project/oras-go/v3/registry/remote/retry"
)
func main() {
// 0. Create a file store
fs, err := file.New("/tmp/")
if err != nil {
panic(err)
}
defer fs.Close()
ctx := context.Background()
// 1. Add files to the file store
mediaType := "application/vnd.test.file"
fileNames := []string{"/tmp/myfile"}
fileDescriptors := make([]v1.Descriptor, 0, len(fileNames))
for _, name := range fileNames {
fileDescriptor, err := fs.Add(ctx, name, mediaType, "")
if err != nil {
panic(err)
}
fileDescriptors = append(fileDescriptors, fileDescriptor)
fmt.Printf("file descriptor for %s: %v\n", name, fileDescriptor)
}
// 2. Pack the files and tag the packed manifest
artifactType := "application/vnd.test.artifact"
opts := oras.PackManifestOptions{
Layers: fileDescriptors,
}
manifestDescriptor, err := oras.PackManifest(ctx, fs, oras.PackManifestVersion1_1, artifactType, opts)
if err != nil {
panic(err)
}
fmt.Println("manifest descriptor:", manifestDescriptor)
tag := "latest"
if err = fs.Tag(ctx, manifestDescriptor, tag); err != nil {
panic(err)
}
// 3. Connect to a remote repository
reg := "myregistry.example.com"
repo, err := remote.NewRepository(reg + "/myrepo")
if err != nil {
panic(err)
}
// Note: The below code can be omitted if authentication is not required
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.NewCache(),
Credential: auth.StaticCredential(reg, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 4. Copy from the file store to the remote repository
_, err = oras.Copy(ctx, fs, tag, repo, tag, oras.DefaultCopyOptions)
if err != nil {
panic(err)
}
}
Index ¶
- Constants
- Variables
- func Copy(ctx context.Context, src ReadOnlyTarget, srcRef string, dst Target, ...) (ocispec.Descriptor, error)
- func CopyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Storage, ...) error
- func ExtendedCopy(ctx context.Context, src ReadOnlyGraphTarget, srcRef string, dst Target, ...) (ocispec.Descriptor, error)
- func ExtendedCopyGraph(ctx context.Context, src content.ReadOnlyGraphStorage, dst content.Storage, ...) error
- func Fetch(ctx context.Context, target ReadOnlyTarget, reference string, ...) (ocispec.Descriptor, io.ReadCloser, error)
- func FetchBytes(ctx context.Context, target ReadOnlyTarget, reference string, ...) (ocispec.Descriptor, []byte, error)
- func Pack(ctx context.Context, pusher content.Pusher, artifactType string, ...) (ocispec.Descriptor, error)deprecated
- func PackManifest(ctx context.Context, pusher content.Pusher, ...) (ocispec.Descriptor, error)
- func PushBytes(ctx context.Context, pusher content.Pusher, mediaType string, ...) (ocispec.Descriptor, error)
- func Resolve(ctx context.Context, target ReadOnlyTarget, reference string, ...) (ocispec.Descriptor, error)
- func Tag(ctx context.Context, target Target, src, dst string) (ocispec.Descriptor, error)
- func TagBytes(ctx context.Context, target Target, mediaType string, contentBytes []byte, ...) (ocispec.Descriptor, error)
- func TagBytesN(ctx context.Context, target Target, mediaType string, contentBytes []byte, ...) (ocispec.Descriptor, error)
- func TagN(ctx context.Context, target Target, srcReference string, ...) (ocispec.Descriptor, error)
- type CopyError
- type CopyErrorOrigin
- type CopyGraphOptions
- type CopyOptions
- type ExtendedCopyGraphOptions
- type ExtendedCopyOptions
- type FetchBytesOptions
- type FetchOptions
- type GraphTarget
- type PackManifestOptions
- type PackManifestVersion
- type PackOptionsdeprecated
- type ReadOnlyGraphTarget
- type ReadOnlyTarget
- type ResolveOptions
- type TagBytesNOptions
- type TagNOptions
- type Target
Examples ¶
- Package (AttachBlobToRemoteRepository)
- Package (CopyArtifactFromRepository)
- Package (ExtendedCopyArtifactAndReferrersFromRepository)
- Package (ExtendedCopyArtifactAndReferrersToRepository)
- Package (PullFilesFromRemoteRepository)
- Package (PullImageFromRemoteRepository)
- Package (PullImageUsingDockerCredentials)
- Package (PushFilesToRemoteRepository)
- Copy (MemoryToMemory)
- Copy (MemoryToOCIStore)
- Copy (MemoryToRepository)
- Copy (RepositoryToMemory)
- Copy (RepositoryToRepository)
- Copy (RepositoryToRepositoryWithMount)
- CopyError
- PackManifest (ImageV10)
- PackManifest (ImageV11)
Constants ¶
const ( // MediaTypeUnknownConfig is the default config mediaType used // - for [Pack] when PackOptions.PackImageManifest is true and // PackOptions.ConfigDescriptor is not specified. // - for [PackManifest] when packManifestVersion is PackManifestVersion1_0 // and PackManifestOptions.ConfigDescriptor is not specified. MediaTypeUnknownConfig = "application/vnd.unknown.config.v1+json" // MediaTypeUnknownArtifact is the default artifactType used for [Pack] // when PackOptions.PackImageManifest is false and artifactType is // not specified. MediaTypeUnknownArtifact = "application/vnd.unknown.artifact.v1" )
Variables ¶
var ( // ErrInvalidDateTimeFormat is returned by [Pack] and [PackManifest] when // "org.opencontainers.artifact.created" or "org.opencontainers.image.created" // is provided, but its value is not in RFC 3339 format. // Reference: https://www.rfc-editor.org/rfc/rfc3339#section-5.6 ErrInvalidDateTimeFormat = errors.New("invalid date and time format") // ErrMissingArtifactType is returned by [PackManifest] when // packManifestVersion is PackManifestVersion1_1 and artifactType is // empty and the config media type is set to // "application/vnd.oci.empty.v1+json". ErrMissingArtifactType = errors.New("missing artifact type") )
var SkipNode = errors.New("skip node")
SkipNode signals to stop copying a node. When returned from PreCopy the blob must exist in the target. This can be used to signal that a blob has been made available in the target repository by "Mount()" or some other technique.
Functions ¶
func Copy ¶
func Copy(ctx context.Context, src ReadOnlyTarget, srcRef string, dst Target, dstRef string, opts CopyOptions) (ocispec.Descriptor, error)
Copy copies a rooted directed acyclic graph (DAG), such as an artifact, from the source Target to the destination Target.
The root node (e.g. a tagged manifest of the artifact) is identified by the source reference. The destination reference will be the same as the source reference if the destination reference is left blank.
Returns the descriptor of the root node on successful copy.
Example (MemoryToMemory) ¶
src := exampleMemoryStore
dst := memory.New()
tagName := "latest"
ctx := context.Background()
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, oras.DefaultCopyOptions)
if err != nil {
panic(err) // Handle error
}
fmt.Println(desc.Digest)
Output: sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
Example (MemoryToOCIStore) ¶
src := exampleMemoryStore
tempDir, err := os.MkdirTemp("", "oras_oci_example_*")
if err != nil {
panic(err) // Handle error
}
defer os.RemoveAll(tempDir)
dst, err := oci.New(tempDir)
if err != nil {
panic(err) // Handle error
}
tagName := "latest"
ctx := context.Background()
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, oras.DefaultCopyOptions)
if err != nil {
panic(err) // Handle error
}
fmt.Println(desc.Digest)
Output: sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
Example (MemoryToRepository) ¶
src := exampleMemoryStore
reg, err := remote.NewRegistry(remoteHost)
if err != nil {
panic(err) // Handle error
}
ctx := context.Background()
dst, err := reg.Repository(ctx, "destination")
if err != nil {
panic(err) // Handle error
}
tagName := "latest"
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, oras.DefaultCopyOptions)
if err != nil {
panic(err) // Handle error
}
fmt.Println(desc.Digest)
Output: sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
Example (RepositoryToMemory) ¶
reg, err := remote.NewRegistry(remoteHost)
if err != nil {
panic(err) // Handle error
}
ctx := context.Background()
src, err := reg.Repository(ctx, "source")
if err != nil {
panic(err) // Handle error
}
dst := memory.New()
tagName := "latest"
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, oras.DefaultCopyOptions)
if err != nil {
panic(err) // Handle error
}
fmt.Println(desc.Digest)
Output: sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
Example (RepositoryToRepository) ¶
reg, err := remote.NewRegistry(remoteHost)
if err != nil {
panic(err) // Handle error
}
ctx := context.Background()
src, err := reg.Repository(ctx, "source")
if err != nil {
panic(err) // Handle error
}
dst, err := reg.Repository(ctx, "destination")
if err != nil {
panic(err) // Handle error
}
tagName := "latest"
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, oras.DefaultCopyOptions)
if err != nil {
panic(err) // Handle error
}
fmt.Println(desc.Digest)
Output: sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
Example (RepositoryToRepositoryWithMount) ¶
reg, err := remote.NewRegistry(remoteHost)
if err != nil {
panic(err) // Handle error
}
ctx := context.Background()
src, err := reg.Repository(ctx, "source")
if err != nil {
panic(err) // Handle error
}
dst, err := reg.Repository(ctx, "destination")
if err != nil {
panic(err) // Handle error
}
tagName := "latest"
opts := oras.CopyOptions{}
// optionally be notified that a mount occurred.
opts.OnMounted = func(ctx context.Context, desc ocispec.Descriptor) error {
// log.Println("Mounted", desc.Digest)
return nil
}
// Enable cross-repository blob mounting
opts.MountFrom = func(ctx context.Context, desc ocispec.Descriptor) ([]string, error) {
// the slice of source repositories may also come from a database of known locations of blobs
return []string{"source/repository/name"}, nil
}
desc, err := oras.Copy(ctx, src, tagName, dst, tagName, opts)
if err != nil {
panic(err) // Handle error
}
fmt.Println("Final", desc.Digest)
Output: Final sha256:7cbb44b44e8ede5a89cf193db3f5f2fd019d89697e6b87e8ed2589e60649b0d1
func CopyGraph ¶
func CopyGraph(ctx context.Context, src content.ReadOnlyStorage, dst content.Storage, root ocispec.Descriptor, opts CopyGraphOptions) error
CopyGraph copies a rooted directed acyclic graph (DAG), such as an artifact, from the source CAS to the destination CAS. The root node (e.g. a manifest of the artifact) is identified by a descriptor.
func ExtendedCopy ¶
func ExtendedCopy(ctx context.Context, src ReadOnlyGraphTarget, srcRef string, dst Target, dstRef string, opts ExtendedCopyOptions) (ocispec.Descriptor, error)
ExtendedCopy copies the directed acyclic graph (DAG) that are reachable from the given tagged node from the source GraphTarget to the destination Target. In other words, it copies a tagged artifact along with its referrers or other predecessor manifests referencing it.
The tagged node (e.g. a tagged manifest of the artifact) is identified by the source reference. The destination reference will be the same as the source reference if the destination reference is left blank.
Returns the descriptor of the tagged node on successful copy.
func ExtendedCopyGraph ¶
func ExtendedCopyGraph(ctx context.Context, src content.ReadOnlyGraphStorage, dst content.Storage, node ocispec.Descriptor, opts ExtendedCopyGraphOptions) error
ExtendedCopyGraph copies the directed acyclic graph (DAG) that are reachable from the given node from the source GraphStorage to the destination Storage. In other words, it copies an artifact along with its referrers or other predecessor manifests referencing it. The node (e.g. a manifest of the artifact) is identified by a descriptor.
func Fetch ¶
func Fetch(ctx context.Context, target ReadOnlyTarget, reference string, opts FetchOptions) (ocispec.Descriptor, io.ReadCloser, error)
Fetch fetches the content identified by the reference.
func FetchBytes ¶
func FetchBytes(ctx context.Context, target ReadOnlyTarget, reference string, opts FetchBytesOptions) (ocispec.Descriptor, []byte, error)
FetchBytes fetches the content bytes identified by the reference.
func Pack
deprecated
func Pack(ctx context.Context, pusher content.Pusher, artifactType string, blobs []ocispec.Descriptor, opts PackOptions) (ocispec.Descriptor, error)
Pack packs the given blobs, generates a manifest for the pack, and pushes it to a content storage.
When opts.PackImageManifest is true, artifactType will be used as the the config descriptor mediaType of the image manifest.
If succeeded, returns a descriptor of the manifest.
Deprecated: This method is deprecated and not recommended for future use. Use PackManifest instead.
func PackManifest ¶
func PackManifest(ctx context.Context, pusher content.Pusher, packManifestVersion PackManifestVersion, artifactType string, opts PackManifestOptions) (ocispec.Descriptor, error)
PackManifest generates an OCI Image Manifest based on the given parameters and pushes the packed manifest to a content storage using pusher. The version of the manifest to be packed is determined by packManifestVersion (Recommended value: PackManifestVersion1_1).
- If packManifestVersion is PackManifestVersion1_1: artifactType MUST NOT be empty unless opts.ConfigDescriptor is specified.
- If packManifestVersion is PackManifestVersion1_0: if opts.ConfigDescriptor is nil, artifactType will be used as the config media type; if artifactType is empty, "application/vnd.unknown.config.v1+json" will be used. if opts.ConfigDescriptor is NOT nil, artifactType will be ignored.
artifactType and opts.ConfigDescriptor.MediaType MUST comply with RFC 6838.
Each time when PackManifest is called, if a time stamp is not specified, a new time stamp is generated in the manifest annotations with the key ocispec.AnnotationCreated (i.e. "org.opencontainers.image.created"). To make PackManifest reproducible, set the key ocispec.AnnotationCreated to a fixed value in opts.ManifestAnnotations. The value MUST conform to RFC 3339.
If succeeded, returns a descriptor of the packed manifest.
Example (ImageV10) ¶
ExampleImageV10 demonstrates packing an OCI Image Manifest as defined in image-spec v1.0.2.
// 0. Create a storage
store := memory.New()
// 1. Set optional parameters
opts := oras.PackManifestOptions{
ManifestAnnotations: map[string]string{
// this time stamp will be automatically generated if not specified
// use a fixed value here to make the pack result reproducible
ocispec.AnnotationCreated: "2000-01-01T00:00:00Z",
},
}
ctx := context.Background()
// 2. Pack a manifest
artifactType := "application/vnd.example+type"
manifestDesc, err := oras.PackManifest(ctx, store, oras.PackManifestVersion1_0, artifactType, opts)
if err != nil {
panic(err)
}
fmt.Println("Manifest descriptor:", manifestDesc)
// 3. Verify the packed manifest
manifestData, err := content.FetchAll(ctx, store, manifestDesc)
if err != nil {
panic(err)
}
fmt.Println("Manifest content:", string(manifestData))
Output: Manifest descriptor: {application/vnd.oci.image.manifest.v1+json sha256:da221a11559704e4971c3dcf6564303707a333c8de8cb5475fc48b0072b36c19 308 [] map[org.opencontainers.image.created:2000-01-01T00:00:00Z] [] <nil> application/vnd.example+type} Manifest content: {"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","config":{"mediaType":"application/vnd.example+type","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2},"layers":[],"annotations":{"org.opencontainers.image.created":"2000-01-01T00:00:00Z"}}
Example (ImageV11) ¶
ExampleImageV11 demonstrates packing an OCI Image Manifest as defined in image-spec v1.1.1.
// 0. Create a storage
store := memory.New()
// 1. Set optional parameters
opts := oras.PackManifestOptions{
ManifestAnnotations: map[string]string{
// this time stamp will be automatically generated if not specified
// use a fixed value here to make the pack result reproducible
ocispec.AnnotationCreated: "2000-01-01T00:00:00Z",
},
}
ctx := context.Background()
// 2. Pack a manifest
artifactType := "application/vnd.example+type"
manifestDesc, err := oras.PackManifest(ctx, store, oras.PackManifestVersion1_1, artifactType, opts)
if err != nil {
panic(err)
}
fmt.Println("Manifest descriptor:", manifestDesc)
// 3. Verify the packed manifest
manifestData, err := content.FetchAll(ctx, store, manifestDesc)
if err != nil {
panic(err)
}
fmt.Println("Manifest content:", string(manifestData))
Output: Manifest descriptor: {application/vnd.oci.image.manifest.v1+json sha256:c259a195a48d8029d75449579c81269ca6225cd5b57d36073a7de6458afdfdbd 528 [] map[org.opencontainers.image.created:2000-01-01T00:00:00Z] [] <nil> application/vnd.example+type} Manifest content: {"schemaVersion":2,"mediaType":"application/vnd.oci.image.manifest.v1+json","artifactType":"application/vnd.example+type","config":{"mediaType":"application/vnd.oci.empty.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2,"data":"e30="},"layers":[{"mediaType":"application/vnd.oci.empty.v1+json","digest":"sha256:44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a","size":2,"data":"e30="}],"annotations":{"org.opencontainers.image.created":"2000-01-01T00:00:00Z"}}
func PushBytes ¶
func PushBytes(ctx context.Context, pusher content.Pusher, mediaType string, contentBytes []byte) (ocispec.Descriptor, error)
PushBytes describes the contentBytes using the given mediaType and pushes it. If mediaType is not specified, "application/octet-stream" is used.
func Resolve ¶
func Resolve(ctx context.Context, target ReadOnlyTarget, reference string, opts ResolveOptions) (ocispec.Descriptor, error)
Resolve resolves a descriptor with provided reference from the target.
func TagBytes ¶
func TagBytes(ctx context.Context, target Target, mediaType string, contentBytes []byte, reference string) (ocispec.Descriptor, error)
TagBytes describes the contentBytes using the given mediaType, pushes it, and tag it with the given reference. If mediaType is not specified, "application/octet-stream" is used.
func TagBytesN ¶
func TagBytesN(ctx context.Context, target Target, mediaType string, contentBytes []byte, references []string, opts TagBytesNOptions) (ocispec.Descriptor, error)
TagBytesN describes the contentBytes using the given mediaType, pushes it, and tag it with the given references. If mediaType is not specified, "application/octet-stream" is used.
Types ¶
type CopyError ¶
type CopyError struct {
// Op is the operation that caused the error.
Op string
// Origin indicates the source of the error.
Origin CopyErrorOrigin
// Err is the underlying error.
Err error
}
CopyError represents an error encountered during a copy operation.
Example ¶
ExampleCopyError demonstrates how to check CopyError returned from copy operations.
src := memory.New()
dst := memory.New()
ctx := context.Background()
// Try to copy a non-existent reference, which is expected to fail
nonExistentRef := "non-existent-reference"
_, err := oras.Copy(ctx, src, nonExistentRef, dst, "", oras.DefaultCopyOptions)
if err != nil {
// Check if the error is a CopyError and print its details
var copyErr *oras.CopyError
if errors.As(err, ©Err) {
fmt.Println("copyErr.Origin:", copyErr.Origin)
fmt.Println("copyErr.Op:", copyErr.Op)
fmt.Println("copyErr.Err:", copyErr.Err)
fmt.Println("copyErr.Error():", copyErr.Error())
return
}
fmt.Println("err is not a CopyError:", err)
return
}
fmt.Println("Copy succeeded unexpectedly")
Output: copyErr.Origin: source copyErr.Op: Resolve copyErr.Err: non-existent-reference: not found copyErr.Error(): failed to perform "Resolve" on source: non-existent-reference: not found
type CopyErrorOrigin ¶
type CopyErrorOrigin int
CopyErrorOrigin defines the source of a copy error.
const ( // CopyErrorOriginSource indicates the error occurred at the source side. CopyErrorOriginSource CopyErrorOrigin = 1 // CopyErrorOriginDestination indicates the error occurred at the destination side. CopyErrorOriginDestination CopyErrorOrigin = 2 )
func (CopyErrorOrigin) String ¶
func (o CopyErrorOrigin) String() string
String returns the string representation of the CopyErrorOrigin.
type CopyGraphOptions ¶
type CopyGraphOptions struct {
// Concurrency limits the maximum number of concurrent copy tasks.
// If less than or equal to 0, a default (currently 3) is used.
Concurrency int
// MaxMetadataBytes limits the maximum size of the metadata that can be
// cached in the memory.
// If less than or equal to 0, a default (currently 4 MiB) is used.
MaxMetadataBytes int64
// PreCopy handles the current descriptor before it is copied. PreCopy can
// return a SkipNode to signal that desc should be skipped when it already
// exists in the target.
PreCopy func(ctx context.Context, desc ocispec.Descriptor) error
// PostCopy handles the current descriptor after it is copied.
PostCopy func(ctx context.Context, desc ocispec.Descriptor) error
// OnCopySkipped will be called when the sub-DAG rooted by the current node
// is skipped.
OnCopySkipped func(ctx context.Context, desc ocispec.Descriptor) error
// MountFrom returns the candidate repositories that desc may be mounted from.
// The OCI references will be tried in turn. If mounting fails on all of them,
// then it falls back to a copy.
MountFrom func(ctx context.Context, desc ocispec.Descriptor) ([]string, error)
// OnMounted will be invoked when desc is mounted.
OnMounted func(ctx context.Context, desc ocispec.Descriptor) error
// FindSuccessors finds the successors of the current node.
// fetcher provides cached access to the source storage, and is suitable
// for fetching non-leaf nodes like manifests. Since anything fetched from
// fetcher will be cached in the memory, it is recommended to use original
// source storage to fetch large blobs.
// If FindSuccessors is nil, content.Successors will be used.
FindSuccessors func(ctx context.Context, fetcher content.Fetcher, desc ocispec.Descriptor) ([]ocispec.Descriptor, error)
}
CopyGraphOptions contains parameters for oras.CopyGraph.
var DefaultCopyGraphOptions CopyGraphOptions
DefaultCopyGraphOptions provides the default CopyGraphOptions.
type CopyOptions ¶
type CopyOptions struct {
CopyGraphOptions
// MapRoot maps the resolved root node to a desired root node for copy.
// When MapRoot is provided, the descriptor resolved from the source
// reference will be passed to MapRoot, and the mapped descriptor will be
// used as the root node for copy.
MapRoot func(ctx context.Context, src content.ReadOnlyStorage, root ocispec.Descriptor) (ocispec.Descriptor, error)
}
CopyOptions contains parameters for oras.Copy.
var DefaultCopyOptions CopyOptions = CopyOptions{ CopyGraphOptions: DefaultCopyGraphOptions, }
DefaultCopyOptions provides the default CopyOptions.
func (*CopyOptions) WithTargetPlatform ¶
func (opts *CopyOptions) WithTargetPlatform(p *ocispec.Platform)
WithTargetPlatform configures opts.MapRoot to select the manifest whose platform matches the given platform. When MapRoot is provided, the platform selection will be applied on the mapped root node.
- If the given platform is nil, no platform selection will be applied.
- If the root node is a manifest, it will remain the same if platform matches, otherwise ErrNotFound will be returned.
- If the root node is a manifest list, it will be mapped to the first matching manifest if exists, otherwise ErrNotFound will be returned.
- Otherwise ErrUnsupported will be returned.
type ExtendedCopyGraphOptions ¶
type ExtendedCopyGraphOptions struct {
CopyGraphOptions
// Depth limits the maximum depth of the directed acyclic graph (DAG) that
// will be extended-copied.
// If Depth is no specified, or the specified value is less than or
// equal to 0, the depth limit will be considered as infinity.
Depth int
// FindPredecessors finds the predecessors of the current node.
// If FindPredecessors is nil, src.Predecessors will be adapted and used.
FindPredecessors func(ctx context.Context, src content.ReadOnlyGraphStorage, desc ocispec.Descriptor) ([]ocispec.Descriptor, error)
}
ExtendedCopyGraphOptions contains parameters for oras.ExtendedCopyGraph.
var DefaultExtendedCopyGraphOptions ExtendedCopyGraphOptions = ExtendedCopyGraphOptions{ CopyGraphOptions: DefaultCopyGraphOptions, }
DefaultExtendedCopyGraphOptions provides the default ExtendedCopyGraphOptions.
func (*ExtendedCopyGraphOptions) FilterAnnotation ¶
func (opts *ExtendedCopyGraphOptions) FilterAnnotation(key string, regex *regexp.Regexp)
FilterAnnotation configures opts.FindPredecessors to filter the predecessors whose annotation matches a given regex pattern.
A predecessor is kept if key is in its annotations and the annotation value matches regex. If regex is nil, predecessors whose annotations contain key will be kept, no matter of the annotation value.
For performance consideration, when using both FilterArtifactType and FilterAnnotation, it's recommended to call FilterArtifactType first.
func (*ExtendedCopyGraphOptions) FilterArtifactType ¶
func (opts *ExtendedCopyGraphOptions) FilterArtifactType(regex *regexp.Regexp)
FilterArtifactType configures opts.FindPredecessors to filter the predecessors whose artifact type matches a given regex pattern.
A predecessor is kept if its artifact type matches regex. If regex is nil, all predecessors will be kept.
For performance consideration, when using both FilterArtifactType and FilterAnnotation, it's recommended to call FilterArtifactType first.
type ExtendedCopyOptions ¶
type ExtendedCopyOptions struct {
ExtendedCopyGraphOptions
}
ExtendedCopyOptions contains parameters for oras.ExtendedCopy.
var DefaultExtendedCopyOptions ExtendedCopyOptions = ExtendedCopyOptions{ ExtendedCopyGraphOptions: DefaultExtendedCopyGraphOptions, }
DefaultExtendedCopyOptions provides the default ExtendedCopyOptions.
type FetchBytesOptions ¶
type FetchBytesOptions struct {
// FetchOptions contains parameters for fetching content.
FetchOptions
// MaxBytes limits the maximum size of the fetched content bytes.
// If less than or equal to 0, a default (currently 4 MiB) is used.
MaxBytes int64
}
FetchBytesOptions contains parameters for oras.FetchBytes.
var DefaultFetchBytesOptions FetchBytesOptions
DefaultFetchBytesOptions provides the default FetchBytesOptions.
type FetchOptions ¶
type FetchOptions struct {
// ResolveOptions contains parameters for resolving reference.
ResolveOptions
}
FetchOptions contains parameters for oras.Fetch.
var DefaultFetchOptions FetchOptions
DefaultFetchOptions provides the default FetchOptions.
type GraphTarget ¶
type GraphTarget interface {
content.GraphStorage
content.TagResolver
}
GraphTarget is a CAS with generic tags that supports direct predecessor node finding.
type PackManifestOptions ¶
type PackManifestOptions struct {
// Subject is the subject of the manifest.
// This option is only valid when PackManifestVersion is
// NOT PackManifestVersion1_0.
Subject *ocispec.Descriptor
// Layers is the layers of the manifest.
Layers []ocispec.Descriptor
// ManifestAnnotations is the annotation map of the manifest. In order to
// make [PackManifest] reproducible, set the key ocispec.AnnotationCreated
// (i.e. "org.opencontainers.image.created") to a fixed value. The value
// must conform to RFC 3339.
ManifestAnnotations map[string]string
// ConfigDescriptor is a pointer to the descriptor of the config blob.
// If not nil, ConfigAnnotations will be ignored.
ConfigDescriptor *ocispec.Descriptor
// ConfigAnnotations is the annotation map of the config descriptor.
// This option is valid only when ConfigDescriptor is nil.
ConfigAnnotations map[string]string
}
PackManifestOptions contains optional parameters for PackManifest.
type PackManifestVersion ¶
type PackManifestVersion int
PackManifestVersion represents the manifest version used for PackManifest.
const ( // PackManifestVersion1_0 represents the OCI Image Manifest defined in // image-spec v1.0.2. // Reference: https://github.com/opencontainers/image-spec/blob/v1.0.2/manifest.md PackManifestVersion1_0 PackManifestVersion = 1 // PackManifestVersion1_1_RC4 represents the OCI Image Manifest defined // in image-spec v1.1.0-rc4. // Reference: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc4/manifest.md // // Deprecated: This constant is deprecated and not recommended for future use. // Use [PackManifestVersion1_1] instead. PackManifestVersion1_1_RC4 PackManifestVersion = PackManifestVersion1_1 // PackManifestVersion1_1 represents the OCI Image Manifest defined in // image-spec v1.1.1. // Reference: https://github.com/opencontainers/image-spec/blob/v1.1.1/manifest.md PackManifestVersion1_1 PackManifestVersion = 2 )
type PackOptions
deprecated
type PackOptions struct {
// Subject is the subject of the manifest.
Subject *ocispec.Descriptor
// ManifestAnnotations is the annotation map of the manifest.
ManifestAnnotations map[string]string
// PackImageManifest controls whether to pack an OCI Image Manifest or not.
// - If true, pack an OCI Image Manifest.
// - If false, pack an OCI Artifact Manifest (deprecated).
//
// Default value: false.
PackImageManifest bool
// ConfigDescriptor is a pointer to the descriptor of the config blob.
// If not nil, artifactType will be implied by the mediaType of the
// specified ConfigDescriptor, and ConfigAnnotations will be ignored.
// This option is valid only when PackImageManifest is true.
ConfigDescriptor *ocispec.Descriptor
// ConfigAnnotations is the annotation map of the config descriptor.
// This option is valid only when PackImageManifest is true
// and ConfigDescriptor is nil.
ConfigAnnotations map[string]string
}
PackOptions contains optional parameters for Pack.
Deprecated: This type is deprecated and not recommended for future use. Use PackManifestOptions instead.
type ReadOnlyGraphTarget ¶
type ReadOnlyGraphTarget interface {
content.ReadOnlyGraphStorage
content.Resolver
}
ReadOnlyGraphTarget represents a read-only GraphTarget.
type ReadOnlyTarget ¶
type ReadOnlyTarget interface {
content.ReadOnlyStorage
content.Resolver
}
ReadOnlyTarget represents a read-only Target.
type ResolveOptions ¶
type ResolveOptions struct {
// TargetPlatform ensures the resolved content matches the target platform
// if the node is a manifest, or selects the first resolved content that
// matches the target platform if the node is a manifest list.
TargetPlatform *ocispec.Platform
// MaxMetadataBytes limits the maximum size of metadata that can be cached
// in the memory.
// If less than or equal to 0, a default (currently 4 MiB) is used.
MaxMetadataBytes int64
}
ResolveOptions contains parameters for oras.Resolve.
var DefaultResolveOptions ResolveOptions
DefaultResolveOptions provides the default ResolveOptions.
type TagBytesNOptions ¶
type TagBytesNOptions struct {
// Concurrency limits the maximum number of concurrent tag tasks.
// If less than or equal to 0, a default (currently 5) is used.
Concurrency int
}
TagBytesNOptions contains parameters for oras.TagBytesN.
var DefaultTagBytesNOptions TagBytesNOptions
DefaultTagBytesNOptions provides the default TagBytesNOptions.
type TagNOptions ¶
type TagNOptions struct {
// Concurrency limits the maximum number of concurrent tag tasks.
// If less than or equal to 0, a default (currently 5) is used.
Concurrency int
// MaxMetadataBytes limits the maximum size of metadata that can be cached
// in the memory.
// If less than or equal to 0, a default (currently 4 MiB) is used.
MaxMetadataBytes int64
}
TagNOptions contains parameters for oras.TagN.
var DefaultTagNOptions TagNOptions
DefaultTagNOptions provides the default TagNOptions.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package content provides implementations to access content stores.
|
Package content provides implementations to access content stores. |
|
file
Package file provides implementation of a content store based on file system.
|
Package file provides implementation of a content store based on file system. |
|
memory
Package memory provides implementation of a memory backed content store.
|
Package memory provides implementation of a memory backed content store. |
|
oci
Package oci provides access to an OCI content store.
|
Package oci provides access to an OCI content store. |
|
internal
|
|
|
Package registry provides high-level operations to manage registries.
|
Package registry provides high-level operations to manage registries. |
|
internal/doc
Package doc provides the constant can be used in example test files.
|
Package doc provides the constant can be used in example test files. |
|
remote
Package remote provides a client to the remote registry.
|
Package remote provides a client to the remote registry. |
|
remote/auth
Package auth provides authentication for a client to a remote registry.
|
Package auth provides authentication for a client to a remote registry. |
|
remote/credentials
Package credentials supports reading, saving, and removing credentials from Docker configuration files and external credential stores that follow the Docker credential helper protocol.
|
Package credentials supports reading, saving, and removing credentials from Docker configuration files and external credential stores that follow the Docker credential helper protocol. |
|
remote/credentials/internal/executer
Package executer is an abstraction for the docker credential helper protocol binaries.
|
Package executer is an abstraction for the docker credential helper protocol binaries. |