Remove automatic repository subdirectories
This commit is contained in:
@@ -166,12 +166,6 @@ func ValidateRepository(r Repository) error {
|
||||
if r.Mount.Remote == "" || !filepath.IsAbs(r.Mount.MountPoint) {
|
||||
return errors.New("managed mount requires remote and absolute mountPoint")
|
||||
}
|
||||
location := filepath.Clean(r.Location)
|
||||
mountPoint := filepath.Clean(r.Mount.MountPoint)
|
||||
relative, err := filepath.Rel(mountPoint, location)
|
||||
if err != nil || relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
|
||||
return errors.New("managed repository location must be inside mountPoint")
|
||||
}
|
||||
}
|
||||
if r.Type == RepositorySFTP && r.CredentialRef != "" {
|
||||
knownHosts := r.Options["knownHostsPath"]
|
||||
|
||||
@@ -79,14 +79,3 @@ func TestRetentionRequiresAtLeastOneRule(t *testing.T) {
|
||||
t.Fatalf("age retention rejected: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestManagedRepositoryLocationMustRemainInsideMountPoint(t *testing.T) {
|
||||
repo := Repository{SchemaVersion: 1, ID: "repo", Name: "NAS", Type: RepositorySMB, Location: "/mnt/remotes/nas/NAS", PasswordRef: "password", Mount: &MountConfig{Managed: true, Remote: "//nas/backups", MountPoint: "/mnt/remotes/nas"}}
|
||||
if err := ValidateRepository(repo); err != nil {
|
||||
t.Fatalf("repository subdirectory rejected: %v", err)
|
||||
}
|
||||
repo.Location = "/mnt/remotes/other/NAS"
|
||||
if err := ValidateRepository(repo); err == nil {
|
||||
t.Fatal("repository location outside mountPoint accepted")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ type MountManager struct {
|
||||
type MountedRepository struct {
|
||||
Repository model.Repository
|
||||
Mounted bool
|
||||
MountPoint string
|
||||
CredentialFile string
|
||||
}
|
||||
|
||||
@@ -33,12 +32,7 @@ func (m *MountManager) Prepare(ctx context.Context, repo model.Repository) (Moun
|
||||
}
|
||||
if repo.Mount == nil || !repo.Mount.Managed {
|
||||
if _, err := os.Stat(repo.Location); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return result, fmt.Errorf("connectivity: external mount unavailable: %w", err)
|
||||
}
|
||||
if _, parentErr := os.Stat(filepath.Dir(repo.Location)); parentErr != nil {
|
||||
return result, fmt.Errorf("connectivity: external mount unavailable: %w", parentErr)
|
||||
}
|
||||
return result, fmt.Errorf("connectivity: external mount unavailable: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
@@ -46,11 +40,6 @@ func (m *MountManager) Prepare(ctx context.Context, repo model.Repository) (Moun
|
||||
if !strings.HasPrefix(point, "/mnt/remotes/") && !strings.HasPrefix(point, "/mnt/disks/") {
|
||||
return result, errors.New("validation: managed mountPoint must be below /mnt/remotes or /mnt/disks")
|
||||
}
|
||||
repositoryPath := filepath.Clean(repo.Location)
|
||||
relative, err := filepath.Rel(point, repositoryPath)
|
||||
if err != nil || relative == ".." || strings.HasPrefix(relative, ".."+string(filepath.Separator)) {
|
||||
return result, errors.New("validation: managed repository location must be inside its mountPoint")
|
||||
}
|
||||
if err := os.MkdirAll(point, 0700); err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -97,7 +86,7 @@ func (m *MountManager) Prepare(ctx context.Context, repo model.Repository) (Moun
|
||||
return result, fmt.Errorf("connectivity: mount repository: %w", err)
|
||||
}
|
||||
result.Mounted = true
|
||||
result.MountPoint = point
|
||||
result.Repository.Location = point
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -108,5 +97,5 @@ func (m *MountManager) Cleanup(ctx context.Context, mounted MountedRepository) e
|
||||
if !mounted.Mounted {
|
||||
return nil
|
||||
}
|
||||
return exec.CommandContext(ctx, "umount", mounted.MountPoint).Run()
|
||||
return exec.CommandContext(ctx, "umount", mounted.Repository.Location).Run()
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package platform
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.casaderoll.de/michael/urbm/internal/model"
|
||||
)
|
||||
|
||||
func TestExternalMountAllowsNewRepositorySubdirectory(t *testing.T) {
|
||||
base := t.TempDir()
|
||||
repo := model.Repository{Type: model.RepositorySMB, Location: filepath.Join(base, "Photos")}
|
||||
manager := &MountManager{}
|
||||
|
||||
mounted, err := manager.Prepare(context.Background(), repo)
|
||||
if err != nil {
|
||||
t.Fatalf("new repository subdirectory rejected: %v", err)
|
||||
}
|
||||
if mounted.Repository.Location != repo.Location {
|
||||
t.Fatalf("location = %q, want %q", mounted.Repository.Location, repo.Location)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExternalMountRejectsMissingBaseDirectory(t *testing.T) {
|
||||
repo := model.Repository{Type: model.RepositoryNFS, Location: filepath.Join(t.TempDir(), "missing", "Photos")}
|
||||
manager := &MountManager{}
|
||||
|
||||
if _, err := manager.Prepare(context.Background(), repo); err == nil {
|
||||
t.Fatal("missing external mount base accepted")
|
||||
}
|
||||
}
|
||||
@@ -226,11 +226,6 @@ func (s *Service) TestRepository(ctx context.Context, repoID string, initialize
|
||||
}
|
||||
defer s.mounts.Cleanup(context.Background(), mounted)
|
||||
if initialize {
|
||||
if mounted.Repository.Type != model.RepositorySFTP {
|
||||
if err := os.MkdirAll(mounted.Repository.Location, 0750); err != nil {
|
||||
return fmt.Errorf("repository: create destination directory: %w", err)
|
||||
}
|
||||
}
|
||||
return s.restic.Init(ctx, mounted.Repository)
|
||||
}
|
||||
_, err = s.restic.Snapshots(ctx, mounted.Repository)
|
||||
|
||||
Reference in New Issue
Block a user