dive-zfs/dive/image/docker/resolver.go
Alex Goodman fcb5ec01ef
gofmt
2019-10-07 18:25:53 -04:00

103 lines
2.2 KiB
Go

package docker
import (
"fmt"
"github.com/wagoodman/dive/dive/image"
"io"
"net/http"
"os"
"strings"
"github.com/docker/cli/cli/connhelper"
"github.com/docker/docker/client"
"golang.org/x/net/context"
)
type resolver struct{}
func NewResolver() *resolver {
return &resolver{}
}
func (r *resolver) Fetch(id string) (*image.Image, error) {
reader, err := r.fetchArchive(id)
if err != nil {
return nil, err
}
defer reader.Close()
img, err := NewImageArchive(reader)
if err != nil {
return nil, err
}
return img.ToImage()
}
func (r *resolver) Build(args []string) (*image.Image, error) {
id, err := buildImageFromCli(args)
if err != nil {
return nil, err
}
return r.Fetch(id)
}
func (r *resolver) fetchArchive(id string) (io.ReadCloser, error) {
var err error
var dockerClient *client.Client
// pull the resolver if it does not exist
ctx := context.Background()
host := os.Getenv("DOCKER_HOST")
var clientOpts []client.Opt
switch strings.Split(host, ":")[0] {
case "ssh":
helper, err := connhelper.GetConnectionHelper(host)
if err != nil {
fmt.Println("docker host", err)
}
clientOpts = append(clientOpts, func(c *client.Client) error {
httpClient := &http.Client{
Transport: &http.Transport{
DialContext: helper.Dialer,
},
}
return client.WithHTTPClient(httpClient)(c)
})
clientOpts = append(clientOpts, client.WithHost(helper.Host))
clientOpts = append(clientOpts, client.WithDialContext(helper.Dialer))
default:
if os.Getenv("DOCKER_TLS_VERIFY") != "" && os.Getenv("DOCKER_CERT_PATH") == "" {
os.Setenv("DOCKER_CERT_PATH", "~/.docker")
}
clientOpts = append(clientOpts, client.FromEnv)
}
clientOpts = append(clientOpts, client.WithAPIVersionNegotiation())
dockerClient, err = client.NewClientWithOpts(clientOpts...)
if err != nil {
return nil, err
}
_, _, err = dockerClient.ImageInspectWithRaw(ctx, id)
if err != nil {
// don't use the API, the CLI has more informative output
fmt.Println("Handler not available locally. Trying to pull '" + id + "'...")
err = runDockerCmd("pull", id)
if err != nil {
return nil, err
}
}
readCloser, err := dockerClient.ImageSave(ctx, []string{id})
if err != nil {
return nil, err
}
return readCloser, nil
}