mirror of
https://github.com/restic/restic.git
synced 2025-10-26 04:58:38 +00:00
init: move more logic into global package
This commit is contained in:
@@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/restic/restic/internal/backend/location"
|
"github.com/restic/restic/internal/backend/location"
|
||||||
"github.com/restic/restic/internal/errors"
|
"github.com/restic/restic/internal/errors"
|
||||||
"github.com/restic/restic/internal/global"
|
"github.com/restic/restic/internal/global"
|
||||||
"github.com/restic/restic/internal/repository"
|
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
"github.com/restic/restic/internal/ui"
|
"github.com/restic/restic/internal/ui"
|
||||||
"github.com/restic/restic/internal/ui/progress"
|
"github.com/restic/restic/internal/ui/progress"
|
||||||
@@ -77,45 +76,16 @@ func runInit(ctx context.Context, opts InitOptions, gopts global.Options, args [
|
|||||||
version = uint(v)
|
version = uint(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
if version < restic.MinRepoVersion || version > restic.MaxRepoVersion {
|
|
||||||
return errors.Fatalf("only repository versions between %v and %v are allowed", restic.MinRepoVersion, restic.MaxRepoVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
chunkerPolynomial, err := maybeReadChunkerPolynomial(ctx, opts, gopts, printer)
|
chunkerPolynomial, err := maybeReadChunkerPolynomial(ctx, opts, gopts, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
gopts.Repo, err = global.ReadRepo(gopts)
|
s, err := global.CreateRepository(ctx, gopts, version, chunkerPolynomial, printer)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gopts.Password, err = global.ReadPasswordTwice(ctx, gopts,
|
|
||||||
"enter password for new repository: ",
|
|
||||||
"enter password again: ")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
be, err := global.Create(ctx, gopts.Repo, gopts, gopts.Extended, printer)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Fatalf("create repository at %s failed: %v", location.StripPassword(gopts.Backends, gopts.Repo), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, err := repository.New(be, repository.Options{
|
|
||||||
Compression: gopts.Compression,
|
|
||||||
PackSize: gopts.PackSize * 1024 * 1024,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Fatalf("%s", err)
|
return errors.Fatalf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Init(ctx, version, gopts.Password, chunkerPolynomial)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Fatalf("create key in repository at %s failed: %v", location.StripPassword(gopts.Backends, gopts.Repo), err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !gopts.JSON {
|
if !gopts.JSON {
|
||||||
printer.P("created restic repository %v at %s", s.Config().ID[:10], location.StripPassword(gopts.Backends, gopts.Repo))
|
printer.P("created restic repository %v at %s", s.Config().ID[:10], location.StripPassword(gopts.Backends, gopts.Repo))
|
||||||
if opts.CopyChunkerParameters && chunkerPolynomial != nil {
|
if opts.CopyChunkerParameters && chunkerPolynomial != nil {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/restic/chunker"
|
||||||
"github.com/restic/restic/internal/backend"
|
"github.com/restic/restic/internal/backend"
|
||||||
"github.com/restic/restic/internal/backend/cache"
|
"github.com/restic/restic/internal/backend/cache"
|
||||||
"github.com/restic/restic/internal/backend/limiter"
|
"github.com/restic/restic/internal/backend/limiter"
|
||||||
@@ -253,7 +254,7 @@ func ReadPasswordTwice(ctx context.Context, gopts Options, prompt1, prompt2 stri
|
|||||||
return pw1, nil
|
return pw1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func ReadRepo(gopts Options) (string, error) {
|
func readRepo(gopts Options) (string, error) {
|
||||||
if gopts.Repo == "" && gopts.RepositoryFile == "" {
|
if gopts.Repo == "" && gopts.RepositoryFile == "" {
|
||||||
return "", errors.Fatal("Please specify repository location (-r or --repository-file)")
|
return "", errors.Fatal("Please specify repository location (-r or --repository-file)")
|
||||||
}
|
}
|
||||||
@@ -282,16 +283,30 @@ const maxKeys = 20
|
|||||||
|
|
||||||
// OpenRepository reads the password and opens the repository.
|
// OpenRepository reads the password and opens the repository.
|
||||||
func OpenRepository(ctx context.Context, gopts Options, printer progress.Printer) (*repository.Repository, error) {
|
func OpenRepository(ctx context.Context, gopts Options, printer progress.Printer) (*repository.Repository, error) {
|
||||||
repo, err := ReadRepo(gopts)
|
repo, err := readRepo(gopts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
be, err := open(ctx, repo, gopts, gopts.Extended, printer)
|
be, err := innerOpenBackend(ctx, repo, gopts, gopts.Extended, false, printer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if config is there
|
||||||
|
fi, err := be.Stat(ctx, backend.Handle{Type: restic.ConfigFile})
|
||||||
|
if be.IsNotExist(err) {
|
||||||
|
//nolint:staticcheck // capitalized error string is intentional
|
||||||
|
return nil, fmt.Errorf("Fatal: %w: unable to open config file: %v\nIs there a repository at the following location?\n%v", ErrNoRepository, err, location.StripPassword(gopts.Backends, repo))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, location.StripPassword(gopts.Backends, repo))
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.Size == 0 {
|
||||||
|
return nil, errors.New("config file has zero size, invalid repository?")
|
||||||
|
}
|
||||||
|
|
||||||
s, err := repository.New(be, repository.Options{
|
s, err := repository.New(be, repository.Options{
|
||||||
Compression: gopts.Compression,
|
Compression: gopts.Compression,
|
||||||
PackSize: gopts.PackSize * 1024 * 1024,
|
PackSize: gopts.PackSize * 1024 * 1024,
|
||||||
@@ -403,7 +418,46 @@ func parseConfig(loc location.Location, opts options.Options) (interface{}, erro
|
|||||||
return cfg, nil
|
return cfg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func innerOpen(ctx context.Context, s string, gopts Options, opts options.Options, create bool, printer progress.Printer) (backend.Backend, error) {
|
// CreateRepository a repository with the given version and chunker polynomial.
|
||||||
|
func CreateRepository(ctx context.Context, gopts Options, version uint, chunkerPolynomial *chunker.Pol, printer progress.Printer) (*repository.Repository, error) {
|
||||||
|
if version < restic.MinRepoVersion || version > restic.MaxRepoVersion {
|
||||||
|
return nil, errors.Fatalf("only repository versions between %v and %v are allowed", restic.MinRepoVersion, restic.MaxRepoVersion)
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := readRepo(gopts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
gopts.Password, err = ReadPasswordTwice(ctx, gopts,
|
||||||
|
"enter password for new repository: ",
|
||||||
|
"enter password again: ")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
be, err := innerOpenBackend(ctx, repo, gopts, gopts.Extended, true, printer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Fatalf("create repository at %s failed: %v", location.StripPassword(gopts.Backends, repo), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := repository.New(be, repository.Options{
|
||||||
|
Compression: gopts.Compression,
|
||||||
|
PackSize: gopts.PackSize * 1024 * 1024,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Fatalf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.Init(ctx, version, gopts.Password, chunkerPolynomial)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Fatalf("create key in repository at %s failed: %v", location.StripPassword(gopts.Backends, repo), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func innerOpenBackend(ctx context.Context, s string, gopts Options, opts options.Options, create bool, printer progress.Printer) (backend.Backend, error) {
|
||||||
debug.Log("parsing location %v", location.StripPassword(gopts.Backends, s))
|
debug.Log("parsing location %v", location.StripPassword(gopts.Backends, s))
|
||||||
loc, err := location.Parse(gopts.Backends, s)
|
loc, err := location.Parse(gopts.Backends, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -481,32 +535,3 @@ func innerOpen(ctx context.Context, s string, gopts Options, opts options.Option
|
|||||||
|
|
||||||
return be, nil
|
return be, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the backend specified by a location config.
|
|
||||||
func open(ctx context.Context, s string, gopts Options, opts options.Options, printer progress.Printer) (backend.Backend, error) {
|
|
||||||
be, err := innerOpen(ctx, s, gopts, opts, false, printer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if config is there
|
|
||||||
fi, err := be.Stat(ctx, backend.Handle{Type: restic.ConfigFile})
|
|
||||||
if be.IsNotExist(err) {
|
|
||||||
//nolint:staticcheck // capitalized error string is intentional
|
|
||||||
return nil, fmt.Errorf("Fatal: %w: unable to open config file: %v\nIs there a repository at the following location?\n%v", ErrNoRepository, err, location.StripPassword(gopts.Backends, s))
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Fatalf("unable to open config file: %v\nIs there a repository at the following location?\n%v", err, location.StripPassword(gopts.Backends, s))
|
|
||||||
}
|
|
||||||
|
|
||||||
if fi.Size == 0 {
|
|
||||||
return nil, errors.New("config file has zero size, invalid repository?")
|
|
||||||
}
|
|
||||||
|
|
||||||
return be, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the backend specified by URI.
|
|
||||||
func Create(ctx context.Context, s string, gopts Options, opts options.Options, printer progress.Printer) (backend.Backend, error) {
|
|
||||||
return innerOpen(ctx, s, gopts, opts, true, printer)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func TestReadRepo(t *testing.T) {
|
|||||||
// test --repo option
|
// test --repo option
|
||||||
var gopts Options
|
var gopts Options
|
||||||
gopts.Repo = tempDir
|
gopts.Repo = tempDir
|
||||||
repo, err := ReadRepo(gopts)
|
repo, err := readRepo(gopts)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
rtest.Equals(t, tempDir, repo)
|
rtest.Equals(t, tempDir, repo)
|
||||||
|
|
||||||
@@ -27,13 +27,13 @@ func TestReadRepo(t *testing.T) {
|
|||||||
|
|
||||||
var gopts2 Options
|
var gopts2 Options
|
||||||
gopts2.RepositoryFile = foo
|
gopts2.RepositoryFile = foo
|
||||||
repo, err = ReadRepo(gopts2)
|
repo, err = readRepo(gopts2)
|
||||||
rtest.OK(t, err)
|
rtest.OK(t, err)
|
||||||
rtest.Equals(t, tempDir, repo)
|
rtest.Equals(t, tempDir, repo)
|
||||||
|
|
||||||
var gopts3 Options
|
var gopts3 Options
|
||||||
gopts3.RepositoryFile = foo + "-invalid"
|
gopts3.RepositoryFile = foo + "-invalid"
|
||||||
_, err = ReadRepo(gopts3)
|
_, err = readRepo(gopts3)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("must not read repository path from invalid file path")
|
t.Fatal("must not read repository path from invalid file path")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user