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

Bucket Pinning Service #2

Merged
merged 33 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
fa2fb8b
gateway: add multipart push paths http endpoint
sanderpick Mar 12, 2021
abf171f
pinning: initial pinning service work
sanderpick Mar 15, 2021
11afd80
pinning: better queue processing
sanderpick Mar 16, 2021
97f220b
gateway: remove thread handling
sanderpick Mar 17, 2021
869f00d
gateway: pull in content-type detection and reader usage from textile
sanderpick Mar 17, 2021
146add9
pinning: bucket-grouped queues
sanderpick Mar 18, 2021
c138d8d
pinning: more routes
sanderpick Mar 19, 2021
ae80b15
chore: mod tidy
sanderpick Mar 19, 2021
901e33c
buckets: allow fast-forward requirement on all mutating methods
sanderpick Mar 19, 2021
048e2e9
pinning: add queue tests
sanderpick Mar 21, 2021
ba5b208
pinning: list queue nits
sanderpick Mar 21, 2021
f3e68c2
buckets: add basic write transactions needed for safe pinning queue
sanderpick Mar 22, 2021
d1ed1c9
pinning: add subdomain support
sanderpick Mar 22, 2021
6b5a3a2
pinning: setup service tests
sanderpick Mar 22, 2021
ff88c3c
pinning: add integration tests with go-pinning-service-http-client
sanderpick Mar 23, 2021
e0ac732
pinning: cleanup tests
sanderpick Mar 23, 2021
b722302
pinning: rework key layout
sanderpick Mar 25, 2021
db82b26
pinning: fix pagination
sanderpick Mar 25, 2021
e40a833
pinning: add read and write validation
sanderpick Mar 27, 2021
b7898ac
pinning: more gateway tests
sanderpick Mar 28, 2021
c116ac4
gateway: adds multipart test
sanderpick Mar 28, 2021
158d6eb
mod: update threads
sanderpick Mar 28, 2021
2ab8704
ci: add a bit more test time for slow ci machine
sanderpick Mar 28, 2021
1dc7c6f
pinning: dial origins while setting pin
sanderpick Mar 29, 2021
402f894
pinning: use textile pinning client fork
sanderpick Mar 29, 2021
750df50
badger: enusre cgo disabled in containers
sanderpick Mar 30, 2021
7c7a3e2
threads: update threads
sanderpick Mar 31, 2021
107004e
docs: adds doc strings
sanderpick Apr 2, 2021
665ae88
buck: adds some pinning helper commands
sanderpick Apr 9, 2021
7db2e12
buck: fix not sending token in thread create
sanderpick Apr 9, 2021
6faf6c5
docker: update compose files
sanderpick May 18, 2021
4524311
docker: add build caching
sanderpick May 18, 2021
5c8d30b
docs: add repo warning
sanderpick May 20, 2021
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
1 change: 0 additions & 1 deletion .bingo/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
# But not these files:
!.gitignore
!*.mod
!*.sum
!README.md
!Variables.mk
!variables.env
Expand Down
12 changes: 6 additions & 6 deletions .bingo/Variables.mk
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,35 @@ BUF := $(GOBIN)/buf-v0.20.5
$(BUF): .bingo/buf.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/buf-v0.20.5"
@cd .bingo && $(GO) build -modfile=buf.mod -o=$(GOBIN)/buf-v0.20.5 "github.com/bufbuild/buf/cmd/buf"
@cd .bingo && $(GO) build -mod=mod -modfile=buf.mod -o=$(GOBIN)/buf-v0.20.5 "github.com/bufbuild/buf/cmd/buf"

GOMPLATE := $(GOBIN)/gomplate-v3.8.0
$(GOMPLATE): .bingo/gomplate.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/gomplate-v3.8.0"
@cd .bingo && $(GO) build -modfile=gomplate.mod -o=$(GOBIN)/gomplate-v3.8.0 "github.com/hairyhenderson/gomplate/v3/cmd/gomplate"
@cd .bingo && $(GO) build -mod=mod -modfile=gomplate.mod -o=$(GOBIN)/gomplate-v3.8.0 "github.com/hairyhenderson/gomplate/v3/cmd/gomplate"

GOVVV := $(GOBIN)/govvv-v0.3.0
$(GOVVV): .bingo/govvv.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/govvv-v0.3.0"
@cd .bingo && $(GO) build -modfile=govvv.mod -o=$(GOBIN)/govvv-v0.3.0 "github.com/ahmetb/govvv"
@cd .bingo && $(GO) build -mod=mod -modfile=govvv.mod -o=$(GOBIN)/govvv-v0.3.0 "github.com/ahmetb/govvv"

GOX := $(GOBIN)/gox-v1.0.1
$(GOX): .bingo/gox.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/gox-v1.0.1"
@cd .bingo && $(GO) build -modfile=gox.mod -o=$(GOBIN)/gox-v1.0.1 "github.com/mitchellh/gox"
@cd .bingo && $(GO) build -mod=mod -modfile=gox.mod -o=$(GOBIN)/gox-v1.0.1 "github.com/mitchellh/gox"

PROTOC_GEN_BUF_CHECK_BREAKING := $(GOBIN)/protoc-gen-buf-check-breaking-v0.20.5
$(PROTOC_GEN_BUF_CHECK_BREAKING): .bingo/protoc-gen-buf-check-breaking.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/protoc-gen-buf-check-breaking-v0.20.5"
@cd .bingo && $(GO) build -modfile=protoc-gen-buf-check-breaking.mod -o=$(GOBIN)/protoc-gen-buf-check-breaking-v0.20.5 "github.com/bufbuild/buf/cmd/protoc-gen-buf-check-breaking"
@cd .bingo && $(GO) build -mod=mod -modfile=protoc-gen-buf-check-breaking.mod -o=$(GOBIN)/protoc-gen-buf-check-breaking-v0.20.5 "github.com/bufbuild/buf/cmd/protoc-gen-buf-check-breaking"

PROTOC_GEN_BUF_CHECK_LINT := $(GOBIN)/protoc-gen-buf-check-lint-v0.20.5
$(PROTOC_GEN_BUF_CHECK_LINT): .bingo/protoc-gen-buf-check-lint.mod
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
@echo "(re)installing $(GOBIN)/protoc-gen-buf-check-lint-v0.20.5"
@cd .bingo && $(GO) build -modfile=protoc-gen-buf-check-lint.mod -o=$(GOBIN)/protoc-gen-buf-check-lint-v0.20.5 "github.com/bufbuild/buf/cmd/protoc-gen-buf-check-lint"
@cd .bingo && $(GO) build -mod=mod -modfile=protoc-gen-buf-check-lint.mod -o=$(GOBIN)/protoc-gen-buf-check-lint-v0.20.5 "github.com/bufbuild/buf/cmd/protoc-gen-buf-check-lint"

2 changes: 1 addition & 1 deletion .bingo/buf.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/bufbuild/buf v0.20.5 // cmd/buf
2 changes: 1 addition & 1 deletion .bingo/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.

go 1.16
go 1.14
2 changes: 1 addition & 1 deletion .bingo/gomplate.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/hairyhenderson/gomplate/v3 v3.8.0 // cmd/gomplate
2 changes: 1 addition & 1 deletion .bingo/govvv.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/ahmetb/govvv v0.3.0
2 changes: 0 additions & 2 deletions .bingo/govvv.sum

This file was deleted.

2 changes: 1 addition & 1 deletion .bingo/gox.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/mitchellh/gox v1.0.1
2 changes: 1 addition & 1 deletion .bingo/protoc-gen-buf-check-breaking.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/bufbuild/buf v0.20.5 // cmd/protoc-gen-buf-check-breaking
2 changes: 1 addition & 1 deletion .bingo/protoc-gen-buf-check-lint.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT

go 1.16
go 1.14

require github.com/bufbuild/buf v0.20.5 // cmd/protoc-gen-buf-check-lint
10 changes: 2 additions & 8 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,17 @@ jobs:
buck:
name: Buck CLI
runs-on: ubuntu-latest
container: golang:1.16.0-buster
steps:
- name: setup
uses: actions/setup-go@v1
with:
go-version: 1.16
- name: checkout
uses: actions/checkout@v1
- name: build
run: make build-buck
buckd:
name: Buck Daemon
runs-on: ubuntu-latest
container: golang:1.16.0-buster
steps:
- name: setup
uses: actions/setup-go@v1
with:
go-version: 1.16
- name: checkout
uses: actions/checkout@v1
- name: build
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ jobs:
release-platform-builds:
name: Release Builds
runs-on: ubuntu-latest
container: golang:1.16.0-buster
steps:
- name: Set up Go
uses: actions/setup-go@v1
with:
go-version: 1.16
- name: Check out code
uses: actions/checkout@v1
- name: Cache dependencies
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

Join us on our [public Slack channel](https://slack.textile.io/) for news, discussions, and status updates. [Check out our blog](https://medium.com/textileio) for the latest posts and announcements.

### WARNING: This repo is pointing to a [feature branch](https://github.com/textileio/go-threads/pull/498) of `go-threads` that handles identities as Decentralized Identifiers (DIDs) and should be considered alpha. The [textile repo](https://github.com/textileio/textile) contains the non-DID-based bucket implementation currently compatible with [Textile's public hub](https://cloud.hub.textile.io/#/access). DID-based buckets will be integrated into the hub mid 2021. In the meantime, you can still use this repo for standalone bucket peers.

## Table of Contents

- [Security](#security)
Expand Down
111 changes: 94 additions & 17 deletions access.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,48 @@ import (
core "github.com/textileio/go-threads/core/thread"
)

// PushPathAccessRoles pushes new access roles to bucket paths.
// Access roles are keyed by did.DID.
// Roles are inherited by path children.
func (b *Buckets) PushPathAccessRoles(
ctx context.Context,
thread core.ID,
key, pth string,
roles map[did.DID]collection.Role,
key string,
identity did.Token,
root path.Resolved,
pth string,
roles map[did.DID]collection.Role,
) (int64, *Bucket, error) {
lk := b.locks.Get(lock(key))
lk.Acquire()
defer lk.Release()
txn, err := b.NewTxn(thread, key, identity)
if err != nil {
return 0, nil, err
}
defer txn.Close()
return txn.PushPathAccessRoles(ctx, root, pth, roles)
}

// PushPathAccessRoles is Txn based PushPathInfo.
func (t *Txn) PushPathAccessRoles(
ctx context.Context,
root path.Resolved,
pth string,
roles map[did.DID]collection.Role,
) (int64, *Bucket, error) {
pth, err := parsePath(pth)
if err != nil {
return 0, nil, err
}

instance, bpth, err := b.getBucketAndPath(ctx, thread, key, pth, identity)
instance, bpth, err := t.b.getBucketAndPath(ctx, t.thread, t.key, t.identity, pth)
if err != nil {
return 0, nil, err
}
if root != nil && root.String() != instance.Path {
return 0, nil, ErrNonFastForward
}

linkKey := instance.GetLinkEncryptionKey()
pathNode, err := dag.GetNodeAtPath(ctx, b.ipfs, bpth, linkKey)
pathNode, err := dag.GetNodeAtPath(ctx, t.b.ipfs, bpth, linkKey)
if err != nil {
return 0, nil, err
}
Expand Down Expand Up @@ -86,7 +106,7 @@ func (b *Buckets) PushPathAccessRoles(
return 0, nil, err
}
}
if err := b.c.Verify(ctx, thread, instance, collection.WithIdentity(identity)); err != nil {
if err := t.b.c.Verify(ctx, t.thread, instance, collection.WithIdentity(t.identity)); err != nil {
return 0, nil, err
}

Expand All @@ -97,7 +117,7 @@ func (b *Buckets) PushPathAccessRoles(
}
nmap, err := dag.EncryptDag(
ctx,
b.ipfs,
t.b.ipfs,
pathNode,
pth,
linkKey,
Expand All @@ -117,41 +137,46 @@ func (b *Buckets) PushPathAccessRoles(
}
pn := nmap[pathNode.Cid()].Node
var dirPath path.Resolved
ctx, dirPath, err = dag.InsertNodeAtPath(ctx, b.ipfs, pn, path.Join(path.New(instance.Path), pth), linkKey)
ctx, dirPath, err = dag.InsertNodeAtPath(ctx, t.b.ipfs, pn, path.Join(path.New(instance.Path), pth), linkKey)
if err != nil {
return 0, nil, err
}
ctx, err = dag.AddAndPinNodes(ctx, b.ipfs, nodes)
ctx, err = dag.AddAndPinNodes(ctx, t.b.ipfs, nodes)
if err != nil {
return 0, nil, err
}
instance.Path = dirPath.String()
}

if err := b.c.Save(ctx, thread, instance, collection.WithIdentity(identity)); err != nil {
if err := t.b.c.Save(ctx, t.thread, instance, collection.WithIdentity(t.identity)); err != nil {
return 0, nil, err
}
}

log.Debugf("pushed access roles for %s in %s", pth, key)
return dag.GetPinnedBytes(ctx), instanceToBucket(thread, instance), nil
log.Debugf("pushed access roles for %s in %s", pth, t.key)
return dag.GetPinnedBytes(ctx), instanceToBucket(t.thread, instance), nil
}

// PullPathAccessRoles pulls access roles for a bucket path.
func (b *Buckets) PullPathAccessRoles(
ctx context.Context,
thread core.ID,
key, pth string,
key string,
identity did.Token,
pth string,
) (map[did.DID]collection.Role, error) {
if err := thread.Validate(); err != nil {
return nil, fmt.Errorf("invalid thread id: %v", err)
}
pth, err := parsePath(pth)
if err != nil {
return nil, err
}
instance, bpth, err := b.getBucketAndPath(ctx, thread, key, pth, identity)
instance, bpth, err := b.getBucketAndPath(ctx, thread, key, identity, pth)
if err != nil {
return nil, err
}
if _, err := dag.GetNodeAtPath(ctx, b.ipfs, bpth, instance.GetLinkEncryptionKey()); err != nil {
if _, err = dag.GetNodeAtPath(ctx, b.ipfs, bpth, instance.GetLinkEncryptionKey()); err != nil {
return nil, fmt.Errorf("could not resolve path: %s", pth)
}
md, _, ok := instance.GetMetadataForPath(pth, false)
Expand All @@ -162,3 +187,55 @@ func (b *Buckets) PullPathAccessRoles(
log.Debugf("pulled access roles for %s in %s", pth, key)
return md.Roles, nil
}

// IsReadablePath returns whether or not a path is readable by an identity.
func (b *Buckets) IsReadablePath(
ctx context.Context,
thread core.ID,
key string,
identity did.Token,
pth string,
) (bool, error) {
if err := thread.Validate(); err != nil {
return false, fmt.Errorf("invalid thread id: %v", err)
}
pth, err := parsePath(pth)
if err != nil {
return false, err
}
instance, err := b.c.GetSafe(ctx, thread, key, collection.WithIdentity(identity))
if err != nil {
return false, err
}
_, doc, err := core.Validate(identity, nil)
if err != nil {
return false, err
}
return instance.IsReadablePath(pth, doc.ID), nil
}

// IsWritablePath returns whether or not a path is writable by an identity.
func (b *Buckets) IsWritablePath(
ctx context.Context,
thread core.ID,
key string,
identity did.Token,
pth string,
) (bool, error) {
if err := thread.Validate(); err != nil {
return false, fmt.Errorf("invalid thread id: %v", err)
}
pth, err := parsePath(pth)
if err != nil {
return false, err
}
instance, err := b.c.GetSafe(ctx, thread, key, collection.WithIdentity(identity))
if err != nil {
return false, err
}
_, doc, err := core.Validate(identity, nil)
if err != nil {
return false, err
}
return instance.IsWritablePath(pth, doc.ID), nil
}
18 changes: 10 additions & 8 deletions api/apitest/apitest.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"github.com/textileio/go-buckets"
"github.com/textileio/go-buckets/api/common"
"github.com/textileio/go-buckets/ipns"
"github.com/textileio/go-buckets/util"
dbc "github.com/textileio/go-threads/api/client"
"github.com/textileio/go-threads/core/did"
tdb "github.com/textileio/go-threads/db"
Expand All @@ -30,25 +29,26 @@ import (
func NewService(t *testing.T) (listenAddr string, host did.DID) {
err := tutil.SetLogLevels(map[string]logging.LogLevel{
"buckets": logging.LevelDebug,
"buckets-api": logging.LevelDebug,
"buckets-ipns": logging.LevelDebug,
"buckets-dns": logging.LevelDebug,
"buckets/api": logging.LevelDebug,
"buckets/ipns": logging.LevelDebug,
"buckets/dns": logging.LevelDebug,
})
require.NoError(t, err)

threadsAddr := GetThreadsApiAddr()
net, err := nc.NewClient(threadsAddr, common.GetClientRPCOpts(threadsAddr)...)
require.NoError(t, err)

// @todo: Fix me
// @todo: Use service description to build client
doc, err := net.GetServices(context.Background())
require.NoError(t, err)

db, err := dbc.NewClient(threadsAddr, common.GetClientRPCOpts(threadsAddr)...)
require.NoError(t, err)
ipfs, err := httpapi.NewApi(GetIPFSApiMultiAddr())
require.NoError(t, err)
ipnsm, err := ipns.NewManager(tdb.NewTxMapDatastore(), ipfs)
ipnsms := tdb.NewTxMapDatastore()
ipnsm, err := ipns.NewManager(ipnsms, ipfs)
require.NoError(t, err)
lib, err := buckets.NewBuckets(net, db, ipfs, ipnsm, nil)
require.NoError(t, err)
Expand All @@ -64,6 +64,8 @@ func NewService(t *testing.T) (listenAddr string, host did.DID) {
server.Stop()
require.NoError(t, lib.Close())
require.NoError(t, ipnsm.Close())
require.NoError(t, ipnsms.Close())
require.NoError(t, db.Close())
require.NoError(t, net.Close())
})

Expand All @@ -83,9 +85,9 @@ func GetThreadsApiAddr() string {
func GetIPFSApiMultiAddr() ma.Multiaddr {
env := os.Getenv("IPFS_API_MULTIADDR")
if env != "" {
return util.MustParseAddr(env)
return tutil.MustParseAddr(env)
}
return util.MustParseAddr("/ip4/127.0.0.1/tcp/5012")
return tutil.MustParseAddr("/ip4/127.0.0.1/tcp/5012")
}

// StartServices starts an ipfs and threads node for tests.
Expand Down
Loading