mirror of
https://github.com/octoleo/restic.git
synced 2024-11-23 05:12:10 +00:00
Rename CloudLayout -> RESTLayout
The REST backend uses a special layout without subdirs below data/. This layout is just used there and nowhere else, and our REST server implementation uses the default layout for the on disk storage. So we remove the REST layout from the auto detection code.
This commit is contained in:
parent
61cade6222
commit
f19852a738
@ -128,19 +128,19 @@ func DetectLayout(repo Filesystem, dir string) (Layout, error) {
|
|||||||
repo = &LocalFilesystem{}
|
repo = &LocalFilesystem{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// key file in the "keys" dir (DefaultLayout or CloudLayout)
|
// key file in the "keys" dir (DefaultLayout)
|
||||||
foundKeysFile, err := hasBackendFile(repo, repo.Join(dir, defaultLayoutPaths[restic.KeyFile]))
|
foundKeysFile, err := hasBackendFile(repo, repo.Join(dir, defaultLayoutPaths[restic.KeyFile]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// key file in the "key" dir (S3Layout)
|
// key file in the "key" dir (S3LegacyLayout)
|
||||||
foundKeyFile, err := hasBackendFile(repo, repo.Join(dir, s3LayoutPaths[restic.KeyFile]))
|
foundKeyFile, err := hasBackendFile(repo, repo.Join(dir, s3LayoutPaths[restic.KeyFile]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// data file in "data" directory (S3Layout or CloudLayout)
|
// data file in "data" directory (S3LegacyLayout)
|
||||||
foundDataFile, err := hasBackendFile(repo, repo.Join(dir, s3LayoutPaths[restic.DataFile]))
|
foundDataFile, err := hasBackendFile(repo, repo.Join(dir, s3LayoutPaths[restic.DataFile]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -152,14 +152,6 @@ func DetectLayout(repo Filesystem, dir string) (Layout, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if foundKeysFile && foundDataFile && !foundKeyFile && !foundDataSubdirFile {
|
|
||||||
debug.Log("found cloud layout at %v", dir)
|
|
||||||
return &CloudLayout{
|
|
||||||
Path: dir,
|
|
||||||
Join: repo.Join,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if foundKeysFile && foundDataSubdirFile && !foundKeyFile && !foundDataFile {
|
if foundKeysFile && foundDataSubdirFile && !foundKeyFile && !foundDataFile {
|
||||||
debug.Log("found default layout at %v", dir)
|
debug.Log("found default layout at %v", dir)
|
||||||
return &DefaultLayout{
|
return &DefaultLayout{
|
||||||
@ -190,11 +182,6 @@ func ParseLayout(repo Filesystem, layout, defaultLayout, path string) (l Layout,
|
|||||||
Path: path,
|
Path: path,
|
||||||
Join: repo.Join,
|
Join: repo.Join,
|
||||||
}
|
}
|
||||||
case "cloud":
|
|
||||||
l = &CloudLayout{
|
|
||||||
Path: path,
|
|
||||||
Join: repo.Join,
|
|
||||||
}
|
|
||||||
case "s3legacy":
|
case "s3legacy":
|
||||||
l = &S3LegacyLayout{
|
l = &S3LegacyLayout{
|
||||||
Path: path,
|
Path: path,
|
||||||
@ -214,7 +201,7 @@ func ParseLayout(repo Filesystem, layout, defaultLayout, path string) (l Layout,
|
|||||||
}
|
}
|
||||||
debug.Log("layout detected: %v", l)
|
debug.Log("layout detected: %v", l)
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("unknown backend layout string %q, may be one of: default, cloud, s3legacy", layout)
|
return nil, errors.Errorf("unknown backend layout string %q, may be one of: default, s3legacy", layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
return l, nil
|
return l, nil
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
package backend
|
|
||||||
|
|
||||||
import "restic"
|
|
||||||
|
|
||||||
// CloudLayout implements the default layout for cloud storage backends, as
|
|
||||||
// described in the Design document.
|
|
||||||
type CloudLayout struct {
|
|
||||||
URL string
|
|
||||||
Path string
|
|
||||||
Join func(...string) string
|
|
||||||
}
|
|
||||||
|
|
||||||
var cloudLayoutPaths = defaultLayoutPaths
|
|
||||||
|
|
||||||
// Dirname returns the directory path for a given file type and name.
|
|
||||||
func (l *CloudLayout) Dirname(h restic.Handle) string {
|
|
||||||
if h.Type == restic.ConfigFile {
|
|
||||||
return l.URL + l.Join(l.Path, "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
return l.URL + l.Join(l.Path, "/", cloudLayoutPaths[h.Type]) + "/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filename returns a path to a file, including its name.
|
|
||||||
func (l *CloudLayout) Filename(h restic.Handle) string {
|
|
||||||
name := h.Name
|
|
||||||
|
|
||||||
if h.Type == restic.ConfigFile {
|
|
||||||
name = "config"
|
|
||||||
}
|
|
||||||
|
|
||||||
return l.URL + l.Join(l.Path, "/", cloudLayoutPaths[h.Type], name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Paths returns all directory names
|
|
||||||
func (l *CloudLayout) Paths() (dirs []string) {
|
|
||||||
for _, p := range cloudLayoutPaths {
|
|
||||||
dirs = append(dirs, l.URL+l.Join(l.Path, p))
|
|
||||||
}
|
|
||||||
return dirs
|
|
||||||
}
|
|
||||||
|
|
||||||
// Basedir returns the base dir name for files of type t.
|
|
||||||
func (l *CloudLayout) Basedir(t restic.FileType) string {
|
|
||||||
return l.URL + l.Join(l.Path, cloudLayoutPaths[t])
|
|
||||||
}
|
|
45
src/restic/backend/layout_rest.go
Normal file
45
src/restic/backend/layout_rest.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package backend
|
||||||
|
|
||||||
|
import "restic"
|
||||||
|
|
||||||
|
// RESTLayout implements the default layout for the REST protocol.
|
||||||
|
type RESTLayout struct {
|
||||||
|
URL string
|
||||||
|
Path string
|
||||||
|
Join func(...string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
var restLayoutPaths = defaultLayoutPaths
|
||||||
|
|
||||||
|
// Dirname returns the directory path for a given file type and name.
|
||||||
|
func (l *RESTLayout) Dirname(h restic.Handle) string {
|
||||||
|
if h.Type == restic.ConfigFile {
|
||||||
|
return l.URL + l.Join(l.Path, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.URL + l.Join(l.Path, "/", restLayoutPaths[h.Type]) + "/"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filename returns a path to a file, including its name.
|
||||||
|
func (l *RESTLayout) Filename(h restic.Handle) string {
|
||||||
|
name := h.Name
|
||||||
|
|
||||||
|
if h.Type == restic.ConfigFile {
|
||||||
|
name = "config"
|
||||||
|
}
|
||||||
|
|
||||||
|
return l.URL + l.Join(l.Path, "/", restLayoutPaths[h.Type], name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Paths returns all directory names
|
||||||
|
func (l *RESTLayout) Paths() (dirs []string) {
|
||||||
|
for _, p := range restLayoutPaths {
|
||||||
|
dirs = append(dirs, l.URL+l.Join(l.Path, p))
|
||||||
|
}
|
||||||
|
return dirs
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basedir returns the base dir name for files of type t.
|
||||||
|
func (l *RESTLayout) Basedir(t restic.FileType) string {
|
||||||
|
return l.URL + l.Join(l.Path, restLayoutPaths[t])
|
||||||
|
}
|
@ -79,7 +79,7 @@ func TestDefaultLayout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCloudLayout(t *testing.T) {
|
func TestRESTLayout(t *testing.T) {
|
||||||
path, cleanup := TempDir(t)
|
path, cleanup := TempDir(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ func TestCloudLayout(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
l := &CloudLayout{
|
l := &RESTLayout{
|
||||||
Path: path,
|
Path: path,
|
||||||
Join: filepath.Join,
|
Join: filepath.Join,
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ func TestCloudLayout(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCloudLayoutURLs(t *testing.T) {
|
func TestRESTLayoutURLs(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
l Layout
|
l Layout
|
||||||
h restic.Handle
|
h restic.Handle
|
||||||
@ -155,19 +155,19 @@ func TestCloudLayoutURLs(t *testing.T) {
|
|||||||
dir string
|
dir string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
&CloudLayout{URL: "https://hostname.foo", Path: "", Join: path.Join},
|
&RESTLayout{URL: "https://hostname.foo", Path: "", Join: path.Join},
|
||||||
restic.Handle{Type: restic.DataFile, Name: "foobar"},
|
restic.Handle{Type: restic.DataFile, Name: "foobar"},
|
||||||
"https://hostname.foo/data/foobar",
|
"https://hostname.foo/data/foobar",
|
||||||
"https://hostname.foo/data/",
|
"https://hostname.foo/data/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&CloudLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join},
|
&RESTLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join},
|
||||||
restic.Handle{Type: restic.LockFile, Name: "foobar"},
|
restic.Handle{Type: restic.LockFile, Name: "foobar"},
|
||||||
"https://hostname.foo:1234/prefix/repo/locks/foobar",
|
"https://hostname.foo:1234/prefix/repo/locks/foobar",
|
||||||
"https://hostname.foo:1234/prefix/repo/locks/",
|
"https://hostname.foo:1234/prefix/repo/locks/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
&CloudLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join},
|
&RESTLayout{URL: "https://hostname.foo:1234/prefix/repo", Path: "/", Join: path.Join},
|
||||||
restic.Handle{Type: restic.ConfigFile, Name: "foobar"},
|
restic.Handle{Type: restic.ConfigFile, Name: "foobar"},
|
||||||
"https://hostname.foo:1234/prefix/repo/config",
|
"https://hostname.foo:1234/prefix/repo/config",
|
||||||
"https://hostname.foo:1234/prefix/repo/",
|
"https://hostname.foo:1234/prefix/repo/",
|
||||||
@ -302,7 +302,6 @@ func TestDetectLayout(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{"repo-layout-local.tar.gz", "*backend.DefaultLayout"},
|
{"repo-layout-local.tar.gz", "*backend.DefaultLayout"},
|
||||||
{"repo-layout-cloud.tar.gz", "*backend.CloudLayout"},
|
|
||||||
{"repo-layout-s3-old.tar.gz", "*backend.S3LegacyLayout"},
|
{"repo-layout-s3-old.tar.gz", "*backend.S3LegacyLayout"},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,12 +341,11 @@ func TestParseLayout(t *testing.T) {
|
|||||||
want string
|
want string
|
||||||
}{
|
}{
|
||||||
{"default", "", "*backend.DefaultLayout"},
|
{"default", "", "*backend.DefaultLayout"},
|
||||||
{"cloud", "", "*backend.CloudLayout"},
|
|
||||||
{"s3legacy", "", "*backend.S3LegacyLayout"},
|
{"s3legacy", "", "*backend.S3LegacyLayout"},
|
||||||
{"", "", "*backend.CloudLayout"},
|
{"", "", "*backend.DefaultLayout"},
|
||||||
}
|
}
|
||||||
|
|
||||||
SetupTarTestFixture(t, path, filepath.Join("testdata", "repo-layout-cloud.tar.gz"))
|
SetupTarTestFixture(t, path, filepath.Join("testdata", "repo-layout-local.tar.gz"))
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.layoutName, func(t *testing.T) {
|
t.Run(test.layoutName, func(t *testing.T) {
|
||||||
|
@ -22,11 +22,6 @@ func TestLayout(t *testing.T) {
|
|||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
||||||
}},
|
}},
|
||||||
{"repo-layout-cloud.tar.gz", "", false, map[string]bool{
|
|
||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
|
||||||
"aa464e9fd598fe4202492ee317ffa728e82fa83a1de1a61996e5bd2d6651646c": false,
|
|
||||||
}},
|
|
||||||
{"repo-layout-s3-old.tar.gz", "", false, map[string]bool{
|
{"repo-layout-s3-old.tar.gz", "", false, map[string]bool{
|
||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
||||||
|
@ -48,7 +48,7 @@ func Open(cfg Config) (restic.Backend, error) {
|
|||||||
url: cfg.URL,
|
url: cfg.URL,
|
||||||
connChan: connChan,
|
connChan: connChan,
|
||||||
client: client,
|
client: client,
|
||||||
Layout: &backend.CloudLayout{URL: url, Join: path.Join},
|
Layout: &backend.RESTLayout{URL: url, Join: path.Join},
|
||||||
}
|
}
|
||||||
|
|
||||||
return be, nil
|
return be, nil
|
||||||
|
@ -28,11 +28,6 @@ func TestLayout(t *testing.T) {
|
|||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
||||||
}},
|
}},
|
||||||
{"repo-layout-cloud.tar.gz", "", false, map[string]bool{
|
|
||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
|
||||||
"aa464e9fd598fe4202492ee317ffa728e82fa83a1de1a61996e5bd2d6651646c": false,
|
|
||||||
}},
|
|
||||||
{"repo-layout-s3-old.tar.gz", "", false, map[string]bool{
|
{"repo-layout-s3-old.tar.gz", "", false, map[string]bool{
|
||||||
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
"fc919a3b421850f6fa66ad22ebcf91e433e79ffef25becf8aef7c7b1eca91683": false,
|
||||||
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
"c089d62788da14f8b7cbf77188305c0874906f0b73d3fce5a8869050e8d0c0e1": false,
|
||||||
|
BIN
src/restic/backend/testdata/repo-layout-cloud.tar.gz
vendored
BIN
src/restic/backend/testdata/repo-layout-cloud.tar.gz
vendored
Binary file not shown.
Loading…
Reference in New Issue
Block a user