mirror of
https://github.com/zrepl/zrepl.git
synced 2025-05-02 07:14:35 +02:00
pruner: skip placeholders + FSes without correspondents on source
fixes #126
This commit is contained in:
parent
b85ec52387
commit
d78d20e2d0
@ -505,6 +505,10 @@ func (t *tui) renderPrunerReport(r *pruner.Report) {
|
|||||||
for _, fs := range all {
|
for _, fs := range all {
|
||||||
t.write(rightPad(fs.Filesystem, maxFSname, " "))
|
t.write(rightPad(fs.Filesystem, maxFSname, " "))
|
||||||
t.write(" ")
|
t.write(" ")
|
||||||
|
if !fs.SkipReason.NotSkipped() {
|
||||||
|
t.printf("skipped: %s\n", fs.SkipReason)
|
||||||
|
continue
|
||||||
|
}
|
||||||
if fs.LastError != "" {
|
if fs.LastError != "" {
|
||||||
t.printf("ERROR (%d): %s\n", fs.ErrorCount, fs.LastError) // whitespace is padding
|
t.printf("ERROR (%d): %s\n", fs.ErrorCount, fs.LastError) // whitespace is padding
|
||||||
continue
|
continue
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
// Try to keep it compatible with gitub.com/zrepl/zrepl/endpoint.Endpoint
|
// Try to keep it compatible with gitub.com/zrepl/zrepl/endpoint.Endpoint
|
||||||
type History interface {
|
type History interface {
|
||||||
ReplicationCursor(ctx context.Context, req *pdu.ReplicationCursorReq) (*pdu.ReplicationCursorRes, error)
|
ReplicationCursor(ctx context.Context, req *pdu.ReplicationCursorReq) (*pdu.ReplicationCursorRes, error)
|
||||||
|
ListFilesystems(ctx context.Context, req *pdu.ListFilesystemReq) (*pdu.ListFilesystemRes, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to keep it compatible with gitub.com/zrepl/zrepl/endpoint.Endpoint
|
// Try to keep it compatible with gitub.com/zrepl/zrepl/endpoint.Endpoint
|
||||||
@ -225,6 +226,7 @@ type FSReport struct {
|
|||||||
Filesystem string
|
Filesystem string
|
||||||
SnapshotList, DestroyList []SnapshotReport
|
SnapshotList, DestroyList []SnapshotReport
|
||||||
ErrorCount int
|
ErrorCount int
|
||||||
|
SkipReason FSSkipReason
|
||||||
LastError string
|
LastError string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +279,10 @@ type fs struct {
|
|||||||
// permanent error during planning
|
// permanent error during planning
|
||||||
planErr error
|
planErr error
|
||||||
|
|
||||||
|
// if != "", the fs was skipped for planning and the field
|
||||||
|
// contains the reason
|
||||||
|
skipReason FSSkipReason
|
||||||
|
|
||||||
// snapshots presented by target
|
// snapshots presented by target
|
||||||
// (type snapshot)
|
// (type snapshot)
|
||||||
snaps []pruning.Snapshot
|
snaps []pruning.Snapshot
|
||||||
@ -289,7 +295,18 @@ type fs struct {
|
|||||||
// only during Exec state, also used by execQueue
|
// only during Exec state, also used by execQueue
|
||||||
execErrLast error
|
execErrLast error
|
||||||
execErrCount int
|
execErrCount int
|
||||||
|
}
|
||||||
|
|
||||||
|
type FSSkipReason string
|
||||||
|
|
||||||
|
const (
|
||||||
|
NotSkipped = ""
|
||||||
|
SkipPlaceholder = "filesystem is placeholder"
|
||||||
|
SkipNoCorrespondenceOnSender = "filesystem has no correspondence on sender"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (r FSSkipReason) NotSkipped() bool {
|
||||||
|
return r == NotSkipped
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fs) Report() FSReport {
|
func (f *fs) Report() FSReport {
|
||||||
@ -299,6 +316,11 @@ func (f *fs) Report() FSReport {
|
|||||||
r := FSReport{}
|
r := FSReport{}
|
||||||
r.Filesystem = f.path
|
r.Filesystem = f.path
|
||||||
r.ErrorCount = f.execErrCount
|
r.ErrorCount = f.execErrCount
|
||||||
|
r.SkipReason = f.skipReason
|
||||||
|
if !r.SkipReason.NotSkipped() {
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
if f.planErr != nil {
|
if f.planErr != nil {
|
||||||
r.LastError = f.planErr.Error()
|
r.LastError = f.planErr.Error()
|
||||||
} else if f.execErrLast != nil {
|
} else if f.execErrLast != nil {
|
||||||
@ -380,6 +402,15 @@ func statePlan(a *args, u updater) state {
|
|||||||
ka = &pruner.Progress
|
ka = &pruner.Progress
|
||||||
})
|
})
|
||||||
|
|
||||||
|
sfssres, err := receiver.ListFilesystems(ctx, &pdu.ListFilesystemReq{})
|
||||||
|
if err != nil {
|
||||||
|
return onErr(u, err)
|
||||||
|
}
|
||||||
|
sfss := make(map[string]*pdu.Filesystem)
|
||||||
|
for _, sfs := range sfssres.GetFilesystems() {
|
||||||
|
sfss[sfs.GetPath()] = sfs
|
||||||
|
}
|
||||||
|
|
||||||
tfssres, err := target.ListFilesystems(ctx, &pdu.ListFilesystemReq{})
|
tfssres, err := target.ListFilesystems(ctx, &pdu.ListFilesystemReq{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return onErr(u, err)
|
return onErr(u, err)
|
||||||
@ -398,6 +429,16 @@ func statePlan(a *args, u updater) state {
|
|||||||
}
|
}
|
||||||
pfss[i] = pfs
|
pfss[i] = pfs
|
||||||
|
|
||||||
|
if tfs.GetIsPlaceholder() {
|
||||||
|
pfs.skipReason = SkipPlaceholder
|
||||||
|
l.WithField("skip_reason", pfs.skipReason).Debug("skipping filesystem")
|
||||||
|
continue
|
||||||
|
} else if sfs := sfss[tfs.GetPath()]; sfs == nil {
|
||||||
|
pfs.skipReason = SkipNoCorrespondenceOnSender
|
||||||
|
l.WithField("skip_reason", pfs.skipReason).WithField("sfs", sfs.GetPath()).Debug("skipping filesystem")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
tfsvsres, err := target.ListFilesystemVersions(ctx, &pdu.ListFilesystemVersionsReq{Filesystem: tfs.Path})
|
tfsvsres, err := target.ListFilesystemVersions(ctx, &pdu.ListFilesystemVersionsReq{Filesystem: tfs.Path})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.WithError(err).Error("cannot list filesystem versions")
|
l.WithError(err).Error("cannot list filesystem versions")
|
||||||
|
Loading…
Reference in New Issue
Block a user