Skip to content
This repository was archived by the owner on Jun 19, 2023. It is now read-only.

Commit a6b1d49

Browse files
committed
pre-branch
1 parent d1e2792 commit a6b1d49

File tree

14 files changed

+1026
-148
lines changed

14 files changed

+1026
-148
lines changed

filesystem/client.go

Lines changed: 1 addition & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1 @@
1-
package fs
2-
3-
import (
4-
"context"
5-
"os"
6-
//pretend we're not the same package
7-
//fs "github.com/ipfs/interface-go-ipfs-core/filesystem"
8-
)
9-
10-
// This file represents a 3rd party user of the API
11-
12-
// Client side using pkg defaults
13-
func client() {
14-
f, err := fs.OpenFile("/ipfs/Qm.../file.ext", flags, perm)
15-
if err != nil {
16-
//...
17-
}
18-
defer f.Close()
19-
x, y := f.Read(someByteSlice)
20-
}
21-
22-
// done
23-
24-
// In addition, clients can also implement their own...
25-
// nodes,
26-
type myNode struct {
27-
myData bool
28-
}
29-
30-
func (mn *myNode) YieldIo(ctx context.Context, nodeType fs.FsType) {
31-
if !mn.myData {
32-
return nil, errIOType // we don't have the data needed to perform this request
33-
}
34-
return constructFileIo(mn.MyData), nil //we have what we need to construct a FsFile interface, so return that
35-
}
36-
37-
// namespace parsers
38-
func myParser(ctx context.Context, name string) (FsNode, error) {
39-
if condition(name) {
40-
return myNode{false}, nil
41-
}
42-
return myNode{true}, nil
43-
}
44-
45-
// and filing systems
46-
func aDifferentFileSystem(ctx context.Context) {
47-
// something like this
48-
fsCtx := deriveFrom(ctx)
49-
return &colonDelimitedRegistry{fsCtx}, nil
50-
}
51-
52-
func clientImp() {
53-
myFs := aDifferentFileSystem(ctx)
54-
55-
_, err = myFs.OpenFile(":myName", flags, perm)
56-
err == os.ErrNotExist // or some other standard error
57-
58-
namespaceCloser, err := myFs.Register(":myName", myParser)
59-
60-
myF, err := myFs.OpenFile(":myName", flags, perm)
61-
myF.Read()
62-
63-
namespaceCloser() // requests for `/myName` are no longer valid according to the filesystem interface (`myFs`)
64-
65-
_, err = myFs.OpenFile(":myName", flags, perm)
66-
err == os.ErrNotExist
67-
68-
_, err = myF.Read()
69-
err == os.ErrInvalid // or some other standard error
70-
}
1+
package fs

filesystem/default.go

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package fs
2+
3+
import (
4+
"context"
5+
"time"
6+
"github.com/ipfs/go-ipfs/core"
7+
)
8+
9+
type defaultFs struct {
10+
// index
11+
PathParserRegistry
12+
13+
//defaultFS specific
14+
ctx context.Context
15+
epoch time.Time
16+
17+
//IPFS parser specifics
18+
ipfsNode core.IpfsNode
19+
}
20+
/* From DRAFT
21+
func NewDefaultFileSystem(parentCtx context.Context) (FileSystem, error) {
22+
// something like this
23+
fsCtx := deriveFrom(parentCtx)
24+
// go onCancel(fsCtx) { callClosers() } ()
25+
return &PathParserRegistry{fsCtx}, nil
26+
}
27+
*/
28+
29+
func newDefaultFs() (FileSystem, error) {
30+
var root defaultFs
31+
root.epoch = time.Now()
32+
33+
// we depend on data from the coreapi to initalize our API nodes
34+
// so fetch it or something and store it on the FS
35+
daemon := fallbackApi()
36+
ctx := deriveCtx(daemon.ctx) // if the daemon cancels, so should we
37+
38+
root.ipfsNode = daemon
39+
40+
// mount base subsystems
41+
for _, pair := range [...]struct {
42+
string
43+
ParseFn
44+
}{
45+
{"/", rNode.Parser()},
46+
{"/ipfs", pinRootParser}, // requests for "/ipfs" are directed at pinRootParser(ctx, requestString)
47+
{"/ipfs/", coreAPIParser}, // all requests beneath "/ipfs/" are directed at coreAPIParser(ctx, requestString)
48+
{"/ipns", keyRootParser},
49+
{"/ipns/", nameAPIParser},
50+
{filesRootPrefix, filesAPIParser},
51+
} {
52+
closer, err := root.Register(pair.string, pair.ParseFn)
53+
if err != nil {
54+
if err == errRegistered {
55+
//TODO: [discuss] consider having Plan9 style unions; Mount() would require flags (union contents go to: front, back, replace)
56+
// doing this complicates our io.Closer consturction, but may be worth having
57+
return nil, fmt.Errorf("%q is already registered", pair.string)
58+
}
59+
return nil, fmt.Errorf("cannot register %q: %s", pair.string, err)
60+
}
61+
62+
// store these somewhere important and call them before you exit
63+
// this will release the namespace at the FS level
64+
root.closers = append(root.closers, closer) // in our example we do nothing with them :^)
65+
}
66+
}
67+
68+
type DescriptorTable interface {
69+
}
70+
71+
func newDescriptorTable() {
72+
}

filesystem/index.go

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -8,63 +8,31 @@ import (
88
"sync"
99

1010
"github.com/ipfs/go-unixfs"
11+
"github.com/multiformats/go-multihash"
12+
"github.com/ipfs/go-cid"
1113
)
1214

13-
// This file represents a partial and theoretical
14-
// pkg-level implementation of a filesystem{}
15-
16-
var (
17-
pkgRoot FileSystem
18-
closers []io.Closer
19-
)
20-
21-
func init() {
22-
23-
// we depend on data from the coreapi to initalize our API nodes
24-
// so fetch it or something and store it on the FS
25-
daemon := fallbackApi()
26-
ctx := deriveCtx(daemon.ctx) // if the daemon cancels, so should we
27-
28-
pkgRoot = NewFileSystem(ctx)
29-
for _, pair := range [...]struct {
30-
string
31-
ParseFn
32-
}{
33-
{"/", rootParser},
34-
{"/ipfs", pinRootParser}, // requests for "/ipfs" are directed at pinRootParser(ctx, requestString)
35-
{"/ipfs/", coreAPIParser}, // all requests beneath "/ipfs/" are directed at coreAPIParser(ctx, requestString)
36-
{"/ipns", keyRootParser},
37-
{"/ipns/", nameAPIParser},
38-
{filesRootPrefix, filesAPIParser},
39-
} {
40-
closer, err := pkgRoot.Register(pair.string, pair.ParseFn)
41-
if err != nil {
42-
if err == errRegistered {
43-
panic(fmt.Sprtinf("%q is already registered", pair.string))
44-
}
45-
panic(fmt.Sprtinf("cannot register %q: %s", pair.string, err))
46-
}
47-
48-
// store these somewhere important and call them before you exit
49-
// this will release the namespace at the FS level
50-
closers = append(closers, closer) // in our example we do nothing with them :^)
51-
}
15+
func Lookup(ctx context.Context, name string) (FsNode, error) {
16+
return pkgRoot.Lookup(ctx, name)
5217
}
5318

54-
func NewDefaultFileSystem(parentCtx context.Context) (FileSystem, error) {
55-
// something like this
56-
fsCtx := deriveFrom(parentCtx)
57-
// go onCancel(fsCtx) { callClosers() } ()
58-
return &PathParserRegistry{fsCtx}, nil
19+
// api's may define Metadata.Cid() however they like
20+
// for the default, we use this QID-like generator
21+
func GenQueryID(path string, md Metadata) (cid.Cid, error) {
22+
mdBuf := make([]byte, 16)
23+
binary.LittleEndian.PutUint64(mdBuf, uint64(md.Size()))
24+
binary.LittleEndian.PutUint64(mdBuf[8:], uint64(md.Type()))
25+
26+
prefix := cid.V1Builder{Codec: cid.DagCBOR, MhType: multihash.BLAKE2B_MIN}
27+
return prefix.Sum(append([]byte(path), mdBuf...))
5928
}
6029

6130
type PathParserRegistry struct {
6231
sync.Mutex
63-
ctx context.Context
6432
nodeParsers map[string]ParseFn
6533
}
6634

67-
func (rr *PathParserRegistry) Register(subrootPath string, nodeParser ParseFn) (io.Closer, error) {
35+
func (rr *PathParserRegistry) Mount(subrootPath string, nodeParser ParseFn) (io.Closer, error) {
6836
rr.Lock()
6937
val, ok := rr.nodeParsers[subrootPath]
7038
if ok || val != nil {
@@ -74,12 +42,14 @@ func (rr *PathParserRegistry) Register(subrootPath string, nodeParser ParseFn) (
7442
rr.nodeParsers[subrootPath] = nodeParsers
7543
return func() {
7644
ri.Lock()
45+
//TODO: somehow trigger cascading close for open subsystem handles
46+
// or note that open handles are still valid, but new handles will not be made
7747
delete(ri.subSystem, subrootPath)
7848
ri.Unlock()
7949
}, nil
8050
}
8151

82-
func (PathParserRegistry) Lookup(ctx context.Context, name string) (FsPath, error) {
52+
func (PathParserRegistry) Lookup(ctx context.Context, name string) (FsNode, error) {
8353
//NOTE: we can use a pkg level cache here, and fallback to the parser only when necessary
8454

8555
/* very simple map lookup
@@ -119,13 +89,7 @@ func Unlock() {
11989
pkgRoot.Unlock()
12090
}
12191

122-
func Lookup(ctx context.Context, name string) (FsPath, error) {
123-
return pkgRoot.Lookup(ctx, name)
124-
}
125-
126-
// ...
127-
128-
func OpenFile(name string, flags flags, perm os.FileMode) (FsFile, error) {
92+
func OpenFile(name string, flags OFlags, perm os.FileMode) (FsFile, error) {
12993
fs.Lock()
13094
defer fs.Unlock()
13195

filesystem/init.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package fs
2+
3+
//TODO: store these in the daemon/ipfs-node scope, or elsewhere
4+
// have something extract the FS from the daemon (`core.fsFrom(IpfsNode)``)
5+
var pkgRoot FileSystem
6+
7+
func init() {
8+
pkgRoot, err = newDefaultFs()
9+
if err != nil {
10+
panic(err)
11+
}
12+
}

0 commit comments

Comments
 (0)