Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reference issue: #5003
Originally intended to be a read-only, Windows-only, variant, we now have an alternate implementation of
ipfs mount
that builds and runs on multiple platforms, and abstracts various APIs to expose an IPFS node as a virtual mutable filesystem.A demo of this is here: https://youtu.be/hh0epHWyt4I
In this document I'll outline the expectations as well as the current faults of the implementation that need to be resolved before final.
The daemon will expose a "mount-root" which will be referenced by name or
/
hereafter.The mount-root is a virtual filesystem that wraps IPFS APIs and exposes them via the fuse filesystem API.
The APIs will be referenced as a "subsystem", while individual subsystems will be refereed to as "root"s.
Paths beneath subsystems will be referenced generically as "node"s.
At current, we expose the following subsystems at the following endpoints: /ipfs, /ipns, /files
The ipfs-root wraps the pin api, to expose pins of the node as files.
i.e. Readdir("/ipfs") would expose the following entries on stock node
QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv, QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn
ipfs-nodes beneath the ipfs-root map to various CoreAPI requests, exposing the ipfs-nodes as native file types with which read-only file system operations can be performed on.
i.e.
Opendir("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv")
Open("/ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/about")
etc.
ipfs-nodes do not have to be pins nor do they have to exist locally on the node's instance. If valid, the mount logic will attempt to fetch them from the network.
The files-root wraps the MFS API and shares the same root as the
ipfs files
command.Exposing the same contents as
ipfs files ls /
and providing generic file system operations for its nodes as above, but also allowing for mutable operations as well.i.e.
Mknod("/files/sub-file")
Mkdir("/files/sub-dir")
etc.
The ipns-root wraps the same systems as the previous roots, as well as the key and name api's specifically.
Exposing the node's keys
ipfs key list
as native file system types. As well as providing key management.i.e.
Mknod("/ipns/key-pointing-to-file")
Mkidir("/ipns/key-pointing-to-directory")
Rename("/ipns/key-old-name", "/ipns/key-new-name")
Unlink("/ipns/key-name")
etc.
ipns-nodes may be referenced via a named path or a CID path. Both of which are valid, but carry different operation access. Paths referenced via key's are resolved locally, and allow for mutable operations.
i.e.
both
/ipns/self
and/ipns/QmTjr6BNmV6v3h7df3gbrNpsQLC5Y91csHWUE3QSYki2QK
are valid ipns-nodes but carry different bejhaviour.Draft / Implementation notes:
Currently, most operations can be performed on most types, but the instance is somewhat fragile and not everything is functioning properly all the time.
Effort is being put into simplifying the codebase and generalizing operation functions.
Currently, paths are being passed in as strings and parsed via a lookup function
LookupPath()
into generic "fusePath" interface objects. Underneath, each node is hard typed, dependent on its path.These objects implement the CoreAPI
Path
type and are passed around to various operation functions.For example, you can derive a fuse compatible IO interface/object from a fusePath, or pass it to the CoreAPI if it's a valid global path.
The current goal is to take the various procedural functions in the codebase and translate them into methods on the objects themselves. This should be a large reduction and more sensible in terms of object life-time/correctness. At current, the common patterns are a procedural and OO mix which should be made more consistent.
Type switches are used extensively but it makes much more sense to just have
path.Read()
thanread(ipfs-path) { switch fusePath.(type) { ipfsRead(ipfs-path) }
It also makes more sense for the IO interface to live on the path, rather than just be associated with it through other means.
There are a number of bad behaviours currently, but non are worth listing in particular.
With the coupling of the nodes, the source of the existing issues should become more apparent or be fixed inherently. A particular example will be ASYNC IO. Currently nodes are very much independent, but the idea is to change how nodes are initialized, locked, and considerations about their lifetime. Simplifying things like this should inadvertently expose and/or fix issues around other operations.
Very little of the config is wired up, things are mostly hard coded or placeholder. The worst offender being all call contexts sharing the context of the daemon, so doing something like calling read on a hash that has no providers will hang indefinitely (or until the OS kills it). Simply defining a sensible timeout context should remedy this.
I have a pretty good understanding of what's wrong with this draft and what still needs to be done but criticism and listing problems are welcomed.