Don't use OwnersCats struct (#2055)
## Description Remove OwnersCats so only the Reason struct or tags pass information between BackupOp and kopia Instead of having a separate struct (OwnersCats) to fetch previous snapshots, generate and use reasons. While this results in some repeated data, it cuts down on the number of distinct structs and simplifies some of the code for getting previous manifests. A future PR should create a shared function to create a service/cat tag given a reason. Only pass in a set of tags to BackupCollections. This pushes the onus of generating the tags for later snapshot lookups to BackupOp and creates a somewhat asymmetric interface as Reason is used for the lookup but tags is used for the backup. This will be updated later so that both paths use a common function to convert from Reason->tags. Despite that, it may result in a cleaner interface with kopia (depending on how far we want to push it) where tags become the main mean of communication. ## 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 - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [x] 🧹 Tech Debt/Cleanup ## Issue(s) * #1916 ## Test Plan - [x] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
bf0a01708a
commit
43c2017492
@ -89,6 +89,10 @@ func MakeTagKV(k string) (string, string) {
|
|||||||
// tagsFromStrings returns a map[string]string with tags for all ownersCats
|
// tagsFromStrings returns a map[string]string with tags for all ownersCats
|
||||||
// passed in. Currently uses placeholder values for each tag because there can
|
// passed in. Currently uses placeholder values for each tag because there can
|
||||||
// be multiple instances of resource owners and categories in a single snapshot.
|
// be multiple instances of resource owners and categories in a single snapshot.
|
||||||
|
// TODO(ashmrtn): Remove in future PR.
|
||||||
|
//
|
||||||
|
//nolint:unused
|
||||||
|
//lint:ignore U1000 will be removed in future PR.
|
||||||
func tagsFromStrings(oc *OwnersCats) map[string]string {
|
func tagsFromStrings(oc *OwnersCats) map[string]string {
|
||||||
if oc == nil {
|
if oc == nil {
|
||||||
return map[string]string{}
|
return map[string]string{}
|
||||||
@ -188,25 +192,18 @@ func fetchPrevManifests(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
sm snapshotManager,
|
sm snapshotManager,
|
||||||
foundMans map[manifest.ID]*ManifestEntry,
|
foundMans map[manifest.ID]*ManifestEntry,
|
||||||
serviceCat ServiceCat,
|
reason Reason,
|
||||||
resourceOwner string,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
) ([]*ManifestEntry, error) {
|
) ([]*ManifestEntry, error) {
|
||||||
tags = normalizeTagKVs(tags)
|
tags = normalizeTagKVs(tags)
|
||||||
serviceCatKey, _ := MakeServiceCat(serviceCat.Service, serviceCat.Category)
|
serviceCatKey, _ := MakeServiceCat(reason.Service, reason.Category)
|
||||||
allTags := normalizeTagKVs(map[string]string{
|
allTags := normalizeTagKVs(map[string]string{
|
||||||
serviceCatKey: "",
|
serviceCatKey: "",
|
||||||
resourceOwner: "",
|
reason.ResourceOwner: "",
|
||||||
})
|
})
|
||||||
|
|
||||||
maps.Copy(allTags, tags)
|
maps.Copy(allTags, tags)
|
||||||
|
|
||||||
reason := Reason{
|
|
||||||
ResourceOwner: resourceOwner,
|
|
||||||
Service: serviceCat.Service,
|
|
||||||
Category: serviceCat.Category,
|
|
||||||
}
|
|
||||||
|
|
||||||
metas, err := sm.FindManifests(ctx, allTags)
|
metas, err := sm.FindManifests(ctx, allTags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "fetching manifest metas by tag")
|
return nil, errors.Wrap(err, "fetching manifest metas by tag")
|
||||||
@ -275,57 +272,54 @@ func fetchPrevManifests(
|
|||||||
func fetchPrevSnapshotManifests(
|
func fetchPrevSnapshotManifests(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
sm snapshotManager,
|
sm snapshotManager,
|
||||||
oc *OwnersCats,
|
reasons []Reason,
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
) []*ManifestEntry {
|
) []*ManifestEntry {
|
||||||
if oc == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
mans := map[manifest.ID]*ManifestEntry{}
|
mans := map[manifest.ID]*ManifestEntry{}
|
||||||
|
|
||||||
// For each serviceCat/resource owner pair that we will be backing up, see if
|
// For each serviceCat/resource owner pair that we will be backing up, see if
|
||||||
// there's a previous incomplete snapshot and/or a previous complete snapshot
|
// there's a previous incomplete snapshot and/or a previous complete snapshot
|
||||||
// we can pass in. Can be expanded to return more than the most recent
|
// we can pass in. Can be expanded to return more than the most recent
|
||||||
// snapshots, but may require more memory at runtime.
|
// snapshots, but may require more memory at runtime.
|
||||||
for _, serviceCat := range oc.ServiceCats {
|
for _, reason := range reasons {
|
||||||
for resourceOwner := range oc.ResourceOwners {
|
found, err := fetchPrevManifests(
|
||||||
found, err := fetchPrevManifests(
|
ctx,
|
||||||
ctx,
|
sm,
|
||||||
sm,
|
mans,
|
||||||
mans,
|
reason,
|
||||||
serviceCat,
|
tags,
|
||||||
resourceOwner,
|
)
|
||||||
tags,
|
if err != nil {
|
||||||
|
logger.Ctx(ctx).Warnw(
|
||||||
|
"fetching previous snapshot manifests for service/category/resource owner",
|
||||||
|
"error",
|
||||||
|
err,
|
||||||
|
"service",
|
||||||
|
reason.Service.String(),
|
||||||
|
"category",
|
||||||
|
reason.Category.String(),
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
logger.Ctx(ctx).Warnw(
|
|
||||||
"fetching previous snapshot manifests for service/category/resource owner",
|
|
||||||
"error",
|
|
||||||
err,
|
|
||||||
"service/category",
|
|
||||||
serviceCat,
|
|
||||||
)
|
|
||||||
|
|
||||||
// Snapshot can still complete fine, just not as efficient.
|
// Snapshot can still complete fine, just not as efficient.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we found more recent snapshots then add them.
|
||||||
|
for _, m := range found {
|
||||||
|
man := mans[m.ID]
|
||||||
|
if man == nil {
|
||||||
|
mans[m.ID] = m
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found more recent snapshots then add them.
|
// If the manifest already exists and it's incomplete then we should
|
||||||
for _, m := range found {
|
// merge the reasons for consistency. This will become easier to handle
|
||||||
found := mans[m.ID]
|
// once we update how checkpoint manifests are tagged.
|
||||||
if found == nil {
|
if len(man.IncompleteReason) == 0 {
|
||||||
mans[m.ID] = m
|
continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the manifest already exists and it's incomplete then we should
|
|
||||||
// merge the reasons for consistency. This will become easier to handle
|
|
||||||
// once we update how checkpoint manifests are tagged.
|
|
||||||
if len(found.IncompleteReason) > 0 {
|
|
||||||
found.Reasons = append(found.Reasons, m.Reasons...)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
man.Reasons = append(man.Reasons, m.Reasons...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,25 +43,53 @@ var (
|
|||||||
testUser2 = "user2"
|
testUser2 = "user2"
|
||||||
testUser3 = "user3"
|
testUser3 = "user3"
|
||||||
|
|
||||||
testAllUsersAllCats = &OwnersCats{
|
testAllUsersAllCats = []Reason{
|
||||||
ResourceOwners: map[string]struct{}{
|
{
|
||||||
testUser1: {},
|
ResourceOwner: testUser1,
|
||||||
testUser2: {},
|
Service: path.ExchangeService,
|
||||||
testUser3: {},
|
Category: path.EmailCategory,
|
||||||
},
|
},
|
||||||
ServiceCats: map[string]ServiceCat{
|
{
|
||||||
testMail: testMailServiceCat,
|
ResourceOwner: testUser1,
|
||||||
testEvents: testEventsServiceCat,
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EventsCategory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceOwner: testUser2,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EmailCategory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceOwner: testUser2,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EventsCategory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceOwner: testUser3,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EmailCategory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceOwner: testUser3,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EventsCategory,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
testAllUsersMail = &OwnersCats{
|
testAllUsersMail = []Reason{
|
||||||
ResourceOwners: map[string]struct{}{
|
{
|
||||||
testUser1: {},
|
ResourceOwner: testUser1,
|
||||||
testUser2: {},
|
Service: path.ExchangeService,
|
||||||
testUser3: {},
|
Category: path.EmailCategory,
|
||||||
},
|
},
|
||||||
ServiceCats: map[string]ServiceCat{
|
{
|
||||||
testMail: testMailServiceCat,
|
ResourceOwner: testUser2,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EmailCategory,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ResourceOwner: testUser3,
|
||||||
|
Service: path.ExchangeService,
|
||||||
|
Category: path.EmailCategory,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -176,7 +204,7 @@ func TestSnapshotFetchUnitSuite(t *testing.T) {
|
|||||||
func (suite *SnapshotFetchUnitSuite) TestFetchPrevSnapshots() {
|
func (suite *SnapshotFetchUnitSuite) TestFetchPrevSnapshots() {
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
input *OwnersCats
|
input []Reason
|
||||||
data []manifestInfo
|
data []manifestInfo
|
||||||
// Use this to denote which manifests in data should be expected. Allows
|
// Use this to denote which manifests in data should be expected. Allows
|
||||||
// defining data in a table while not repeating things between data and
|
// defining data in a table while not repeating things between data and
|
||||||
@ -813,7 +841,7 @@ func (suite *SnapshotFetchUnitSuite) TestFetchPrevSnapshots_customTags() {
|
|||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
input *OwnersCats
|
input []Reason
|
||||||
tags map[string]string
|
tags map[string]string
|
||||||
// Use this to denote which manifests in data should be expected. Allows
|
// Use this to denote which manifests in data should be expected. Allows
|
||||||
// defining data in a table while not repeating things between data and
|
// defining data in a table while not repeating things between data and
|
||||||
|
|||||||
@ -119,8 +119,6 @@ func (w Wrapper) BackupCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
previousSnapshots []IncrementalBase,
|
previousSnapshots []IncrementalBase,
|
||||||
collections []data.Collection,
|
collections []data.Collection,
|
||||||
service path.ServiceType,
|
|
||||||
oc *OwnersCats,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
) (*BackupStats, *details.Builder, map[string]path.Path, error) {
|
) (*BackupStats, *details.Builder, map[string]path.Path, error) {
|
||||||
@ -158,7 +156,6 @@ func (w Wrapper) BackupCollections(
|
|||||||
ctx,
|
ctx,
|
||||||
previousSnapshots,
|
previousSnapshots,
|
||||||
dirTree,
|
dirTree,
|
||||||
oc,
|
|
||||||
tags,
|
tags,
|
||||||
progress,
|
progress,
|
||||||
)
|
)
|
||||||
@ -173,7 +170,6 @@ func (w Wrapper) makeSnapshotWithRoot(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
prevSnapEntries []IncrementalBase,
|
prevSnapEntries []IncrementalBase,
|
||||||
root fs.Directory,
|
root fs.Directory,
|
||||||
oc *OwnersCats,
|
|
||||||
addlTags map[string]string,
|
addlTags map[string]string,
|
||||||
progress *corsoProgress,
|
progress *corsoProgress,
|
||||||
) (*BackupStats, error) {
|
) (*BackupStats, error) {
|
||||||
@ -231,7 +227,8 @@ func (w Wrapper) makeSnapshotWithRoot(
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
man.Tags = tagsFromStrings(oc)
|
man.Tags = map[string]string{}
|
||||||
|
|
||||||
for k, v := range addlTags {
|
for k, v := range addlTags {
|
||||||
mk, mv := MakeTagKV(k)
|
mk, mv := MakeTagKV(k)
|
||||||
|
|
||||||
@ -442,12 +439,12 @@ func (w Wrapper) DeleteSnapshot(
|
|||||||
// normalized inside the func using MakeTagKV.
|
// normalized inside the func using MakeTagKV.
|
||||||
func (w Wrapper) FetchPrevSnapshotManifests(
|
func (w Wrapper) FetchPrevSnapshotManifests(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
oc *OwnersCats,
|
reasons []Reason,
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
) ([]*ManifestEntry, error) {
|
) ([]*ManifestEntry, error) {
|
||||||
if w.c == nil {
|
if w.c == nil {
|
||||||
return nil, errors.WithStack(errNotConnected)
|
return nil, errors.WithStack(errNotConnected)
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetchPrevSnapshotManifests(ctx, w.c, oc, tags), nil
|
return fetchPrevSnapshotManifests(ctx, w.c, reasons, tags), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -207,39 +207,21 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
k, v := MakeServiceCat(path.ExchangeService, path.EmailCategory)
|
// tags that are supplied by the caller. This includes basic tags to support
|
||||||
oc := &OwnersCats{
|
// lookups and extra tags the caller may want to apply.
|
||||||
ResourceOwners: map[string]struct{}{
|
tags := map[string]string{
|
||||||
testUser: {},
|
|
||||||
},
|
|
||||||
ServiceCats: map[string]ServiceCat{
|
|
||||||
k: v,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// tags that are expected to populate as a side effect
|
|
||||||
// of the backup process.
|
|
||||||
baseTagKeys := []string{
|
|
||||||
serviceCatTag(suite.testPath1),
|
|
||||||
suite.testPath1.ResourceOwner(),
|
|
||||||
serviceCatTag(suite.testPath2),
|
|
||||||
suite.testPath2.ResourceOwner(),
|
|
||||||
}
|
|
||||||
|
|
||||||
// tags that are supplied by the caller.
|
|
||||||
customTags := map[string]string{
|
|
||||||
"fnords": "smarf",
|
"fnords": "smarf",
|
||||||
"brunhilda": "",
|
"brunhilda": "",
|
||||||
|
|
||||||
|
suite.testPath1.ResourceOwner(): "",
|
||||||
|
suite.testPath2.ResourceOwner(): "",
|
||||||
|
serviceCatTag(suite.testPath1): "",
|
||||||
|
serviceCatTag(suite.testPath2): "",
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedTags := map[string]string{}
|
expectedTags := map[string]string{}
|
||||||
|
|
||||||
for _, k := range baseTagKeys {
|
maps.Copy(expectedTags, normalizeTagKVs(tags))
|
||||||
tk, tv := MakeTagKV(k)
|
|
||||||
expectedTags[tk] = tv
|
|
||||||
}
|
|
||||||
|
|
||||||
maps.Copy(expectedTags, normalizeTagKVs(customTags))
|
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
name string
|
name string
|
||||||
@ -266,9 +248,7 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() {
|
|||||||
suite.ctx,
|
suite.ctx,
|
||||||
prevSnaps,
|
prevSnaps,
|
||||||
collections,
|
collections,
|
||||||
path.ExchangeService,
|
tags,
|
||||||
oc,
|
|
||||||
customTags,
|
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@ -325,14 +305,9 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() {
|
|||||||
|
|
||||||
w := &Wrapper{k}
|
w := &Wrapper{k}
|
||||||
|
|
||||||
mapK, mapV := MakeServiceCat(path.ExchangeService, path.EmailCategory)
|
tags := map[string]string{
|
||||||
oc := &OwnersCats{
|
testUser: "",
|
||||||
ResourceOwners: map[string]struct{}{
|
serviceCatString(path.ExchangeService, path.EmailCategory): "",
|
||||||
testUser: {},
|
|
||||||
},
|
|
||||||
ServiceCats: map[string]ServiceCat{
|
|
||||||
mapK: mapV,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dc1 := mockconnector.NewMockExchangeCollection(suite.testPath1, 1)
|
dc1 := mockconnector.NewMockExchangeCollection(suite.testPath1, 1)
|
||||||
@ -348,9 +323,7 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() {
|
|||||||
ctx,
|
ctx,
|
||||||
nil,
|
nil,
|
||||||
[]data.Collection{dc1, dc2},
|
[]data.Collection{dc1, dc2},
|
||||||
path.ExchangeService,
|
tags,
|
||||||
oc,
|
|
||||||
nil,
|
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -380,14 +353,9 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() {
|
|||||||
func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() {
|
func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() {
|
||||||
t := suite.T()
|
t := suite.T()
|
||||||
|
|
||||||
k, v := MakeServiceCat(path.ExchangeService, path.EmailCategory)
|
tags := map[string]string{
|
||||||
oc := &OwnersCats{
|
testUser: "",
|
||||||
ResourceOwners: map[string]struct{}{
|
serviceCatString(path.ExchangeService, path.EmailCategory): "",
|
||||||
testUser: {},
|
|
||||||
},
|
|
||||||
ServiceCats: map[string]ServiceCat{
|
|
||||||
k: v,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
collections := []data.Collection{
|
collections := []data.Collection{
|
||||||
@ -431,9 +399,7 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() {
|
|||||||
suite.ctx,
|
suite.ctx,
|
||||||
nil,
|
nil,
|
||||||
collections,
|
collections,
|
||||||
path.ExchangeService,
|
tags,
|
||||||
oc,
|
|
||||||
nil,
|
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -477,8 +443,6 @@ func (suite *KopiaIntegrationSuite) TestBackupCollectionsHandlesNoCollections()
|
|||||||
ctx,
|
ctx,
|
||||||
nil,
|
nil,
|
||||||
test.collections,
|
test.collections,
|
||||||
path.UnknownService,
|
|
||||||
&OwnersCats{},
|
|
||||||
nil,
|
nil,
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
@ -622,23 +586,16 @@ func (suite *KopiaSimpleRepoIntegrationSuite) SetupTest() {
|
|||||||
collections = append(collections, collection)
|
collections = append(collections, collection)
|
||||||
}
|
}
|
||||||
|
|
||||||
k, v := MakeServiceCat(path.ExchangeService, path.EmailCategory)
|
tags := map[string]string{
|
||||||
oc := &OwnersCats{
|
testUser: "",
|
||||||
ResourceOwners: map[string]struct{}{
|
serviceCatString(path.ExchangeService, path.EmailCategory): "",
|
||||||
testUser: {},
|
|
||||||
},
|
|
||||||
ServiceCats: map[string]ServiceCat{
|
|
||||||
k: v,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stats, deets, _, err := suite.w.BackupCollections(
|
stats, deets, _, err := suite.w.BackupCollections(
|
||||||
suite.ctx,
|
suite.ctx,
|
||||||
nil,
|
nil,
|
||||||
collections,
|
collections,
|
||||||
path.ExchangeService,
|
tags,
|
||||||
oc,
|
|
||||||
nil,
|
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|||||||
@ -115,7 +115,7 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
tenantID = op.account.ID()
|
tenantID = op.account.ID()
|
||||||
startTime = time.Now()
|
startTime = time.Now()
|
||||||
detailsStore = streamstore.New(op.kopia, tenantID, op.Selectors.PathService())
|
detailsStore = streamstore.New(op.kopia, tenantID, op.Selectors.PathService())
|
||||||
oc = selectorToOwnersCats(op.Selectors)
|
reasons = selectorToReasons(op.Selectors)
|
||||||
uib = useIncrementalBackup(op.Selectors, op.Options)
|
uib = useIncrementalBackup(op.Selectors, op.Options)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -151,7 +151,14 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
mans, mdColls, canUseMetaData, err := produceManifestsAndMetadata(ctx, op.kopia, op.store, oc, tenantID, uib)
|
mans, mdColls, canUseMetaData, err := produceManifestsAndMetadata(
|
||||||
|
ctx,
|
||||||
|
op.kopia,
|
||||||
|
op.store,
|
||||||
|
reasons,
|
||||||
|
tenantID,
|
||||||
|
uib,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
opStats.readErr = errors.Wrap(err, "connecting to M365")
|
opStats.readErr = errors.Wrap(err, "connecting to M365")
|
||||||
return opStats.readErr
|
return opStats.readErr
|
||||||
@ -173,8 +180,7 @@ func (op *BackupOperation) Run(ctx context.Context) (err error) {
|
|||||||
ctx,
|
ctx,
|
||||||
op.kopia,
|
op.kopia,
|
||||||
tenantID,
|
tenantID,
|
||||||
op.Selectors,
|
reasons,
|
||||||
oc,
|
|
||||||
mans,
|
mans,
|
||||||
cs,
|
cs,
|
||||||
op.Results.BackupID,
|
op.Results.BackupID,
|
||||||
@ -246,8 +252,6 @@ type backuper interface {
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.Collection,
|
cs []data.Collection,
|
||||||
service path.ServiceType,
|
|
||||||
oc *kopia.OwnersCats,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
) (*kopia.BackupStats, *details.Builder, map[string]path.Path, error)
|
) (*kopia.BackupStats, *details.Builder, map[string]path.Path, error)
|
||||||
@ -298,7 +302,7 @@ func produceManifestsAndMetadata(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
kw *kopia.Wrapper,
|
kw *kopia.Wrapper,
|
||||||
sw *store.Wrapper,
|
sw *store.Wrapper,
|
||||||
oc *kopia.OwnersCats,
|
reasons []kopia.Reason,
|
||||||
tenantID string,
|
tenantID string,
|
||||||
getMetadata bool,
|
getMetadata bool,
|
||||||
) ([]*kopia.ManifestEntry, []data.Collection, bool, error) {
|
) ([]*kopia.ManifestEntry, []data.Collection, bool, error) {
|
||||||
@ -309,7 +313,7 @@ func produceManifestsAndMetadata(
|
|||||||
|
|
||||||
ms, err := kw.FetchPrevSnapshotManifests(
|
ms, err := kw.FetchPrevSnapshotManifests(
|
||||||
ctx,
|
ctx,
|
||||||
oc,
|
reasons,
|
||||||
map[string]string{kopia.TagBackupCategory: ""})
|
map[string]string{kopia.TagBackupCategory: ""})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
@ -427,28 +431,28 @@ func collectMetadata(
|
|||||||
return dcs, nil
|
return dcs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectorToOwnersCats(sel selectors.Selector) *kopia.OwnersCats {
|
func selectorToReasons(sel selectors.Selector) []kopia.Reason {
|
||||||
service := sel.PathService()
|
service := sel.PathService()
|
||||||
oc := &kopia.OwnersCats{
|
reasons := []kopia.Reason{}
|
||||||
ResourceOwners: map[string]struct{}{},
|
|
||||||
ServiceCats: map[string]kopia.ServiceCat{},
|
|
||||||
}
|
|
||||||
|
|
||||||
oc.ResourceOwners[sel.DiscreteOwner] = struct{}{}
|
|
||||||
|
|
||||||
pcs, err := sel.PathCategories()
|
pcs, err := sel.PathCategories()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &kopia.OwnersCats{}
|
// This is technically safe, it's just that the resulting backup won't be
|
||||||
|
// usable as a base for future incremental backups.
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, sl := range [][]path.CategoryType{pcs.Includes, pcs.Filters} {
|
for _, sl := range [][]path.CategoryType{pcs.Includes, pcs.Filters} {
|
||||||
for _, cat := range sl {
|
for _, cat := range sl {
|
||||||
k, v := kopia.MakeServiceCat(service, cat)
|
reasons = append(reasons, kopia.Reason{
|
||||||
oc.ServiceCats[k] = v
|
ResourceOwner: sel.DiscreteOwner,
|
||||||
|
Service: service,
|
||||||
|
Category: cat,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return oc
|
return reasons
|
||||||
}
|
}
|
||||||
|
|
||||||
func builderFromReason(tenant string, r kopia.Reason) (*path.Builder, error) {
|
func builderFromReason(tenant string, r kopia.Reason) (*path.Builder, error) {
|
||||||
@ -479,8 +483,7 @@ func consumeBackupDataCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
bu backuper,
|
bu backuper,
|
||||||
tenantID string,
|
tenantID string,
|
||||||
sel selectors.Selector,
|
reasons []kopia.Reason,
|
||||||
oc *kopia.OwnersCats,
|
|
||||||
mans []*kopia.ManifestEntry,
|
mans []*kopia.ManifestEntry,
|
||||||
cs []data.Collection,
|
cs []data.Collection,
|
||||||
backupID model.StableID,
|
backupID model.StableID,
|
||||||
@ -498,6 +501,15 @@ func consumeBackupDataCollections(
|
|||||||
kopia.TagBackupCategory: "",
|
kopia.TagBackupCategory: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, reason := range reasons {
|
||||||
|
tags[reason.ResourceOwner] = ""
|
||||||
|
|
||||||
|
// TODO(ashmrtn): Create a separate helper function to go from service/cat
|
||||||
|
// to a tag.
|
||||||
|
serviceCat, _ := kopia.MakeServiceCat(reason.Service, reason.Category)
|
||||||
|
tags[serviceCat] = ""
|
||||||
|
}
|
||||||
|
|
||||||
bases := make([]kopia.IncrementalBase, 0, len(mans))
|
bases := make([]kopia.IncrementalBase, 0, len(mans))
|
||||||
|
|
||||||
for _, m := range mans {
|
for _, m := range mans {
|
||||||
@ -518,7 +530,7 @@ func consumeBackupDataCollections(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return bu.BackupCollections(ctx, bases, cs, sel.PathService(), oc, tags, isIncremental)
|
return bu.BackupCollections(ctx, bases, cs, tags, isIncremental)
|
||||||
}
|
}
|
||||||
|
|
||||||
func matchesReason(reasons []kopia.Reason, p path.Path) bool {
|
func matchesReason(reasons []kopia.Reason, p path.Path) bool {
|
||||||
|
|||||||
@ -176,16 +176,18 @@ func checkBackupIsInManifests(
|
|||||||
for _, category := range categories {
|
for _, category := range categories {
|
||||||
t.Run(category.String(), func(t *testing.T) {
|
t.Run(category.String(), func(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
sck, scv = kopia.MakeServiceCat(sel.PathService(), category)
|
reasons = []kopia.Reason{
|
||||||
oc = &kopia.OwnersCats{
|
{
|
||||||
ResourceOwners: map[string]struct{}{resourceOwner: {}},
|
ResourceOwner: resourceOwner,
|
||||||
ServiceCats: map[string]kopia.ServiceCat{sck: scv},
|
Service: sel.PathService(),
|
||||||
|
Category: category,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
tags = map[string]string{kopia.TagBackupCategory: ""}
|
tags = map[string]string{kopia.TagBackupCategory: ""}
|
||||||
found bool
|
found bool
|
||||||
)
|
)
|
||||||
|
|
||||||
mans, err := kw.FetchPrevSnapshotManifests(ctx, oc, tags)
|
mans, err := kw.FetchPrevSnapshotManifests(ctx, reasons, tags)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, man := range mans {
|
for _, man := range mans {
|
||||||
|
|||||||
@ -61,8 +61,6 @@ type mockBackuper struct {
|
|||||||
checkFunc func(
|
checkFunc func(
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.Collection,
|
cs []data.Collection,
|
||||||
service path.ServiceType,
|
|
||||||
oc *kopia.OwnersCats,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
)
|
)
|
||||||
@ -72,13 +70,11 @@ func (mbu mockBackuper) BackupCollections(
|
|||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.Collection,
|
cs []data.Collection,
|
||||||
service path.ServiceType,
|
|
||||||
oc *kopia.OwnersCats,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
) (*kopia.BackupStats, *details.Builder, map[string]path.Path, error) {
|
) (*kopia.BackupStats, *details.Builder, map[string]path.Path, error) {
|
||||||
if mbu.checkFunc != nil {
|
if mbu.checkFunc != nil {
|
||||||
mbu.checkFunc(bases, cs, service, oc, tags, buildTreeWithBase)
|
mbu.checkFunc(bases, cs, tags, buildTreeWithBase)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &kopia.BackupStats{}, &details.Builder{}, nil, nil
|
return &kopia.BackupStats{}, &details.Builder{}, nil, nil
|
||||||
@ -673,8 +669,6 @@ func (suite *BackupOpSuite) TestBackupOperation_ConsumeBackupDataCollections_Pat
|
|||||||
manifest2 = &snapshot.Manifest{
|
manifest2 = &snapshot.Manifest{
|
||||||
ID: "id2",
|
ID: "id2",
|
||||||
}
|
}
|
||||||
|
|
||||||
sel = selectors.NewExchangeBackup([]string{resourceOwner}).Selector
|
|
||||||
)
|
)
|
||||||
|
|
||||||
table := []struct {
|
table := []struct {
|
||||||
@ -768,8 +762,6 @@ func (suite *BackupOpSuite) TestBackupOperation_ConsumeBackupDataCollections_Pat
|
|||||||
checkFunc: func(
|
checkFunc: func(
|
||||||
bases []kopia.IncrementalBase,
|
bases []kopia.IncrementalBase,
|
||||||
cs []data.Collection,
|
cs []data.Collection,
|
||||||
service path.ServiceType,
|
|
||||||
oc *kopia.OwnersCats,
|
|
||||||
tags map[string]string,
|
tags map[string]string,
|
||||||
buildTreeWithBase bool,
|
buildTreeWithBase bool,
|
||||||
) {
|
) {
|
||||||
@ -782,7 +774,6 @@ func (suite *BackupOpSuite) TestBackupOperation_ConsumeBackupDataCollections_Pat
|
|||||||
ctx,
|
ctx,
|
||||||
mbu,
|
mbu,
|
||||||
tenant,
|
tenant,
|
||||||
sel,
|
|
||||||
nil,
|
nil,
|
||||||
test.inputMan,
|
test.inputMan,
|
||||||
nil,
|
nil,
|
||||||
|
|||||||
@ -77,8 +77,6 @@ func (ss *streamStore) WriteBackupDetails(
|
|||||||
ctx,
|
ctx,
|
||||||
nil,
|
nil,
|
||||||
[]data.Collection{dc},
|
[]data.Collection{dc},
|
||||||
ss.service,
|
|
||||||
nil,
|
|
||||||
nil,
|
nil,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user