Skip to content

Instantly share code, notes, and snippets.

@cpuguy83 cpuguy83/pull.go
Last active Jul 12, 2019

Embed
What would you like to do?
package main
import (
"context"
"fmt"
"io/ioutil"
"os"
"github.com/containerd/containerd/content/local"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
)
func main() {
var csDir string
if len(os.Args) > 1 {
dir, err := ioutil.TempDir("", "testPull")
if err != nil {
panic(err)
}
defer func() {
e := recover()
if e == nil {
return
}
os.RemoveAll(dir)
panic(e)
}()
} else {
csDir = os.Args[1]
}
// this store is a local content addressible store
// it satifies the "Ingestor" interface used by the call to `images.Dispatch`
cs, err := local.NewStore(csDir)
if err != nil {
panic(err)
}
fmt.Println(csDir)
resolver := docker.NewResolver(docker.ResolverOptions{})
ctx := context.Background()
name, desc, err := resolver.Resolve(ctx, "docker.io/tianon/true:latest")
if err != nil {
panic(err)
}
fetcher, err := resolver.Fetcher(ctx, name)
if err != nil {
panic(err)
}
r, err := fetcher.Fetch(ctx, desc)
if err != nil {
panic(err)
}
defer r.Close()
// Handler which reads a descriptor and fetches the referenced data (e.g. image layers) from the remote
h := remotes.FetchHandler(cs, fetcher)
// This traverses the OCI descriptor to fetch the image and store it into the local store initialized above.
// All content hashes are verified in this step
if err := images.Dispatch(ctx, h, desc); err != nil {
panic(err)
}
}
@vbatts

This comment has been minimized.

Copy link

vbatts commented Aug 6, 2018

https://gist.github.com/cpuguy83/541dc445fad44193068a1f8f365a9c0e#file-pull-go-L17
off by one. os.Args[0] is set so it's 1, then get's out of bounds on line 31.

Very nice, concise example. Thanks for sharing.

@cpuguy83

This comment has been minimized.

Copy link
Owner Author

cpuguy83 commented Aug 6, 2018

Thanks @vbatts! Fixed.

@jdolitsky

This comment has been minimized.

Copy link

jdolitsky commented Dec 24, 2018

@cpuguy83 thanks for this great example.

I got caught up on how to do a full recursive fetch. I think it might be helpful for others if something was added like

h := images.Handlers(remotes.FetchHandler(cs, fetcher), images.ChildrenHandler(cs))

and also maybe a description for this gist such as "containerd pull without containerd daemon". Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.