func (f *File) Unlink() error {
	log.Debugf("removing %s", f.Path)
	err := os.Remove(f.Path)
	if os.IsNotExist(err) {
		return nil
	}
	return err
}
Unlink deletes the file specified by the Path field.
package util
import (
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/user"
	"path"
	"regexp"
	"strconv"
	"syscall"
	log "github.com/sirupsen/logrus"
)
var idRegexp = regexp.MustCompile(`^\d+$`)
type Path string
type File struct {
	Path  string `json:"path" yaml:"path"`
	Owner string `json:"owner" yaml:"owner"`
	Group string `json:"group" yaml:"group"`
	Mode  string `json:"mode" yaml:"mode"`
	uid, gid int
	mode     os.FileMode
}
func NewFile(path, owner, group, mode string) (*File, error) {
	f := File{
		Path:  path,
		Owner: owner,
		Group: group,
		Mode:  mode,
	}
	if err := f.parse(); err != nil {
		return nil, err
	}
	return &f, nil
}
func (f *File) UnmarshalYAML(unmarshal func(interface{}) error) error {
	type alias File
	if err := unmarshal((*alias)(f)); err != nil {
		return err
	}
	return f.parse()
}
func (f *File) UnmarshalJSON(data []byte) error {
	type alias File
	if err := json.Unmarshal(data, (*alias)(f)); err != nil {
		return err
	}
	return f.parse()
}
func (f *File) parse() (err error) {
	if f.Path == "" {
		return errors.New("missing path")
	}
	if f.Mode == "" {
		f.Mode = "0644"
	}
	var u *user.User
	if f.Owner == "" || f.Group == "" {
		u, err = user.Current()
		if err != nil {
			return err
		}
		if f.Owner == "" {
			f.Owner = u.Uid
		}
		if f.Group == "" {
			f.Group = u.Gid
		}
	}
	if idRegexp.MatchString(f.Owner) {
		f.uid, err = strconv.Atoi(f.Owner)
		if err != nil {
			return err
		}
	} else {
		if u == nil {
			u, err = user.Lookup(f.Owner)
			if err != nil {
				return err
			}
			f.uid, err = strconv.Atoi(u.Uid)
			if err != nil {
				return err
			}
		}
	}
	if idRegexp.MatchString(f.Group) {
		f.gid, err = strconv.Atoi(f.Group)
		if err != nil {
			return err
		}
	} else {
		var g *user.Group
		g, err = user.LookupGroup(f.Group)
		if err != nil {
			return err
		}
		f.gid, err = strconv.Atoi(g.Gid)
		if err != nil {
			return err
		}
	}
	mode, err := strconv.ParseUint(f.Mode, 0, 32)
	if err != nil {
		return err
	}
	f.mode = os.FileMode(mode)
	return nil
}
func (f *File) CheckPermissions() error {
	st, err := os.Stat(f.Path)
	if err != nil {
		return err
	}
	if st.Mode() != f.mode {
		return fmt.Errorf("mode has changed from %s to %s", f.mode, st.Mode())
	}
	unixStat, ok := st.Sys().(*syscall.Stat_t)
	if !ok {
		log.Warningf("Certmgr doesn't know how to verify ownership for %s", f.Path)
		return nil
	}
	if unixStat.Uid != uint32(f.uid) {
		return fmt.Errorf("uid has changed from %d to %d", uint32(f.uid), unixStat.Uid)
	}
	if unixStat.Gid != uint32(f.gid) {
		return fmt.Errorf("uid has changed from %d to %d", uint32(f.uid), unixStat.Gid)
	}
	return nil
}
func (f *File) ReadFile() ([]byte, error) {
	return ioutil.ReadFile(f.Path)
}
func (f *File) WriteFile(data []byte) error {
	tmpFile, err := ioutil.TempFile(path.Dir(f.Path), path.Base(f.Path))
	if err != nil {
		return err
	}
	defer func() {
		if tmpFile != nil {
			os.Remove(tmpFile.Name())
		}
	}()
	err = tmpFile.Chown(f.uid, f.gid)
	if err != nil {
		return err
	}
	err = tmpFile.Chmod(f.mode)
	if err != nil {
		return err
	}
	_, err = tmpFile.Write(data)
	if err != nil {
		return err
	}
	err = os.Rename(tmpFile.Name(), f.Path)
	if err != nil {
		return err
	}
	tmpFile = nil
	return nil
}