Add a way to get lineage info from a backup
Add a helper function that deserializes persisted lineage information and returns it in a nicer form.
This commit is contained in:
parent
d1fba10aeb
commit
2295c5cc20
@ -7,6 +7,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/dustin/go-humanize"
|
||||
|
||||
"github.com/alcionai/corso/src/cli/print"
|
||||
@ -14,6 +15,7 @@ import (
|
||||
"github.com/alcionai/corso/src/internal/common/str"
|
||||
"github.com/alcionai/corso/src/internal/model"
|
||||
"github.com/alcionai/corso/src/internal/stats"
|
||||
"github.com/alcionai/corso/src/pkg/backup/identity"
|
||||
"github.com/alcionai/corso/src/pkg/fault"
|
||||
"github.com/alcionai/corso/src/pkg/selectors"
|
||||
)
|
||||
@ -180,6 +182,66 @@ func New(
|
||||
return b
|
||||
}
|
||||
|
||||
// PersistedBaseSet contains information extracted from the backup model
|
||||
// relating to its lineage. It only contains the backup ID and Reasons each
|
||||
// base was selected instead of the full set of information contained in other
|
||||
// structs like BackupBases.
|
||||
type PersistedBaseSet struct {
|
||||
Merge map[model.StableID][]identity.Reasoner
|
||||
Assist map[model.StableID][]identity.Reasoner
|
||||
}
|
||||
|
||||
func (b Backup) Bases() (PersistedBaseSet, error) {
|
||||
res := PersistedBaseSet{
|
||||
Merge: map[model.StableID][]identity.Reasoner{},
|
||||
Assist: map[model.StableID][]identity.Reasoner{},
|
||||
}
|
||||
|
||||
for id, reasons := range b.MergeBases {
|
||||
for _, reason := range reasons {
|
||||
service, cat, err := serviceCatStringToTypes(reason)
|
||||
if err != nil {
|
||||
return res, clues.Wrap(err, "getting Reason info").With(
|
||||
"base_type", "merge",
|
||||
"base_backup_id", id,
|
||||
"input_string", reason)
|
||||
}
|
||||
|
||||
res.Merge[id] = append(res.Merge[id], identity.NewReason(
|
||||
// Tenant ID not currently stored in backup model.
|
||||
"",
|
||||
str.First(
|
||||
b.ProtectedResourceID,
|
||||
b.Selector.DiscreteOwner),
|
||||
service,
|
||||
cat))
|
||||
}
|
||||
}
|
||||
|
||||
for id, reasons := range b.AssistBases {
|
||||
for _, reason := range reasons {
|
||||
service, cat, err := serviceCatStringToTypes(reason)
|
||||
if err != nil {
|
||||
return res, clues.Wrap(err, "getting Reason info").With(
|
||||
"base_type", "assist",
|
||||
"base_backup_id", id,
|
||||
"input_string", reason)
|
||||
}
|
||||
|
||||
res.Assist[id] = append(res.Assist[id], identity.NewReason(
|
||||
// Tenant ID not currently stored in backup model.
|
||||
"",
|
||||
str.First(
|
||||
b.ProtectedResourceID,
|
||||
b.Selector.DiscreteOwner),
|
||||
service,
|
||||
cat))
|
||||
}
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// CLI Output
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
@ -2,7 +2,9 @@ package backup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"github.com/alcionai/clues"
|
||||
"github.com/kopia/kopia/repo/manifest"
|
||||
"github.com/kopia/kopia/snapshot"
|
||||
|
||||
@ -40,6 +42,41 @@ func serviceCatString(
|
||||
return serviceCatPrefix + service.String() + separator + category.String()
|
||||
}
|
||||
|
||||
func serviceCatStringToTypes(
|
||||
input string,
|
||||
) (path.ServiceType, path.CategoryType, error) {
|
||||
trimmed := strings.TrimPrefix(input, serviceCatPrefix)
|
||||
// No prefix found -> unexpected format.
|
||||
if trimmed == input {
|
||||
return path.UnknownService,
|
||||
path.UnknownCategory,
|
||||
clues.New("missing tag prefix")
|
||||
}
|
||||
|
||||
parts := strings.Split(trimmed, separator)
|
||||
if len(parts) != 2 {
|
||||
return path.UnknownService,
|
||||
path.UnknownCategory,
|
||||
clues.New("missing tag separator")
|
||||
}
|
||||
|
||||
cat := path.ToCategoryType(parts[1])
|
||||
if cat == path.UnknownCategory {
|
||||
return path.UnknownService,
|
||||
path.UnknownCategory,
|
||||
clues.New("parsing category").With("input_category", parts[1])
|
||||
}
|
||||
|
||||
service := path.ToServiceType(parts[0])
|
||||
if service == path.UnknownService {
|
||||
return path.UnknownService,
|
||||
path.UnknownCategory,
|
||||
clues.New("parsing service").With("input_service", parts[0])
|
||||
}
|
||||
|
||||
return service, cat, nil
|
||||
}
|
||||
|
||||
// reasonTags returns the set of key-value pairs that can be used as tags to
|
||||
// represent this Reason.
|
||||
// nolint
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user