Reputation: 31
I’m trying to figure out how I can use the Go client (http://godoc.org/github.com/moby/moby/client) to pull a file from a docker image at a specific version (tag)
I want to download the image and then copy a file from the image onto the local file system. I see a lot of commands for dealing with an image, but not how to access its contents. I do see ways to access a container’s contents.
I’m suspecting I would need to download the image, create a container with the image and finally copy the contents out of the container. Though if I could avoid creating a container, that would be preferred.
Does anyone know exactly how to do this? Code snippet would be appreciated.
Thanks!
Upvotes: 2
Views: 4928
Reputation: 6079
You must start the container, copy the file and then remove the container... It's not really an expensive operation since the container isn't started anyway.
Here's a working example that copies a file from the specified image to standard output. The API is straightforward to follow:
https://gist.github.com/ricardobranco777/a3be772935dfb1a183e0831496925585
package main
import (
"archive/tar"
"fmt"
"io"
"io/ioutil"
"os"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"golang.org/x/net/context"
)
func main() {
if len(os.Args) != 3 {
fmt.Fprintf(os.Stderr, "Usage: %s IMAGE FILE\n", os.Args[0])
os.Exit(1)
}
imageName := os.Args[1]
filePath := os.Args[2]
ctx := context.Background()
cli, err := client.NewEnvClient()
if err != nil {
panic(err)
}
out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
if err != nil {
panic(err)
}
defer out.Close()
if _, err := ioutil.ReadAll(out); err != nil {
panic(err)
}
info, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName,
}, nil, nil, "")
if err != nil {
panic(err)
}
tarStream, _, err := cli.CopyFromContainer(ctx, info.ID, filePath)
if err != nil {
panic(err)
}
tr := tar.NewReader(tarStream)
if _, err := tr.Next(); err != nil {
panic(err)
}
io.Copy(os.Stdout, tr)
if err := cli.ContainerRemove(ctx, info.ID, types.ContainerRemoveOptions{}); err != nil {
panic(err)
}
}
Upvotes: 3