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

130 lines
2.5 KiB
Go

package podman
import (
"bufio"
"context"
"fmt"
"github.com/containers/libpod/libpod"
"github.com/wagoodman/dive/dive/image"
"github.com/wagoodman/dive/dive/image/docker"
"io/ioutil"
"os"
)
type resolver struct{}
func NewResolver() *resolver {
return &resolver{}
}
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) Fetch(id string) (*image.Image, error) {
img, err := r.resolveFromDisk(id)
if err == nil {
return img, err
}
// todo: remove print of error
fmt.Println(err)
img, err = r.resolveFromDockerArchive(id)
if err == nil {
return img, err
}
return nil, fmt.Errorf("unable to resolve image '%s'", id)
}
func (r *resolver) resolveFromDisk(id string) (*image.Image, error) {
var img *ImageDirectoryRef
var err error
runtime, err := libpod.NewRuntime(context.TODO())
if err != nil {
return nil, err
}
images, err := runtime.ImageRuntime().GetImages()
if err != nil {
return nil, err
}
ImageLoop:
for _, candidateImage := range images {
for _, name := range candidateImage.Names() {
if name == id {
img, err = NewImageDirectoryRef(candidateImage)
if err != nil {
return nil, err
}
break ImageLoop
}
}
}
if img == nil {
return nil, fmt.Errorf("could not find image by name: '%s'", id)
}
return img.ToImage()
}
func (r *resolver) resolveFromDockerArchive(id string) (*image.Image, error) {
path, err := r.fetchDockerArchive(id)
if err != nil {
return nil, err
}
defer os.Remove(path)
file, err := os.Open(path)
defer file.Close()
img, err := docker.NewImageArchive(ioutil.NopCloser(bufio.NewReader(file)))
if err != nil {
return nil, err
}
return img.ToImage()
}
func (r *resolver) fetchDockerArchive(id string) (string, error) {
var err error
var ctx = context.Background()
runtime, err := libpod.NewRuntime(ctx)
if err != nil {
return "", err
}
images, err := runtime.ImageRuntime().GetImages()
if err != nil {
return "", err
}
for _, item := range images {
for _, name := range item.Names() {
if name == id {
file, err := ioutil.TempFile(os.TempDir(), "dive-resolver-tar")
if err != nil {
return "", err
}
err = item.Save(ctx, "dive-export", "docker-archive", file.Name(), []string{}, false, false)
if err != nil {
return "", err
}
return file.Name(), nil
}
}
}
return "", fmt.Errorf("image could not be found")
}