mirror of
https://github.com/offen/docker-volume-backup.git
synced 2026-04-23 00:45:36 +02:00
Paths are joined with client side separators when targeting remotes (#547)
Currently, filepath.Join is used to join path fragments that are supposed to be created on remote storage backends. This could theoretically cause problems when the separators used by the client and the remotes do not match. It's unlikely this causes problems right now, but it's definitely better to rectify it before it causes further confusion. This was raised in #541
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -128,7 +129,7 @@ func (b *azureBlobStorage) Copy(file string) error {
|
|||||||
_, err = b.client.UploadStream(
|
_, err = b.client.UploadStream(
|
||||||
context.Background(),
|
context.Background(),
|
||||||
b.containerName,
|
b.containerName,
|
||||||
filepath.Join(b.DestinationPath, filepath.Base(file)),
|
path.Join(b.DestinationPath, filepath.Base(file)),
|
||||||
fileReader,
|
fileReader,
|
||||||
b.uploadStreamOptions,
|
b.uploadStreamOptions,
|
||||||
)
|
)
|
||||||
@@ -141,7 +142,7 @@ func (b *azureBlobStorage) Copy(file string) error {
|
|||||||
// Prune rotates away backups according to the configuration and provided
|
// Prune rotates away backups according to the configuration and provided
|
||||||
// deadline for the Azure Blob storage backend.
|
// deadline for the Azure Blob storage backend.
|
||||||
func (b *azureBlobStorage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
|
func (b *azureBlobStorage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
|
||||||
lookupPrefix := filepath.Join(b.DestinationPath, pruningPrefix)
|
lookupPrefix := path.Join(b.DestinationPath, pruningPrefix)
|
||||||
pager := b.client.NewListBlobsFlatPager(b.containerName, &container.ListBlobsFlatOptions{
|
pager := b.client.NewListBlobsFlatPager(b.containerName, &container.ListBlobsFlatOptions{
|
||||||
Prefix: &lookupPrefix,
|
Prefix: &lookupPrefix,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -195,7 +194,7 @@ loop:
|
|||||||
_, err = b.client.UploadSessionFinish(
|
_, err = b.client.UploadSessionFinish(
|
||||||
files.NewUploadSessionFinishArg(
|
files.NewUploadSessionFinishArg(
|
||||||
files.NewUploadSessionCursor(sessionId, 0),
|
files.NewUploadSessionCursor(sessionId, 0),
|
||||||
files.NewCommitInfo(filepath.Join(b.DestinationPath, name)),
|
files.NewCommitInfo(path.Join(b.DestinationPath, name)),
|
||||||
), nil)
|
), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrap(err, "error finishing the upload session")
|
return errwrap.Wrap(err, "error finishing the upload session")
|
||||||
@@ -247,7 +246,7 @@ func (b *dropboxStorage) Prune(deadline time.Time, pruningPrefix string) (*stora
|
|||||||
|
|
||||||
pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
|
pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
if _, err := b.client.DeleteV2(files.NewDeleteArg(filepath.Join(b.DestinationPath, match.Name))); err != nil {
|
if _, err := b.client.DeleteV2(files.NewDeleteArg(path.Join(b.DestinationPath, match.Name))); err != nil {
|
||||||
return errwrap.Wrap(err, "error removing file from Dropbox storage")
|
return errwrap.Wrap(err, "error removing file from Dropbox storage")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/minio/minio-go/v7"
|
"github.com/minio/minio-go/v7"
|
||||||
@@ -124,7 +123,7 @@ func (b *s3Storage) Copy(file string) error {
|
|||||||
putObjectOptions.PartSize = uint64(partSize)
|
putObjectOptions.PartSize = uint64(partSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := b.client.FPutObject(context.Background(), b.bucket, filepath.Join(b.DestinationPath, name), file, putObjectOptions); err != nil {
|
if _, err := b.client.FPutObject(context.Background(), b.bucket, path.Join(b.DestinationPath, name), file, putObjectOptions); err != nil {
|
||||||
if errResp := minio.ToErrorResponse(err); errResp.Message != "" {
|
if errResp := minio.ToErrorResponse(err); errResp.Message != "" {
|
||||||
return errwrap.Wrap(
|
return errwrap.Wrap(
|
||||||
nil,
|
nil,
|
||||||
@@ -147,7 +146,7 @@ func (b *s3Storage) Copy(file string) error {
|
|||||||
// Prune rotates away backups according to the configuration and provided deadline for the S3/Minio storage backend.
|
// Prune rotates away backups according to the configuration and provided deadline for the S3/Minio storage backend.
|
||||||
func (b *s3Storage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
|
func (b *s3Storage) Prune(deadline time.Time, pruningPrefix string) (*storage.PruneStats, error) {
|
||||||
candidates := b.client.ListObjects(context.Background(), b.bucket, minio.ListObjectsOptions{
|
candidates := b.client.ListObjects(context.Background(), b.bucket, minio.ListObjectsOptions{
|
||||||
Prefix: filepath.Join(b.DestinationPath, pruningPrefix),
|
Prefix: path.Join(b.DestinationPath, pruningPrefix),
|
||||||
Recursive: true,
|
Recursive: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -115,7 +114,7 @@ func (b *sshStorage) Copy(file string) error {
|
|||||||
}
|
}
|
||||||
defer source.Close()
|
defer source.Close()
|
||||||
|
|
||||||
destination, err := b.sftpClient.Create(filepath.Join(b.DestinationPath, name))
|
destination, err := b.sftpClient.Create(path.Join(b.DestinationPath, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errwrap.Wrap(err, "error creating file")
|
return errwrap.Wrap(err, "error creating file")
|
||||||
}
|
}
|
||||||
@@ -180,7 +179,7 @@ func (b *sshStorage) Prune(deadline time.Time, pruningPrefix string) (*storage.P
|
|||||||
|
|
||||||
pruneErr := b.DoPrune(b.Name(), len(matches), len(candidates), deadline, func() error {
|
pruneErr := b.DoPrune(b.Name(), len(matches), len(candidates), deadline, func() error {
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
if err := b.sftpClient.Remove(filepath.Join(b.DestinationPath, match)); err != nil {
|
if err := b.sftpClient.Remove(path.Join(b.DestinationPath, match)); err != nil {
|
||||||
return errwrap.Wrap(err, "error removing file")
|
return errwrap.Wrap(err, "error removing file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ func (b *webDavStorage) Copy(file string) error {
|
|||||||
return errwrap.Wrap(err, "error opening the file to be uploaded")
|
return errwrap.Wrap(err, "error opening the file to be uploaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := b.client.WriteStream(filepath.Join(b.DestinationPath, name), r, 0644); err != nil {
|
if err := b.client.WriteStream(path.Join(b.DestinationPath, name), r, 0644); err != nil {
|
||||||
return errwrap.Wrap(err, "error uploading the file")
|
return errwrap.Wrap(err, "error uploading the file")
|
||||||
}
|
}
|
||||||
b.Log(storage.LogLevelInfo, b.Name(), "Uploaded a copy of backup '%s' to '%s' at path '%s'.", file, b.url, b.DestinationPath)
|
b.Log(storage.LogLevelInfo, b.Name(), "Uploaded a copy of backup '%s' to '%s' at path '%s'.", file, b.url, b.DestinationPath)
|
||||||
@@ -110,7 +109,7 @@ func (b *webDavStorage) Prune(deadline time.Time, pruningPrefix string) (*storag
|
|||||||
|
|
||||||
pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
|
pruneErr := b.DoPrune(b.Name(), len(matches), lenCandidates, deadline, func() error {
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
if err := b.client.Remove(filepath.Join(b.DestinationPath, match.Name())); err != nil {
|
if err := b.client.Remove(path.Join(b.DestinationPath, match.Name())); err != nil {
|
||||||
return errwrap.Wrap(err, "error removing file")
|
return errwrap.Wrap(err, "error removing file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user