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

GO-2042 file limits by identity #38

Merged
merged 9 commits into from
Sep 21, 2023
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
28 changes: 28 additions & 0 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,23 @@ jobs:
- name: git config
run: git config --global url.https://${{ secrets.ANYTYPE_PAT }}@github.com/.insteadOf https://github.com/

# check license {{
- name: Setup license repository
uses: actions/checkout@master
with:
repository: anyproto/open
ref: refs/heads/main
path: ./open
- name: Check licenses
run: |
cd open
python3 tools/generate.py --platform golang
cd ..
sudo gem install license_finder
license_finder inherited_decisions add open/decisions.yml
license_finder --enabled-package-managers gomodules
# }}

- name: deps
run: make deps CGO_ENABLED=0

Expand All @@ -46,6 +63,16 @@ jobs:
TESTCOVERAGE_THRESHOLD: 0
run: |
go test ./... -coverprofile coverage.out -covermode count

generated_pattern='^\/\/ Code generated .* DO NOT EDIT\.$'
files_list=$(grep -rl "$generated_pattern" . | grep '\.go$' | sed 's/^\.\///')

for file in $files_list; do
echo "Removing $file from coverage report"
grep -v "$file" coverage.out > temp_file
mv temp_file coverage.out
done

go tool cover -func coverage.out
echo "Quality Gate: checking test coverage is above threshold ..."
echo "Threshold : $TESTCOVERAGE_THRESHOLD %"
Expand All @@ -58,3 +85,4 @@ jobs:
echo "Failed"
exit 1
fi
- uses: seriousben/go-patch-cover-action@v1
73 changes: 33 additions & 40 deletions filenode/filenode.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,10 @@ func (fn *fileNode) Get(ctx context.Context, k cid.Cid) (blocks.Block, error) {
}

func (fn *fileNode) Add(ctx context.Context, spaceId string, fileId string, bs []blocks.Block) error {
// temporary code for migration
if fileId == "migration" {
return fn.migrate(ctx, bs)
}
if err := fn.ValidateSpaceId(ctx, spaceId, true); err != nil {
return err
}
unlock, err := fn.index.Lock(ctx, testutil.BlocksToKeys(bs))
if err != nil {
return err
}
defer unlock()
toUpload, err := fn.index.GetNonExistentBlocks(ctx, bs)
storeKey, err := fn.StoreKey(ctx, spaceId, true)
if err != nil {
return err
}
if len(toUpload) > 0 {
if err = fn.store.Add(ctx, toUpload); err != nil {
return err
}
}
return fn.index.Bind(ctx, spaceId, fileId, bs)
}

func (fn *fileNode) migrate(ctx context.Context, bs []blocks.Block) error {
unlock, err := fn.index.Lock(ctx, testutil.BlocksToKeys(bs))
if err != nil {
return err
Expand All @@ -107,19 +86,20 @@ func (fn *fileNode) migrate(ctx context.Context, bs []blocks.Block) error {
return err
}
}
return fn.index.AddBlocks(ctx, toUpload)
return fn.index.Bind(ctx, storeKey, fileId, bs)
}

func (fn *fileNode) Check(ctx context.Context, spaceId string, cids ...cid.Cid) (result []*fileproto.BlockAvailability, err error) {
var storeKey string
if spaceId != "" {
if err = fn.ValidateSpaceId(ctx, spaceId, false); err != nil {
if storeKey, err = fn.StoreKey(ctx, spaceId, false); err != nil {
return
}
}
result = make([]*fileproto.BlockAvailability, 0, len(cids))
var inSpaceM = make(map[string]struct{})
if spaceId != "" {
inSpace, err := fn.index.ExistsInSpace(ctx, spaceId, cids)
inSpace, err := fn.index.ExistsInStorage(ctx, storeKey, cids)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -148,33 +128,43 @@ func (fn *fileNode) Check(ctx context.Context, spaceId string, cids ...cid.Cid)
}

func (fn *fileNode) BlocksBind(ctx context.Context, spaceId, fileId string, cids ...cid.Cid) (err error) {
if err = fn.ValidateSpaceId(ctx, spaceId, true); err != nil {
storeKey, err := fn.StoreKey(ctx, spaceId, true)
if err != nil {
return err
}
unlock, err := fn.index.Lock(ctx, cids)
if err != nil {
return err
}
defer unlock()
return fn.index.BindCids(ctx, spaceId, fileId, cids)
return fn.index.BindCids(ctx, storeKey, fileId, cids)
}

func (fn *fileNode) ValidateSpaceId(ctx context.Context, spaceId string, checkLimit bool) (err error) {
func (fn *fileNode) StoreKey(ctx context.Context, spaceId string, checkLimit bool) (storageKey string, err error) {
if spaceId == "" {
return fileprotoerr.ErrForbidden
return "", fileprotoerr.ErrForbidden
}
// this call also confirms that space exists and valid
limitBytes, err := fn.limit.Check(ctx, spaceId)
limitBytes, storageKey, err := fn.limit.Check(ctx, spaceId)
if err != nil {
return
}

if storageKey != spaceId {
// try to move store to the new key
mErr := fn.index.MoveStorage(ctx, spaceId, storageKey)
if mErr != nil && mErr != index.ErrStorageNotFound && mErr != index.ErrTargetStorageExists {
return "", mErr
}
}

if checkLimit {
currentSize, e := fn.index.SpaceSize(ctx, spaceId)
currentSize, e := fn.index.StorageSize(ctx, storageKey)
if e != nil {
return e
return "", e
}
if currentSize >= limitBytes {
return fileprotoerr.ErrSpaceLimitExceeded
return "", fileprotoerr.ErrSpaceLimitExceeded
}
}
return
Expand All @@ -183,13 +173,14 @@ func (fn *fileNode) ValidateSpaceId(ctx context.Context, spaceId string, checkLi
func (fn *fileNode) SpaceInfo(ctx context.Context, spaceId string) (info *fileproto.SpaceInfoResponse, err error) {
info = &fileproto.SpaceInfoResponse{}
// we have space/identity validation in limit.Check
if info.LimitBytes, err = fn.limit.Check(ctx, spaceId); err != nil {
var storageKey string
if info.LimitBytes, storageKey, err = fn.limit.Check(ctx, spaceId); err != nil {
return nil, err
}
if info.UsageBytes, err = fn.index.SpaceSize(ctx, spaceId); err != nil {
if info.UsageBytes, err = fn.index.StorageSize(ctx, storageKey); err != nil {
return nil, err
}
si, err := fn.index.SpaceInfo(ctx, spaceId)
si, err := fn.index.StorageInfo(ctx, storageKey)
if err != nil {
return nil, err
}
Expand All @@ -199,22 +190,24 @@ func (fn *fileNode) SpaceInfo(ctx context.Context, spaceId string) (info *filepr
}

func (fn *fileNode) FilesDelete(ctx context.Context, spaceId string, fileIds []string) (err error) {
if err = fn.ValidateSpaceId(ctx, spaceId, false); err != nil {
storeKey, err := fn.StoreKey(ctx, spaceId, false)
if err != nil {
return
}
for _, fileId := range fileIds {
if err = fn.index.UnBind(ctx, spaceId, fileId); err != nil {
if err = fn.index.UnBind(ctx, storeKey, fileId); err != nil {
return
}
}
return
}

func (fn *fileNode) FileInfo(ctx context.Context, spaceId, fileId string) (info *fileproto.FileInfo, err error) {
if err = fn.ValidateSpaceId(ctx, spaceId, false); err != nil {
storeKey, err := fn.StoreKey(ctx, spaceId, false)
if err != nil {
return
}
fi, err := fn.index.FileInfo(ctx, spaceId, fileId)
fi, err := fn.index.FileInfo(ctx, storeKey, fileId)
if err != nil {
return nil, err
}
Expand Down
64 changes: 37 additions & 27 deletions filenode/filenode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ func TestFileNode_Add(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var (
spaceId = testutil.NewRandSpaceId()
fileId = testutil.NewRandCid().String()
b = testutil.NewRandBlock(1024)
spaceId = testutil.NewRandSpaceId()
storeKey = "sk:" + spaceId
fileId = testutil.NewRandCid().String()
b = testutil.NewRandBlock(1024)
)

fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), nil)
fx.index.EXPECT().SpaceSize(ctx, spaceId).Return(uint64(120), nil)
fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), storeKey, nil)
fx.index.EXPECT().MoveStorage(ctx, spaceId, storeKey).AnyTimes()
fx.index.EXPECT().StorageSize(ctx, storeKey).Return(uint64(120), nil)
fx.index.EXPECT().Lock(ctx, []cid.Cid{b.Cid()}).Return(func() {}, nil)
fx.index.EXPECT().GetNonExistentBlocks(ctx, []blocks.Block{b}).Return([]blocks.Block{b}, nil)
fx.store.EXPECT().Add(ctx, []blocks.Block{b})
fx.index.EXPECT().Bind(ctx, spaceId, fileId, []blocks.Block{b})
fx.index.EXPECT().Bind(ctx, storeKey, fileId, []blocks.Block{b})

resp, err := fx.handler.BlockPush(ctx, &fileproto.BlockPushRequest{
SpaceId: spaceId,
Expand All @@ -56,13 +58,15 @@ func TestFileNode_Add(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var (
spaceId = testutil.NewRandSpaceId()
fileId = testutil.NewRandCid().String()
b = testutil.NewRandBlock(1024)
spaceId = testutil.NewRandSpaceId()
storeKey = "sk:" + spaceId
fileId = testutil.NewRandCid().String()
b = testutil.NewRandBlock(1024)
)

fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), nil)
fx.index.EXPECT().SpaceSize(ctx, spaceId).Return(uint64(124), nil)
fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), storeKey, nil)
fx.index.EXPECT().MoveStorage(ctx, spaceId, storeKey).AnyTimes()
fx.index.EXPECT().StorageSize(ctx, storeKey).Return(uint64(124), nil)

resp, err := fx.handler.BlockPush(ctx, &fileproto.BlockPushRequest{
SpaceId: spaceId,
Expand Down Expand Up @@ -146,13 +150,15 @@ func TestFileNode_Check(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var spaceId = testutil.NewRandSpaceId()
var storeKey = "sk:" + spaceId
var bs = testutil.NewRandBlocks(3)
cids := make([][]byte, len(bs))
for _, b := range bs {
cids = append(cids, b.Cid().Bytes())
}
fx.limit.EXPECT().Check(ctx, spaceId)
fx.index.EXPECT().ExistsInSpace(ctx, spaceId, testutil.BlocksToKeys(bs)).Return(testutil.BlocksToKeys(bs[:1]), nil)
fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(100000), storeKey, nil)
fx.index.EXPECT().MoveStorage(ctx, spaceId, storeKey).AnyTimes()
fx.index.EXPECT().ExistsInStorage(ctx, storeKey, testutil.BlocksToKeys(bs)).Return(testutil.BlocksToKeys(bs[:1]), nil)
fx.index.EXPECT().Exists(ctx, bs[1].Cid()).Return(true, nil)
fx.index.EXPECT().Exists(ctx, bs[2].Cid()).Return(false, nil)
resp, err := fx.handler.BlocksCheck(ctx, &fileproto.BlocksCheckRequest{
Expand All @@ -170,21 +176,23 @@ func TestFileNode_BlocksBind(t *testing.T) {
fx := newFixture(t)
defer fx.Finish(t)
var (
spaceId = testutil.NewRandSpaceId()
fileId = testutil.NewRandCid().String()
bs = testutil.NewRandBlocks(3)
cidsB = make([][]byte, len(bs))
cids = make([]cid.Cid, len(bs))
spaceId = testutil.NewRandSpaceId()
storeKey = "sk:" + spaceId
fileId = testutil.NewRandCid().String()
bs = testutil.NewRandBlocks(3)
cidsB = make([][]byte, len(bs))
cids = make([]cid.Cid, len(bs))
)
for i, b := range bs {
cids[i] = b.Cid()
cidsB[i] = b.Cid().Bytes()
}

fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), nil)
fx.index.EXPECT().SpaceSize(ctx, spaceId).Return(uint64(12), nil)
fx.limit.EXPECT().Check(ctx, spaceId).Return(uint64(123), storeKey, nil)
fx.index.EXPECT().MoveStorage(ctx, spaceId, storeKey).AnyTimes()
fx.index.EXPECT().StorageSize(ctx, storeKey).Return(uint64(12), nil)
fx.index.EXPECT().Lock(ctx, cids).Return(func() {}, nil)
fx.index.EXPECT().BindCids(ctx, spaceId, fileId, cids)
fx.index.EXPECT().BindCids(ctx, storeKey, fileId, cids)

resp, err := fx.handler.BlocksBind(ctx, &fileproto.BlocksBindRequest{
SpaceId: spaceId,
Expand All @@ -200,13 +208,15 @@ func TestFileNode_FileInfo(t *testing.T) {
defer fx.Finish(t)

var (
spaceId = testutil.NewRandSpaceId()
fileId1 = testutil.NewRandCid().String()
fileId2 = testutil.NewRandCid().String()
spaceId = testutil.NewRandSpaceId()
storeKey = "sk:" + spaceId
fileId1 = testutil.NewRandCid().String()
fileId2 = testutil.NewRandCid().String()
)
fx.limit.EXPECT().Check(ctx, spaceId).AnyTimes()
fx.index.EXPECT().FileInfo(ctx, spaceId, fileId1).Return(index.FileInfo{1, 1}, nil)
fx.index.EXPECT().FileInfo(ctx, spaceId, fileId2).Return(index.FileInfo{2, 2}, nil)
fx.limit.EXPECT().Check(ctx, spaceId).AnyTimes().Return(uint64(100000), storeKey, nil)
fx.index.EXPECT().MoveStorage(ctx, spaceId, storeKey).AnyTimes()
fx.index.EXPECT().FileInfo(ctx, storeKey, fileId1).Return(index.FileInfo{1, 1}, nil)
fx.index.EXPECT().FileInfo(ctx, storeKey, fileId2).Return(index.FileInfo{2, 2}, nil)

resp, err := fx.handler.FilesInfo(ctx, &fileproto.FilesInfoRequest{
SpaceId: spaceId,
Expand Down
3 changes: 2 additions & 1 deletion filenode/rpchandler.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ func (r rpcHandler) FilesInfo(ctx context.Context, req *fileproto.FilesInfoReque
resp = &fileproto.FilesInfoResponse{
FilesInfo: make([]*fileproto.FileInfo, len(req.FileIds)),
}
if err = r.f.ValidateSpaceId(ctx, req.SpaceId, false); err != nil {
_, err = r.f.StoreKey(ctx, req.SpaceId, false)
if err != nil {
return nil, err
}
var info *fileproto.FileInfo
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21

require (
github.com/ahmetb/govvv v0.3.0
github.com/anyproto/any-sync v0.3.0
github.com/anyproto/any-sync v0.3.1
github.com/aws/aws-sdk-go v1.44.327
github.com/go-redsync/redsync/v4 v4.8.1
github.com/gogo/protobuf v1.3.2
Expand All @@ -14,8 +14,8 @@ require (
github.com/redis/go-redis/v9 v9.1.0
github.com/stretchr/testify v1.8.4
go.uber.org/atomic v1.11.0
go.uber.org/mock v0.2.0
go.uber.org/zap v1.25.0
go.uber.org/mock v0.3.0
go.uber.org/zap v1.26.0
gopkg.in/yaml.v3 v3.0.1
)

Expand Down
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/ahmetb/govvv v0.3.0 h1:YGLGwEyiUwHFy5eh/RUhdupbuaCGBYn5T5GWXp+WJB0=
github.com/ahmetb/govvv v0.3.0/go.mod h1:4WRFpdWtc/YtKgPFwa1dr5+9hiRY5uKAL08bOlxOR6s=
github.com/anyproto/any-sync v0.3.0 h1:4lVxHf6aA2BrefGqjzbyn/wnSuNoriU2o8IsABBMfJE=
github.com/anyproto/any-sync v0.3.0/go.mod h1:8uddvzx/4Le7c9v5tb0jgma4GuAWfUDMTeRCBLu0MTo=
github.com/anyproto/any-sync v0.3.1 h1:AHsIYyhM9J+eqKVjnsuGgT/4u+f47JyEhfIBMnDLIIA=
github.com/anyproto/any-sync v0.3.1/go.mod h1:v0w3l3FBWjzNgg5t8aWlI+aYkcA8kLaoJFfr/GHsWYk=
github.com/anyproto/go-chash v0.1.0 h1:I9meTPjXFRfXZHRJzjOHC/XF7Q5vzysKkiT/grsogXY=
github.com/anyproto/go-chash v0.1.0/go.mod h1:0UjNQi3PDazP0fINpFYu6VKhuna+W/V+1vpXHAfNgLY=
github.com/anyproto/go-slip10 v1.0.0 h1:uAEtSuudR3jJBOfkOXf3bErxVoxbuKwdoJN55M1i6IA=
Expand All @@ -15,8 +15,6 @@ github.com/anyproto/go-slip21 v1.0.0/go.mod h1:gbIJt7HAdr5DuT4f2pFTKCBSUWYsm/fys
github.com/aws/aws-sdk-go v1.44.327 h1:ZS8oO4+7MOBLhkdwIhgtVeDzCeWOlTfKJS7EgggbIEY=
github.com/aws/aws-sdk-go v1.44.327/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bsm/ginkgo/v2 v2.5.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
Expand Down Expand Up @@ -226,14 +224,14 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU=
go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM=
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c=
go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk=
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
Expand Down
Loading