Go
Source code: github.com/oras-project/oras-go
Introduction
The ORAS Go client library provides the ability to replicate artifacts between different Targets.
Furthermore, the version v2
is a registry client conforming image-spec v1.1.0-rc.2 and distribution-spec v1.1.0-rc1.
Using the ORAS Go client library, you can develop your own registry client:
myclient push artifacts.example.com/myartifact:1.0 ./mything.thang
Usage
The package oras.land/oras-go/v2
can quickly be imported in other Go-based tools that
wish to benefit from the ability to store arbitrary content in container registries.
-
Get the
oras.land/oras-go/v2
packagego get oras.land/oras-go/v2
-
Import and use the
v2
packageimport "oras.land/oras-go/v2"
-
Run
go mod tidy
The API documentation and examples are available at pkg.go.dev.
Quick Start
Push files to a remote repository
package main
import (
"context"
"fmt"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content/file"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/retry"
)
func pushFiles() error {
// 0. Create a file store
fs, err := file.New("/tmp/")
if err != nil {
return err
}
defer fs.Close()
ctx := context.Background()
// 1. Add files to a file store
mediaType := "example/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 {
return 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 := "example/files"
manifestDescriptor, err := oras.Pack(ctx, fs, artifactType, fileDescriptors, oras.PackOptions{
PackImageManifest: true,
})
if err != nil {
return err
}
fmt.Println("manifest descriptor:", manifestDescriptor)
tag := "latest"
if err = fs.Tag(ctx, manifestDescriptor, tag); err != nil {
return 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.DefaultCache,
Credential: auth.StaticCredential(reg, auth.Credential{
Username: "username",
Password: "password",
}),
}
// 3. Copy from the file store to the remote repository
_, err = oras.Copy(ctx, fs, tag, repo, tag, oras.DefaultCopyOptions)
return err
}
func main() {
if err := pushFiles(); err != nil {
panic(err)
}
}
Pull files from a remote repository
package main
import (
"context"
"fmt"
"oras.land/oras-go/v2"
"oras.land/oras-go/v2/content/file"
"oras.land/oras-go/v2/registry/remote"
"oras.land/oras-go/v2/registry/remote/auth"
"oras.land/oras-go/v2/registry/remote/retry"
)
func pullFiles() error {
// 0. Create a file store
fs, err := file.New("/tmp/")
if err != nil {
return 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 {
return err
}
// Note: The below code can be omitted if authentication is not required
repo.Client = &auth.Client{
Client: retry.DefaultClient,
Cache: auth.DefaultCache,
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 {
return err
}
fmt.Println("manifest descriptor:", manifestDescriptor)
return nil
}
func main() {
if err := pullFiles(); err != nil {
panic(err)
}
}
Last update:
February 24, 2023