2
2
mirror of https://github.com/octoleo/restic.git synced 2024-11-26 06:46:34 +00:00

server: Add config

This commit is contained in:
Alexander Neumann 2015-05-03 17:37:12 +02:00
parent bebb08ee7e
commit d4bf5bb279
5 changed files with 55 additions and 24 deletions

View File

@ -184,7 +184,7 @@ func (arch *Archiver) SaveFile(p *Progress, node *Node) error {
} }
chnker := GetChunker("archiver.SaveFile") chnker := GetChunker("archiver.SaveFile")
chnker.Reset(file, arch.s.ChunkerPolynomial()) chnker.Reset(file, arch.s.Config.ChunkerPolynomial)
resultChannels := [](<-chan saveResult){} resultChannels := [](<-chan saveResult){}
defer FreeChunker("archiver.SaveFile", chnker) defer FreeChunker("archiver.SaveFile", chnker)

View File

@ -24,7 +24,7 @@ func NewCache(s *server.Server) (*Cache, error) {
return nil, err return nil, err
} }
basedir := filepath.Join(cacheDir, s.ID()) basedir := filepath.Join(cacheDir, s.Config.ID)
debug.Log("Cache.New", "opened cache at %v", basedir) debug.Log("Cache.New", "opened cache at %v", basedir)
return &Cache{base: basedir}, nil return &Cache{base: basedir}, nil

View File

@ -74,14 +74,13 @@ func (cmd CmdInit) Execute(args []string) error {
} }
s := server.NewServer(be) s := server.NewServer(be)
err = s.CreateMasterKey(pw)
_, err = server.CreateMasterKey(s, pw)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "creating key in backend at %s failed: %v\n", opts.Repo, err) fmt.Fprintf(os.Stderr, "creating key in backend at %s failed: %v\n", opts.Repo, err)
os.Exit(1) os.Exit(1)
} }
fmt.Printf("created restic backend %v at %s\n", s.ID()[:10], opts.Repo) fmt.Printf("created restic backend %v at %s\n", s.Config.ID[:10], opts.Repo)
fmt.Println("Please note that knowledge of your password is required to access the repository.") fmt.Println("Please note that knowledge of your password is required to access the repository.")
fmt.Println("Losing your password means that your data is irrecoverably lost.") fmt.Println("Losing your password means that your data is irrecoverably lost.")

View File

@ -50,9 +50,9 @@ type Key struct {
name string name string
} }
// CreateMasterKey creates a new master key in the given backend and encrypts // createMasterKey creates a new master key in the given backend and encrypts
// it with the password. // it with the password.
func CreateMasterKey(s *Server, password string) (*Key, error) { func createMasterKey(s *Server, password string) (*Key, error) {
return AddKey(s, password, nil) return AddKey(s, password, nil)
} }

View File

@ -2,7 +2,9 @@ package server
import ( import (
"bytes" "bytes"
"crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -16,10 +18,19 @@ import (
"github.com/restic/restic/pack" "github.com/restic/restic/pack"
) )
// Config contains the configuration for a repository.
type Config struct {
Version uint `json:"version"`
ID string `json:"id"`
ChunkerPolynomial chunker.Pol `json:"chunker_polynomial"`
}
// Server is used to access a repository in a backend.
type Server struct { type Server struct {
be backend.Backend be backend.Backend
key *Key Config Config
idx *Index key *Key
idx *Index
pm sync.Mutex pm sync.Mutex
packs []*pack.Packer packs []*pack.Packer
@ -32,11 +43,6 @@ func NewServer(be backend.Backend) *Server {
} }
} }
// ChunkerPolynomial returns the secret polynomial used for content defined chunking.
func (s *Server) ChunkerPolynomial() chunker.Pol {
return chunker.Pol(s.key.Master().ChunkerPolynomial)
}
// Find loads the list of all blobs of type t and searches for names which start // Find loads the list of all blobs of type t and searches for names which start
// with prefix. If none is found, nil and ErrNoIDPrefixFound is returned. If // with prefix. If none is found, nil and ErrNoIDPrefixFound is returned. If
// more than one is found, nil and ErrMultipleIDMatches is returned. // more than one is found, nil and ErrMultipleIDMatches is returned.
@ -365,12 +371,12 @@ func (s *Server) SaveJSON(t pack.BlobType, item interface{}) (backend.ID, error)
// SaveJSONUnpacked serialises item as JSON and encrypts and saves it in the // SaveJSONUnpacked serialises item as JSON and encrypts and saves it in the
// backend as type t, without a pack. It returns the storage hash. // backend as type t, without a pack. It returns the storage hash.
func (s *Server) SaveJSONUnpacked(t backend.Type, item interface{}) (backend.ID, error) { func (s *Server) SaveJSONUnpacked(t backend.Type, item interface{}) (backend.ID, error) {
// create blob // create file
blob, err := s.be.Create() blob, err := s.be.Create()
if err != nil { if err != nil {
return nil, err return nil, err
} }
debug.Log("Server.SaveJSONUnpacked", "create new pack %p", blob) debug.Log("Server.SaveJSONUnpacked", "create new file %p", blob)
// hash // hash
hw := backend.NewHashingWriter(blob, sha256.New()) hw := backend.NewHashingWriter(blob, sha256.New())
@ -521,6 +527,36 @@ func (s *Server) loadIndex(id string) error {
return nil return nil
} }
const repositoryIDSize = sha256.Size
const RepositoryVersion = 1
func (s *Server) createConfig() (err error) {
s.Config.ChunkerPolynomial, err = chunker.RandomPolynomial()
if err != nil {
return err
}
newID := make([]byte, repositoryIDSize)
_, err = io.ReadFull(rand.Reader, newID)
if err != nil {
return err
}
s.Config.ID = hex.EncodeToString(newID)
s.Config.Version = RepositoryVersion
debug.Log("Server.createConfig", "New config: %#v", s.Config)
_, err = s.SaveJSONUnpacked(backend.Config, s.Config)
return err
}
func (s *Server) loadConfig(cfg *Config) error {
return s.LoadJSONUnpacked(backend.Config, nil, cfg)
}
// SearchKey tries to find a key for which the supplied password works,
// afterwards the repository config is read and parsed.
func (s *Server) SearchKey(password string) error { func (s *Server) SearchKey(password string) error {
key, err := SearchKey(s, password) key, err := SearchKey(s, password)
if err != nil { if err != nil {
@ -528,19 +564,19 @@ func (s *Server) SearchKey(password string) error {
} }
s.key = key s.key = key
return nil return s.loadConfig(&s.Config)
} }
// CreateMasterKey creates a new key with the supplied password, afterwards the // CreateMasterKey creates a new key with the supplied password, afterwards the
// repository config is created. // repository config is created.
func (s *Server) CreateMasterKey(password string) error { func (s *Server) CreateMasterKey(password string) error {
key, err := CreateMasterKey(s, password) key, err := createMasterKey(s, password)
if err != nil { if err != nil {
return err return err
} }
s.key = key s.key = key
return nil return s.createConfig()
} }
func (s *Server) Decrypt(ciphertext []byte) ([]byte, error) { func (s *Server) Decrypt(ciphertext []byte) ([]byte, error) {
@ -602,10 +638,6 @@ func (s *Server) Delete() error {
return errors.New("Delete() called for backend that does not implement this method") return errors.New("Delete() called for backend that does not implement this method")
} }
func (s *Server) ID() string {
return "empty"
}
func (s *Server) Location() string { func (s *Server) Location() string {
return s.be.Location() return s.be.Location()
} }