diff --git a/src/internal/version/capability_string.go b/src/internal/version/capability_string.go new file mode 100644 index 000000000..30d31ceee --- /dev/null +++ b/src/internal/version/capability_string.go @@ -0,0 +1,24 @@ +// Code generated by "stringer -type=Capability"; DO NOT EDIT. + +package version + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[UnknownCapability-0] + _ = x[ImmutableIDCapability-1] +} + +const _Capability_name = "UnknownCapabilityImmutableIDCapability" + +var _Capability_index = [...]uint8{0, 17, 38} + +func (i Capability) String() string { + if i < 0 || i >= Capability(len(_Capability_index)-1) { + return "Capability(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Capability_name[_Capability_index[i]:_Capability_index[i+1]] +} diff --git a/src/internal/version/repo.go b/src/internal/version/repo.go new file mode 100644 index 000000000..888fb1ba1 --- /dev/null +++ b/src/internal/version/repo.go @@ -0,0 +1,21 @@ +package version + +const Repo = 1 + +// Capability constants denote the type of capability supported by a repo version. +type Capability int + +//go:generate go run golang.org/x/tools/cmd/stringer -type=Capability +const ( + UnknownCapability = Capability(iota) + ImmutableIDCapability +) + +func RepoCapabilities(v int) map[string]struct{} { + if v > 1 { + return map[string]struct{}{ + ImmutableIDCapability.String(): {}, + } + } + return map[string]struct{}{} +} diff --git a/src/pkg/repository/repository.go b/src/pkg/repository/repository.go index 2fe7a43aa..218e3124a 100644 --- a/src/pkg/repository/repository.go +++ b/src/pkg/repository/repository.go @@ -79,15 +79,16 @@ type Repository interface { type repository struct { ID string CreatedAt time.Time - Version string // in case of future breaking changes + Version int // in case of future breaking changes Account account.Account // the user's m365 account connection details Storage storage.Storage // the storage provider details and configuration Opts control.Options - Bus events.Eventer - dataLayer *kopia.Wrapper - modelStore *kopia.ModelStore + Bus events.Eventer + dataLayer *kopia.Wrapper + modelStore *kopia.ModelStore + Capabilities map[string]struct{} } func (r repository) GetID() string { @@ -152,14 +153,15 @@ func Initialize( bus.SetRepoID(repoID) r := &repository{ - ID: repoID, - Version: "v1", - Account: acct, - Storage: s, - Bus: bus, - Opts: opts, - dataLayer: w, - modelStore: ms, + ID: repoID, + Version: version.Repo, + Account: acct, + Storage: s, + Bus: bus, + Opts: opts, + dataLayer: w, + modelStore: ms, + Capabilities: version.RepoCapabilities(version.Repo), } if err := newRepoModel(ctx, ms, r.ID); err != nil { @@ -225,7 +227,9 @@ func Connect( return nil, clues.Wrap(err, "constructing event bus") } - rm := &repositoryModel{} + rm := &repositoryModel{ + Version: version.Repo, + } // Do not query repo ID if metrics are disabled if !opts.DisableMetrics { @@ -241,14 +245,15 @@ func Connect( // todo: ID and CreatedAt should get retrieved from a stored kopia config. return &repository{ - ID: string(rm.ID), - Version: "v1", - Account: acct, - Storage: s, - Bus: bus, - Opts: opts, - dataLayer: w, - modelStore: ms, + ID: string(rm.ID), + Version: rm.Version, + Account: acct, + Storage: s, + Bus: bus, + Opts: opts, + dataLayer: w, + modelStore: ms, + Capabilities: version.RepoCapabilities(rm.Version), }, nil } @@ -581,6 +586,9 @@ func deleteBackup( // repositoryModel identifies the current repository type repositoryModel struct { model.BaseModel + + // Version represents the version of the repository + Version int `json:"version"` } // should only be called on init.