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.Reset(file, arch.s.ChunkerPolynomial())
chnker.Reset(file, arch.s.Config.ChunkerPolynomial)
resultChannels := [](<-chan saveResult){}
defer FreeChunker("archiver.SaveFile", chnker)

View File

@ -24,7 +24,7 @@ func NewCache(s *server.Server) (*Cache, error) {
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)
return &Cache{base: basedir}, nil

View File

@ -74,14 +74,13 @@ func (cmd CmdInit) Execute(args []string) error {
}
s := server.NewServer(be)
_, err = server.CreateMasterKey(s, pw)
err = s.CreateMasterKey(pw)
if err != nil {
fmt.Fprintf(os.Stderr, "creating key in backend at %s failed: %v\n", opts.Repo, err)
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("Losing your password means that your data is irrecoverably lost.")

View File

@ -50,9 +50,9 @@ type Key struct {
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.
func CreateMasterKey(s *Server, password string) (*Key, error) {
func createMasterKey(s *Server, password string) (*Key, error) {
return AddKey(s, password, nil)
}

View File

@ -2,7 +2,9 @@ package server
import (
"bytes"
"crypto/rand"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
@ -16,10 +18,19 @@ import (
"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 {
be backend.Backend
key *Key
idx *Index
be backend.Backend
Config Config
key *Key
idx *Index
pm sync.Mutex
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
// with prefix. If none is found, nil and ErrNoIDPrefixFound is returned. If
// 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
// backend as type t, without a pack. It returns the storage hash.
func (s *Server) SaveJSONUnpacked(t backend.Type, item interface{}) (backend.ID, error) {
// create blob
// create file
blob, err := s.be.Create()
if err != nil {
return nil, err
}
debug.Log("Server.SaveJSONUnpacked", "create new pack %p", blob)
debug.Log("Server.SaveJSONUnpacked", "create new file %p", blob)
// hash
hw := backend.NewHashingWriter(blob, sha256.New())
@ -521,6 +527,36 @@ func (s *Server) loadIndex(id string) error {
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 {
key, err := SearchKey(s, password)
if err != nil {
@ -528,19 +564,19 @@ func (s *Server) SearchKey(password string) error {
}
s.key = key
return nil
return s.loadConfig(&s.Config)
}
// CreateMasterKey creates a new key with the supplied password, afterwards the
// repository config is created.
func (s *Server) CreateMasterKey(password string) error {
key, err := CreateMasterKey(s, password)
key, err := createMasterKey(s, password)
if err != nil {
return err
}
s.key = key
return nil
return s.createConfig()
}
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")
}
func (s *Server) ID() string {
return "empty"
}
func (s *Server) Location() string {
return s.be.Location()
}