* rework CI validation workflow and makefile * enable push * fix job names * fix license check * fix snapshot builds * fix acceptance tests * fix linting * disable pull request event * rework windows runner caching * disable release pipeline and add issue templates
103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
package docker
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/docker/cli/cli/connhelper"
|
|
"github.com/docker/docker/client"
|
|
"golang.org/x/net/context"
|
|
|
|
"github.com/wagoodman/dive/dive/image"
|
|
)
|
|
|
|
type engineResolver struct{}
|
|
|
|
func NewResolverFromEngine() *engineResolver {
|
|
return &engineResolver{}
|
|
}
|
|
|
|
func (r *engineResolver) 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 *engineResolver) Build(args []string) (*image.Image, error) {
|
|
id, err := buildImageFromCli(args)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return r.Fetch(id)
|
|
}
|
|
|
|
func (r *engineResolver) fetchArchive(id string) (io.ReadCloser, error) {
|
|
var err error
|
|
var dockerClient *client.Client
|
|
|
|
// pull the engineResolver 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
|
|
}
|