From 481415492808a6ecffe1188e5373bad0e1e5ad0f Mon Sep 17 00:00:00 2001 From: Vaibhav Kamra Date: Tue, 19 Sep 2023 21:05:12 -0700 Subject: [PATCH] Support opening repository in read-only mode (#4302) Useful for running read only operations against the repository --- #### Does this PR need a docs update or release note? - [ ] :white_check_mark: Yes, it's included - [ ] :clock1: Yes, but in a later PR - [x] :no_entry: No #### Type of change - [ ] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [x] :robot: Supportability/Tests - [ ] :computer: CI/Deployment - [ ] :broom: Tech Debt/Cleanup #### Issue(s) * # #### Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- src/internal/kopia/conn.go | 1 + src/pkg/control/repository/repo.go | 1 + src/pkg/repository/repository_test.go | 25 +++++++++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/src/internal/kopia/conn.go b/src/internal/kopia/conn.go index 7ec79c9ed..001fd3f0f 100644 --- a/src/internal/kopia/conn.go +++ b/src/internal/kopia/conn.go @@ -184,6 +184,7 @@ func (w *conn) commonConnect( ClientOptions: repo.ClientOptions{ Username: opts.User, Hostname: opts.Host, + ReadOnly: opts.ReadOnly, }, } diff --git a/src/pkg/control/repository/repo.go b/src/pkg/control/repository/repo.go index 6d1869f91..791e05131 100644 --- a/src/pkg/control/repository/repo.go +++ b/src/pkg/control/repository/repo.go @@ -11,6 +11,7 @@ type Options struct { // ViewTimestamp is the time at which the repo should be opened at if // immutable backups are being used. If nil then the current time is used. ViewTimestamp *time.Time `json:"viewTimestamp"` + ReadOnly bool `json:"readonly,omitempty"` } type Maintenance struct { diff --git a/src/pkg/repository/repository_test.go b/src/pkg/repository/repository_test.go index bd123d24c..d929cd615 100644 --- a/src/pkg/repository/repository_test.go +++ b/src/pkg/repository/repository_test.go @@ -393,6 +393,31 @@ func (suite *RepositoryIntegrationSuite) TestConnect_DisableMetrics() { assert.Equal(t, r.GetID(), r.GetID()) } +func (suite *RepositoryIntegrationSuite) TestConnect_ReadOnly() { + t := suite.T() + + ctx, flush := tester.NewContext(t) + defer flush() + + // need to initialize the repository before we can test connecting to it. + st := storeTD.NewPrefixedS3Storage(t) + + repo, err := Initialize( + ctx, + account.Account{}, + st, + control.DefaultOptions(), + ctrlRepo.Retention{}) + require.NoError(t, err) + + // now re-connect + r, err := Connect(ctx, account.Account{}, st, repo.GetID(), control.Options{Repo: ctrlRepo.Options{ReadOnly: true}}) + assert.NoError(t, err) + + // now we have repoID beforehand + assert.Equal(t, r.GetID(), r.GetID()) +} + // Test_Options tests that the options are passed through to the repository // correctly func (suite *RepositoryIntegrationSuite) Test_Options() {