mirror of
https://github.com/restic/restic.git
synced 2025-01-02 21:25:12 +00:00
add proper constants for node type
This commit is contained in:
parent
3b438e5c7c
commit
ca1e5e10b6
42 changed files with 206 additions and 206 deletions
|
@ -108,9 +108,9 @@ func (s *DiffStat) Add(node *restic.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
s.Files++
|
s.Files++
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
s.Dirs++
|
s.Dirs++
|
||||||
default:
|
default:
|
||||||
s.Others++
|
s.Others++
|
||||||
|
@ -124,7 +124,7 @@ func addBlobs(bs restic.BlobSet, node *restic.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
for _, blob := range node.Content {
|
for _, blob := range node.Content {
|
||||||
h := restic.BlobHandle{
|
h := restic.BlobHandle{
|
||||||
ID: blob,
|
ID: blob,
|
||||||
|
@ -132,7 +132,7 @@ func addBlobs(bs restic.BlobSet, node *restic.Node) {
|
||||||
}
|
}
|
||||||
bs.Insert(h)
|
bs.Insert(h)
|
||||||
}
|
}
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
h := restic.BlobHandle{
|
h := restic.BlobHandle{
|
||||||
ID: *node.Subtree,
|
ID: *node.Subtree,
|
||||||
Type: restic.TreeBlob,
|
Type: restic.TreeBlob,
|
||||||
|
@ -184,14 +184,14 @@ func (c *Comparer) printDir(ctx context.Context, mode string, stats *DiffStat, b
|
||||||
}
|
}
|
||||||
|
|
||||||
name := path.Join(prefix, node.Name)
|
name := path.Join(prefix, node.Name)
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
name += "/"
|
name += "/"
|
||||||
}
|
}
|
||||||
c.printChange(NewChange(name, mode))
|
c.printChange(NewChange(name, mode))
|
||||||
stats.Add(node)
|
stats.Add(node)
|
||||||
addBlobs(blobs, node)
|
addBlobs(blobs, node)
|
||||||
|
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
err := c.printDir(ctx, mode, stats, blobs, name, *node.Subtree)
|
err := c.printDir(ctx, mode, stats, blobs, name, *node.Subtree)
|
||||||
if err != nil && err != context.Canceled {
|
if err != nil && err != context.Canceled {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
|
@ -216,7 +216,7 @@ func (c *Comparer) collectDir(ctx context.Context, blobs restic.BlobSet, id rest
|
||||||
|
|
||||||
addBlobs(blobs, node)
|
addBlobs(blobs, node)
|
||||||
|
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
err := c.collectDir(ctx, blobs, *node.Subtree)
|
err := c.collectDir(ctx, blobs, *node.Subtree)
|
||||||
if err != nil && err != context.Canceled {
|
if err != nil && err != context.Canceled {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
|
@ -284,12 +284,12 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
|
||||||
mod += "T"
|
mod += "T"
|
||||||
}
|
}
|
||||||
|
|
||||||
if node2.Type == "dir" {
|
if node2.Type == restic.NodeTypeDir {
|
||||||
name += "/"
|
name += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
if node1.Type == "file" &&
|
if node1.Type == restic.NodeTypeFile &&
|
||||||
node2.Type == "file" &&
|
node2.Type == restic.NodeTypeFile &&
|
||||||
!reflect.DeepEqual(node1.Content, node2.Content) {
|
!reflect.DeepEqual(node1.Content, node2.Content) {
|
||||||
mod += "M"
|
mod += "M"
|
||||||
stats.ChangedFiles++
|
stats.ChangedFiles++
|
||||||
|
@ -311,7 +311,7 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
|
||||||
c.printChange(NewChange(name, mod))
|
c.printChange(NewChange(name, mod))
|
||||||
}
|
}
|
||||||
|
|
||||||
if node1.Type == "dir" && node2.Type == "dir" {
|
if node1.Type == restic.NodeTypeDir && node2.Type == restic.NodeTypeDir {
|
||||||
var err error
|
var err error
|
||||||
if (*node1.Subtree).Equal(*node2.Subtree) {
|
if (*node1.Subtree).Equal(*node2.Subtree) {
|
||||||
err = c.collectDir(ctx, stats.BlobsCommon, *node1.Subtree)
|
err = c.collectDir(ctx, stats.BlobsCommon, *node1.Subtree)
|
||||||
|
@ -324,13 +324,13 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
|
||||||
}
|
}
|
||||||
case t1 && !t2:
|
case t1 && !t2:
|
||||||
prefix := path.Join(prefix, name)
|
prefix := path.Join(prefix, name)
|
||||||
if node1.Type == "dir" {
|
if node1.Type == restic.NodeTypeDir {
|
||||||
prefix += "/"
|
prefix += "/"
|
||||||
}
|
}
|
||||||
c.printChange(NewChange(prefix, "-"))
|
c.printChange(NewChange(prefix, "-"))
|
||||||
stats.Removed.Add(node1)
|
stats.Removed.Add(node1)
|
||||||
|
|
||||||
if node1.Type == "dir" {
|
if node1.Type == restic.NodeTypeDir {
|
||||||
err := c.printDir(ctx, "-", &stats.Removed, stats.BlobsBefore, prefix, *node1.Subtree)
|
err := c.printDir(ctx, "-", &stats.Removed, stats.BlobsBefore, prefix, *node1.Subtree)
|
||||||
if err != nil && err != context.Canceled {
|
if err != nil && err != context.Canceled {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
|
@ -338,13 +338,13 @@ func (c *Comparer) diffTree(ctx context.Context, stats *DiffStatsContainer, pref
|
||||||
}
|
}
|
||||||
case !t1 && t2:
|
case !t1 && t2:
|
||||||
prefix := path.Join(prefix, name)
|
prefix := path.Join(prefix, name)
|
||||||
if node2.Type == "dir" {
|
if node2.Type == restic.NodeTypeDir {
|
||||||
prefix += "/"
|
prefix += "/"
|
||||||
}
|
}
|
||||||
c.printChange(NewChange(prefix, "+"))
|
c.printChange(NewChange(prefix, "+"))
|
||||||
stats.Added.Add(node2)
|
stats.Added.Add(node2)
|
||||||
|
|
||||||
if node2.Type == "dir" {
|
if node2.Type == restic.NodeTypeDir {
|
||||||
err := c.printDir(ctx, "+", &stats.Added, stats.BlobsAfter, prefix, *node2.Subtree)
|
err := c.printDir(ctx, "+", &stats.Added, stats.BlobsAfter, prefix, *node2.Subtree)
|
||||||
if err != nil && err != context.Canceled {
|
if err != nil && err != context.Canceled {
|
||||||
Warnf("error: %v\n", err)
|
Warnf("error: %v\n", err)
|
||||||
|
|
|
@ -95,15 +95,15 @@ func printFromTree(ctx context.Context, tree *restic.Tree, repo restic.BlobLoade
|
||||||
// first item it finds and dump that according to the switch case below.
|
// first item it finds and dump that according to the switch case below.
|
||||||
if node.Name == pathComponents[0] {
|
if node.Name == pathComponents[0] {
|
||||||
switch {
|
switch {
|
||||||
case l == 1 && dump.IsFile(node):
|
case l == 1 && node.Type == restic.NodeTypeFile:
|
||||||
return d.WriteNode(ctx, node)
|
return d.WriteNode(ctx, node)
|
||||||
case l > 1 && dump.IsDir(node):
|
case l > 1 && node.Type == restic.NodeTypeDir:
|
||||||
subtree, err := restic.LoadTree(ctx, repo, *node.Subtree)
|
subtree, err := restic.LoadTree(ctx, repo, *node.Subtree)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "cannot load subtree for %q", item)
|
return errors.Wrapf(err, "cannot load subtree for %q", item)
|
||||||
}
|
}
|
||||||
return printFromTree(ctx, subtree, repo, item, pathComponents[1:], d, canWriteArchiveFunc)
|
return printFromTree(ctx, subtree, repo, item, pathComponents[1:], d, canWriteArchiveFunc)
|
||||||
case dump.IsDir(node):
|
case node.Type == restic.NodeTypeDir:
|
||||||
if err := canWriteArchiveFunc(); err != nil {
|
if err := canWriteArchiveFunc(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func printFromTree(ctx context.Context, tree *restic.Tree, repo restic.BlobLoade
|
||||||
return d.DumpTree(ctx, subtree, item)
|
return d.DumpTree(ctx, subtree, item)
|
||||||
case l > 1:
|
case l > 1:
|
||||||
return fmt.Errorf("%q should be a dir, but is a %q", item, node.Type)
|
return fmt.Errorf("%q should be a dir, but is a %q", item, node.Type)
|
||||||
case !dump.IsFile(node):
|
case node.Type != restic.NodeTypeFile:
|
||||||
return fmt.Errorf("%q should be a file, but is a %q", item, node.Type)
|
return fmt.Errorf("%q should be a file, but is a %q", item, node.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -298,7 +298,7 @@ func (f *Finder) findInSnapshot(ctx context.Context, sn *restic.Snapshot) error
|
||||||
}
|
}
|
||||||
|
|
||||||
var errIfNoMatch error
|
var errIfNoMatch error
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
var childMayMatch bool
|
var childMayMatch bool
|
||||||
for _, pat := range f.pat.pattern {
|
for _, pat := range f.pat.pattern {
|
||||||
mayMatch, err := filter.ChildMatch(pat, normalizedNodepath)
|
mayMatch, err := filter.ChildMatch(pat, normalizedNodepath)
|
||||||
|
@ -357,7 +357,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "dir" && f.treeIDs != nil {
|
if node.Type == restic.NodeTypeDir && f.treeIDs != nil {
|
||||||
treeID := node.Subtree
|
treeID := node.Subtree
|
||||||
found := false
|
found := false
|
||||||
if _, ok := f.treeIDs[treeID.Str()]; ok {
|
if _, ok := f.treeIDs[treeID.Str()]; ok {
|
||||||
|
@ -377,7 +377,7 @@ func (f *Finder) findIDs(ctx context.Context, sn *restic.Snapshot) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "file" && f.blobIDs != nil {
|
if node.Type == restic.NodeTypeFile && f.blobIDs != nil {
|
||||||
for _, id := range node.Content {
|
for _, id := range node.Content {
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
|
|
|
@ -137,7 +137,7 @@ func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
||||||
size uint64 // Target for Size pointer.
|
size uint64 // Target for Size pointer.
|
||||||
}{
|
}{
|
||||||
Name: node.Name,
|
Name: node.Name,
|
||||||
Type: node.Type,
|
Type: string(node.Type),
|
||||||
Path: path,
|
Path: path,
|
||||||
UID: node.UID,
|
UID: node.UID,
|
||||||
GID: node.GID,
|
GID: node.GID,
|
||||||
|
@ -153,7 +153,7 @@ func lsNodeJSON(enc *json.Encoder, path string, node *restic.Node) error {
|
||||||
}
|
}
|
||||||
// Always print size for regular files, even when empty,
|
// Always print size for regular files, even when empty,
|
||||||
// but never for other types.
|
// but never for other types.
|
||||||
if node.Type == "file" {
|
if node.Type == restic.NodeTypeFile {
|
||||||
n.Size = &n.size
|
n.Size = &n.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ func lsNcduNode(_ string, node *restic.Node) ([]byte, error) {
|
||||||
Dev: node.DeviceID,
|
Dev: node.DeviceID,
|
||||||
Ino: node.Inode,
|
Ino: node.Inode,
|
||||||
NLink: node.Links,
|
NLink: node.Links,
|
||||||
NotReg: node.Type != "dir" && node.Type != "file",
|
NotReg: node.Type != restic.NodeTypeDir && node.Type != restic.NodeTypeFile,
|
||||||
UID: node.UID,
|
UID: node.UID,
|
||||||
GID: node.GID,
|
GID: node.GID,
|
||||||
Mode: uint16(node.Mode & os.ModePerm),
|
Mode: uint16(node.Mode & os.ModePerm),
|
||||||
|
@ -238,7 +238,7 @@ func (p *ncduLsPrinter) Node(path string, node *restic.Node, _ bool) {
|
||||||
Warnf("JSON encode failed: %v\n", err)
|
Warnf("JSON encode failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out))
|
fmt.Fprintf(p.out, ",\n%s[\n%s%s", strings.Repeat(" ", p.depth), strings.Repeat(" ", p.depth+1), string(out))
|
||||||
p.depth++
|
p.depth++
|
||||||
} else {
|
} else {
|
||||||
|
@ -409,7 +409,7 @@ func runLs(ctx context.Context, opts LsOptions, gopts GlobalOptions, args []stri
|
||||||
|
|
||||||
// otherwise, signal the walker to not walk recursively into any
|
// otherwise, signal the walker to not walk recursively into any
|
||||||
// subdirs
|
// subdirs
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
// immediately generate leaveDir if the directory is skipped
|
// immediately generate leaveDir if the directory is skipped
|
||||||
if printedDir {
|
if printedDir {
|
||||||
printer.LeaveDir(nodepath)
|
printer.LeaveDir(nodepath)
|
||||||
|
|
|
@ -23,7 +23,7 @@ var lsTestNodes = []lsTestNode{
|
||||||
path: "/bar/baz",
|
path: "/bar/baz",
|
||||||
Node: restic.Node{
|
Node: restic.Node{
|
||||||
Name: "baz",
|
Name: "baz",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Size: 12345,
|
Size: 12345,
|
||||||
UID: 10000000,
|
UID: 10000000,
|
||||||
GID: 20000000,
|
GID: 20000000,
|
||||||
|
@ -39,7 +39,7 @@ var lsTestNodes = []lsTestNode{
|
||||||
path: "/foo/empty",
|
path: "/foo/empty",
|
||||||
Node: restic.Node{
|
Node: restic.Node{
|
||||||
Name: "empty",
|
Name: "empty",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Size: 0,
|
Size: 0,
|
||||||
UID: 1001,
|
UID: 1001,
|
||||||
GID: 1001,
|
GID: 1001,
|
||||||
|
@ -56,7 +56,7 @@ var lsTestNodes = []lsTestNode{
|
||||||
path: "/foo/link",
|
path: "/foo/link",
|
||||||
Node: restic.Node{
|
Node: restic.Node{
|
||||||
Name: "link",
|
Name: "link",
|
||||||
Type: "symlink",
|
Type: restic.NodeTypeSymlink,
|
||||||
Mode: os.ModeSymlink | 0777,
|
Mode: os.ModeSymlink | 0777,
|
||||||
LinkTarget: "not printed",
|
LinkTarget: "not printed",
|
||||||
},
|
},
|
||||||
|
@ -66,7 +66,7 @@ var lsTestNodes = []lsTestNode{
|
||||||
path: "/some/directory",
|
path: "/some/directory",
|
||||||
Node: restic.Node{
|
Node: restic.Node{
|
||||||
Name: "directory",
|
Name: "directory",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: os.ModeDir | 0755,
|
Mode: os.ModeDir | 0755,
|
||||||
ModTime: time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC),
|
ModTime: time.Date(2020, 1, 2, 3, 4, 5, 0, time.UTC),
|
||||||
AccessTime: time.Date(2021, 2, 3, 4, 5, 6, 7, time.UTC),
|
AccessTime: time.Date(2021, 2, 3, 4, 5, 6, 7, time.UTC),
|
||||||
|
@ -79,7 +79,7 @@ var lsTestNodes = []lsTestNode{
|
||||||
path: "/some/sticky",
|
path: "/some/sticky",
|
||||||
Node: restic.Node{
|
Node: restic.Node{
|
||||||
Name: "sticky",
|
Name: "sticky",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: os.ModeDir | 0755 | os.ModeSetuid | os.ModeSetgid | os.ModeSticky,
|
Mode: os.ModeDir | 0755 | os.ModeSetuid | os.ModeSetgid | os.ModeSticky,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -139,19 +139,19 @@ func TestLsNcdu(t *testing.T) {
|
||||||
Paths: []string{"/example"},
|
Paths: []string{"/example"},
|
||||||
})
|
})
|
||||||
printer.Node("/directory", &restic.Node{
|
printer.Node("/directory", &restic.Node{
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Name: "directory",
|
Name: "directory",
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
}, false)
|
}, false)
|
||||||
printer.Node("/directory/data", &restic.Node{
|
printer.Node("/directory/data", &restic.Node{
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Name: "data",
|
Name: "data",
|
||||||
Size: 42,
|
Size: 42,
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
}, false)
|
}, false)
|
||||||
printer.LeaveDir("/directory")
|
printer.LeaveDir("/directory")
|
||||||
printer.Node("/file", &restic.Node{
|
printer.Node("/file", &restic.Node{
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Name: "file",
|
Name: "file",
|
||||||
Size: 12345,
|
Size: 12345,
|
||||||
ModTime: modTime,
|
ModTime: modTime,
|
||||||
|
|
|
@ -88,7 +88,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, node := range tree.Nodes {
|
for _, node := range tree.Nodes {
|
||||||
if node.Type == "dir" && node.Subtree != nil {
|
if node.Type == restic.NodeTypeDir && node.Subtree != nil {
|
||||||
trees[*node.Subtree] = true
|
trees[*node.Subtree] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ func runRecover(ctx context.Context, gopts GlobalOptions) error {
|
||||||
for id := range roots {
|
for id := range roots {
|
||||||
var subtreeID = id
|
var subtreeID = id
|
||||||
node := restic.Node{
|
node := restic.Node{
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Name: id.Str(),
|
Name: id.Str(),
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
Subtree: &subtreeID,
|
Subtree: &subtreeID,
|
||||||
|
|
|
@ -92,7 +92,7 @@ func runRepairSnapshots(ctx context.Context, gopts GlobalOptions, opts RepairOpt
|
||||||
// - files whose contents are not fully available (-> file will be modified)
|
// - files whose contents are not fully available (-> file will be modified)
|
||||||
rewriter := walker.NewTreeRewriter(walker.RewriteOpts{
|
rewriter := walker.NewTreeRewriter(walker.RewriteOpts{
|
||||||
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,7 +276,7 @@ func statsWalkTree(repo restic.Loader, opts StatsOptions, stats *statsContainer,
|
||||||
// will still be restored
|
// will still be restored
|
||||||
stats.TotalFileCount++
|
stats.TotalFileCount++
|
||||||
|
|
||||||
if node.Links == 1 || node.Type == "dir" {
|
if node.Links == 1 || node.Type == restic.NodeTypeDir {
|
||||||
stats.TotalSize += node.Size
|
stats.TotalSize += node.Size
|
||||||
} else {
|
} else {
|
||||||
// if hardlinks are present only count each deviceID+inode once
|
// if hardlinks are present only count each deviceID+inode once
|
||||||
|
|
|
@ -24,20 +24,20 @@ func formatNode(path string, n *restic.Node, long bool, human bool) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Type {
|
switch n.Type {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
mode = 0
|
mode = 0
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
mode = os.ModeDir
|
mode = os.ModeDir
|
||||||
case "symlink":
|
case restic.NodeTypeSymlink:
|
||||||
mode = os.ModeSymlink
|
mode = os.ModeSymlink
|
||||||
target = fmt.Sprintf(" -> %v", n.LinkTarget)
|
target = fmt.Sprintf(" -> %v", n.LinkTarget)
|
||||||
case "dev":
|
case restic.NodeTypeDev:
|
||||||
mode = os.ModeDevice
|
mode = os.ModeDevice
|
||||||
case "chardev":
|
case restic.NodeTypeCharDev:
|
||||||
mode = os.ModeDevice | os.ModeCharDevice
|
mode = os.ModeDevice | os.ModeCharDevice
|
||||||
case "fifo":
|
case restic.NodeTypeFifo:
|
||||||
mode = os.ModeNamedPipe
|
mode = os.ModeNamedPipe
|
||||||
case "socket":
|
case restic.NodeTypeSocket:
|
||||||
mode = os.ModeSocket
|
mode = os.ModeSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ func TestFormatNode(t *testing.T) {
|
||||||
testPath := "/test/path"
|
testPath := "/test/path"
|
||||||
node := restic.Node{
|
node := restic.Node{
|
||||||
Name: "baz",
|
Name: "baz",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Size: 14680064,
|
Size: 14680064,
|
||||||
UID: 1000,
|
UID: 1000,
|
||||||
GID: 2000,
|
GID: 2000,
|
||||||
|
|
|
@ -232,7 +232,7 @@ func (arch *Archiver) trackItem(item string, previous, current *restic.Node, s I
|
||||||
}
|
}
|
||||||
|
|
||||||
switch current.Type {
|
switch current.Type {
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
switch {
|
switch {
|
||||||
case previous == nil:
|
case previous == nil:
|
||||||
arch.summary.Dirs.New++
|
arch.summary.Dirs.New++
|
||||||
|
@ -242,7 +242,7 @@ func (arch *Archiver) trackItem(item string, previous, current *restic.Node, s I
|
||||||
arch.summary.Dirs.Changed++
|
arch.summary.Dirs.Changed++
|
||||||
}
|
}
|
||||||
|
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
switch {
|
switch {
|
||||||
case previous == nil:
|
case previous == nil:
|
||||||
arch.summary.Files.New++
|
arch.summary.Files.New++
|
||||||
|
@ -261,7 +261,7 @@ func (arch *Archiver) nodeFromFileInfo(snPath, filename string, fi os.FileInfo,
|
||||||
node.AccessTime = node.ModTime
|
node.AccessTime = node.ModTime
|
||||||
}
|
}
|
||||||
if feature.Flag.Enabled(feature.DeviceIDForHardlinks) {
|
if feature.Flag.Enabled(feature.DeviceIDForHardlinks) {
|
||||||
if node.Links == 1 || node.Type == "dir" {
|
if node.Links == 1 || node.Type == restic.NodeTypeDir {
|
||||||
// the DeviceID is only necessary for hardlinked files
|
// the DeviceID is only necessary for hardlinked files
|
||||||
// when using subvolumes or snapshots their deviceIDs tend to change which causes
|
// when using subvolumes or snapshots their deviceIDs tend to change which causes
|
||||||
// restic to upload new tree blobs
|
// restic to upload new tree blobs
|
||||||
|
@ -280,7 +280,7 @@ func (arch *Archiver) nodeFromFileInfo(snPath, filename string, fi os.FileInfo,
|
||||||
// loadSubtree tries to load the subtree referenced by node. In case of an error, nil is returned.
|
// loadSubtree tries to load the subtree referenced by node. In case of an error, nil is returned.
|
||||||
// If there is no node to load, then nil is returned without an error.
|
// If there is no node to load, then nil is returned without an error.
|
||||||
func (arch *Archiver) loadSubtree(ctx context.Context, node *restic.Node) (*restic.Tree, error) {
|
func (arch *Archiver) loadSubtree(ctx context.Context, node *restic.Node) (*restic.Tree, error) {
|
||||||
if node == nil || node.Type != "dir" || node.Subtree == nil {
|
if node == nil || node.Type != restic.NodeTypeDir || node.Subtree == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,7 +583,7 @@ func fileChanged(fs fs.FS, fi os.FileInfo, node *restic.Node, ignoreFlags uint)
|
||||||
switch {
|
switch {
|
||||||
case node == nil:
|
case node == nil:
|
||||||
return true
|
return true
|
||||||
case node.Type != "file":
|
case node.Type != restic.NodeTypeFile:
|
||||||
// We're only called for regular files, so this is a type change.
|
// We're only called for regular files, so this is a type change.
|
||||||
return true
|
return true
|
||||||
case uint64(fi.Size()) != node.Size:
|
case uint64(fi.Size()) != node.Size:
|
||||||
|
|
|
@ -730,7 +730,7 @@ func TestFilChangedSpecialCases(t *testing.T) {
|
||||||
t.Run("type-change", func(t *testing.T) {
|
t.Run("type-change", func(t *testing.T) {
|
||||||
fi := lstat(t, filename)
|
fi := lstat(t, filename)
|
||||||
node := nodeFromFI(t, filename, fi)
|
node := nodeFromFI(t, filename, fi)
|
||||||
node.Type = "symlink"
|
node.Type = "restic.NodeTypeSymlink"
|
||||||
if !fileChanged(&fs.Local{}, fi, node, 0) {
|
if !fileChanged(&fs.Local{}, fi, node, 0) {
|
||||||
t.Fatal("node with changed type detected as unchanged")
|
t.Fatal("node with changed type detected as unchanged")
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ func (s *fileSaver) saveFile(ctx context.Context, chnker *chunker.Chunker, snPat
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
_ = f.Close()
|
_ = f.Close()
|
||||||
completeError(errors.Errorf("node type %q is wrong", node.Type))
|
completeError(errors.Errorf("node type %q is wrong", node.Type))
|
||||||
return
|
return
|
||||||
|
|
|
@ -289,7 +289,7 @@ func TestEnsureTree(ctx context.Context, t testing.TB, prefix string, repo resti
|
||||||
|
|
||||||
switch e := entry.(type) {
|
switch e := entry.(type) {
|
||||||
case TestDir:
|
case TestDir:
|
||||||
if node.Type != "dir" {
|
if node.Type != restic.NodeTypeDir {
|
||||||
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "dir")
|
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "dir")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -301,13 +301,13 @@ func TestEnsureTree(ctx context.Context, t testing.TB, prefix string, repo resti
|
||||||
|
|
||||||
TestEnsureTree(ctx, t, path.Join(prefix, node.Name), repo, *node.Subtree, e)
|
TestEnsureTree(ctx, t, path.Join(prefix, node.Name), repo, *node.Subtree, e)
|
||||||
case TestFile:
|
case TestFile:
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "file")
|
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "file")
|
||||||
}
|
}
|
||||||
TestEnsureFileContent(ctx, t, repo, nodePrefix, node, e)
|
TestEnsureFileContent(ctx, t, repo, nodePrefix, node, e)
|
||||||
case TestSymlink:
|
case TestSymlink:
|
||||||
if node.Type != "symlink" {
|
if node.Type != restic.NodeTypeSymlink {
|
||||||
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "file")
|
t.Errorf("tree node %v has wrong type %q, want %q", nodePrefix, node.Type, "symlink")
|
||||||
}
|
}
|
||||||
|
|
||||||
if e.Target != node.LinkTarget {
|
if e.Target != node.LinkTarget {
|
||||||
|
|
|
@ -344,7 +344,7 @@ func (c *Checker) checkTree(id restic.ID, tree *restic.Tree) (errs []error) {
|
||||||
|
|
||||||
for _, node := range tree.Nodes {
|
for _, node := range tree.Nodes {
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
if node.Content == nil {
|
if node.Content == nil {
|
||||||
errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("file %q has nil blob list", node.Name)})
|
errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("file %q has nil blob list", node.Name)})
|
||||||
}
|
}
|
||||||
|
@ -380,7 +380,7 @@ func (c *Checker) checkTree(id restic.ID, tree *restic.Tree) (errs []error) {
|
||||||
c.blobRefs.Unlock()
|
c.blobRefs.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
if node.Subtree == nil {
|
if node.Subtree == nil {
|
||||||
errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("dir node %q has no subtree", node.Name)})
|
errs = append(errs, &Error{TreeID: id, Err: errors.Errorf("dir node %q has no subtree", node.Name)})
|
||||||
continue
|
continue
|
||||||
|
@ -391,7 +391,7 @@ func (c *Checker) checkTree(id restic.ID, tree *restic.Tree) (errs []error) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
case "symlink", "socket", "chardev", "dev", "fifo":
|
case restic.NodeTypeSymlink, restic.NodeTypeSocket, restic.NodeTypeCharDev, restic.NodeTypeDev, restic.NodeTypeFifo:
|
||||||
// nothing to check
|
// nothing to check
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -482,7 +482,7 @@ func TestCheckerBlobTypeConfusion(t *testing.T) {
|
||||||
|
|
||||||
damagedNode := &restic.Node{
|
damagedNode := &restic.Node{
|
||||||
Name: "damaged",
|
Name: "damaged",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: 42,
|
Size: 42,
|
||||||
Content: restic.IDs{restic.TestParseID("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")},
|
Content: restic.IDs{restic.TestParseID("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")},
|
||||||
|
@ -507,14 +507,14 @@ func TestCheckerBlobTypeConfusion(t *testing.T) {
|
||||||
|
|
||||||
malNode := &restic.Node{
|
malNode := &restic.Node{
|
||||||
Name: "aaaaa",
|
Name: "aaaaa",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: uint64(len(buf)),
|
Size: uint64(len(buf)),
|
||||||
Content: restic.IDs{id},
|
Content: restic.IDs{id},
|
||||||
}
|
}
|
||||||
dirNode := &restic.Node{
|
dirNode := &restic.Node{
|
||||||
Name: "bbbbb",
|
Name: "bbbbb",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
Subtree: &id,
|
Subtree: &id,
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ func sendNodes(ctx context.Context, repo restic.BlobLoader, root *restic.Node, c
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is no directory we are finished
|
// If this is no directory we are finished
|
||||||
if !IsDir(root) {
|
if root.Type != restic.NodeTypeDir {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ func sendNodes(ctx context.Context, repo restic.BlobLoader, root *restic.Node, c
|
||||||
|
|
||||||
node.Path = path.Join(root.Path, nodepath)
|
node.Path = path.Join(root.Path, nodepath)
|
||||||
|
|
||||||
if !IsFile(node) && !IsDir(node) && !IsLink(node) {
|
if node.Type != restic.NodeTypeFile && node.Type != restic.NodeTypeDir && node.Type != restic.NodeTypeSymlink {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,18 +176,3 @@ func (d *Dumper) writeNode(ctx context.Context, w io.Writer, node *restic.Node)
|
||||||
|
|
||||||
return wg.Wait()
|
return wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsDir checks if the given node is a directory.
|
|
||||||
func IsDir(node *restic.Node) bool {
|
|
||||||
return node.Type == "dir"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLink checks if the given node as a link.
|
|
||||||
func IsLink(node *restic.Node) bool {
|
|
||||||
return node.Type == "symlink"
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsFile checks if the given node is a file.
|
|
||||||
func IsFile(node *restic.Node) bool {
|
|
||||||
return node.Type == "file"
|
|
||||||
}
|
|
||||||
|
|
|
@ -79,16 +79,16 @@ func (d *Dumper) dumpNodeTar(ctx context.Context, node *restic.Node, w *tar.Writ
|
||||||
header.Mode |= cISVTX
|
header.Mode |= cISVTX
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsFile(node) {
|
if node.Type == restic.NodeTypeFile {
|
||||||
header.Typeflag = tar.TypeReg
|
header.Typeflag = tar.TypeReg
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsLink(node) {
|
if node.Type == restic.NodeTypeSymlink {
|
||||||
header.Typeflag = tar.TypeSymlink
|
header.Typeflag = tar.TypeSymlink
|
||||||
header.Linkname = node.LinkTarget
|
header.Linkname = node.LinkTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsDir(node) {
|
if node.Type == restic.NodeTypeDir {
|
||||||
header.Typeflag = tar.TypeDir
|
header.Typeflag = tar.TypeDir
|
||||||
header.Name += "/"
|
header.Name += "/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ func TestFieldTooLong(t *testing.T) {
|
||||||
node := restic.Node{
|
node := restic.Node{
|
||||||
Name: "file_with_xattr",
|
Name: "file_with_xattr",
|
||||||
Path: "/file_with_xattr",
|
Path: "/file_with_xattr",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
ExtendedAttributes: []restic.ExtendedAttribute{
|
ExtendedAttributes: []restic.ExtendedAttribute{
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,7 @@ func (d *Dumper) dumpNodeZip(ctx context.Context, node *restic.Node, zw *zip.Wri
|
||||||
}
|
}
|
||||||
header.SetMode(node.Mode)
|
header.SetMode(node.Mode)
|
||||||
|
|
||||||
if IsDir(node) {
|
if node.Type == restic.NodeTypeDir {
|
||||||
header.Name += "/"
|
header.Name += "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ func (d *Dumper) dumpNodeZip(ctx context.Context, node *restic.Node, zw *zip.Wri
|
||||||
return errors.Wrap(err, "ZipHeader")
|
return errors.Wrap(err, "ZipHeader")
|
||||||
}
|
}
|
||||||
|
|
||||||
if IsLink(node) {
|
if node.Type == restic.NodeTypeSymlink {
|
||||||
if _, err = w.Write([]byte(node.LinkTarget)); err != nil {
|
if _, err = w.Write([]byte(node.LinkTarget)); err != nil {
|
||||||
return errors.Wrap(err, "Write")
|
return errors.Wrap(err, "Write")
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/restic"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ func ClearAttribute(path string, attribute uint32) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenHandleForEA return a file handle for file or dir for setting/getting EAs
|
// OpenHandleForEA return a file handle for file or dir for setting/getting EAs
|
||||||
func OpenHandleForEA(nodeType, path string, writeAccess bool) (handle windows.Handle, err error) {
|
func OpenHandleForEA(nodeType restic.NodeType, path string, writeAccess bool) (handle windows.Handle, err error) {
|
||||||
path = fixpath(path)
|
path = fixpath(path)
|
||||||
fileAccess := windows.FILE_READ_EA
|
fileAccess := windows.FILE_READ_EA
|
||||||
if writeAccess {
|
if writeAccess {
|
||||||
|
@ -113,10 +114,10 @@ func OpenHandleForEA(nodeType, path string, writeAccess bool) (handle windows.Ha
|
||||||
}
|
}
|
||||||
|
|
||||||
switch nodeType {
|
switch nodeType {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
utf16Path := windows.StringToUTF16Ptr(path)
|
utf16Path := windows.StringToUTF16Ptr(path)
|
||||||
handle, err = windows.CreateFile(utf16Path, uint32(fileAccess), 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, 0)
|
handle, err = windows.CreateFile(utf16Path, uint32(fileAccess), 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, 0)
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
utf16Path := windows.StringToUTF16Ptr(path)
|
utf16Path := windows.StringToUTF16Ptr(path)
|
||||||
handle, err = windows.CreateFile(utf16Path, uint32(fileAccess), 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
handle, err = windows.CreateFile(utf16Path, uint32(fileAccess), 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -25,7 +25,7 @@ func NodeFromFileInfo(path string, fi os.FileInfo, ignoreXattrListError bool) (*
|
||||||
}
|
}
|
||||||
|
|
||||||
node.Type = nodeTypeFromFileInfo(fi)
|
node.Type = nodeTypeFromFileInfo(fi)
|
||||||
if node.Type == "file" {
|
if node.Type == restic.NodeTypeFile {
|
||||||
node.Size = uint64(fi.Size())
|
node.Size = uint64(fi.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,27 +33,27 @@ func NodeFromFileInfo(path string, fi os.FileInfo, ignoreXattrListError bool) (*
|
||||||
return node, err
|
return node, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeTypeFromFileInfo(fi os.FileInfo) string {
|
func nodeTypeFromFileInfo(fi os.FileInfo) restic.NodeType {
|
||||||
switch fi.Mode() & os.ModeType {
|
switch fi.Mode() & os.ModeType {
|
||||||
case 0:
|
case 0:
|
||||||
return "file"
|
return restic.NodeTypeFile
|
||||||
case os.ModeDir:
|
case os.ModeDir:
|
||||||
return "dir"
|
return restic.NodeTypeDir
|
||||||
case os.ModeSymlink:
|
case os.ModeSymlink:
|
||||||
return "symlink"
|
return restic.NodeTypeSymlink
|
||||||
case os.ModeDevice | os.ModeCharDevice:
|
case os.ModeDevice | os.ModeCharDevice:
|
||||||
return "chardev"
|
return restic.NodeTypeCharDev
|
||||||
case os.ModeDevice:
|
case os.ModeDevice:
|
||||||
return "dev"
|
return restic.NodeTypeDev
|
||||||
case os.ModeNamedPipe:
|
case os.ModeNamedPipe:
|
||||||
return "fifo"
|
return restic.NodeTypeFifo
|
||||||
case os.ModeSocket:
|
case os.ModeSocket:
|
||||||
return "socket"
|
return restic.NodeTypeSocket
|
||||||
case os.ModeIrregular:
|
case os.ModeIrregular:
|
||||||
return "irregular"
|
return restic.NodeTypeIrregular
|
||||||
}
|
}
|
||||||
|
|
||||||
return ""
|
return restic.NodeTypeInvalid
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodeFillExtra(node *restic.Node, path string, fi os.FileInfo, ignoreXattrListError bool) error {
|
func nodeFillExtra(node *restic.Node, path string, fi os.FileInfo, ignoreXattrListError bool) error {
|
||||||
|
@ -74,25 +74,25 @@ func nodeFillExtra(node *restic.Node, path string, fi os.FileInfo, ignoreXattrLi
|
||||||
nodeFillUser(node, stat)
|
nodeFillUser(node, stat)
|
||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
node.Size = uint64(stat.size())
|
node.Size = uint64(stat.size())
|
||||||
node.Links = uint64(stat.nlink())
|
node.Links = uint64(stat.nlink())
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
case "symlink":
|
case restic.NodeTypeSymlink:
|
||||||
var err error
|
var err error
|
||||||
node.LinkTarget, err = Readlink(path)
|
node.LinkTarget, err = Readlink(path)
|
||||||
node.Links = uint64(stat.nlink())
|
node.Links = uint64(stat.nlink())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.WithStack(err)
|
return errors.WithStack(err)
|
||||||
}
|
}
|
||||||
case "dev":
|
case restic.NodeTypeDev:
|
||||||
node.Device = uint64(stat.rdev())
|
node.Device = uint64(stat.rdev())
|
||||||
node.Links = uint64(stat.nlink())
|
node.Links = uint64(stat.nlink())
|
||||||
case "chardev":
|
case restic.NodeTypeCharDev:
|
||||||
node.Device = uint64(stat.rdev())
|
node.Device = uint64(stat.rdev())
|
||||||
node.Links = uint64(stat.nlink())
|
node.Links = uint64(stat.nlink())
|
||||||
case "fifo":
|
case restic.NodeTypeFifo:
|
||||||
case "socket":
|
case restic.NodeTypeSocket:
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("unsupported file type %q", node.Type)
|
return errors.Errorf("unsupported file type %q", node.Type)
|
||||||
}
|
}
|
||||||
|
@ -178,31 +178,31 @@ func NodeCreateAt(node *restic.Node, path string) error {
|
||||||
debug.Log("create node %v at %v", node.Name, path)
|
debug.Log("create node %v at %v", node.Name, path)
|
||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
if err := nodeCreateDirAt(node, path); err != nil {
|
if err := nodeCreateDirAt(node, path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
if err := nodeCreateFileAt(path); err != nil {
|
if err := nodeCreateFileAt(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "symlink":
|
case restic.NodeTypeSymlink:
|
||||||
if err := nodeCreateSymlinkAt(node, path); err != nil {
|
if err := nodeCreateSymlinkAt(node, path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "dev":
|
case restic.NodeTypeDev:
|
||||||
if err := nodeCreateDevAt(node, path); err != nil {
|
if err := nodeCreateDevAt(node, path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "chardev":
|
case restic.NodeTypeCharDev:
|
||||||
if err := nodeCreateCharDevAt(node, path); err != nil {
|
if err := nodeCreateCharDevAt(node, path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "fifo":
|
case restic.NodeTypeFifo:
|
||||||
if err := nodeCreateFifoAt(path); err != nil {
|
if err := nodeCreateFifoAt(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case "socket":
|
case restic.NodeTypeSocket:
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("filetype %q not implemented", node.Type)
|
return errors.Errorf("filetype %q not implemented", node.Type)
|
||||||
|
@ -305,7 +305,7 @@ func nodeRestoreMetadata(node *restic.Node, path string, warn func(msg string))
|
||||||
// Moving RestoreTimestamps and restoreExtendedAttributes calls above as for readonly files in windows
|
// Moving RestoreTimestamps and restoreExtendedAttributes calls above as for readonly files in windows
|
||||||
// calling Chmod below will no longer allow any modifications to be made on the file and the
|
// calling Chmod below will no longer allow any modifications to be made on the file and the
|
||||||
// calls above would fail.
|
// calls above would fail.
|
||||||
if node.Type != "symlink" {
|
if node.Type != restic.NodeTypeSymlink {
|
||||||
if err := Chmod(path, node.Mode); err != nil {
|
if err := Chmod(path, node.Mode); err != nil {
|
||||||
if firsterr == nil {
|
if firsterr == nil {
|
||||||
firsterr = errors.WithStack(err)
|
firsterr = errors.WithStack(err)
|
||||||
|
@ -322,7 +322,7 @@ func NodeRestoreTimestamps(node *restic.Node, path string) error {
|
||||||
syscall.NsecToTimespec(node.ModTime.UnixNano()),
|
syscall.NsecToTimespec(node.ModTime.UnixNano()),
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "symlink" {
|
if node.Type == restic.NodeTypeSymlink {
|
||||||
return nodeRestoreSymlinkTimestamps(path, utimes)
|
return nodeRestoreSymlinkTimestamps(path, utimes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ func parseTime(s string) time.Time {
|
||||||
var nodeTests = []restic.Node{
|
var nodeTests = []restic.Node{
|
||||||
{
|
{
|
||||||
Name: "testFile",
|
Name: "testFile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -90,7 +90,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testSuidFile",
|
Name: "testSuidFile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -101,7 +101,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testSuidFile2",
|
Name: "testSuidFile2",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -112,7 +112,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testSticky",
|
Name: "testSticky",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -123,7 +123,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testDir",
|
Name: "testDir",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Subtree: nil,
|
Subtree: nil,
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -134,7 +134,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testSymlink",
|
Name: "testSymlink",
|
||||||
Type: "symlink",
|
Type: restic.NodeTypeSymlink,
|
||||||
LinkTarget: "invalid",
|
LinkTarget: "invalid",
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -148,7 +148,7 @@ var nodeTests = []restic.Node{
|
||||||
// metadata, so we can test if CreateAt works with pre-existing files.
|
// metadata, so we can test if CreateAt works with pre-existing files.
|
||||||
{
|
{
|
||||||
Name: "testFile",
|
Name: "testFile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -159,7 +159,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testDir",
|
Name: "testDir",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Subtree: nil,
|
Subtree: nil,
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -170,7 +170,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testXattrFile",
|
Name: "testXattrFile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -184,7 +184,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testXattrDir",
|
Name: "testXattrDir",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Subtree: nil,
|
Subtree: nil,
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -198,7 +198,7 @@ var nodeTests = []restic.Node{
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testXattrFileMacOSResourceFork",
|
Name: "testXattrFileMacOSResourceFork",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Content: restic.IDs{},
|
Content: restic.IDs{},
|
||||||
UID: uint32(os.Getuid()),
|
UID: uint32(os.Getuid()),
|
||||||
GID: uint32(os.Getgid()),
|
GID: uint32(os.Getgid()),
|
||||||
|
@ -268,7 +268,7 @@ func TestNodeRestoreAt(t *testing.T) {
|
||||||
"%v: UID doesn't match (%v != %v)", test.Type, test.UID, n2.UID)
|
"%v: UID doesn't match (%v != %v)", test.Type, test.UID, n2.UID)
|
||||||
rtest.Assert(t, test.GID == n2.GID,
|
rtest.Assert(t, test.GID == n2.GID,
|
||||||
"%v: GID doesn't match (%v != %v)", test.Type, test.GID, n2.GID)
|
"%v: GID doesn't match (%v != %v)", test.Type, test.GID, n2.GID)
|
||||||
if test.Type != "symlink" {
|
if test.Type != restic.NodeTypeSymlink {
|
||||||
// On OpenBSD only root can set sticky bit (see sticky(8)).
|
// On OpenBSD only root can set sticky bit (see sticky(8)).
|
||||||
if runtime.GOOS != "openbsd" && runtime.GOOS != "netbsd" && runtime.GOOS != "solaris" && test.Name == "testSticky" {
|
if runtime.GOOS != "openbsd" && runtime.GOOS != "netbsd" && runtime.GOOS != "solaris" && test.Name == "testSticky" {
|
||||||
rtest.Assert(t, test.Mode == n2.Mode,
|
rtest.Assert(t, test.Mode == n2.Mode,
|
||||||
|
@ -288,11 +288,11 @@ func TestNodeRestoreAt(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func AssertFsTimeEqual(t *testing.T, label string, nodeType string, t1 time.Time, t2 time.Time) {
|
func AssertFsTimeEqual(t *testing.T, label string, nodeType restic.NodeType, t1 time.Time, t2 time.Time) {
|
||||||
var equal bool
|
var equal bool
|
||||||
|
|
||||||
// Go currently doesn't support setting timestamps of symbolic links on darwin and bsd
|
// Go currently doesn't support setting timestamps of symbolic links on darwin and bsd
|
||||||
if nodeType == "symlink" {
|
if nodeType == restic.NodeTypeSymlink {
|
||||||
switch runtime.GOOS {
|
switch runtime.GOOS {
|
||||||
case "darwin", "freebsd", "openbsd", "netbsd", "solaris":
|
case "darwin", "freebsd", "openbsd", "netbsd", "solaris":
|
||||||
return
|
return
|
||||||
|
|
|
@ -42,7 +42,7 @@ func checkFile(t testing.TB, stat *syscall.Stat_t, node *restic.Node) {
|
||||||
t.Errorf("Dev does not match, want %v, got %v", stat.Dev, node.DeviceID)
|
t.Errorf("Dev does not match, want %v, got %v", stat.Dev, node.DeviceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Size != uint64(stat.Size) && node.Type != "symlink" {
|
if node.Size != uint64(stat.Size) && node.Type != restic.NodeTypeSymlink {
|
||||||
t.Errorf("Size does not match, want %v, got %v", stat.Size, node.Size)
|
t.Errorf("Size does not match, want %v, got %v", stat.Size, node.Size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,9 +135,9 @@ func TestNodeFromFileInfo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file", "symlink":
|
case restic.NodeTypeFile, restic.NodeTypeSymlink:
|
||||||
checkFile(t, s, node)
|
checkFile(t, s, node)
|
||||||
case "dev", "chardev":
|
case restic.NodeTypeDev, restic.NodeTypeCharDev:
|
||||||
checkFile(t, s, node)
|
checkFile(t, s, node)
|
||||||
checkDevice(t, s, node)
|
checkDevice(t, s, node)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -139,7 +139,7 @@ func closeFileHandle(fileHandle windows.Handle, path string) {
|
||||||
|
|
||||||
// restoreExtendedAttributes handles restore of the Windows Extended Attributes to the specified path.
|
// restoreExtendedAttributes handles restore of the Windows Extended Attributes to the specified path.
|
||||||
// The Windows API requires setting of all the Extended Attributes in one call.
|
// The Windows API requires setting of all the Extended Attributes in one call.
|
||||||
func restoreExtendedAttributes(nodeType, path string, eas []ExtendedAttribute) (err error) {
|
func restoreExtendedAttributes(nodeType restic.NodeType, path string, eas []ExtendedAttribute) (err error) {
|
||||||
var fileHandle windows.Handle
|
var fileHandle windows.Handle
|
||||||
if fileHandle, err = OpenHandleForEA(nodeType, path, true); fileHandle == 0 {
|
if fileHandle, err = OpenHandleForEA(nodeType, path, true); fileHandle == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -386,7 +386,7 @@ func nodeFillGenericAttributes(node *restic.Node, path string, fi os.FileInfo, s
|
||||||
}
|
}
|
||||||
|
|
||||||
var sd *[]byte
|
var sd *[]byte
|
||||||
if node.Type == "file" || node.Type == "dir" {
|
if node.Type == restic.NodeTypeFile || node.Type == restic.NodeTypeDir {
|
||||||
// Check EA support and get security descriptor for file/dir only
|
// Check EA support and get security descriptor for file/dir only
|
||||||
allowExtended, err = checkAndStoreEASupport(path)
|
allowExtended, err = checkAndStoreEASupport(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -24,14 +24,14 @@ func TestRestoreSecurityDescriptors(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
tempDir := t.TempDir()
|
tempDir := t.TempDir()
|
||||||
for i, sd := range TestFileSDs {
|
for i, sd := range TestFileSDs {
|
||||||
testRestoreSecurityDescriptor(t, sd, tempDir, "file", fmt.Sprintf("testfile%d", i))
|
testRestoreSecurityDescriptor(t, sd, tempDir, restic.NodeTypeFile, fmt.Sprintf("testfile%d", i))
|
||||||
}
|
}
|
||||||
for i, sd := range TestDirSDs {
|
for i, sd := range TestDirSDs {
|
||||||
testRestoreSecurityDescriptor(t, sd, tempDir, "dir", fmt.Sprintf("testdir%d", i))
|
testRestoreSecurityDescriptor(t, sd, tempDir, restic.NodeTypeDir, fmt.Sprintf("testdir%d", i))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testRestoreSecurityDescriptor(t *testing.T, sd string, tempDir, fileType, fileName string) {
|
func testRestoreSecurityDescriptor(t *testing.T, sd string, tempDir string, fileType restic.NodeType, fileName string) {
|
||||||
// Decode the encoded string SD to get the security descriptor input in bytes.
|
// Decode the encoded string SD to get the security descriptor input in bytes.
|
||||||
sdInputBytes, err := base64.StdEncoding.DecodeString(sd)
|
sdInputBytes, err := base64.StdEncoding.DecodeString(sd)
|
||||||
test.OK(t, errors.Wrapf(err, "Error decoding SD for: %s", fileName))
|
test.OK(t, errors.Wrapf(err, "Error decoding SD for: %s", fileName))
|
||||||
|
@ -56,7 +56,7 @@ func testRestoreSecurityDescriptor(t *testing.T, sd string, tempDir, fileType, f
|
||||||
CompareSecurityDescriptors(t, testPath, *sdByteFromRestoredNode, *sdBytesFromRestoredPath)
|
CompareSecurityDescriptors(t, testPath, *sdByteFromRestoredNode, *sdBytesFromRestoredPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNode(name string, fileType string, genericAttributes map[restic.GenericAttributeType]json.RawMessage) restic.Node {
|
func getNode(name string, fileType restic.NodeType, genericAttributes map[restic.GenericAttributeType]json.RawMessage) restic.Node {
|
||||||
return restic.Node{
|
return restic.Node{
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: fileType,
|
Type: fileType,
|
||||||
|
@ -113,7 +113,7 @@ func TestRestoreFileAttributes(t *testing.T) {
|
||||||
expectedNodes := []restic.Node{
|
expectedNodes := []restic.Node{
|
||||||
{
|
{
|
||||||
Name: fmt.Sprintf("testfile%d", i),
|
Name: fmt.Sprintf("testfile%d", i),
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0655,
|
Mode: 0655,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -146,7 +146,7 @@ func TestRestoreFileAttributes(t *testing.T) {
|
||||||
expectedNodes := []restic.Node{
|
expectedNodes := []restic.Node{
|
||||||
{
|
{
|
||||||
Name: fmt.Sprintf("testdirectory%d", i),
|
Name: fmt.Sprintf("testdirectory%d", i),
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -164,7 +164,7 @@ func runGenericAttributesTest(t *testing.T, tempDir string, genericAttributeName
|
||||||
expectedNodes := []restic.Node{
|
expectedNodes := []restic.Node{
|
||||||
{
|
{
|
||||||
Name: "testfile",
|
Name: "testfile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -173,7 +173,7 @@ func runGenericAttributesTest(t *testing.T, tempDir string, genericAttributeName
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testdirectory",
|
Name: "testdirectory",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -200,12 +200,12 @@ func restoreAndGetNode(t *testing.T, tempDir string, testNode *restic.Node, warn
|
||||||
err := os.MkdirAll(filepath.Dir(testPath), testNode.Mode)
|
err := os.MkdirAll(filepath.Dir(testPath), testNode.Mode)
|
||||||
test.OK(t, errors.Wrapf(err, "Failed to create parent directories for: %s", testPath))
|
test.OK(t, errors.Wrapf(err, "Failed to create parent directories for: %s", testPath))
|
||||||
|
|
||||||
if testNode.Type == "file" {
|
if testNode.Type == restic.NodeTypeFile {
|
||||||
|
|
||||||
testFile, err := os.Create(testPath)
|
testFile, err := os.Create(testPath)
|
||||||
test.OK(t, errors.Wrapf(err, "Failed to create test file: %s", testPath))
|
test.OK(t, errors.Wrapf(err, "Failed to create test file: %s", testPath))
|
||||||
testFile.Close()
|
testFile.Close()
|
||||||
} else if testNode.Type == "dir" {
|
} else if testNode.Type == restic.NodeTypeDir {
|
||||||
|
|
||||||
err := os.Mkdir(testPath, testNode.Mode)
|
err := os.Mkdir(testPath, testNode.Mode)
|
||||||
test.OK(t, errors.Wrapf(err, "Failed to create test directory: %s", testPath))
|
test.OK(t, errors.Wrapf(err, "Failed to create test directory: %s", testPath))
|
||||||
|
@ -242,7 +242,7 @@ func TestNewGenericAttributeType(t *testing.T) {
|
||||||
expectedNodes := []restic.Node{
|
expectedNodes := []restic.Node{
|
||||||
{
|
{
|
||||||
Name: "testfile",
|
Name: "testfile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -251,7 +251,7 @@ func TestNewGenericAttributeType(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testdirectory",
|
Name: "testdirectory",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -274,7 +274,7 @@ func TestRestoreExtendedAttributes(t *testing.T) {
|
||||||
expectedNodes := []restic.Node{
|
expectedNodes := []restic.Node{
|
||||||
{
|
{
|
||||||
Name: "testfile",
|
Name: "testfile",
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -285,7 +285,7 @@ func TestRestoreExtendedAttributes(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "testdirectory",
|
Name: "testdirectory",
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
ModTime: parseTime("2005-05-14 21:07:03.111"),
|
||||||
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
AccessTime: parseTime("2005-05-14 21:07:04.222"),
|
||||||
|
@ -301,9 +301,9 @@ func TestRestoreExtendedAttributes(t *testing.T) {
|
||||||
var handle windows.Handle
|
var handle windows.Handle
|
||||||
var err error
|
var err error
|
||||||
utf16Path := windows.StringToUTF16Ptr(testPath)
|
utf16Path := windows.StringToUTF16Ptr(testPath)
|
||||||
if node.Type == "file" {
|
if node.Type == restic.NodeTypeFile {
|
||||||
handle, err = windows.CreateFile(utf16Path, windows.FILE_READ_EA, 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, 0)
|
handle, err = windows.CreateFile(utf16Path, windows.FILE_READ_EA, 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, 0)
|
||||||
} else if node.Type == "dir" {
|
} else if node.Type == restic.NodeTypeDir {
|
||||||
handle, err = windows.CreateFile(utf16Path, windows.FILE_READ_EA, 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
handle, err = windows.CreateFile(utf16Path, windows.FILE_READ_EA, 0, nil, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||||
}
|
}
|
||||||
test.OK(t, errors.Wrapf(err, "Error opening file/directory for: %s", testPath))
|
test.OK(t, errors.Wrapf(err, "Error opening file/directory for: %s", testPath))
|
||||||
|
|
|
@ -23,13 +23,13 @@ func setAndVerifyXattr(t *testing.T, file string, attrs []restic.ExtendedAttribu
|
||||||
}
|
}
|
||||||
|
|
||||||
node := &restic.Node{
|
node := &restic.Node{
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
ExtendedAttributes: attrs,
|
ExtendedAttributes: attrs,
|
||||||
}
|
}
|
||||||
rtest.OK(t, nodeRestoreExtendedAttributes(node, file))
|
rtest.OK(t, nodeRestoreExtendedAttributes(node, file))
|
||||||
|
|
||||||
nodeActual := &restic.Node{
|
nodeActual := &restic.Node{
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
}
|
}
|
||||||
rtest.OK(t, nodeFillExtendedAttributes(nodeActual, file, false))
|
rtest.OK(t, nodeFillExtendedAttributes(nodeActual, file, false))
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ func unwrapCtxCanceled(err error) error {
|
||||||
// replaceSpecialNodes replaces nodes with name "." and "/" by their contents.
|
// replaceSpecialNodes replaces nodes with name "." and "/" by their contents.
|
||||||
// Otherwise, the node is returned.
|
// Otherwise, the node is returned.
|
||||||
func replaceSpecialNodes(ctx context.Context, repo restic.BlobLoader, node *restic.Node) ([]*restic.Node, error) {
|
func replaceSpecialNodes(ctx context.Context, repo restic.BlobLoader, node *restic.Node) ([]*restic.Node, error) {
|
||||||
if node.Type != "dir" || node.Subtree == nil {
|
if node.Type != restic.NodeTypeDir || node.Subtree == nil {
|
||||||
return []*restic.Node{node}, nil
|
return []*restic.Node{node}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ func (d *dir) calcNumberOfLinks() uint32 {
|
||||||
// of directories contained by d
|
// of directories contained by d
|
||||||
count := uint32(2)
|
count := uint32(2)
|
||||||
for _, node := range d.items {
|
for _, node := range d.items {
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,11 +182,11 @@ func (d *dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
|
||||||
name := cleanupNodeName(node.Name)
|
name := cleanupNodeName(node.Name)
|
||||||
var typ fuse.DirentType
|
var typ fuse.DirentType
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
typ = fuse.DT_Dir
|
typ = fuse.DT_Dir
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
typ = fuse.DT_File
|
typ = fuse.DT_File
|
||||||
case "symlink":
|
case restic.NodeTypeSymlink:
|
||||||
typ = fuse.DT_Link
|
typ = fuse.DT_Link
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,13 +215,13 @@ func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
|
||||||
}
|
}
|
||||||
inode := inodeFromNode(d.inode, node)
|
inode := inodeFromNode(d.inode, node)
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
return newDir(d.root, inode, d.inode, node)
|
return newDir(d.root, inode, d.inode, node)
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
return newFile(d.root, inode, node)
|
return newFile(d.root, inode, node)
|
||||||
case "symlink":
|
case restic.NodeTypeSymlink:
|
||||||
return newLink(d.root, inode, node)
|
return newLink(d.root, inode, node)
|
||||||
case "dev", "chardev", "fifo", "socket":
|
case restic.NodeTypeDev, restic.NodeTypeCharDev, restic.NodeTypeFifo, restic.NodeTypeSocket:
|
||||||
return newOther(d.root, inode, node)
|
return newOther(d.root, inode, node)
|
||||||
default:
|
default:
|
||||||
debug.Log(" node %v has unknown type %v", name, node.Type)
|
debug.Log(" node %v has unknown type %v", name, node.Type)
|
||||||
|
|
|
@ -249,7 +249,7 @@ func TestBlocks(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInodeFromNode(t *testing.T) {
|
func TestInodeFromNode(t *testing.T) {
|
||||||
node := &restic.Node{Name: "foo.txt", Type: "chardev", Links: 2}
|
node := &restic.Node{Name: "foo.txt", Type: restic.NodeTypeCharDev, Links: 2}
|
||||||
ino1 := inodeFromNode(1, node)
|
ino1 := inodeFromNode(1, node)
|
||||||
ino2 := inodeFromNode(2, node)
|
ino2 := inodeFromNode(2, node)
|
||||||
rtest.Assert(t, ino1 == ino2, "inodes %d, %d of hard links differ", ino1, ino2)
|
rtest.Assert(t, ino1 == ino2, "inodes %d, %d of hard links differ", ino1, ino2)
|
||||||
|
@ -261,9 +261,9 @@ func TestInodeFromNode(t *testing.T) {
|
||||||
|
|
||||||
// Regression test: in a path a/b/b, the grandchild should not get the
|
// Regression test: in a path a/b/b, the grandchild should not get the
|
||||||
// same inode as the grandparent.
|
// same inode as the grandparent.
|
||||||
a := &restic.Node{Name: "a", Type: "dir", Links: 2}
|
a := &restic.Node{Name: "a", Type: restic.NodeTypeDir, Links: 2}
|
||||||
ab := &restic.Node{Name: "b", Type: "dir", Links: 2}
|
ab := &restic.Node{Name: "b", Type: restic.NodeTypeDir, Links: 2}
|
||||||
abb := &restic.Node{Name: "b", Type: "dir", Links: 2}
|
abb := &restic.Node{Name: "b", Type: restic.NodeTypeDir, Links: 2}
|
||||||
inoA := inodeFromNode(1, a)
|
inoA := inodeFromNode(1, a)
|
||||||
inoAb := inodeFromNode(inoA, ab)
|
inoAb := inodeFromNode(inoA, ab)
|
||||||
inoAbb := inodeFromNode(inoAb, abb)
|
inoAbb := inodeFromNode(inoAb, abb)
|
||||||
|
@ -272,7 +272,7 @@ func TestInodeFromNode(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLink(t *testing.T) {
|
func TestLink(t *testing.T) {
|
||||||
node := &restic.Node{Name: "foo.txt", Type: "symlink", Links: 1, LinkTarget: "dst", ExtendedAttributes: []restic.ExtendedAttribute{
|
node := &restic.Node{Name: "foo.txt", Type: restic.NodeTypeSymlink, Links: 1, LinkTarget: "dst", ExtendedAttributes: []restic.ExtendedAttribute{
|
||||||
{Name: "foo", Value: []byte("bar")},
|
{Name: "foo", Value: []byte("bar")},
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -305,11 +305,11 @@ func BenchmarkInode(b *testing.B) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no_hard_links",
|
name: "no_hard_links",
|
||||||
node: restic.Node{Name: "a somewhat long-ish filename.svg.bz2", Type: "fifo"},
|
node: restic.Node{Name: "a somewhat long-ish filename.svg.bz2", Type: restic.NodeTypeFifo},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "hard_link",
|
name: "hard_link",
|
||||||
node: restic.Node{Name: "some other filename", Type: "file", Links: 2},
|
node: restic.Node{Name: "some other filename", Type: restic.NodeTypeFile, Links: 2},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
b.Run(sub.name, func(b *testing.B) {
|
b.Run(sub.name, func(b *testing.B) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ func inodeFromName(parent uint64, name string) uint64 {
|
||||||
|
|
||||||
// inodeFromNode generates an inode number for a file within a snapshot.
|
// inodeFromNode generates an inode number for a file within a snapshot.
|
||||||
func inodeFromNode(parent uint64, node *restic.Node) (inode uint64) {
|
func inodeFromNode(parent uint64, node *restic.Node) (inode uint64) {
|
||||||
if node.Links > 1 && node.Type != "dir" {
|
if node.Links > 1 && node.Type != restic.NodeTypeDir {
|
||||||
// If node has hard links, give them all the same inode,
|
// If node has hard links, give them all the same inode,
|
||||||
// irrespective of the parent.
|
// irrespective of the parent.
|
||||||
var buf [16]byte
|
var buf [16]byte
|
||||||
|
|
|
@ -46,7 +46,7 @@ func FindUsedBlobs(ctx context.Context, repo Loader, treeIDs IDs, blobs FindBlob
|
||||||
lock.Lock()
|
lock.Lock()
|
||||||
for _, node := range tree.Nodes {
|
for _, node := range tree.Nodes {
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case NodeTypeFile:
|
||||||
for _, blob := range node.Content {
|
for _, blob := range node.Content {
|
||||||
blobs.Insert(BlobHandle{ID: blob, Type: DataBlob})
|
blobs.Insert(BlobHandle{ID: blob, Type: DataBlob})
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,10 +67,24 @@ func storeGenericAttributeType(attributeTypes ...GenericAttributeType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NodeType string
|
||||||
|
|
||||||
|
var (
|
||||||
|
NodeTypeFile = NodeType("file")
|
||||||
|
NodeTypeDir = NodeType("dir")
|
||||||
|
NodeTypeSymlink = NodeType("symlink")
|
||||||
|
NodeTypeDev = NodeType("dev")
|
||||||
|
NodeTypeCharDev = NodeType("chardev")
|
||||||
|
NodeTypeFifo = NodeType("fifo")
|
||||||
|
NodeTypeSocket = NodeType("socket")
|
||||||
|
NodeTypeIrregular = NodeType("irregular")
|
||||||
|
NodeTypeInvalid = NodeType("")
|
||||||
|
)
|
||||||
|
|
||||||
// Node is a file, directory or other item in a backup.
|
// Node is a file, directory or other item in a backup.
|
||||||
type Node struct {
|
type Node struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Type string `json:"type"`
|
Type NodeType `json:"type"`
|
||||||
Mode os.FileMode `json:"mode,omitempty"`
|
Mode os.FileMode `json:"mode,omitempty"`
|
||||||
ModTime time.Time `json:"mtime,omitempty"`
|
ModTime time.Time `json:"mtime,omitempty"`
|
||||||
AccessTime time.Time `json:"atime,omitempty"`
|
AccessTime time.Time `json:"atime,omitempty"`
|
||||||
|
@ -110,19 +124,19 @@ func (n Nodes) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
|
||||||
func (node Node) String() string {
|
func (node Node) String() string {
|
||||||
var mode os.FileMode
|
var mode os.FileMode
|
||||||
switch node.Type {
|
switch node.Type {
|
||||||
case "file":
|
case NodeTypeFile:
|
||||||
mode = 0
|
mode = 0
|
||||||
case "dir":
|
case NodeTypeDir:
|
||||||
mode = os.ModeDir
|
mode = os.ModeDir
|
||||||
case "symlink":
|
case NodeTypeSymlink:
|
||||||
mode = os.ModeSymlink
|
mode = os.ModeSymlink
|
||||||
case "dev":
|
case NodeTypeDev:
|
||||||
mode = os.ModeDevice
|
mode = os.ModeDevice
|
||||||
case "chardev":
|
case NodeTypeCharDev:
|
||||||
mode = os.ModeDevice | os.ModeCharDevice
|
mode = os.ModeDevice | os.ModeCharDevice
|
||||||
case "fifo":
|
case NodeTypeFifo:
|
||||||
mode = os.ModeNamedPipe
|
mode = os.ModeNamedPipe
|
||||||
case "socket":
|
case NodeTypeSocket:
|
||||||
mode = os.ModeSocket
|
mode = os.ModeSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) I
|
||||||
|
|
||||||
node := &Node{
|
node := &Node{
|
||||||
Name: fmt.Sprintf("dir-%v", treeSeed),
|
Name: fmt.Sprintf("dir-%v", treeSeed),
|
||||||
Type: "dir",
|
Type: NodeTypeDir,
|
||||||
Mode: 0755,
|
Mode: 0755,
|
||||||
Subtree: &id,
|
Subtree: &id,
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ func (fs *fakeFileSystem) saveTree(ctx context.Context, seed int64, depth int) I
|
||||||
|
|
||||||
node := &Node{
|
node := &Node{
|
||||||
Name: fmt.Sprintf("file-%v", fileSeed),
|
Name: fmt.Sprintf("file-%v", fileSeed),
|
||||||
Type: "file",
|
Type: NodeTypeFile,
|
||||||
Mode: 0644,
|
Mode: 0644,
|
||||||
Size: uint64(fileSize),
|
Size: uint64(fileSize),
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ func (t *Tree) Sort() {
|
||||||
// Subtrees returns a slice of all subtree IDs of the tree.
|
// Subtrees returns a slice of all subtree IDs of the tree.
|
||||||
func (t *Tree) Subtrees() (trees IDs) {
|
func (t *Tree) Subtrees() (trees IDs) {
|
||||||
for _, node := range t.Nodes {
|
for _, node := range t.Nodes {
|
||||||
if node.Type == "dir" && node.Subtree != nil {
|
if node.Type == NodeTypeDir && node.Subtree != nil {
|
||||||
trees = append(trees, *node.Subtree)
|
trees = append(trees, *node.Subtree)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ func FindTreeDirectory(ctx context.Context, repo BlobLoader, id *ID, dir string)
|
||||||
if node == nil {
|
if node == nil {
|
||||||
return nil, fmt.Errorf("path %s: not found", subfolder)
|
return nil, fmt.Errorf("path %s: not found", subfolder)
|
||||||
}
|
}
|
||||||
if node.Type != "dir" || node.Subtree == nil {
|
if node.Type != NodeTypeDir || node.Subtree == nil {
|
||||||
return nil, fmt.Errorf("path %s: not a directory", subfolder)
|
return nil, fmt.Errorf("path %s: not a directory", subfolder)
|
||||||
}
|
}
|
||||||
id = node.Subtree
|
id = node.Subtree
|
||||||
|
|
|
@ -202,18 +202,18 @@ func (res *Restorer) traverseTreeInner(ctx context.Context, target, location str
|
||||||
}
|
}
|
||||||
|
|
||||||
// sockets cannot be restored
|
// sockets cannot be restored
|
||||||
if node.Type == "socket" {
|
if node.Type == restic.NodeTypeSocket {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedForRestore, childMayBeSelected := res.SelectFilter(nodeLocation, node.Type == "dir")
|
selectedForRestore, childMayBeSelected := res.SelectFilter(nodeLocation, node.Type == restic.NodeTypeDir)
|
||||||
debug.Log("SelectFilter returned %v %v for %q", selectedForRestore, childMayBeSelected, nodeLocation)
|
debug.Log("SelectFilter returned %v %v for %q", selectedForRestore, childMayBeSelected, nodeLocation)
|
||||||
|
|
||||||
if selectedForRestore {
|
if selectedForRestore {
|
||||||
hasRestored = true
|
hasRestored = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type == "dir" {
|
if node.Type == restic.NodeTypeDir {
|
||||||
if node.Subtree == nil {
|
if node.Subtree == nil {
|
||||||
return nil, hasRestored, errors.Errorf("Dir without subtree in tree %v", treeID.Str())
|
return nil, hasRestored, errors.Errorf("Dir without subtree in tree %v", treeID.Str())
|
||||||
}
|
}
|
||||||
|
@ -377,7 +377,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) (uint64, error)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
res.opts.Progress.AddFile(0)
|
res.opts.Progress.AddFile(0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -433,7 +433,7 @@ func (res *Restorer) RestoreTo(ctx context.Context, dst string) (uint64, error)
|
||||||
err = res.traverseTree(ctx, dst, *res.sn.Tree, treeVisitor{
|
err = res.traverseTree(ctx, dst, *res.sn.Tree, treeVisitor{
|
||||||
visitNode: func(node *restic.Node, target, location string) error {
|
visitNode: func(node *restic.Node, target, location string) error {
|
||||||
debug.Log("second pass, visitNode: restore node %q", location)
|
debug.Log("second pass, visitNode: restore node %q", location)
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
_, err := res.withOverwriteCheck(ctx, node, target, location, false, nil, func(_ bool, _ *fileState) error {
|
_, err := res.withOverwriteCheck(ctx, node, target, location, false, nil, func(_ bool, _ *fileState) error {
|
||||||
return res.restoreNodeTo(node, target, location)
|
return res.restoreNodeTo(node, target, location)
|
||||||
})
|
})
|
||||||
|
@ -547,7 +547,7 @@ func (res *Restorer) withOverwriteCheck(ctx context.Context, node *restic.Node,
|
||||||
|
|
||||||
var matches *fileState
|
var matches *fileState
|
||||||
updateMetadataOnly := false
|
updateMetadataOnly := false
|
||||||
if node.Type == "file" && !isHardlink {
|
if node.Type == restic.NodeTypeFile && !isHardlink {
|
||||||
// if a file fails to verify, then matches is nil which results in restoring from scratch
|
// if a file fails to verify, then matches is nil which results in restoring from scratch
|
||||||
matches, buf, _ = res.verifyFile(ctx, target, node, false, res.opts.Overwrite == OverwriteIfChanged, buf)
|
matches, buf, _ = res.verifyFile(ctx, target, node, false, res.opts.Overwrite == OverwriteIfChanged, buf)
|
||||||
// skip files that are already correct completely
|
// skip files that are already correct completely
|
||||||
|
@ -616,7 +616,7 @@ func (res *Restorer) VerifyFiles(ctx context.Context, dst string, countRestoredF
|
||||||
|
|
||||||
err := res.traverseTree(ctx, dst, *res.sn.Tree, treeVisitor{
|
err := res.traverseTree(ctx, dst, *res.sn.Tree, treeVisitor{
|
||||||
visitNode: func(node *restic.Node, target, location string) error {
|
visitNode: func(node *restic.Node, target, location string) error {
|
||||||
if node.Type != "file" {
|
if node.Type != restic.NodeTypeFile {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if metadataOnly, ok := res.hasRestoredFile(location); !ok || metadataOnly {
|
if metadataOnly, ok := res.hasRestoredFile(location); !ok || metadataOnly {
|
||||||
|
|
|
@ -108,7 +108,7 @@ func saveDir(t testing.TB, repo restic.BlobSaver, nodes map[string]Node, inode u
|
||||||
mode = 0644
|
mode = 0644
|
||||||
}
|
}
|
||||||
err := tree.Insert(&restic.Node{
|
err := tree.Insert(&restic.Node{
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
ModTime: node.ModTime,
|
ModTime: node.ModTime,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -123,7 +123,7 @@ func saveDir(t testing.TB, repo restic.BlobSaver, nodes map[string]Node, inode u
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
case Symlink:
|
case Symlink:
|
||||||
err := tree.Insert(&restic.Node{
|
err := tree.Insert(&restic.Node{
|
||||||
Type: "symlink",
|
Type: restic.NodeTypeSymlink,
|
||||||
Mode: os.ModeSymlink | 0o777,
|
Mode: os.ModeSymlink | 0o777,
|
||||||
ModTime: node.ModTime,
|
ModTime: node.ModTime,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -143,7 +143,7 @@ func saveDir(t testing.TB, repo restic.BlobSaver, nodes map[string]Node, inode u
|
||||||
}
|
}
|
||||||
|
|
||||||
err := tree.Insert(&restic.Node{
|
err := tree.Insert(&restic.Node{
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
Mode: mode,
|
Mode: mode,
|
||||||
ModTime: node.ModTime,
|
ModTime: node.ModTime,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|
|
@ -124,7 +124,7 @@ func (p *Progress) CompleteItem(item string, previous, current *restic.Node, s a
|
||||||
}
|
}
|
||||||
|
|
||||||
switch current.Type {
|
switch current.Type {
|
||||||
case "dir":
|
case restic.NodeTypeDir:
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
p.addProcessed(Counter{Dirs: 1})
|
p.addProcessed(Counter{Dirs: 1})
|
||||||
p.mu.Unlock()
|
p.mu.Unlock()
|
||||||
|
@ -138,7 +138,7 @@ func (p *Progress) CompleteItem(item string, previous, current *restic.Node, s a
|
||||||
p.printer.CompleteItem("dir modified", item, s, d)
|
p.printer.CompleteItem("dir modified", item, s, d)
|
||||||
}
|
}
|
||||||
|
|
||||||
case "file":
|
case restic.NodeTypeFile:
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
p.addProcessed(Counter{Files: 1})
|
p.addProcessed(Counter{Files: 1})
|
||||||
delete(p.currentFiles, item)
|
delete(p.currentFiles, item)
|
||||||
|
|
|
@ -55,10 +55,10 @@ func TestProgress(t *testing.T) {
|
||||||
prog.CompleteBlob(1024)
|
prog.CompleteBlob(1024)
|
||||||
|
|
||||||
// "dir unchanged"
|
// "dir unchanged"
|
||||||
node := restic.Node{Type: "dir"}
|
node := restic.Node{Type: restic.NodeTypeDir}
|
||||||
prog.CompleteItem("foo", &node, &node, archiver.ItemStats{}, 0)
|
prog.CompleteItem("foo", &node, &node, archiver.ItemStats{}, 0)
|
||||||
// "file new"
|
// "file new"
|
||||||
node.Type = "file"
|
node.Type = restic.NodeTypeFile
|
||||||
prog.CompleteItem("foo", nil, &node, archiver.ItemStats{}, 0)
|
prog.CompleteItem("foo", nil, &node, archiver.ItemStats{}, 0)
|
||||||
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
|
@ -65,7 +65,7 @@ func NewSnapshotSizeRewriter(rewriteNode NodeRewriteFunc) (*TreeRewriter, QueryR
|
||||||
t := NewTreeRewriter(RewriteOpts{
|
t := NewTreeRewriter(RewriteOpts{
|
||||||
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
||||||
node = rewriteNode(node, path)
|
node = rewriteNode(node, path)
|
||||||
if node != nil && node.Type == "file" {
|
if node != nil && node.Type == restic.NodeTypeFile {
|
||||||
count++
|
count++
|
||||||
size += node.Size
|
size += node.Size
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ func (t *TreeRewriter) RewriteTree(ctx context.Context, repo BlobLoadSaver, node
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "dir" {
|
if node.Type != restic.NodeTypeDir {
|
||||||
err = tb.AddNode(node)
|
err = tb.AddNode(node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return restic.ID{}, err
|
return restic.ID{}, err
|
||||||
|
|
|
@ -110,7 +110,7 @@ func checkIncreaseNodeSize(increase uint64) checkRewriteFunc {
|
||||||
return func(t testing.TB) (rewriter *TreeRewriter, final func(testing.TB)) {
|
return func(t testing.TB) (rewriter *TreeRewriter, final func(testing.TB)) {
|
||||||
rewriter = NewTreeRewriter(RewriteOpts{
|
rewriter = NewTreeRewriter(RewriteOpts{
|
||||||
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
RewriteNode: func(node *restic.Node, path string) *restic.Node {
|
||||||
if node.Type == "file" {
|
if node.Type == restic.NodeTypeFile {
|
||||||
node.Size += increase
|
node.Size += increase
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
|
@ -329,7 +329,7 @@ func TestSnapshotSizeQuery(t *testing.T) {
|
||||||
if path == "/bar" {
|
if path == "/bar" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if node.Type == "file" {
|
if node.Type == restic.NodeTypeFile {
|
||||||
node.Size += 21
|
node.Size += 21
|
||||||
}
|
}
|
||||||
return node
|
return node
|
||||||
|
|
|
@ -63,11 +63,11 @@ func walk(ctx context.Context, repo restic.BlobLoader, prefix string, parentTree
|
||||||
|
|
||||||
p := path.Join(prefix, node.Name)
|
p := path.Join(prefix, node.Name)
|
||||||
|
|
||||||
if node.Type == "" {
|
if node.Type == restic.NodeTypeInvalid {
|
||||||
return errors.Errorf("node type is empty for node %q", node.Name)
|
return errors.Errorf("node type is empty for node %q", node.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "dir" {
|
if node.Type != restic.NodeTypeDir {
|
||||||
err := visitor.ProcessNode(parentTreeID, p, node, nil)
|
err := visitor.ProcessNode(parentTreeID, p, node, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == ErrSkipNode {
|
if err == ErrSkipNode {
|
||||||
|
|
|
@ -38,7 +38,7 @@ func buildTreeMap(tree TestTree, m TreeMap) restic.ID {
|
||||||
case TestFile:
|
case TestFile:
|
||||||
err := tb.AddNode(&restic.Node{
|
err := tb.AddNode(&restic.Node{
|
||||||
Name: name,
|
Name: name,
|
||||||
Type: "file",
|
Type: restic.NodeTypeFile,
|
||||||
Size: elem.Size,
|
Size: elem.Size,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -49,7 +49,7 @@ func buildTreeMap(tree TestTree, m TreeMap) restic.ID {
|
||||||
err := tb.AddNode(&restic.Node{
|
err := tb.AddNode(&restic.Node{
|
||||||
Name: name,
|
Name: name,
|
||||||
Subtree: &id,
|
Subtree: &id,
|
||||||
Type: "dir",
|
Type: restic.NodeTypeDir,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
Loading…
Reference in a new issue