restic/snapshot.go

101 lines
2.1 KiB
Go
Raw Normal View History

2014-12-05 20:45:49 +00:00
package restic
2014-08-04 18:47:04 +00:00
import (
2014-08-11 20:47:24 +00:00
"fmt"
2014-08-04 18:47:04 +00:00
"os"
"os/user"
2014-09-23 20:39:12 +00:00
"path/filepath"
"strconv"
2014-08-04 18:47:04 +00:00
"time"
2014-09-23 20:39:12 +00:00
2014-12-05 20:45:49 +00:00
"github.com/restic/restic/backend"
"github.com/restic/restic/repository"
2014-08-04 18:47:04 +00:00
)
type Snapshot struct {
Time time.Time `json:"time"`
Parent *backend.ID `json:"parent,omitempty"`
Tree *backend.ID `json:"tree"`
Paths []string `json:"paths"`
Hostname string `json:"hostname,omitempty"`
Username string `json:"username,omitempty"`
UID uint32 `json:"uid,omitempty"`
GID uint32 `json:"gid,omitempty"`
Excludes []string `json:"excludes,omitempty"`
id *backend.ID // plaintext ID, used during restore
2014-08-04 18:47:04 +00:00
}
2015-03-02 13:48:47 +00:00
func NewSnapshot(paths []string) (*Snapshot, error) {
for i, path := range paths {
if p, err := filepath.Abs(path); err != nil {
paths[i] = p
}
2014-09-23 20:39:12 +00:00
}
2014-08-04 18:47:04 +00:00
sn := &Snapshot{
2015-03-02 13:48:47 +00:00
Paths: paths,
Time: time.Now(),
2014-08-04 18:47:04 +00:00
}
hn, err := os.Hostname()
if err == nil {
sn.Hostname = hn
}
err = sn.fillUserInfo()
if err != nil {
return nil, err
2014-08-04 18:47:04 +00:00
}
return sn, nil
2014-08-04 18:47:04 +00:00
}
2015-05-09 21:59:58 +00:00
func LoadSnapshot(repo *repository.Repository, id backend.ID) (*Snapshot, error) {
sn := &Snapshot{id: &id}
2015-05-09 11:32:52 +00:00
err := repo.LoadJSONUnpacked(backend.Snapshot, id, sn)
2014-08-04 20:46:14 +00:00
if err != nil {
return nil, err
}
return sn, nil
2014-08-04 18:47:04 +00:00
}
2014-08-11 20:47:24 +00:00
func (sn Snapshot) String() string {
2015-03-02 13:48:47 +00:00
return fmt.Sprintf("<Snapshot of %v at %s>", sn.Paths, sn.Time)
2014-08-11 20:47:24 +00:00
}
func (sn Snapshot) ID() *backend.ID {
return sn.id
}
func (sn *Snapshot) fillUserInfo() error {
usr, err := user.Current()
if err != nil {
return nil
}
sn.Username = usr.Username
// We ignore the error. On Windows Uid is not a number
uid, _ := strconv.ParseInt(usr.Uid, 10, 32)
sn.UID = uint32(uid)
// We ignore the error. On Windows Gid is not a number
gid, _ := strconv.ParseInt(usr.Gid, 10, 32)
sn.GID = uint32(gid)
return nil
}
// FindSnapshot takes a string and tries to find a snapshot whose ID matches
// the string as closely as possible.
func FindSnapshot(repo *repository.Repository, s string) (backend.ID, error) {
// find snapshot id with prefix
name, err := backend.Find(repo.Backend(), backend.Snapshot, s)
if err != nil {
return backend.ID{}, err
}
return backend.ParseID(name)
}