mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-08-01 02:11:15 -04:00
Merge branch 'origin/main' into 'next-release/main'
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
|
||||
"github.com/opencloud-eu/opencloud/pkg/config/parser"
|
||||
oclog "github.com/opencloud-eu/opencloud/pkg/log"
|
||||
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
|
||||
storageUsersParser "github.com/opencloud-eu/opencloud/services/storage-users/pkg/config/parser"
|
||||
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/event"
|
||||
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/revaconfig"
|
||||
@@ -95,6 +96,39 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
storageRoot := cfg.Drivers.Posix.Root
|
||||
root := storageRoot
|
||||
defaultRoot := true
|
||||
if v, err := cmd.Flags().GetString("basepath"); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to parse command-line parameter '--basepath': %v\n", err)
|
||||
os.Exit(1)
|
||||
} else if v != "" {
|
||||
root = v
|
||||
if !filepath.IsAbs(v) {
|
||||
if v, err = filepath.Abs(v); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to make the basepath mentioned using '--basepath' absolute: %v\n", err)
|
||||
os.Exit(1)
|
||||
} else {
|
||||
root = v
|
||||
}
|
||||
} else {
|
||||
root = v
|
||||
}
|
||||
root = filepath.Clean(root)
|
||||
defaultRoot = false
|
||||
}
|
||||
|
||||
// ensure that, if a basepath has been indicated, it is under the storage root
|
||||
if !defaultRoot {
|
||||
if contained, err := filepathx.IsSameOrContainedBy(storageRoot, root); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Failed to determine whether the specified basepath %q is contained by the storage root %q: %v\n", root, storageRoot, err)
|
||||
os.Exit(1)
|
||||
} else if !contained {
|
||||
fmt.Fprintf(os.Stderr, "The specified basepath %q is neither the storage root %q, nor a subdirectory thereof, nor a file underneath it\n", root, storageRoot)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// We want to initialize the driver but disable scanfs on boot, so we can trigger it manually afterwards
|
||||
drivers := revaconfig.StorageProviderDrivers(cfg)
|
||||
drivers["posix"] = revaconfig.Posix(cfg, false, false)
|
||||
@@ -112,6 +146,10 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
|
||||
oclog.Pretty(true),
|
||||
oclog.Color(false)).Logger
|
||||
|
||||
if !defaultRoot {
|
||||
log = log.With().Str("basepath", root).Logger()
|
||||
}
|
||||
|
||||
f, ok := registry.NewFuncs["posix"]
|
||||
if !ok {
|
||||
fmt.Fprintf(os.Stderr, "posix driver not found in registry\n")
|
||||
@@ -130,8 +168,12 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Println("Starting posixfs scan...")
|
||||
err = cacher.WarmupIDCache(cfg.Drivers.Posix.Root, true, false)
|
||||
if defaultRoot {
|
||||
fmt.Println("Starting posixfs scan...")
|
||||
} else {
|
||||
fmt.Printf("Starting posixfs scan at '%s'...\n", root)
|
||||
}
|
||||
err = cacher.WarmupIDCache(root, true, false)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Scan failed: %v\n", err)
|
||||
return err
|
||||
@@ -141,6 +183,7 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringP("basepath", "p", "", "the root under which to scan files, which may be a directory or a file (when omitted, detaults to using the storage root)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package filepathx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// JailJoin joins any number of path elements into a single path,
|
||||
@@ -10,3 +12,27 @@ import (
|
||||
func JailJoin(jail string, elem ...string) string {
|
||||
return filepath.Join(jail, filepath.Join(append([]string{"/"}, elem...)...))
|
||||
}
|
||||
|
||||
// Determines whether the file or directory 'child' is same as or underneath the directory 'parent'.
|
||||
//
|
||||
// Note that 'parent' is expected to be a directory.
|
||||
func IsSameOrContainedBy(parent string, child string) (bool, error) {
|
||||
absParent, err := filepath.Abs(parent)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to make parent directory absolute: %q: %w", parent, err)
|
||||
}
|
||||
|
||||
absChild, err := filepath.Abs(child)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to make child file/directory absolute: %q: %w", child, err)
|
||||
}
|
||||
|
||||
rel, err := filepath.Rel(absParent, absChild)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("failed to determine the relative path between the parent directory %q and the child file/directory: %q: %w", absParent, absChild, err)
|
||||
}
|
||||
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package filepathx_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestJailJoin(t *testing.T) {
|
||||
@@ -61,3 +64,23 @@ func TestJailJoin(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSameOrContainedBy(t *testing.T) {
|
||||
for _, tt := range []struct {
|
||||
parent string
|
||||
child string
|
||||
expected bool
|
||||
}{
|
||||
{"foo", "foo", true},
|
||||
{"/foo", "/foo", true},
|
||||
{"foo", "foo/bar", true},
|
||||
{"foo", "bar", false},
|
||||
} {
|
||||
t.Run(fmt.Sprintf("%s: %s vs %s", t.Name(), strings.ReplaceAll(tt.parent, "/", "."), strings.ReplaceAll(tt.child, "/", ".")), func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
b, err := filepathx.IsSameOrContainedBy(tt.parent, tt.child)
|
||||
require.NoError(err)
|
||||
require.Equal(tt.expected, b)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user