From 9ec532da93f2401459c8d17594590edfba08af12 Mon Sep 17 00:00:00 2001 From: Ralf Haferkamp Date: Thu, 2 Oct 2025 12:10:01 +0200 Subject: [PATCH] deps: Bump reva to latest main for getting https://github.com/opencloud-eu/reva/pull/360 --- go.mod | 8 +-- go.sum | 16 ++--- .../internal/grpc/interceptors/auth/auth.go | 5 +- .../reva/v2/pkg/group/manager/ldap/ldap.go | 5 ++ .../v2/pkg/group/manager/loader/loader.go | 1 + .../reva/v2/pkg/group/manager/null/null.go | 62 ++++++++++++++++++ .../reva/v2/pkg/sharedconf/sharedconf.go | 6 ++ .../v2/pkg/storage/fs/posix/lookup/lookup.go | 16 +++++ .../pkg/storage/fs/posix/tree/assimilation.go | 2 +- .../reva/v2/pkg/storage/fs/posix/tree/tree.go | 19 ++---- .../storage/pkg/decomposedfs/lookup/lookup.go | 5 ++ .../storage/pkg/decomposedfs/node/locks.go | 64 +++++++++++++++---- .../pkg/storage/pkg/decomposedfs/node/node.go | 11 +++- .../pkg/storage/pkg/decomposedfs/tree/tree.go | 2 +- .../reva/v2/pkg/utils/ldap/identity.go | 11 ++++ .../go.etcd.io/etcd/api/v3/version/version.go | 2 +- .../etcd/client/v3/retry_interceptor.go | 6 +- vendor/modules.txt | 15 +++-- 18 files changed, 203 insertions(+), 53 deletions(-) create mode 100644 vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/null/null.go diff --git a/go.mod b/go.mod index 69c4ea772..9f0394f47 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( github.com/open-policy-agent/opa v1.9.0 github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 - github.com/opencloud-eu/reva/v2 v2.38.1-0.20250924125540-eaa2437c36b2 + github.com/opencloud-eu/reva/v2 v2.38.1-0.20251002093930-dcce351c08d6 github.com/opensearch-project/opensearch-go/v4 v4.5.0 github.com/orcaman/concurrent-map v1.0.0 github.com/pkg/errors v0.9.1 @@ -361,9 +361,9 @@ require ( github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect github.com/yashtewari/glob-intersection v0.2.0 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.etcd.io/etcd/api/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect - go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.etcd.io/etcd/api/v3 v3.6.5 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect + go.etcd.io/etcd/client/v3 v3.6.5 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.38.0 // indirect diff --git a/go.sum b/go.sum index c82faaf63..69dd019a6 100644 --- a/go.sum +++ b/go.sum @@ -946,8 +946,8 @@ github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+l github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI= github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 h1:vD/EdfDUrv4omSFjrinT8Mvf+8D7f9g4vgQ2oiDrVUI= github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q= -github.com/opencloud-eu/reva/v2 v2.38.1-0.20250924125540-eaa2437c36b2 h1:e3B6KbWMjloKpqoTwTwvBLoCETRyyCDkQsqwRQMUdxc= -github.com/opencloud-eu/reva/v2 v2.38.1-0.20250924125540-eaa2437c36b2/go.mod h1:8mGCM9tLIPsC5aEKS022Z5u89u6jKuOl0znK0gNFReM= +github.com/opencloud-eu/reva/v2 v2.38.1-0.20251002093930-dcce351c08d6 h1:b/agGaz/lQtZ8rikiqf4onpdpdllcUez/NO2pDWhEuU= +github.com/opencloud-eu/reva/v2 v2.38.1-0.20251002093930-dcce351c08d6/go.mod h1:kv+7Jfn0uqAg4Wy5rX4XuT5aX7DKvbtGp9hVcsES2+M= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -1257,12 +1257,12 @@ github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQ go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo= go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E= -go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= -go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= -go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= -go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= -go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= -go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/api/v3 v3.6.5 h1:pMMc42276sgR1j1raO/Qv3QI9Af/AuyQUW6CBAWuntA= +go.etcd.io/etcd/api/v3 v3.6.5/go.mod h1:ob0/oWA/UQQlT1BmaEkWQzI0sJ1M0Et0mMpaABxguOQ= +go.etcd.io/etcd/client/pkg/v3 v3.6.5 h1:Duz9fAzIZFhYWgRjp/FgNq2gO1jId9Yae/rLn3RrBP8= +go.etcd.io/etcd/client/pkg/v3 v3.6.5/go.mod h1:8Wx3eGRPiy0qOFMZT/hfvdos+DjEaPxdIDiCDUv/FQk= +go.etcd.io/etcd/client/v3 v3.6.5 h1:yRwZNFBx/35VKHTcLDeO7XVLbCBFbPi+XV4OC3QJf2U= +go.etcd.io/etcd/client/v3 v3.6.5/go.mod h1:ZqwG/7TAFZ0BJ0jXRPoJjKQJtbFo/9NIY8uoFFKcCyo= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= diff --git a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/auth.go b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/auth.go index 5d1274776..3b5801219 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/auth.go +++ b/vendor/github.com/opencloud-eu/reva/v2/internal/grpc/interceptors/auth/auth.go @@ -150,7 +150,10 @@ func NewUnary(m map[string]interface{}, unprotected []string, tp trace.TracerPro log.Warn().Err(err).Msg("access token is invalid") return nil, status.Errorf(codes.PermissionDenied, "auth: core access token is invalid") } - + if sharedconf.MultiTenantEnabled() && u.GetId().GetType() != userpb.UserType_USER_TYPE_SERVICE && u.GetId().GetTenantId() == "" { + log.Warn().Msg("user has no tenant id, rejecting request") + return nil, status.Errorf(codes.PermissionDenied, "auth: user has no tenant id, rejecting request") + } // store user and scopes in context ctx = ctxpkg.ContextSetUser(ctx, u) ctx = ctxpkg.ContextSetScopes(ctx, tokenScope) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap/ldap.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap/ldap.go index 517874a49..f4b32f069 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap/ldap.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap/ldap.go @@ -32,6 +32,7 @@ import ( "github.com/opencloud-eu/reva/v2/pkg/errtypes" "github.com/opencloud-eu/reva/v2/pkg/group" "github.com/opencloud-eu/reva/v2/pkg/group/manager/registry" + "github.com/opencloud-eu/reva/v2/pkg/sharedconf" "github.com/opencloud-eu/reva/v2/pkg/utils" ldapIdentity "github.com/opencloud-eu/reva/v2/pkg/utils/ldap" "github.com/pkg/errors" @@ -71,6 +72,10 @@ func parseConfig(m map[string]interface{}) (*config, error) { // New returns a group manager implementation that connects to a LDAP server to provide group metadata. func New(m map[string]interface{}) (group.Manager, error) { + if sharedconf.MultiTenantEnabled() { + return nil, errtypes.NotSupported("ldap group manager does not support multi-tenancy") + } + mgr := &manager{} err := mgr.Configure(m) if err != nil { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/loader/loader.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/loader/loader.go index c0ad45d85..8bd36e7b3 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/loader/loader.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/loader/loader.go @@ -22,5 +22,6 @@ import ( // Load core group manager drivers. _ "github.com/opencloud-eu/reva/v2/pkg/group/manager/json" _ "github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap" + _ "github.com/opencloud-eu/reva/v2/pkg/group/manager/null" // Add your own here ) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/null/null.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/null/null.go new file mode 100644 index 000000000..e6d913395 --- /dev/null +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/group/manager/null/null.go @@ -0,0 +1,62 @@ +// Copyright 2018-2020 CERN +// Copyright 2025 OpenCloud GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package null + +import ( + "context" + + grouppb "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" + userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + "github.com/opencloud-eu/reva/v2/pkg/errtypes" + "github.com/opencloud-eu/reva/v2/pkg/group" + "github.com/opencloud-eu/reva/v2/pkg/group/manager/registry" +) + +func init() { + registry.Register("null", New) +} + +type manager struct { +} + +// New returns a group manager implementation that return NOT FOUND or empty result set for every call +func New(m map[string]interface{}) (group.Manager, error) { + return &manager{}, nil +} + +func (m *manager) GetGroup(ctx context.Context, gid *grouppb.GroupId, skipFetchingMembers bool) (*grouppb.Group, error) { + return nil, errtypes.NotFound(gid.OpaqueId) +} + +func (m *manager) GetGroupByClaim(ctx context.Context, claim, value string, skipFetchingMembers bool) (*grouppb.Group, error) { + return nil, errtypes.NotFound(value) +} + +func (m *manager) FindGroups(ctx context.Context, query string, skipFetchingMembers bool) ([]*grouppb.Group, error) { + return []*grouppb.Group{}, nil +} + +func (m *manager) GetMembers(ctx context.Context, gid *grouppb.GroupId) ([]*userpb.UserId, error) { + return nil, errtypes.NotFound(gid.OpaqueId) +} + +func (m *manager) HasMember(ctx context.Context, gid *grouppb.GroupId, uid *userpb.UserId) (bool, error) { + return false, errtypes.NotFound(gid.OpaqueId) +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/sharedconf/sharedconf.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/sharedconf/sharedconf.go index 88593e4cd..40875b8dd 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/sharedconf/sharedconf.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/sharedconf/sharedconf.go @@ -42,6 +42,7 @@ type conf struct { GatewaySVC string `mapstructure:"gatewaysvc"` DataGateway string `mapstructure:"datagateway"` SkipUserGroupsInToken bool `mapstructure:"skip_user_groups_in_token"` + MultiTenantEnabled bool `mapstructure:"multi_tenant_enabled"` GRPCClientOptions ClientOptions `mapstructure:"grpc_client_options"` } @@ -107,6 +108,11 @@ func SkipUserGroupsInToken() bool { return sharedConf.SkipUserGroupsInToken } +// MultiTenantEnabled returns whether this is a mulit-tenant enabled configuratio +func MultiTenantEnabled() bool { + return sharedConf.MultiTenantEnabled +} + // GRPCClientOptions returns the global grpc client options func GRPCClientOptions() ClientOptions { return sharedConf.GRPCClientOptions diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go index 658e5c529..ef69a56e6 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/lookup/lookup.go @@ -303,6 +303,22 @@ func (lu *Lookup) InternalPath(spaceID, nodeID string) string { return path } +// LockfilePaths returns the paths(s) to the lockfile of the node +func (lu *Lookup) LockfilePaths(spaceID, nodeID string) []string { + spaceRoot, _ := lu.IDCache.Get(context.Background(), spaceID, spaceID) + if len(spaceRoot) == 0 { + return nil + } + paths := []string{filepath.Join(spaceRoot, MetadataDir, Pathify(nodeID, 4, 2)+".lock")} + + nodepath := lu.InternalPath(spaceID, nodeID) + if len(nodepath) > 0 { + paths = append(paths, nodepath+".lock") + } + + return paths +} + // VersionPath returns the path to the version of the node func (lu *Lookup) VersionPath(spaceID, nodeID, version string) string { spaceRoot, _ := lu.IDCache.Get(context.Background(), spaceID, spaceID) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go index b92bc72a1..6db899f5f 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/assimilation.go @@ -399,7 +399,7 @@ func (t *Tree) generateTempNodeId(path string) string { return strings.ReplaceAll(strings.TrimPrefix(path, "/"), "/", "-") } else { // Use sha256 if path too long - pathHash := fmt.Sprintf("%x", sha256.Sum256([]byte(path)))[:240] + pathHash := fmt.Sprintf("%x", sha256.Sum256([]byte(path))) t.log.Info().Str("path", path).Msg("path too long, using sha256 as lock: " + pathHash) return pathHash } diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go index f021c4234..936a4ed29 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/tree/tree.go @@ -343,8 +343,6 @@ func (t *Tree) CreateDir(ctx context.Context, n *node.Node) (err error) { // Move replaces the target with the source func (t *Tree) Move(ctx context.Context, oldNode *node.Node, newNode *node.Node) (err error) { - lockFilePath := oldNode.LockFilePath() - if oldNode.SpaceID != newNode.SpaceID { // WebDAV RFC https://www.rfc-editor.org/rfc/rfc4918#section-9.9.4 says to use // > 502 (Bad Gateway) - This may occur when the destination is on another @@ -400,14 +398,6 @@ func (t *Tree) Move(ctx context.Context, oldNode *node.Node, newNode *node.Node) return errors.Wrap(err, "posixfs: could not update node attributes") } - // rename the lock (if it exists) - if _, err := os.Stat(lockFilePath); err == nil { - err = os.Rename(lockFilePath, newNode.LockFilePath()) - if err != nil { - return errors.Wrap(err, "posixfs: could not move lock") - } - } - // update id cache for the moved subtree. if oldNode.IsDir(ctx) { err = t.WarmupIDCache(filepath.Join(newNode.ParentPath(), newNode.Name), false, false) @@ -582,8 +572,11 @@ func (t *Tree) Delete(ctx context.Context, n *node.Node) error { } // Remove lock file if it exists - if err := os.Remove(n.LockFilePath()); err != nil { - t.log.Error().Err(err).Str("path", n.LockFilePath()).Msg("could not remove lock file") + paths := n.LockFilePaths() + for _, lockFilePath := range paths { + if err := os.Remove(lockFilePath); err != nil && !os.IsNotExist(err) { + t.log.Error().Err(err).Str("path", lockFilePath).Msg("could not remove lock file") + } } err := t.trashbin.MoveToTrash(ctx, n, path) @@ -747,7 +740,7 @@ func (t *Tree) isInternal(path string) bool { } func isLockFile(path string) bool { - return strings.HasSuffix(path, ".lock") || strings.HasSuffix(path, ".flock") || strings.HasSuffix(path, ".mlock") + return strings.HasSuffix(path, ".flock") || strings.HasSuffix(path, ".mlock") } func isTrash(path string) bool { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go index 8612ca978..37a4af3e4 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/lookup/lookup.go @@ -273,6 +273,11 @@ func (lu *Lookup) InternalPath(spaceID, nodeID string) string { return filepath.Join(lu.Options.Root, "spaces", Pathify(spaceID, 1, 2), "nodes", Pathify(nodeID, 4, 2)) } +// LockfilePaths returns the paths(s) to the lockfile of the node +func (lu *Lookup) LockfilePaths(spaceID, nodeID string) []string { + return []string{lu.InternalPath(spaceID, nodeID) + ".lock"} +} + // VersionPath returns the internal path for a version of a node // Deprecated: use InternalPath instead func (lu *Lookup) VersionPath(spaceID, nodeID, version string) string { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/locks.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/locks.go index 3dd9ad57c..4e0e87019 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/locks.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/locks.go @@ -40,7 +40,7 @@ import ( func (n *Node) SetLock(ctx context.Context, lock *provider.Lock) error { ctx, span := tracer.Start(ctx, "SetLock") defer span.End() - lockFilePath := n.LockFilePath() + lockFilePath := n.LockFilePaths()[0] // ensure parent path exists if err := os.MkdirAll(filepath.Dir(lockFilePath), 0700); err != nil { @@ -90,7 +90,7 @@ func (n *Node) SetLock(ctx context.Context, lock *provider.Lock) error { } // ReadLock reads the lock id for a node -func (n Node) ReadLock(ctx context.Context, skipFileLock bool) (*provider.Lock, error) { +func (n *Node) ReadLock(ctx context.Context, skipFileLock bool) (*provider.Lock, error) { ctx, span := tracer.Start(ctx, "ReadLock") defer span.End() @@ -124,10 +124,7 @@ func (n Node) ReadLock(ctx context.Context, skipFileLock bool) (*provider.Lock, }() } - _, subspan = tracer.Start(ctx, "os.Open") - f, err := os.Open(n.LockFilePath()) - subspan.End() - + f, err := openAndMigrateLockFile(ctx, n, os.O_RDONLY, 0) if err != nil { if errors.Is(err, fs.ErrNotExist) { return nil, errtypes.NotFound("no lock found") @@ -182,7 +179,7 @@ func (n *Node) RefreshLock(ctx context.Context, lock *provider.Lock, existingLoc } }() - f, err := os.OpenFile(n.LockFilePath(), os.O_RDWR, os.ModeExclusive) + f, err := openAndMigrateLockFile(ctx, n, os.O_RDWR, os.ModeExclusive) switch { case errors.Is(err, fs.ErrNotExist): return errtypes.PreconditionFailed("lock does not exist") @@ -190,7 +187,6 @@ func (n *Node) RefreshLock(ctx context.Context, lock *provider.Lock, existingLoc return errors.Wrap(err, "Decomposedfs: could not open lock file") } defer f.Close() - readLock := &provider.Lock{} if err := json.NewDecoder(f).Decode(readLock); err != nil { return errors.Wrap(err, "Decomposedfs: could not read lock") @@ -246,7 +242,7 @@ func (n *Node) Unlock(ctx context.Context, lock *provider.Lock) error { } }() - f, err := os.OpenFile(n.LockFilePath(), os.O_RDONLY, os.ModeExclusive) + f, err := openAndMigrateLockFile(ctx, n, os.O_RDONLY, os.ModeExclusive) switch { case errors.Is(err, fs.ErrNotExist): return errtypes.Aborted("lock does not exist") @@ -323,8 +319,12 @@ func readLocksIntoOpaque(ctx context.Context, n *Node, ri *provider.ResourceInfo } func (n *Node) hasLocks(ctx context.Context) bool { - _, err := os.Stat(n.LockFilePath()) // FIXME better error checking - return err == nil + for _, p := range n.LockFilePaths() { + if _, err := os.Stat(p); err == nil { + return true + } + } + return false } func isLockModificationAllowed(ctx context.Context, oldLock *provider.Lock, newLock *provider.Lock) (bool, error) { @@ -358,3 +358,45 @@ func isLockModificationAllowed(ctx context.Context, oldLock *provider.Lock, newL return appNameEquals && lockUserEquals && contextUserEquals, nil } + +// openAndMigrateLockFile opens the lock file for a node, migrating any legacy lock files if found +// This is needed to support the transition to the new lock file scheme in the posix driver. +// Once this transition period is over the migration code can be removed again. +func openAndMigrateLockFile(ctx context.Context, n *Node, flag int, perm os.FileMode) (*os.File, error) { + lockfilePaths := n.LockFilePaths() + + // check for legacy lock files and migrate them + for i := 1; i < len(lockfilePaths); i++ { + fi, err := os.Stat(lockfilePaths[i]) + if err == nil { + if fi.Size() == 0 { + // this is not a lock file of ours. ignore + continue + } + + f, err := os.Open(lockfilePaths[i]) + if err != nil { + continue + } + defer f.Close() + readLock := &provider.Lock{} + if err := json.NewDecoder(f).Decode(readLock); err != nil { + // this is not a lock file of ours. ignore + continue + } + + // legacy lock file found, move it to the new location + err = os.MkdirAll(filepath.Dir(lockfilePaths[0]), 0700) + if err != nil { + return nil, errors.Wrap(err, "Decomposedfs: could not create lock file directory") + } + if err := os.Rename(lockfilePaths[i], lockfilePaths[0]); err != nil { + return nil, errors.Wrap(err, "Decomposedfs: could not migrate lock file") + } + } else if !errors.Is(err, fs.ErrNotExist) { + return nil, errors.Wrap(err, "Decomposedfs: could not stat legacy lock file") + } + } + + return os.OpenFile(lockfilePaths[0], flag, perm) +} diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go index 6ec4ce86b..616dfe097 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node/node.go @@ -158,6 +158,7 @@ type PathLookup interface { InternalRoot() string InternalSpaceRoot(spaceID string) string InternalPath(spaceID, nodeID string) string + LockfilePaths(spaceID, nodeID string) []string VersionPath(spaceID, nodeID, version string) string Path(ctx context.Context, n *Node, hasPermission PermissionFunc) (path string, err error) MetadataBackend() metadata.Backend @@ -635,9 +636,13 @@ func (n *Node) ParentPath() string { return n.lu.InternalPath(n.SpaceID, n.ParentID) } -// LockFilePath returns the internal path of the lock file of the node -func (n *Node) LockFilePath() string { - return n.InternalPath() + ".lock" +// LockfilePaths returns the paths(s) to the lockfile of the node +// Returning multiple paths allows for supporting legacy lockfiles +// while migrating to a new lockfile scheme. The first element is always the +// path to use for new locks. +// In the future only one path should remain at which point the function can return a single string. +func (n *Node) LockFilePaths() []string { + return n.lu.LockfilePaths(n.SpaceID, n.ID) } // CalculateEtag returns a hash of fileid + tmtime (or mtime) diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go index 23b3b994d..c9767db17 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/tree/tree.go @@ -501,7 +501,7 @@ func (t *Tree) Delete(ctx context.Context, n *node.Node) (err error) { } // Remove lock file if it exists - _ = os.Remove(n.LockFilePath()) + _ = os.Remove(n.LockFilePaths()[0]) // finally remove the entry from the parent dir if err = os.Remove(path); err != nil { diff --git a/vendor/github.com/opencloud-eu/reva/v2/pkg/utils/ldap/identity.go b/vendor/github.com/opencloud-eu/reva/v2/pkg/utils/ldap/identity.go index 697f68008..e0cf46d91 100644 --- a/vendor/github.com/opencloud-eu/reva/v2/pkg/utils/ldap/identity.go +++ b/vendor/github.com/opencloud-eu/reva/v2/pkg/utils/ldap/identity.go @@ -28,6 +28,7 @@ import ( "github.com/google/uuid" "github.com/opencloud-eu/reva/v2/pkg/appctx" "github.com/opencloud-eu/reva/v2/pkg/errtypes" + "github.com/opencloud-eu/reva/v2/pkg/sharedconf" "github.com/pkg/errors" "github.com/rs/zerolog/log" "go.opentelemetry.io/otel/attribute" @@ -180,6 +181,16 @@ func (i *Identity) Setup() error { return fmt.Errorf("invalid disable mechanism setting: %s", i.User.DisableMechanism) } + if sharedconf.MultiTenantEnabled() { + if i.User.Schema.TenantID == "" { + return fmt.Errorf("Invalid configuration: a 'tenantId' user schema attribute must be defined for multi-tenant setups") + } + } else { + if i.User.Schema.TenantID != "" { + return fmt.Errorf("Invalid configuration: Superfluous 'tenantId' user schema attribute defined for single-tenant setups") + } + } + return nil } diff --git a/vendor/go.etcd.io/etcd/api/v3/version/version.go b/vendor/go.etcd.io/etcd/api/v3/version/version.go index d77e31a97..9e7bc64c1 100644 --- a/vendor/go.etcd.io/etcd/api/v3/version/version.go +++ b/vendor/go.etcd.io/etcd/api/v3/version/version.go @@ -26,7 +26,7 @@ import ( var ( // MinClusterVersion is the min cluster version this etcd binary is compatible with. MinClusterVersion = "3.0.0" - Version = "3.6.4" + Version = "3.6.5" APIVersion = "unknown" // Git SHA Value will be set during build diff --git a/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go b/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go index 2b9301a58..7703e673b 100644 --- a/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go +++ b/vendor/go.etcd.io/etcd/client/v3/retry_interceptor.go @@ -351,11 +351,11 @@ func isContextError(err error) bool { func contextErrToGRPCErr(err error) error { switch { case errors.Is(err, context.DeadlineExceeded): - return status.Errorf(codes.DeadlineExceeded, err.Error()) + return status.Error(codes.DeadlineExceeded, err.Error()) case errors.Is(err, context.Canceled): - return status.Errorf(codes.Canceled, err.Error()) + return status.Error(codes.Canceled, err.Error()) default: - return status.Errorf(codes.Unknown, err.Error()) + return status.Error(codes.Unknown, err.Error()) } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0d79df4a0..60db564c9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1329,7 +1329,7 @@ github.com/opencloud-eu/icap-client # github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20250724122329-41ba6b191e76 ## explicit; go 1.18 github.com/opencloud-eu/libre-graph-api-go -# github.com/opencloud-eu/reva/v2 v2.38.1-0.20250924125540-eaa2437c36b2 +# github.com/opencloud-eu/reva/v2 v2.38.1-0.20251002093930-dcce351c08d6 ## explicit; go 1.24.1 github.com/opencloud-eu/reva/v2/cmd/revad/internal/grace github.com/opencloud-eu/reva/v2/cmd/revad/runtime @@ -1488,6 +1488,7 @@ github.com/opencloud-eu/reva/v2/pkg/group github.com/opencloud-eu/reva/v2/pkg/group/manager/json github.com/opencloud-eu/reva/v2/pkg/group/manager/ldap github.com/opencloud-eu/reva/v2/pkg/group/manager/loader +github.com/opencloud-eu/reva/v2/pkg/group/manager/null github.com/opencloud-eu/reva/v2/pkg/group/manager/registry github.com/opencloud-eu/reva/v2/pkg/logger github.com/opencloud-eu/reva/v2/pkg/mentix @@ -2191,8 +2192,8 @@ go.etcd.io/bbolt go.etcd.io/bbolt/errors go.etcd.io/bbolt/internal/common go.etcd.io/bbolt/internal/freelist -# go.etcd.io/etcd/api/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/api/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/api/v3/authpb go.etcd.io/etcd/api/v3/etcdserverpb go.etcd.io/etcd/api/v3/membershippb @@ -2200,8 +2201,8 @@ go.etcd.io/etcd/api/v3/mvccpb go.etcd.io/etcd/api/v3/v3rpc/rpctypes go.etcd.io/etcd/api/v3/version go.etcd.io/etcd/api/v3/versionpb -# go.etcd.io/etcd/client/pkg/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/client/pkg/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/client/pkg/v3/fileutil go.etcd.io/etcd/client/pkg/v3/logutil go.etcd.io/etcd/client/pkg/v3/systemd @@ -2209,8 +2210,8 @@ go.etcd.io/etcd/client/pkg/v3/tlsutil go.etcd.io/etcd/client/pkg/v3/transport go.etcd.io/etcd/client/pkg/v3/types go.etcd.io/etcd/client/pkg/v3/verify -# go.etcd.io/etcd/client/v3 v3.6.4 -## explicit; go 1.23.0 +# go.etcd.io/etcd/client/v3 v3.6.5 +## explicit; go 1.24 go.etcd.io/etcd/client/v3 go.etcd.io/etcd/client/v3/credentials go.etcd.io/etcd/client/v3/internal/endpoint