func (image *image) Ensure(ctx context.Context) error {
	image.ensureOnce.Do(func() {
		image.ensureErr = func() (err error) {
			inspectDigest := func() (string, error) {
				out, err := exec.CommandContext(ctx, "docker", "image", "inspect", "--format", "{{ .Id }}", image.name).CombinedOutput()
				id := string(bytes.TrimSpace(out))
				return id, err
			}
			var digest string
			if digest, err = inspectDigest(); err != nil {
				if err := exec.CommandContext(ctx, "docker", "image", "pull", image.name).Run(); err != nil {
					return errors.Wrap(err, "pulling image")
				}
				digest, err = inspectDigest()
				if err != nil {
					return errors.Wrap(err, "not found after pulling image")
				}
			}
			if digest == "" {
				return errors.Errorf("unexpected empty docker image content ID for %q", image.name)
			}
			image.digest = digest
			return nil
		}()
	})
	return image.ensureErr
}
Ensure ensures that the image has been pulled by Docker. Note that it does
not attempt to pull a newer version of the image if it exists locally.
package docker
import (
	"bytes"
	"context"
	"fmt"
	"strings"
	"sync"
	"github.com/cockroachdb/errors"
	"github.com/sourcegraph/src-cli/internal/exec"
)
type UIDGID struct {
	UID int
	GID int
}
func (ug UIDGID) String() string {
	return fmt.Sprintf("%d:%d", ug.UID, ug.GID)
}
var Root = UIDGID{UID: 0, GID: 0}
type Image interface {
	Digest(context.Context) (string, error)
	Ensure(context.Context) error
	UIDGID(context.Context) (UIDGID, error)
}
type image struct {
	name string
	digest string
	ensureErr  error
	ensureOnce sync.Once
	uidGid     UIDGID
	uidGidErr  error
	uidGidOnce sync.Once
}
func (image *image) Digest(ctx context.Context) (string, error) {
	ensureErr := image.Ensure(ctx)
	return image.digest, ensureErr
}