corso/src/pkg/backup/backup_bases.go
Ashlie Martinez 216f29888f Move BackupBases interface and structs definitions
Move the interfact and struct definitions from the kopia package to the
backup package so that we can initialize the backup model with lineage
information sourced from BackupBases in a later PR.
2023-10-04 13:19:15 -07:00

111 lines
3.3 KiB
Go

package backup
import (
"context"
"github.com/kopia/kopia/repo/manifest"
"github.com/kopia/kopia/snapshot"
"github.com/alcionai/corso/src/pkg/backup/identity"
"github.com/alcionai/corso/src/pkg/path"
)
const (
// Kopia does not do comparisons properly for empty tags right now so add some
// placeholder value to them.
legacyDefaultTagValue = "0"
// Kopia CLI prefixes all user tags with "tag:"[1]. Maintaining this will
// ensure we don't accidentally take reserved tags and that tags can be
// displayed with kopia CLI.
// (permalinks)
// [1] https://github.com/kopia/kopia/blob/05e729a7858a6e86cb48ba29fb53cb6045efce2b/cli/command_snapshot_create.go#L169
LegacyUserTagPrefix = "tag:"
tenantIDKey = "tenant"
resourceIDKey = "resource"
serviceCatPrefix = "sc-"
// Sentinel value for tags. Could technically be empty but we'll store
// something for now.
//nolint
defaultTagValue = "1"
)
func serviceCatString(
service path.ServiceType,
category path.CategoryType,
) string {
return serviceCatPrefix + service.String() + category.String()
}
// reasonTags returns the set of key-value pairs that can be used as tags to
// represent this Reason.
// nolint
func reasonTags(r identity.Reasoner) map[string]string {
return map[string]string{
tenantIDKey: r.Tenant(),
resourceIDKey: r.ProtectedResource(),
serviceCatString(r.Service(), r.Category()): defaultTagValue,
}
}
// nolint
type BackupEntry struct {
*Backup
Reasons []identity.Reasoner
}
type ManifestEntry struct {
*snapshot.Manifest
// Reasons contains the ResourceOwners and Service/Categories that caused this
// snapshot to be selected as a base. We can't reuse OwnersCats here because
// it's possible some ResourceOwners will have a subset of the Categories as
// the reason for selecting a snapshot. For example:
// 1. backup user1 email,contacts -> B1
// 2. backup user1 contacts -> B2 (uses B1 as base)
// 3. backup user1 email,contacts,events (uses B1 for email, B2 for contacts)
Reasons []identity.Reasoner
}
// MakeTagKV normalizes the provided key to protect it from clobbering
// similarly named tags from non-user input (user inputs are still open
// to collisions amongst eachother).
// Returns the normalized Key plus a default value. If you're embedding a
// key-only tag, the returned default value msut be used instead of an
// empty string.
func MakeTagKV(k string) (string, string) {
return LegacyUserTagPrefix + k, legacyDefaultTagValue
}
func (me ManifestEntry) GetTag(key string) (string, bool) {
k, _ := MakeTagKV(key)
v, ok := me.Tags[k]
return v, ok
}
// nolint
type BackupBases interface {
// ConvertToAssistBase converts the base with the given item data snapshot ID
// from a merge base to an assist base.
ConvertToAssistBase(manifestID manifest.ID)
Backups() []BackupEntry
UniqueAssistBackups() []BackupEntry
MinBackupVersion() int
MergeBases() []ManifestEntry
DisableMergeBases()
UniqueAssistBases() []ManifestEntry
DisableAssistBases()
MergeBackupBases(
ctx context.Context,
other BackupBases,
reasonToKey func(identity.Reasoner) string,
) BackupBases
// SnapshotAssistBases returns the set of bases to use for kopia assisted
// incremental snapshot operations. It consists of the union of merge bases
// and assist bases. If DisableAssistBases has been called then it returns
// nil.
SnapshotAssistBases() []ManifestEntry
}