Skip to content

Commit

Permalink
fix spaces stat requests (cs3org#2501)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas authored and butonic committed Feb 14, 2022
1 parent 0443b41 commit 99fdf2d
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
6 changes: 6 additions & 0 deletions changelog/unreleased/spaces-stat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Bugfix: Fix spaces stat

When stating a space e.g. the Share Jail and that space contains another space, in this case a share
then the stat would sometimes get the sub space instead of the Share Jail itself.

https://github.com/cs3org/reva/pull/2501
62 changes: 61 additions & 1 deletion internal/grpc/services/gateway/storageprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ func (s *svc) Unlock(ctx context.Context, req *provider.UnlockRequest) (*provide
// Stat returns the Resoure info for a given resource by forwarding the request to the responsible provider.
// TODO cache info
func (s *svc) Stat(ctx context.Context, req *provider.StatRequest) (*provider.StatResponse, error) {
c, _, ref, err := s.findAndUnwrap(ctx, req.Ref)
c, _, ref, err := s.findAndUnwrapUnique(ctx, req.Ref)
if err != nil {
return &provider.StatResponse{
Status: status.NewNotFound(ctx, fmt.Sprintf("gateway could not find space for ref=%+v", req.Ref)),
Expand Down Expand Up @@ -991,6 +991,16 @@ func (s *svc) find(ctx context.Context, ref *provider.Reference) (provider.Provi
return client, p[0], err
}

func (s *svc) findUnique(ctx context.Context, ref *provider.Reference) (provider.ProviderAPIClient, *registry.ProviderInfo, error) {
p, err := s.findSingleSpace(ctx, ref)
if err != nil {
return nil, nil, err
}

client, err := s.getStorageProviderClient(ctx, p[0])
return client, p[0], err
}

// FIXME findAndUnwrap currently just returns the first provider ... which may not be what is needed.
// for the ListRecycle call we need an exact match, for Stat and List we need to query all related providers
func (s *svc) findAndUnwrap(ctx context.Context, ref *provider.Reference) (provider.ProviderAPIClient, *registry.ProviderInfo, *provider.Reference, error) {
Expand All @@ -1014,6 +1024,27 @@ func (s *svc) findAndUnwrap(ctx context.Context, ref *provider.Reference) (provi
return c, p, relativeReference, nil
}

func (s *svc) findAndUnwrapUnique(ctx context.Context, ref *provider.Reference) (provider.ProviderAPIClient, *registry.ProviderInfo, *provider.Reference, error) {
c, p, err := s.findUnique(ctx, ref)
if err != nil {
return nil, nil, nil, err
}

var (
root *provider.ResourceId
mountPath string
)
for _, space := range decodeSpaces(p) {
mountPath = decodePath(space)
root = space.Root
break // TODO can there be more than one space for a path?
}

relativeReference := unwrap(ref, mountPath, root)

return c, p, relativeReference, nil
}

func (s *svc) getStorageProviderClient(_ context.Context, p *registry.ProviderInfo) (provider.ProviderAPIClient, error) {
c, err := pool.GetStorageProviderServiceClient(p.Address)
if err != nil {
Expand Down Expand Up @@ -1060,6 +1091,35 @@ func (s *svc) findSpaces(ctx context.Context, ref *provider.Reference) ([]*regis
return s.findProvider(ctx, listReq)
}

func (s *svc) findSingleSpace(ctx context.Context, ref *provider.Reference) ([]*registry.ProviderInfo, error) {
switch {
case ref == nil:
return nil, errtypes.BadRequest("missing reference")
case ref.ResourceId != nil:
// no action needed in that case
case ref.Path != "": // TODO implement a mount path cache in the registry?
// nothing to do here either
default:
return nil, errtypes.BadRequest("invalid reference, at least path or id must be set")
}

filters := map[string]string{
"path": ref.Path,
"unique": "true",
}
if ref.ResourceId != nil {
filters["storage_id"] = ref.ResourceId.StorageId
filters["opaque_id"] = ref.ResourceId.OpaqueId
}

listReq := &registry.ListStorageProvidersRequest{
Opaque: &typesv1beta1.Opaque{},
}
sdk.EncodeOpaqueMap(listReq.Opaque, filters)

return s.findProvider(ctx, listReq)
}

func (s *svc) findProvider(ctx context.Context, listReq *registry.ListStorageProvidersRequest) ([]*registry.ProviderInfo, error) {
// lookup
c, err := pool.GetStorageRegistryClient(s.c.StorageRegistryEndpoint)
Expand Down

0 comments on commit 99fdf2d

Please sign in to comment.