From 5c77c25747770200213ff41ddf0dc794ac14f551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Oct 2021 13:54:25 +0200 Subject: [PATCH 1/6] storage: Add Group tags to StorageInfo --- extern/sector-storage/stores/index.go | 5 +++++ extern/sector-storage/stores/local.go | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index 2a37e653a..ca0c4ea03 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -37,6 +37,9 @@ type StorageInfo struct { CanSeal bool CanStore bool + + Groups []string + AllowTo []string } type HealthReport struct { @@ -168,6 +171,8 @@ func (i *Index) StorageAttach(ctx context.Context, si StorageInfo, st fsutil.FsS i.stores[si.ID].info.MaxStorage = si.MaxStorage i.stores[si.ID].info.CanSeal = si.CanSeal i.stores[si.ID].info.CanStore = si.CanStore + i.stores[si.ID].info.Groups = si.Groups + i.stores[si.ID].info.AllowTo = si.AllowTo return nil } diff --git a/extern/sector-storage/stores/local.go b/extern/sector-storage/stores/local.go index c2e8e3df6..8121c418d 100644 --- a/extern/sector-storage/stores/local.go +++ b/extern/sector-storage/stores/local.go @@ -46,6 +46,13 @@ type LocalStorageMeta struct { // MaxStorage specifies the maximum number of bytes to use for sector storage // (0 = unlimited) MaxStorage uint64 + + // List of storage groups this path belongs to + Groups []string + + // List of storage groups to which data from this path can be moved. If none + // are specified, allow to all + AllowTo []string } // StorageConfig .lotusstorage/storage.json @@ -212,6 +219,8 @@ func (st *Local) OpenPath(ctx context.Context, p string) error { MaxStorage: meta.MaxStorage, CanSeal: meta.CanSeal, CanStore: meta.CanStore, + Groups: meta.Groups, + AllowTo: meta.AllowTo, }, fst) if err != nil { return xerrors.Errorf("declaring storage in index: %w", err) @@ -276,6 +285,8 @@ func (st *Local) Redeclare(ctx context.Context) error { MaxStorage: meta.MaxStorage, CanSeal: meta.CanSeal, CanStore: meta.CanStore, + Groups: meta.Groups, + AllowTo: meta.AllowTo, }, fst) if err != nil { return xerrors.Errorf("redeclaring storage in index: %w", err) From 8b548ac02ff583860b470bcbaccfbcb0e24d222e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Oct 2021 14:06:04 +0200 Subject: [PATCH 2/6] storage: Check allowlists in StorageFindSector --- extern/sector-storage/stores/index.go | 32 +++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index ca0c4ea03..ac6475a07 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -29,6 +29,8 @@ var SkippedHeartbeatThresh = HeartbeatInterval * 5 // filesystem, local or networked / shared by multiple machines type ID string +type Group = string + type StorageInfo struct { ID ID URLs []string // TODO: Support non-http transports @@ -38,8 +40,8 @@ type StorageInfo struct { CanSeal bool CanStore bool - Groups []string - AllowTo []string + Groups []Group + AllowTo []Group } type HealthReport struct { @@ -297,6 +299,8 @@ func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storif storageIDs := map[ID]uint64{} isprimary := map[ID]bool{} + allowTo := map[Group]struct{}{} + for _, pathType := range storiface.PathTypes { if ft&pathType == 0 { continue @@ -328,6 +332,14 @@ func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storif urls[k] = rl.String() } + if allowTo != nil && len(st.info.AllowTo) > 0 { + for _, group := range st.info.AllowTo { + allowTo[group] = struct{}{} + } + } else { + allowTo = nil // allow to any + } + out = append(out, SectorStorageInfo{ ID: id, URLs: urls, @@ -370,6 +382,22 @@ func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storif continue } + if allowTo != nil { + allow := false + for _, group := range st.info.Groups { + if _, found := allowTo[group]; found { + log.Debugf("path %s in allowed group %s", st.info.ID, group) + allow = true + break + } + } + + if !allow { + log.Debugf("not selecting on %s, not in allowed group, allow %#v; path has %#v", st.info.ID, allowTo, st.info.Groups) + continue + } + } + urls := make([]string, len(st.info.URLs)) for k, u := range st.info.URLs { rl, err := url.Parse(u) From 2a1505b3645842e22d373577bb653a313aae3170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Oct 2021 14:36:15 +0200 Subject: [PATCH 3/6] storage: Test StorageFindSector with groups --- extern/sector-storage/stores/index.go | 2 +- extern/sector-storage/stores/index_test.go | 154 +++++++++++++++++++++ 2 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 extern/sector-storage/stores/index_test.go diff --git a/extern/sector-storage/stores/index.go b/extern/sector-storage/stores/index.go index ac6475a07..12cb26a56 100644 --- a/extern/sector-storage/stores/index.go +++ b/extern/sector-storage/stores/index.go @@ -393,7 +393,7 @@ func (i *Index) StorageFindSector(ctx context.Context, s abi.SectorID, ft storif } if !allow { - log.Debugf("not selecting on %s, not in allowed group, allow %#v; path has %#v", st.info.ID, allowTo, st.info.Groups) + log.Debugf("not selecting on %s, not in allowed group, allow %+v; path has %+v", st.info.ID, allowTo, st.info.Groups) continue } } diff --git a/extern/sector-storage/stores/index_test.go b/extern/sector-storage/stores/index_test.go new file mode 100644 index 000000000..bb4239035 --- /dev/null +++ b/extern/sector-storage/stores/index_test.go @@ -0,0 +1,154 @@ +package stores + +import ( + "context" + "testing" + + "github.com/google/uuid" + logging "github.com/ipfs/go-log/v2" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/extern/sector-storage/fsutil" + "github.com/filecoin-project/lotus/extern/sector-storage/storiface" +) + +func init() { + logging.SetLogLevel("stores", "DEBUG") +} + +func newTestStorage() StorageInfo { + return StorageInfo{ + ID: ID(uuid.New().String()), + CanSeal: true, + CanStore: true, + Groups: nil, + AllowTo: nil, + } +} + +var bigFsStat = fsutil.FsStat{ + Capacity: 1 << 40, + Available: 1 << 40, + FSAvailable: 1 << 40, + Reserved: 0, + Max: 0, + Used: 0, +} + +const s32g = 32 << 30 + +func TestFindSimple(t *testing.T) { + ctx := context.Background() + + i := NewIndex() + stor1 := newTestStorage() + stor2 := newTestStorage() + + require.NoError(t, i.StorageAttach(ctx, stor1, bigFsStat)) + require.NoError(t, i.StorageAttach(ctx, stor2, bigFsStat)) + + s1 := abi.SectorID{ + Miner: 12, + Number: 34, + } + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, true) + require.NoError(t, err) + require.Len(t, si, 0) + } + + require.NoError(t, i.StorageDeclareSector(ctx, stor1.ID, s1, storiface.FTSealed, true)) + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, false) + require.NoError(t, err) + require.Len(t, si, 1) + require.Equal(t, stor1.ID, si[0].ID) + } + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, true) + require.NoError(t, err) + require.Len(t, si, 2) + } +} + +func TestFindNoAllow(t *testing.T) { + ctx := context.Background() + + i := NewIndex() + stor1 := newTestStorage() + stor1.AllowTo = []Group{"grp1"} + stor2 := newTestStorage() + + require.NoError(t, i.StorageAttach(ctx, stor1, bigFsStat)) + require.NoError(t, i.StorageAttach(ctx, stor2, bigFsStat)) + + s1 := abi.SectorID{ + Miner: 12, + Number: 34, + } + require.NoError(t, i.StorageDeclareSector(ctx, stor1.ID, s1, storiface.FTSealed, true)) + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, false) + require.NoError(t, err) + require.Len(t, si, 1) + require.Equal(t, stor1.ID, si[0].ID) + } + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, true) + require.NoError(t, err) + require.Len(t, si, 1) + require.Equal(t, stor1.ID, si[0].ID) + } +} + +func TestFindAllow(t *testing.T) { + ctx := context.Background() + + i := NewIndex() + + stor1 := newTestStorage() + stor1.AllowTo = []Group{"grp1"} + + stor2 := newTestStorage() + stor2.Groups = []Group{"grp1"} + + stor3 := newTestStorage() + stor3.Groups = []Group{"grp2"} + + require.NoError(t, i.StorageAttach(ctx, stor1, bigFsStat)) + require.NoError(t, i.StorageAttach(ctx, stor2, bigFsStat)) + require.NoError(t, i.StorageAttach(ctx, stor3, bigFsStat)) + + s1 := abi.SectorID{ + Miner: 12, + Number: 34, + } + require.NoError(t, i.StorageDeclareSector(ctx, stor1.ID, s1, storiface.FTSealed, true)) + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, false) + require.NoError(t, err) + require.Len(t, si, 1) + require.Equal(t, stor1.ID, si[0].ID) + } + + { + si, err := i.StorageFindSector(ctx, s1, storiface.FTSealed, s32g, true) + require.NoError(t, err) + require.Len(t, si, 2) + if si[0].ID == stor1.ID { + require.Equal(t, stor1.ID, si[0].ID) + require.Equal(t, stor2.ID, si[1].ID) + } else { + require.Equal(t, stor1.ID, si[1].ID) + require.Equal(t, stor2.ID, si[0].ID) + } + } +} From b1781c33ce47cb5149f3901ccc2b323953267fe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 18 Oct 2021 19:54:07 +0200 Subject: [PATCH 4/6] Show group info in storage list --- cmd/lotus-miner/storage.go | 9 ++++++++- documentation/en/api-v0-methods-miner.md | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/cmd/lotus-miner/storage.go b/cmd/lotus-miner/storage.go index e7508eb29..5eb4ce2da 100644 --- a/cmd/lotus-miner/storage.go +++ b/cmd/lotus-miner/storage.go @@ -322,10 +322,17 @@ var storageListCmd = &cli.Command{ if si.CanStore { fmt.Print(color.CyanString("Store")) } - fmt.Println("") } else { fmt.Print(color.HiYellowString("Use: ReadOnly")) } + fmt.Println() + + if len(si.Groups) > 0 { + fmt.Printf("\tGroups: %s\n", strings.Join(si.Groups, ", ")) + } + if len(si.AllowTo) > 0 { + fmt.Printf("\tAllowTo: %s\n", strings.Join(si.AllowTo, ", ")) + } if localPath, ok := local[s.ID]; ok { fmt.Printf("\tLocal: %s\n", color.GreenString(localPath)) diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 4d14bcb0e..c642854e7 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -2148,7 +2148,9 @@ Inputs: "Weight": 42, "MaxStorage": 42, "CanSeal": true, - "CanStore": true + "CanStore": true, + "Groups": null, + "AllowTo": null }, { "Capacity": 9, @@ -2258,7 +2260,9 @@ Response: "Weight": 42, "MaxStorage": 42, "CanSeal": true, - "CanStore": true + "CanStore": true, + "Groups": null, + "AllowTo": null } ``` From e362d4790386f2bf24e21689208ee327119a7151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 6 Oct 2021 15:53:32 +0200 Subject: [PATCH 5/6] Add optional group flags to storage attach commands --- build/openrpc/miner.json.gz | Bin 10466 -> 10500 bytes cmd/lotus-miner/storage.go | 10 ++++++++++ cmd/lotus-seal-worker/storage.go | 10 ++++++++++ documentation/en/cli-lotus-miner.md | 2 ++ documentation/en/cli-lotus-worker.md | 2 ++ 5 files changed, 24 insertions(+) diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index cbafb066d783eb1ef7b7e451aa1f15a0c505839f..9fa81cb426a0f2891f028f691bfa02e052f0a984 100644 GIT binary patch delta 10364 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 aRjCb+jE9HM5C1;^0RR8YN}XxR-~j+4pIz1f delta 10364 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 Date: Tue, 23 Nov 2021 16:16:27 +0100 Subject: [PATCH 6/6] update storage attach allowTo usage --- cmd/lotus-miner/storage.go | 2 +- cmd/lotus-seal-worker/storage.go | 2 +- documentation/en/cli-lotus-miner.md | 2 +- documentation/en/cli-lotus-worker.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-miner/storage.go b/cmd/lotus-miner/storage.go index e2c6860f9..4df6a9904 100644 --- a/cmd/lotus-miner/storage.go +++ b/cmd/lotus-miner/storage.go @@ -101,7 +101,7 @@ over time }, &cli.StringSliceFlag{ Name: "allow-to", - Usage: "group names to which data from this path can be sent (allow all if not specified)", + Usage: "path groups allowed to pull data from this path (allow all if not specified)", }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-seal-worker/storage.go b/cmd/lotus-seal-worker/storage.go index 5bd296b1a..721523fd0 100644 --- a/cmd/lotus-seal-worker/storage.go +++ b/cmd/lotus-seal-worker/storage.go @@ -57,7 +57,7 @@ var storageAttachCmd = &cli.Command{ }, &cli.StringSliceFlag{ Name: "allow-to", - Usage: "group names to which data from this path can be sent (allow all if not specified)", + Usage: "path groups allowed to pull data from this path (allow all if not specified)", }, }, Action: func(cctx *cli.Context) error { diff --git a/documentation/en/cli-lotus-miner.md b/documentation/en/cli-lotus-miner.md index a21e4fe94..bc039d743 100644 --- a/documentation/en/cli-lotus-miner.md +++ b/documentation/en/cli-lotus-miner.md @@ -1984,7 +1984,7 @@ OPTIONS: --store (for init) use path for long-term storage (default: false) --max-storage value (for init) limit storage space for sectors (expensive for very large paths!) --groups value path group names - --allow-to value group names to which data from this path can be sent (allow all if not specified) + --allow-to value path groups allowed to pull data from this path (allow all if not specified) --help, -h show help (default: false) ``` diff --git a/documentation/en/cli-lotus-worker.md b/documentation/en/cli-lotus-worker.md index dba65236e..3b0c7ae4f 100644 --- a/documentation/en/cli-lotus-worker.md +++ b/documentation/en/cli-lotus-worker.md @@ -95,7 +95,7 @@ OPTIONS: --store (for init) use path for long-term storage (default: false) --max-storage value (for init) limit storage space for sectors (expensive for very large paths!) --groups value path group names - --allow-to value group names to which data from this path can be sent (allow all if not specified) + --allow-to value path groups allowed to pull data from this path (allow all if not specified) --help, -h show help (default: false) ```