diff --git a/pkg/controller/restic_repository_controller.go b/pkg/controller/restic_repository_controller.go index 9f550c8fa..f72ce76e0 100644 --- a/pkg/controller/restic_repository_controller.go +++ b/pkg/controller/restic_repository_controller.go @@ -162,10 +162,10 @@ func (c *resticRepositoryController) initializeRepo(req *v1.ResticRepository, lo }) } -// ensureRepo first checks the repo, and returns if check passes. If it fails, -// attempts to init the repo, and returns the result. +// ensureRepo first tries to connect to the repo, and returns if it succeeds. If it fails, +// it attempts to init the repo, and returns the result. func ensureRepo(repo *v1.ResticRepository, repoManager restic.RepositoryManager) error { - if repoManager.CheckRepo(repo) == nil { + if repoManager.ConnectToRepo(repo) == nil { return nil } diff --git a/pkg/restic/command_factory.go b/pkg/restic/command_factory.go index 591d6f9d3..4d1a993d1 100644 --- a/pkg/restic/command_factory.go +++ b/pkg/restic/command_factory.go @@ -84,6 +84,13 @@ func InitCommand(repoIdentifier string) *Command { } } +func StatsCommand(repoIdentifier string) *Command { + return &Command{ + Command: "stats", + RepoIdentifier: repoIdentifier, + } +} + func CheckCommand(repoIdentifier string) *Command { return &Command{ Command: "check", diff --git a/pkg/restic/command_factory_test.go b/pkg/restic/command_factory_test.go index 5e2714038..636ddf849 100644 --- a/pkg/restic/command_factory_test.go +++ b/pkg/restic/command_factory_test.go @@ -96,6 +96,13 @@ func TestInitCommand(t *testing.T) { assert.Equal(t, "repo-id", c.RepoIdentifier) } +func TestStatsCommand(t *testing.T) { + c := StatsCommand("repo-id") + + assert.Equal(t, "stats", c.Command) + assert.Equal(t, "repo-id", c.RepoIdentifier) +} + func TestCheckCommand(t *testing.T) { c := CheckCommand("repo-id") diff --git a/pkg/restic/repository_manager.go b/pkg/restic/repository_manager.go index 65e307d68..d1dc6a785 100644 --- a/pkg/restic/repository_manager.go +++ b/pkg/restic/repository_manager.go @@ -42,6 +42,12 @@ type RepositoryManager interface { // InitRepo initializes a repo with the specified name and identifier. InitRepo(repo *arkv1api.ResticRepository) error + // ConnectToRepo runs the 'restic stats' command against the + // specified repo, and returns an error if it fails. This is + // intended to be used to ensure that the repo exists/can be + // authenticated to. + ConnectToRepo(repo *arkv1api.ResticRepository) error + // CheckRepo checks the specified repo for errors. CheckRepo(repo *arkv1api.ResticRepository) error @@ -170,6 +176,14 @@ func (rm *repositoryManager) InitRepo(repo *arkv1api.ResticRepository) error { return rm.exec(InitCommand(repo.Spec.ResticIdentifier), repo.Spec.BackupStorageLocation) } +func (rm *repositoryManager) ConnectToRepo(repo *arkv1api.ResticRepository) error { + // restic stats requires a non-exclusive lock + rm.repoLocker.Lock(repo.Name) + defer rm.repoLocker.Unlock(repo.Name) + + return rm.exec(StatsCommand(repo.Spec.ResticIdentifier), repo.Spec.BackupStorageLocation) +} + func (rm *repositoryManager) CheckRepo(repo *arkv1api.ResticRepository) error { // restic check requires an exclusive lock rm.repoLocker.LockExclusive(repo.Name)