backend/server: remove id and version from backend
This commit is contained in:
parent
1cedff0e9e
commit
2fb1783885
6 changed files with 28 additions and 246 deletions
|
@ -11,10 +11,7 @@ const (
|
||||||
Lock = "lock"
|
Lock = "lock"
|
||||||
Snapshot = "snapshot"
|
Snapshot = "snapshot"
|
||||||
Index = "index"
|
Index = "index"
|
||||||
)
|
Config = "config"
|
||||||
|
|
||||||
const (
|
|
||||||
Version = 1
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// A Backend manages data stored somewhere.
|
// A Backend manages data stored somewhere.
|
||||||
|
@ -43,17 +40,9 @@ type Backend interface {
|
||||||
// Close the backend
|
// Close the backend
|
||||||
Close() error
|
Close() error
|
||||||
|
|
||||||
Identifier
|
|
||||||
Lister
|
Lister
|
||||||
}
|
}
|
||||||
|
|
||||||
type Identifier interface {
|
|
||||||
// ID returns a unique ID for a specific repository. This means restic can
|
|
||||||
// recognize repositories accessed via different methods (e.g. local file
|
|
||||||
// access and sftp).
|
|
||||||
ID() string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Lister interface {
|
type Lister interface {
|
||||||
// List returns a channel that yields all names of blobs of type t in
|
// List returns a channel that yields all names of blobs of type t in
|
||||||
// lexicographic order. A goroutine is started for this. If the channel
|
// lexicographic order. A goroutine is started for this. If the channel
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package local
|
package local
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -11,7 +8,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/restic/restic/backend"
|
"github.com/restic/restic/backend"
|
||||||
)
|
)
|
||||||
|
@ -20,8 +16,6 @@ var ErrWrongData = errors.New("wrong data returned by backend, checksum does not
|
||||||
|
|
||||||
type Local struct {
|
type Local struct {
|
||||||
p string
|
p string
|
||||||
ver uint
|
|
||||||
id string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open opens the local backend at dir.
|
// Open opens the local backend at dir.
|
||||||
|
@ -36,68 +30,19 @@ func Open(dir string) (*Local, error) {
|
||||||
filepath.Join(dir, backend.Paths.Temp),
|
filepath.Join(dir, backend.Paths.Temp),
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if all necessary dirs and files are there
|
// test if all necessary dirs are there
|
||||||
for _, d := range items {
|
for _, d := range items {
|
||||||
if _, err := os.Stat(d); err != nil {
|
if _, err := os.Stat(d); err != nil {
|
||||||
return nil, fmt.Errorf("%s does not exist", d)
|
return nil, fmt.Errorf("%s does not exist", d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read version file
|
return &Local{p: dir}, nil
|
||||||
f, err := os.Open(filepath.Join(dir, backend.Paths.Version))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to read version file: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var version uint
|
|
||||||
n, err := fmt.Fscanf(f, "%d", &version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if n != 1 {
|
|
||||||
return nil, errors.New("could not read version from file")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check version
|
|
||||||
if version != backend.Version {
|
|
||||||
return nil, fmt.Errorf("wrong version %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// read ID
|
|
||||||
f, err = os.Open(filepath.Join(dir, backend.Paths.ID))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := strings.TrimSpace(string(buf))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Local{p: dir, ver: version, id: id}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates all the necessary files and directories for a new local
|
// Create creates all the necessary files and directories for a new local
|
||||||
// backend at dir.
|
// backend at dir. Afterwards a new config blob should must created.
|
||||||
func Create(dir string) (*Local, error) {
|
func Create(dir string) (*Local, error) {
|
||||||
versionFile := filepath.Join(dir, backend.Paths.Version)
|
|
||||||
idFile := filepath.Join(dir, backend.Paths.ID)
|
|
||||||
dirs := []string{
|
dirs := []string{
|
||||||
dir,
|
dir,
|
||||||
filepath.Join(dir, backend.Paths.Data),
|
filepath.Join(dir, backend.Paths.Data),
|
||||||
|
@ -108,15 +53,10 @@ func Create(dir string) (*Local, error) {
|
||||||
filepath.Join(dir, backend.Paths.Temp),
|
filepath.Join(dir, backend.Paths.Temp),
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if files already exist
|
// test if config file already exist
|
||||||
_, err := os.Lstat(versionFile)
|
_, err := os.Lstat(backend.Paths.Config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, errors.New("version file already exists")
|
return nil, errors.New("config file already exists")
|
||||||
}
|
|
||||||
|
|
||||||
_, err = os.Lstat(idFile)
|
|
||||||
if err == nil {
|
|
||||||
return nil, errors.New("id file already exists")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if directories already exist
|
// test if directories already exist
|
||||||
|
@ -134,44 +74,6 @@ func Create(dir string) (*Local, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create version file
|
|
||||||
f, err := os.Create(versionFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(f, "%d\n", backend.Version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// create ID file
|
|
||||||
id := make([]byte, sha256.Size)
|
|
||||||
_, err = rand.Read(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err = os.Create(idFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(f, hex.EncodeToString(id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// open backend
|
// open backend
|
||||||
return Open(dir)
|
return Open(dir)
|
||||||
}
|
}
|
||||||
|
@ -265,6 +167,10 @@ func (b *Local) Create() (backend.Blob, error) {
|
||||||
|
|
||||||
// Construct path for given Type and name.
|
// Construct path for given Type and name.
|
||||||
func filename(base string, t backend.Type, name string) string {
|
func filename(base string, t backend.Type, name string) string {
|
||||||
|
if t == backend.Config {
|
||||||
|
return filepath.Join(base, "config")
|
||||||
|
}
|
||||||
|
|
||||||
return filepath.Join(dirname(base, t, name), name)
|
return filepath.Join(dirname(base, t, name), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,16 +282,6 @@ func (b *Local) List(t backend.Type, done <-chan struct{}) <-chan string {
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns the version of this local backend.
|
|
||||||
func (b *Local) Version() uint {
|
|
||||||
return b.ver
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the ID of this local backend.
|
|
||||||
func (b *Local) ID() string {
|
|
||||||
return b.id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete removes the repository and all files.
|
// Delete removes the repository and all files.
|
||||||
func (b *Local) Delete() error { return os.RemoveAll(b.p) }
|
func (b *Local) Delete() error { return os.RemoveAll(b.p) }
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,7 @@ var Paths = struct {
|
||||||
Locks string
|
Locks string
|
||||||
Keys string
|
Keys string
|
||||||
Temp string
|
Temp string
|
||||||
Version string
|
Config string
|
||||||
ID string
|
|
||||||
}{
|
}{
|
||||||
"data",
|
"data",
|
||||||
"snapshots",
|
"snapshots",
|
||||||
|
@ -19,8 +18,7 @@ var Paths = struct {
|
||||||
"locks",
|
"locks",
|
||||||
"keys",
|
"keys",
|
||||||
"tmp",
|
"tmp",
|
||||||
"version",
|
"config",
|
||||||
"id",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default modes for file-based backends
|
// Default modes for file-based backends
|
||||||
|
|
|
@ -2,18 +2,15 @@ package sftp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/pkg/sftp"
|
"github.com/pkg/sftp"
|
||||||
"github.com/restic/restic/backend"
|
"github.com/restic/restic/backend"
|
||||||
|
@ -26,8 +23,6 @@ const (
|
||||||
type SFTP struct {
|
type SFTP struct {
|
||||||
c *sftp.Client
|
c *sftp.Client
|
||||||
p string
|
p string
|
||||||
ver uint
|
|
||||||
id string
|
|
||||||
|
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
}
|
}
|
||||||
|
@ -81,8 +76,7 @@ func Open(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
filepath.Join(dir, backend.Paths.Index),
|
filepath.Join(dir, backend.Paths.Index),
|
||||||
filepath.Join(dir, backend.Paths.Locks),
|
filepath.Join(dir, backend.Paths.Locks),
|
||||||
filepath.Join(dir, backend.Paths.Keys),
|
filepath.Join(dir, backend.Paths.Keys),
|
||||||
filepath.Join(dir, backend.Paths.Version),
|
filepath.Join(dir, backend.Paths.Temp),
|
||||||
filepath.Join(dir, backend.Paths.ID),
|
|
||||||
}
|
}
|
||||||
for _, d := range items {
|
for _, d := range items {
|
||||||
if _, err := sftp.c.Lstat(d); err != nil {
|
if _, err := sftp.c.Lstat(d); err != nil {
|
||||||
|
@ -90,64 +84,18 @@ func Open(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read version file
|
|
||||||
f, err := sftp.c.Open(filepath.Join(dir, backend.Paths.Version))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to read version file: %v\n", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var version uint
|
|
||||||
n, err := fmt.Fscanf(f, "%d", &version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if n != 1 {
|
|
||||||
return nil, errors.New("could not read version from file")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check version
|
|
||||||
if version != backend.Version {
|
|
||||||
return nil, fmt.Errorf("wrong version %d", version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// read ID
|
|
||||||
f, err = sftp.c.Open(filepath.Join(dir, backend.Paths.ID))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
buf, err := ioutil.ReadAll(f)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sftp.id = strings.TrimSpace(string(buf))
|
|
||||||
sftp.p = dir
|
sftp.p = dir
|
||||||
|
|
||||||
return sftp, nil
|
return sftp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates all the necessary files and directories for a new sftp
|
// Create creates all the necessary files and directories for a new sftp
|
||||||
// backend at dir.
|
// backend at dir. Afterwards a new config blob should must created.
|
||||||
func Create(dir string, program string, args ...string) (*SFTP, error) {
|
func Create(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
sftp, err := startClient(program, args...)
|
sftp, err := startClient(program, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
versionFile := filepath.Join(dir, backend.Paths.Version)
|
|
||||||
idFile := filepath.Join(dir, backend.Paths.ID)
|
|
||||||
dirs := []string{
|
dirs := []string{
|
||||||
dir,
|
dir,
|
||||||
filepath.Join(dir, backend.Paths.Data),
|
filepath.Join(dir, backend.Paths.Data),
|
||||||
|
@ -158,15 +106,10 @@ func Create(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
filepath.Join(dir, backend.Paths.Temp),
|
filepath.Join(dir, backend.Paths.Temp),
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if files already exist
|
// test if config file already exist
|
||||||
_, err = sftp.c.Lstat(versionFile)
|
_, err = sftp.c.Lstat(backend.Paths.Config)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, errors.New("version file already exists")
|
return nil, errors.New("config file already exists")
|
||||||
}
|
|
||||||
|
|
||||||
_, err = sftp.c.Lstat(idFile)
|
|
||||||
if err == nil {
|
|
||||||
return nil, errors.New("id file already exists")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test if directories already exist
|
// test if directories already exist
|
||||||
|
@ -184,44 +127,6 @@ func Create(dir string, program string, args ...string) (*SFTP, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// create version file
|
|
||||||
f, err := sftp.c.Create(versionFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintf(f, "%d\n", backend.Version)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// create ID file
|
|
||||||
id := make([]byte, sha256.Size)
|
|
||||||
_, err = rand.Read(id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
f, err = sftp.c.Create(idFile)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = fmt.Fprintln(f, hex.EncodeToString(id))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = f.Close()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sftp.c.Close()
|
err = sftp.c.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -389,6 +294,10 @@ func (r *SFTP) Create() (backend.Blob, error) {
|
||||||
|
|
||||||
// Construct path for given backend.Type and name.
|
// Construct path for given backend.Type and name.
|
||||||
func (r *SFTP) filename(t backend.Type, name string) string {
|
func (r *SFTP) filename(t backend.Type, name string) string {
|
||||||
|
if t == backend.Config {
|
||||||
|
return filepath.Join(r.p, "config")
|
||||||
|
}
|
||||||
|
|
||||||
return filepath.Join(r.dirname(t, name), name)
|
return filepath.Join(r.dirname(t, name), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,16 +451,6 @@ func (r *SFTP) List(t backend.Type, done <-chan struct{}) <-chan string {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns the version of this local backend.
|
|
||||||
func (r *SFTP) Version() uint {
|
|
||||||
return r.ver
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID returns the ID of this local backend.
|
|
||||||
func (r *SFTP) ID() string {
|
|
||||||
return r.id
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close closes the sftp connection and terminates the underlying command.
|
// Close closes the sftp connection and terminates the underlying command.
|
||||||
func (s *SFTP) Close() error {
|
func (s *SFTP) Close() error {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
|
|
4
cache.go
4
cache.go
|
@ -18,13 +18,13 @@ type Cache struct {
|
||||||
base string
|
base string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewCache(be backend.Identifier) (*Cache, error) {
|
func NewCache(s *server.Server) (*Cache, error) {
|
||||||
cacheDir, err := getCacheDir()
|
cacheDir, err := getCacheDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
basedir := filepath.Join(cacheDir, be.ID())
|
basedir := filepath.Join(cacheDir, s.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
|
||||||
|
|
|
@ -601,7 +601,7 @@ func (s *Server) Delete() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ID() string {
|
func (s *Server) ID() string {
|
||||||
return s.be.ID()
|
return "empty"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Location() string {
|
func (s *Server) Location() string {
|
||||||
|
|
Loading…
Reference in a new issue