Have kopia package generate tags during backup based on Reasons (#3869)
Move tag generation from the backup op to the kopia package. This makes it match the pattern that finding base backups uses where a set of Reasons and a separate set of additional tags are provided --- #### Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No #### Type of change - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Supportability/Tests - [ ] 💻 CI/Deployment - [x] 🧹 Tech Debt/Cleanup #### Issue(s) * #2360 #### Test Plan - [x] 💪 Manual - [x] ⚡ Unit test - [x] 💚 E2E
This commit is contained in:
parent
7677299ace
commit
62d4c68c04
@ -39,8 +39,6 @@ type Reasoner interface {
|
|||||||
// SubtreePath returns the path prefix for data in existing backups that have
|
// SubtreePath returns the path prefix for data in existing backups that have
|
||||||
// parameters (tenant, protected resourced, etc) that match this Reasoner.
|
// parameters (tenant, protected resourced, etc) that match this Reasoner.
|
||||||
SubtreePath() (path.Path, error)
|
SubtreePath() (path.Path, error)
|
||||||
// TODO(ashmrtn): Remove this when kopia generates tags from Reasons.
|
|
||||||
TagKeys() []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReason(
|
func NewReason(
|
||||||
@ -92,9 +90,7 @@ func (r reason) SubtreePath() (path.Path, error) {
|
|||||||
return p, clues.Wrap(err, "building path").OrNil()
|
return p, clues.Wrap(err, "building path").OrNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ashmrtn): Remove this when kopia generates tags based off Reasons. Here
|
func tagKeys(r Reasoner) []string {
|
||||||
// at the moment so things compile.
|
|
||||||
func (r reason) TagKeys() []string {
|
|
||||||
return []string{
|
return []string{
|
||||||
r.ProtectedResource(),
|
r.ProtectedResource(),
|
||||||
serviceCatString(r.Service(), r.Category()),
|
serviceCatString(r.Service(), r.Category()),
|
||||||
@ -334,7 +330,7 @@ func (b *baseFinder) getBase(
|
|||||||
) (*BackupEntry, *ManifestEntry, []ManifestEntry, error) {
|
) (*BackupEntry, *ManifestEntry, []ManifestEntry, error) {
|
||||||
allTags := map[string]string{}
|
allTags := map[string]string{}
|
||||||
|
|
||||||
for _, k := range r.TagKeys() {
|
for _, k := range tagKeys(r) {
|
||||||
allTags[k] = ""
|
allTags[k] = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ type (
|
|||||||
BackupConsumer interface {
|
BackupConsumer interface {
|
||||||
ConsumeBackupCollections(
|
ConsumeBackupCollections(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
backupReasons []kopia.Reasoner,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.BackupCollection,
|
cs []data.BackupCollection,
|
||||||
pmr prefixmatcher.StringSetReader,
|
pmr prefixmatcher.StringSetReader,
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/kopia/kopia/snapshot/policy"
|
"github.com/kopia/kopia/snapshot/policy"
|
||||||
"github.com/kopia/kopia/snapshot/snapshotfs"
|
"github.com/kopia/kopia/snapshot/snapshotfs"
|
||||||
"github.com/kopia/kopia/snapshot/snapshotmaintenance"
|
"github.com/kopia/kopia/snapshot/snapshotmaintenance"
|
||||||
|
"golang.org/x/exp/maps"
|
||||||
|
|
||||||
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
"github.com/alcionai/corso/src/internal/common/prefixmatcher"
|
||||||
"github.com/alcionai/corso/src/internal/common/ptr"
|
"github.com/alcionai/corso/src/internal/common/ptr"
|
||||||
@ -145,10 +146,11 @@ type IncrementalBase struct {
|
|||||||
// complete backup of all data.
|
// complete backup of all data.
|
||||||
func (w Wrapper) ConsumeBackupCollections(
|
func (w Wrapper) ConsumeBackupCollections(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
backupReasons []Reasoner,
|
||||||
previousSnapshots []IncrementalBase,
|
previousSnapshots []IncrementalBase,
|
||||||
collections []data.BackupCollection,
|
collections []data.BackupCollection,
|
||||||
globalExcludeSet prefixmatcher.StringSetReader,
|
globalExcludeSet prefixmatcher.StringSetReader,
|
||||||
tags map[string]string,
|
additionalTags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
) (*BackupStats, *details.Builder, DetailsMergeInfoer, error) {
|
) (*BackupStats, *details.Builder, DetailsMergeInfoer, error) {
|
||||||
@ -190,6 +192,19 @@ func (w Wrapper) ConsumeBackupCollections(
|
|||||||
return nil, nil, nil, clues.Wrap(err, "building kopia directories")
|
return nil, nil, nil, clues.Wrap(err, "building kopia directories")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add some extra tags so we can look things up by reason.
|
||||||
|
tags := maps.Clone(additionalTags)
|
||||||
|
if tags == nil {
|
||||||
|
// Some platforms seem to return nil if the input is nil.
|
||||||
|
tags = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range backupReasons {
|
||||||
|
for _, k := range tagKeys(r) {
|
||||||
|
tags[k] = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s, err := w.makeSnapshotWithRoot(
|
s, err := w.makeSnapshotWithRoot(
|
||||||
ctx,
|
ctx,
|
||||||
previousSnapshots,
|
previousSnapshots,
|
||||||
|
|||||||
@ -718,15 +718,17 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedTags := map[string]string{}
|
||||||
|
|
||||||
|
maps.Copy(expectedTags, tags)
|
||||||
|
|
||||||
for _, r := range reasons {
|
for _, r := range reasons {
|
||||||
for _, k := range r.TagKeys() {
|
for _, k := range tagKeys(r) {
|
||||||
tags[k] = ""
|
expectedTags[k] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedTags := map[string]string{}
|
expectedTags = normalizeTagKVs(expectedTags)
|
||||||
|
|
||||||
maps.Copy(expectedTags, normalizeTagKVs(tags))
|
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
@ -757,6 +759,7 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
|
|||||||
|
|
||||||
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
|
reasons,
|
||||||
prevSnaps,
|
prevSnaps,
|
||||||
collections,
|
collections,
|
||||||
nil,
|
nil,
|
||||||
@ -847,15 +850,17 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() {
|
|||||||
storePath.Category()),
|
storePath.Category()),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expectedTags := map[string]string{}
|
||||||
|
|
||||||
|
maps.Copy(expectedTags, tags)
|
||||||
|
|
||||||
for _, r := range reasons {
|
for _, r := range reasons {
|
||||||
for _, k := range r.TagKeys() {
|
for _, k := range tagKeys(r) {
|
||||||
tags[k] = ""
|
expectedTags[k] = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedTags := map[string]string{}
|
expectedTags = normalizeTagKVs(expectedTags)
|
||||||
|
|
||||||
maps.Copy(expectedTags, normalizeTagKVs(tags))
|
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
@ -942,6 +947,7 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() {
|
|||||||
|
|
||||||
stats, deets, prevShortRefs, err := suite.w.ConsumeBackupCollections(
|
stats, deets, prevShortRefs, err := suite.w.ConsumeBackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
|
reasons,
|
||||||
prevSnaps,
|
prevSnaps,
|
||||||
collections,
|
collections,
|
||||||
nil,
|
nil,
|
||||||
@ -1018,13 +1024,8 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() {
|
|||||||
|
|
||||||
w := &Wrapper{k}
|
w := &Wrapper{k}
|
||||||
|
|
||||||
tags := map[string]string{}
|
|
||||||
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
||||||
|
|
||||||
for _, k := range r.TagKeys() {
|
|
||||||
tags[k] = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
dc1 := exchMock.NewCollection(suite.storePath1, suite.locPath1, 1)
|
dc1 := exchMock.NewCollection(suite.storePath1, suite.locPath1, 1)
|
||||||
dc2 := exchMock.NewCollection(suite.storePath2, suite.locPath2, 1)
|
dc2 := exchMock.NewCollection(suite.storePath2, suite.locPath2, 1)
|
||||||
|
|
||||||
@ -1036,10 +1037,11 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() {
|
|||||||
|
|
||||||
stats, _, _, err := w.ConsumeBackupCollections(
|
stats, _, _, err := w.ConsumeBackupCollections(
|
||||||
ctx,
|
ctx,
|
||||||
|
[]Reasoner{r},
|
||||||
nil,
|
nil,
|
||||||
[]data.BackupCollection{dc1, dc2},
|
[]data.BackupCollection{dc1, dc2},
|
||||||
nil,
|
nil,
|
||||||
tags,
|
nil,
|
||||||
true,
|
true,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -1110,13 +1112,8 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() {
|
|||||||
|
|
||||||
loc1 := path.Builder{}.Append(suite.storePath1.Folders()...)
|
loc1 := path.Builder{}.Append(suite.storePath1.Folders()...)
|
||||||
loc2 := path.Builder{}.Append(suite.storePath2.Folders()...)
|
loc2 := path.Builder{}.Append(suite.storePath2.Folders()...)
|
||||||
tags := map[string]string{}
|
|
||||||
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
||||||
|
|
||||||
for _, k := range r.TagKeys() {
|
|
||||||
tags[k] = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
collections := []data.BackupCollection{
|
collections := []data.BackupCollection{
|
||||||
&mockBackupCollection{
|
&mockBackupCollection{
|
||||||
path: suite.storePath1,
|
path: suite.storePath1,
|
||||||
@ -1158,10 +1155,11 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() {
|
|||||||
|
|
||||||
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
|
[]Reasoner{r},
|
||||||
nil,
|
nil,
|
||||||
collections,
|
collections,
|
||||||
nil,
|
nil,
|
||||||
tags,
|
nil,
|
||||||
true,
|
true,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
require.Error(t, err, clues.ToCore(err))
|
require.Error(t, err, clues.ToCore(err))
|
||||||
@ -1233,6 +1231,7 @@ func (suite *KopiaIntegrationSuite) TestBackupCollectionsHandlesNoCollections()
|
|||||||
s, d, _, err := suite.w.ConsumeBackupCollections(
|
s, d, _, err := suite.w.ConsumeBackupCollections(
|
||||||
ctx,
|
ctx,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
test.collections,
|
test.collections,
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
@ -1385,19 +1384,15 @@ func (suite *KopiaSimpleRepoIntegrationSuite) SetupTest() {
|
|||||||
collections = append(collections, collection)
|
collections = append(collections, collection)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags := map[string]string{}
|
|
||||||
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory)
|
||||||
|
|
||||||
for _, k := range r.TagKeys() {
|
|
||||||
tags[k] = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
stats, deets, _, err := suite.w.ConsumeBackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
|
[]Reasoner{r},
|
||||||
nil,
|
nil,
|
||||||
collections,
|
collections,
|
||||||
nil,
|
nil,
|
||||||
tags,
|
nil,
|
||||||
false,
|
false,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
@ -1443,12 +1438,6 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
|
|||||||
man, err := suite.w.c.LoadSnapshot(suite.ctx, suite.snapshotID)
|
man, err := suite.w.c.LoadSnapshot(suite.ctx, suite.snapshotID)
|
||||||
require.NoError(suite.T(), err, "getting base snapshot: %v", clues.ToCore(err))
|
require.NoError(suite.T(), err, "getting base snapshot: %v", clues.ToCore(err))
|
||||||
|
|
||||||
tags := map[string]string{}
|
|
||||||
|
|
||||||
for _, k := range r.TagKeys() {
|
|
||||||
tags[k] = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
excludeItem bool
|
excludeItem bool
|
||||||
@ -1537,6 +1526,7 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
|
|||||||
|
|
||||||
stats, _, _, err := suite.w.ConsumeBackupCollections(
|
stats, _, _, err := suite.w.ConsumeBackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
|
[]Reasoner{r},
|
||||||
[]IncrementalBase{
|
[]IncrementalBase{
|
||||||
{
|
{
|
||||||
Manifest: man,
|
Manifest: man,
|
||||||
@ -1547,7 +1537,7 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() {
|
|||||||
},
|
},
|
||||||
test.cols(),
|
test.cols(),
|
||||||
excluded,
|
excluded,
|
||||||
tags,
|
nil,
|
||||||
true,
|
true,
|
||||||
fault.New(true))
|
fault.New(true))
|
||||||
require.NoError(t, err, clues.ToCore(err))
|
require.NoError(t, err, clues.ToCore(err))
|
||||||
|
|||||||
@ -495,12 +495,6 @@ func consumeBackupCollections(
|
|||||||
kopia.TagBackupCategory: "",
|
kopia.TagBackupCategory: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, reason := range reasons {
|
|
||||||
for _, k := range reason.TagKeys() {
|
|
||||||
tags[k] = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AssistBases should be the upper bound for how many snapshots we pass in.
|
// AssistBases should be the upper bound for how many snapshots we pass in.
|
||||||
bases := make([]kopia.IncrementalBase, 0, len(bbs.AssistBases()))
|
bases := make([]kopia.IncrementalBase, 0, len(bbs.AssistBases()))
|
||||||
// Track IDs we've seen already so we don't accidentally duplicate some
|
// Track IDs we've seen already so we don't accidentally duplicate some
|
||||||
@ -578,6 +572,7 @@ func consumeBackupCollections(
|
|||||||
|
|
||||||
kopiaStats, deets, itemsSourcedFromBase, err := bc.ConsumeBackupCollections(
|
kopiaStats, deets, itemsSourcedFromBase, err := bc.ConsumeBackupCollections(
|
||||||
ctx,
|
ctx,
|
||||||
|
reasons,
|
||||||
bases,
|
bases,
|
||||||
cs,
|
cs,
|
||||||
pmr,
|
pmr,
|
||||||
|
|||||||
@ -107,6 +107,7 @@ func checkPaths(t *testing.T, expected, got []path.Path) {
|
|||||||
|
|
||||||
type mockBackupConsumer struct {
|
type mockBackupConsumer struct {
|
||||||
checkFunc func(
|
checkFunc func(
|
||||||
|
backupReasons []kopia.Reasoner,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.BackupCollection,
|
cs []data.BackupCollection,
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
@ -115,6 +116,7 @@ type mockBackupConsumer struct {
|
|||||||
|
|
||||||
func (mbu mockBackupConsumer) ConsumeBackupCollections(
|
func (mbu mockBackupConsumer) ConsumeBackupCollections(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
backupReasons []kopia.Reasoner,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.BackupCollection,
|
cs []data.BackupCollection,
|
||||||
excluded prefixmatcher.StringSetReader,
|
excluded prefixmatcher.StringSetReader,
|
||||||
@ -123,7 +125,7 @@ func (mbu mockBackupConsumer) ConsumeBackupCollections(
|
|||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
) (*kopia.BackupStats, *details.Builder, kopia.DetailsMergeInfoer, error) {
|
) (*kopia.BackupStats, *details.Builder, kopia.DetailsMergeInfoer, error) {
|
||||||
if mbu.checkFunc != nil {
|
if mbu.checkFunc != nil {
|
||||||
mbu.checkFunc(bases, cs, tags, buildTreeWithBase)
|
mbu.checkFunc(backupReasons, bases, cs, tags, buildTreeWithBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &kopia.BackupStats{}, &details.Builder{}, nil, nil
|
return &kopia.BackupStats{}, &details.Builder{}, nil, nil
|
||||||
@ -537,6 +539,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections
|
|||||||
|
|
||||||
mbu := &mockBackupConsumer{
|
mbu := &mockBackupConsumer{
|
||||||
checkFunc: func(
|
checkFunc: func(
|
||||||
|
backupReasons []kopia.Reasoner,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.BackupCollection,
|
cs []data.BackupCollection,
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
|
|||||||
@ -234,6 +234,7 @@ func write(
|
|||||||
backupStats, _, _, err := bup.ConsumeBackupCollections(
|
backupStats, _, _, err := bup.ConsumeBackupCollections(
|
||||||
ctx,
|
ctx,
|
||||||
nil,
|
nil,
|
||||||
|
nil,
|
||||||
dbcs,
|
dbcs,
|
||||||
prefixmatcher.NopReader[map[string]struct{}](),
|
prefixmatcher.NopReader[map[string]struct{}](),
|
||||||
nil,
|
nil,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user