2015-06-21 13:02:56 +02:00
package main
import (
2022-02-13 00:52:03 +01:00
"strconv"
2020-09-19 12:41:52 +02:00
"github.com/restic/chunker"
2020-03-20 22:52:27 +00:00
"github.com/restic/restic/internal/backend/location"
2017-07-23 14:21:03 +02:00
"github.com/restic/restic/internal/errors"
"github.com/restic/restic/internal/repository"
2022-02-13 00:52:03 +01:00
"github.com/restic/restic/internal/restic"
2016-09-17 12:36:05 +02:00
"github.com/spf13/cobra"
2015-06-21 13:02:56 +02:00
)
2016-09-17 12:36:05 +02:00
var cmdInit = & cobra . Command {
Use : "init" ,
2017-09-11 09:32:44 -07:00
Short : "Initialize a new repository" ,
2016-09-17 12:36:05 +02:00
Long : `
The "init" command initializes a new repository .
2019-11-04 22:03:38 -08:00
EXIT STATUS
== == == == == =
Exit status is 0 if the command was successful , and non - zero if there was any error .
2016-09-17 12:36:05 +02:00
` ,
2017-08-06 21:02:16 +02:00
DisableAutoGenTag : true ,
2016-09-17 12:36:05 +02:00
RunE : func ( cmd * cobra . Command , args [ ] string ) error {
2020-09-19 12:41:52 +02:00
return runInit ( initOptions , globalOptions , args )
2016-09-17 12:36:05 +02:00
} ,
2015-06-21 13:02:56 +02:00
}
2020-09-19 12:41:52 +02:00
// InitOptions bundles all options for the init command.
type InitOptions struct {
secondaryRepoOptions
CopyChunkerParameters bool
2022-02-13 00:52:03 +01:00
RepositoryVersion string
2020-09-19 12:41:52 +02:00
}
var initOptions InitOptions
2016-09-17 12:36:05 +02:00
func init ( ) {
cmdRoot . AddCommand ( cmdInit )
2020-09-19 12:41:52 +02:00
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)" )
2022-02-13 00:52:03 +01:00
f . StringVar ( & initOptions . RepositoryVersion , "repository-version" , "stable" , "repository format version to use, allowed values are a format version, 'latest' and 'stable'" )
2016-09-17 12:36:05 +02:00
}
2020-09-19 12:41:52 +02:00
func runInit ( opts InitOptions , gopts GlobalOptions , args [ ] string ) error {
2022-02-13 00:52:03 +01:00
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 )
}
2020-09-19 12:41:52 +02:00
chunkerPolynomial , err := maybeReadChunkerPolynomial ( opts , gopts )
if err != nil {
return err
}
2020-08-30 23:20:57 +02:00
repo , err := ReadRepo ( gopts )
if err != nil {
return err
}
2017-07-24 23:15:31 +02:00
gopts . password , err = ReadPasswordTwice ( gopts ,
2018-01-20 09:51:49 +01:00
"enter password for new repository: " ,
2017-07-24 23:15:31 +02:00
"enter password again: " )
if err != nil {
return err
2015-06-21 13:02:56 +02:00
}
2021-02-14 11:39:28 -08:00
be , err := create ( repo , gopts . extended )
if err != nil {
return errors . Fatalf ( "create repository at %s failed: %v\n" , location . StripPassword ( gopts . Repo ) , err )
}
2022-07-02 23:30:26 +02:00
s , err := repository . New ( be , repository . Options {
Compression : gopts . Compression ,
PackSize : gopts . MinPackSize * 1024 * 1024 ,
} )
if err != nil {
return err
}
2016-03-06 12:34:23 +01:00
2022-02-13 00:52:03 +01:00
err = s . Init ( gopts . ctx , version , gopts . password , chunkerPolynomial )
2015-06-21 13:02:56 +02:00
if err != nil {
2020-03-20 22:52:27 +00:00
return errors . Fatalf ( "create key in repository at %s failed: %v\n" , location . StripPassword ( gopts . Repo ) , err )
2015-06-21 13:02:56 +02:00
}
2020-03-20 22:52:27 +00:00
Verbosef ( "created restic repository %v at %s\n" , s . Config ( ) . ID [ : 10 ] , location . StripPassword ( gopts . Repo ) )
2016-09-17 12:36:05 +02:00
Verbosef ( "\n" )
Verbosef ( "Please note that knowledge of your password is required to access\n" )
Verbosef ( "the repository. Losing your password means that your data is\n" )
Verbosef ( "irrecoverably lost.\n" )
2015-06-21 13:02:56 +02:00
return nil
}
2020-09-19 12:41:52 +02:00
func maybeReadChunkerPolynomial ( opts InitOptions , gopts GlobalOptions ) ( * chunker . Pol , error ) {
if opts . CopyChunkerParameters {
otherGopts , err := fillSecondaryGlobalOpts ( opts . secondaryRepoOptions , gopts , "secondary" )
if err != nil {
return nil , err
}
otherRepo , err := OpenRepository ( otherGopts )
if err != nil {
return nil , err
}
pol := otherRepo . Config ( ) . ChunkerPolynomial
return & pol , nil
}
if opts . Repo != "" {
return nil , errors . Fatal ( "Secondary repository must only be specified when copying the chunker parameters" )
}
return nil , nil
}