init: Add flag to specify created repository version

This commit is contained in:
Michael Eischer 2022-02-13 00:52:03 +01:00 committed by Alexander Neumann
parent 4b957e7373
commit 362ab06023
4 changed files with 42 additions and 10 deletions

View file

@ -1,10 +1,13 @@
package main
import (
"strconv"
"github.com/restic/chunker"
"github.com/restic/restic/internal/backend/location"
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/repository"
"github.com/restic/restic/internal/restic"
"github.com/spf13/cobra"
)
@ -30,6 +33,7 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
type InitOptions struct {
secondaryRepoOptions
CopyChunkerParameters bool
RepositoryVersion string
}
var initOptions InitOptions
@ -40,9 +44,26 @@ func init() {
f := cmdInit.Flags()
initSecondaryRepoOptions(f, &initOptions.secondaryRepoOptions, "secondary", "to copy chunker parameters from")
f.BoolVar(&initOptions.CopyChunkerParameters, "copy-chunker-params", false, "copy chunker parameters from the secondary repository (useful with the copy command)")
f.StringVar(&initOptions.RepositoryVersion, "repository-version", "stable", "repository format version to use, allowed values are a format version, 'latest' and 'stable'")
}
func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
var version uint
if opts.RepositoryVersion == "latest" || opts.RepositoryVersion == "" {
version = restic.MaxRepoVersion
} else if opts.RepositoryVersion == "stable" {
version = restic.StableRepoVersion
} else {
v, err := strconv.ParseUint(opts.RepositoryVersion, 10, 32)
if err != nil {
return errors.Fatal("invalid repository version")
}
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(opts, gopts)
if err != nil {
return err
@ -67,7 +88,7 @@ func runInit(opts InitOptions, gopts GlobalOptions, args []string) error {
s := repository.New(be)
err = s.Init(gopts.ctx, gopts.password, chunkerPolynomial)
err = s.Init(gopts.ctx, version, gopts.password, chunkerPolynomial)
if err != nil {
return errors.Fatalf("create key in repository at %s failed: %v\n", location.StripPassword(gopts.Repo), err)
}

View file

@ -661,7 +661,15 @@ func (r *Repository) SearchKey(ctx context.Context, password string, maxKeys int
// Init creates a new master key with the supplied password, initializes and
// saves the repository config.
func (r *Repository) Init(ctx context.Context, password string, chunkerPolynomial *chunker.Pol) error {
func (r *Repository) Init(ctx context.Context, version uint, password string, chunkerPolynomial *chunker.Pol) error {
if version > restic.MaxRepoVersion {
return fmt.Errorf("repo version %v too high", version)
}
if version < restic.MinRepoVersion {
return fmt.Errorf("repo version %v too low", version)
}
has, err := r.be.Test(ctx, restic.Handle{Type: restic.ConfigFile})
if err != nil {
return err
@ -670,7 +678,7 @@ func (r *Repository) Init(ctx context.Context, password string, chunkerPolynomia
return errors.New("repository master key and config already initialized")
}
cfg, err := restic.CreateConfig()
cfg, err := restic.CreateConfig(version)
if err != nil {
return err
}

View file

@ -18,9 +18,12 @@ type Config struct {
ChunkerPolynomial chunker.Pol `json:"chunker_polynomial"`
}
// RepoVersion is the version that is written to the config when a repository
const MinRepoVersion = 1
const MaxRepoVersion = 2
// StableRepoVersion is the version that is written to the config when a repository
// is newly created with Init().
const RepoVersion = 1
const StableRepoVersion = 1
// JSONUnpackedLoader loads unpacked JSON.
type JSONUnpackedLoader interface {
@ -29,7 +32,7 @@ type JSONUnpackedLoader interface {
// CreateConfig creates a config file with a randomly selected polynomial and
// ID.
func CreateConfig() (Config, error) {
func CreateConfig(version uint) (Config, error) {
var (
err error
cfg Config
@ -41,7 +44,7 @@ func CreateConfig() (Config, error) {
}
cfg.ID = NewRandomID().String()
cfg.Version = RepoVersion
cfg.Version = version
debug.Log("New config: %#v", cfg)
return cfg, nil
@ -52,7 +55,7 @@ func TestCreateConfig(t testing.TB, pol chunker.Pol) (cfg Config) {
cfg.ChunkerPolynomial = pol
cfg.ID = NewRandomID().String()
cfg.Version = RepoVersion
cfg.Version = StableRepoVersion
return cfg
}
@ -77,7 +80,7 @@ func LoadConfig(ctx context.Context, r JSONUnpackedLoader) (Config, error) {
return Config{}, err
}
if cfg.Version != RepoVersion {
if cfg.Version < MinRepoVersion || cfg.Version > MaxRepoVersion {
return Config{}, errors.Errorf("unsupported repository version %v", cfg.Version)
}

View file

@ -32,7 +32,7 @@ func TestConfig(t *testing.T) {
return restic.ID{}, nil
}
cfg1, err := restic.CreateConfig()
cfg1, err := restic.CreateConfig(restic.MaxRepoVersion)
rtest.OK(t, err)
_, err = saver(save).SaveJSONUnpacked(restic.ConfigFile, cfg1)