mirror of
https://github.com/octoleo/restic.git
synced 2024-11-29 16:23:59 +00:00
server: Add config
This commit is contained in:
parent
bebb08ee7e
commit
d4bf5bb279
@ -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)
|
||||||
|
|
||||||
|
2
cache.go
2
cache.go
@ -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
|
||||||
|
@ -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.")
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user