func getProfileV0(profilePath string) (ProfileManifestV0JSON, error) {
	var manifest ProfileManifestV0JSON
	empty := ProfileManifestV0JSON{
		Kind: ProfileManifestV0K,
	}
	b, err := ioutil.ReadFile(profilePath)
	if err != nil {
		if err == io.EOF {
			return empty, nil
		}
		return ProfileManifestV0JSON{}, err
	}
	if len(b) == 0 {
		return empty, nil
	}
	if err := json.Unmarshal(b, &manifest); err != nil {
		return ProfileManifestV0JSON{}, err
	}
	if manifest.Kind != ProfileManifestV0K {
		return manifest, errors.Errorf("expected manifest kind %s, got %s", ProfileManifestV0K, manifest.Kind)
	}
	return manifest, nil
}
getProfileV0 reads a profile from the given path, returning the unmarshalled
JSON (v0) profile manifest.
package torcx
import (
	"bufio"
	"encoding/json"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
)
var DefaultLowerProfiles = []string{VendorProfileName, OemProfileName}
func CurrentProfileNames() (string, []string, error) {
	meta, err := ReadMetadata(SealPath)
	if err != nil {
		return "", nil, err
	}
	upperProfile, ok := meta[SealUpperProfile]
	if !ok {
		return "", nil, errors.New("unable to determine current upper profile name")
	}
	lowerString, ok := meta[SealLowerProfiles]
	if !ok {
		return "", nil, errors.New("unable to determine current lower profile names")
	}
	lowerProfiles := strings.Split(lowerString, ":")
	return upperProfile, lowerProfiles, nil
}
func CurrentProfilePath() (string, error) {
	var path string
	meta, err := ReadMetadata(SealPath)
	if err != nil {
		return "", err
	}
	path, ok := meta[SealRunProfilePath]
	if !ok {
		return "", errors.New("unable to determine current profile path")
	}
	if path == "" {
		return "", errors.New("invalid profile path")
	}
	return path, nil
}
func (cc *CommonConfig) NextProfileName() (string, error) {
	fc, err := ioutil.ReadFile(cc.NextProfile())
	if err != nil {
		return "", errors.Wrapf(err, "unable to read profile file")
	}
	profileName := strings.TrimSpace(string(fc))
	profileName = strings.TrimSuffix(profileName, ".json")
	profiles, err := ListProfiles(cc.ProfileDirs())
	if err != nil {
		return "", errors.Wrap(err, "could not list profiles")
	}
	if profileName == "" {
		return "", errors.New("missing profile name")
	}
	if _, ok := profiles[profileName]; !ok {
		return "", errors.Errorf("profile %q not found", profileName)
	}
	return profileName, nil
}
func (cc *CommonConfig) SetNextProfileName(name string) error {
	if err := os.MkdirAll(cc.UserProfileDir(), 0755); err != nil {
		return err
	}
	line := strings.TrimSpace(name) + "\n"
	return ioutil.WriteFile(cc.NextProfile(), []byte(line), 0644)
}
func ReadCurrentProfile() ([]Image, error) {
	path, err := CurrentProfilePath()
	if err != nil {
		return nil, err
	}
	return ReadProfilePath(path)
}
func ReadProfilePath(path string) ([]Image, error) {
	fp, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer fp.Close()
	return readProfileReader(bufio.NewReader(fp))
}
func readProfileReader(in io.Reader) ([]Image, error) {
	var container kindValueJSON
	err := json.NewDecoder(in).Decode(&container)
	if err == io.EOF {
		return nil, nil
	}
	if err != nil {
		return nil, err
	}
	switch container.Kind {
	case ProfileManifestV0K:
		manifest := ProfileManifestV0JSON{
			Kind: container.Kind,
		}
		if err := json.Unmarshal(container.Value, &manifest.Value); err != nil {
			return nil, err
		}
		return ImagesFromJSONV0(manifest.Value), nil
	case ProfileManifestV1K:
		manifest := ProfileManifestV1JSON{
			Kind: container.Kind,
		}
		if err := json.Unmarshal(container.Value, &manifest.Value); err != nil {
			return nil, err
		}
		return ImagesFromJSONV1(manifest.Value), nil
	}
	return nil, errors.Errorf("unknown profile kind %s", container.Kind)
}
func AddToProfile(profilePath string, im Image) error {
	st, err := os.Stat(profilePath)
	if err != nil {
		return err
	}
	v1Profile, err := getProfileV1(profilePath)
	if err == nil {
		return addToProfileV1(profilePath, st.Mode().Perm(), v1Profile, &im)
	}
	v0Profile, err := getProfileV0(profilePath)
	if err == nil {
		return addToProfileV0(profilePath, st.Mode().Perm(), v0Profile, &im)
	}
	return errors.Wrapf(err, "unable to unmarshal profile to %s", profilePath)
}