func (pulledImg *PulledImage) writeConfig() error {
	configFile, err := getConfig(pulledImg.img)
	if err != nil {
		return err
	}
	jdata, err := json.MarshalIndent(configFile, "", " ")
	if err != nil {
		return err
	}
	configPath := filepath.Join(pulledImg.spec.Dest, "config.json")
	jsonFile, err := os.Create(configPath)
	if err != nil {
		return err
	}
	_, err = jsonFile.Write(jdata)
	return err
}
extract config.json from image and write to image.Dest.
assumes image.Dest is valid.
package rootfs
import (
	"encoding/json"
	"fmt"
	"os"
	"os/user"
	"path/filepath"
	"strconv"
	"github.com/ForAllSecure/rootfs_builder/util"
	"github.com/google/go-containerregistry/pkg/name"
	v1 "github.com/google/go-containerregistry/pkg/v1"
	"github.com/google/go-containerregistry/pkg/v1/partial"
	"github.com/pkg/errors"
)
type Spec struct {
	Dest string
	User string
	UseSubuid bool
	subuid    int
	subgid    int
}
type PulledImage struct {
	spec Spec
	name string
	img  v1.Image
}
func (pulledImg *PulledImage) Digest() (string, error) {
	_, err := getConfig(pulledImg.img)
	if err != nil {
		return "", err
	}
	hash, err := pulledImg.img.Digest()
	if err != nil {
		return "", errors.WithStack(err)
	}
	ref, err := name.ParseReference(pulledImg.name, name.WeakValidation)
	if err != nil {
		return "", errors.WithStack(err)
	}
	buf := fmt.Sprintf("%s/%s@%s\n", ref.Context().RegistryStr(), ref.Context().RepositoryStr(), hash.String())
	return buf, nil
}
func (pulledImg *PulledImage) Extract() error {
	err := pulledImg.validateDest()
	if err != nil {
		return err
	}
	err = pulledImg.writeConfig()
	if err != nil {
		return err
	}
	layers, err := pulledImg.img.Layers()
	if err != nil {
		return err
	}
	rootfsPath := filepath.Join(pulledImg.spec.Dest, "rootfs")
	if err := os.MkdirAll(rootfsPath, 0755); err != nil {
		return err
	}
	if err := pulledImg.validateUser(); err != nil {
		return err
	}
	for _, layer := range layers {
		err = extractLayer(layer, rootfsPath, pulledImg.spec.subuid, pulledImg.spec.subgid)
		if err != nil {
			return err
		}
	}
	if err := os.Chown(rootfsPath, pulledImg.spec.subuid, pulledImg.spec.subuid); err != nil {
		return err
	}
	return nil
}
func (pulledImg *PulledImage) validateUser() error {
	userObj, err := user.Current()
	if pulledImg.spec.User != "" {
		userObj, err = user.Lookup(pulledImg.spec.User)
	}
	if err != nil {
		return err
	}
	subuid, err := strconv.Atoi(userObj.Uid)
	if err != nil {
		return err
	}
	subgid, err := strconv.Atoi(userObj.Gid)
	if err != nil {
		return err
	}
	if pulledImg.spec.UseSubuid {
		subuid, subgid, err = util.GetSubid(userObj)
		if err != nil {
			return err
		}
	}
	pulledImg.spec.subuid = subuid
	pulledImg.spec.subgid = subgid
	return nil
}
func (pulledImg *PulledImage) validateDest() error {
	if pulledImg.spec.Dest == "" {
		return errors.New("Specify output destination for rootfs")
	}
	if _, err := os.Stat(pulledImg.spec.Dest); os.IsNotExist(err) {
		_ = os.Mkdir(pulledImg.spec.Dest, 0755)
	}
	return nil
}