Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach the owncloud storage driver home handling #571

Merged
merged 1 commit into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/oc-phoenix/frontend.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ chunk_folder = "/var/tmp/reva/chunks"
# for eos we need to rewrite the path
# TODO strip the username from the path so the CS3 namespace can be mounted
# at the files/<username> endpoint? what about migration? separate reva instance
files_namespace = "/"
files_namespace = "/oc"

# similar to the dav/files endpoint we can configure a prefix for the old webdav endpoint
# we use the old webdav endpoint to present the cs3 namespace
Expand Down
6 changes: 1 addition & 5 deletions examples/oc-phoenix/storage-home.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,13 @@ driver = "owncloud"
mount_path = "/home"
mount_id = "123e4567-e89b-12d3-a456-426655440000"
expose_data_server = true
path_wrapper = "context"
data_server_url = "http://localhost:12001/data"
enable_home_creation = true

[grpc.services.storageprovider.drivers.owncloud]
datadirectory = "/var/tmp/reva/data"
layout = "{{.Username}}"
enable_home = true

[grpc.services.storageprovider.path_wrappers.context]
prefix = ""
layout = "{{.Username}}"

[http]
address = "0.0.0.0:12001"
Expand Down
107 changes: 64 additions & 43 deletions pkg/storage/fs/owncloud/owncloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,10 @@ func init() {

type config struct {
DataDirectory string `mapstructure:"datadirectory"`
Scan bool `mapstructure:"scan"`
UserLayout string `mapstructure:"user_layout"`
Redis string `mapstructure:"redis"`
Layout string `mapstructure:"layout"`
EnableHome bool `mapstructure:"enable_home"`
Scan bool `mapstructure:"scan"`
}

func parseConfig(m map[string]interface{}) (*config, error) {
Expand All @@ -170,8 +171,8 @@ func (c *config) init(m map[string]interface{}) {
if c.Redis == "" {
c.Redis = ":6379"
}
if c.Layout == "" {
c.Layout = "{{.Username}}"
if c.UserLayout == "" {
c.UserLayout = "{{.Username}}"
}
// default to scanning if not configured
if _, ok := m["scan"]; !ok {
Expand Down Expand Up @@ -270,26 +271,36 @@ func (fs *ocfs) scanFiles(ctx context.Context, conn redis.Conn) {
// the incoming path starts with /<username>, so we need to insert the files subfolder into the path
// and prefix the datadirectory
// TODO the path handed to a storage provider should not contain the username
func (fs *ocfs) wrap(ctx context.Context, fn string) string {
// trim all /
fn = strings.Trim(fn, "/")
// p = "" or
// p = <username> or
// p = <username>/foo/bar.txt
parts := strings.SplitN(fn, "/", 2)

switch len(parts) {
case 1:
// parts = "" or "<username>"
if parts[0] == "" {
return fs.c.DataDirectory
func (fs *ocfs) wrap(ctx context.Context, fn string) (internal string) {
if fs.c.EnableHome {
layout, err := fs.GetHome(ctx)
if err != nil {
panic(err)
}
internal = path.Join(fs.c.DataDirectory, layout, "files", fn)
} else {
// trim all /
fn = strings.Trim(fn, "/")
// p = "" or
// p = <username> or
// p = <username>/foo/bar.txt
parts := strings.SplitN(fn, "/", 2)

switch len(parts) {
case 1:
// parts = "" or "<username>"
if parts[0] == "" {
internal = fs.c.DataDirectory
return
}
// parts = "<username>"
internal = path.Join(fs.c.DataDirectory, parts[0], "files")
default:
// parts = "<username>", "foo/bar.txt"
internal = path.Join(fs.c.DataDirectory, parts[0], "files", parts[1])
}
// parts = "<username>"
return path.Join(fs.c.DataDirectory, parts[0], "files")
default:
// parts = "<username>", "foo/bar.txt"
return path.Join(fs.c.DataDirectory, parts[0], "files", parts[1])
}
return
}

// ownloud stores versions in the files_versions subfolder
Expand Down Expand Up @@ -329,27 +340,37 @@ func (fs *ocfs) getRecyclePath(ctx context.Context) (string, error) {
return path.Join(fs.c.DataDirectory, u.GetUsername(), "files_trashbin/files"), nil
}

func (fs *ocfs) unwrap(ctx context.Context, np string) string {
// np = /data/<username>/files/foo/bar.txt
// remove data dir
if fs.c.DataDirectory != "/" {
// fs.c.DataDirectory is a clean puth, so it never ends in /
np = strings.TrimPrefix(np, fs.c.DataDirectory)
// np = /<username>/files/foo/bar.txt
}
func (fs *ocfs) unwrap(ctx context.Context, np string) (external string) {
if fs.c.EnableHome {
layout, err := fs.GetHome(ctx)
if err != nil {
panic(err)
}
trim := path.Join(fs.c.DataDirectory, layout, "files")
external = strings.TrimPrefix(np, trim)
} else {
// np = /data/<username>/files/foo/bar.txt
// remove data dir
if fs.c.DataDirectory != "/" {
// fs.c.DataDirectory is a clean path, so it never ends in /
np = strings.TrimPrefix(np, fs.c.DataDirectory)
// np = /<username>/files/foo/bar.txt
}

parts := strings.SplitN(np, "/", 4)
// parts = "", "<username>", "files", "foo/bar.txt"
switch len(parts) {
case 1:
return "/"
case 2:
return path.Join("/", parts[1])
case 3:
return path.Join("/", parts[1])
default:
return path.Join("/", parts[1], parts[3])
parts := strings.SplitN(np, "/", 4)
// parts = "", "<username>", "files", "foo/bar.txt"
switch len(parts) {
case 1:
external = "/"
case 2:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use a fallthrough here, it makes it more readable to my eyes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

external = path.Join("/", parts[1])
case 3:
external = path.Join("/", parts[1])
default:
external = path.Join("/", parts[1], parts[3])
}
}
return
}

func getOwner(fn string) string {
Expand Down Expand Up @@ -851,7 +872,7 @@ func (fs *ocfs) CreateHome(ctx context.Context) error {
err = errors.Wrap(err, "oc CreateHome: no user in ctx and home is enabled")
panic(err)
}
layout := templates.WithUser(u, fs.c.Layout)
layout := templates.WithUser(u, fs.c.UserLayout)

homePaths := []string{
path.Join(fs.c.DataDirectory, layout, "files"),
Expand Down Expand Up @@ -883,7 +904,7 @@ func (fs *ocfs) GetHome(ctx context.Context) (string, error) {
err = errors.Wrap(err, "oc GetHome: no user in ctx and home is enabled")
panic(err)
}
relativeHome := templates.WithUser(u, fs.c.Layout)
relativeHome := templates.WithUser(u, fs.c.UserLayout)
return relativeHome, nil
}

Expand Down