func IDsFromStat(rootPath, file string, r *UidRange) (Resolver, error) {
	if strings.HasPrefix(file, "/") {
		return idsFromStat{filepath.Join(rootPath, file), r}, nil
	}
	return nil, fmt.Errorf("invalid filename %q", file)
}
IDsFromStat returns a new UID/GID resolver deriving the UID/GID from file attributes
and unshifts the UID/GID if the given range is not nil.
If the given id does not start with a slash "/" an error is returned.
package user
import (
	"errors"
	"fmt"
	"path/filepath"
	"strconv"
	"strings"
	"syscall"
	"github.com/coreos/rkt/pkg/group"
	"github.com/coreos/rkt/pkg/passwd"
	"github.com/hashicorp/errwrap"
)
type Resolver interface {
	IDs() (uid int, gid int, err error)
}
type idsFromEtc struct {
	rootPath string
	username string
	group    string
}
func IDsFromEtc(rootPath, username, group string) (Resolver, error) {
	return idsFromEtc{
		rootPath: rootPath,
		username: username,
		group:    group,
	}, nil
}
func (e idsFromEtc) IDs() (uid int, gid int, err error) {
	uid, gid = -1, -1
	uid, err = passwd.LookupUidFromFile(
		e.username,
		filepath.Join(e.rootPath, "etc/passwd"),
	)
	if e.username != "" && err != nil {
		return
	}
	gid, err = group.LookupGidFromFile(
		e.group,
		filepath.Join(e.rootPath, "etc/group"),
	)
	if e.group != "" && err != nil {
		return
	}
	return uid, gid, nil
}
type idsFromStat struct {
	path string
	r    *UidRange
}