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

swarm/api: support mounting manifests via FUSE #3690

Merged
merged 1 commit into from
Mar 23, 2017
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
15 changes: 15 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,34 @@ matrix:
include:
- os: linux
dist: trusty
sudo: required
go: 1.7.5
script:
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
- sudo modprobe fuse
- sudo chmod 666 /dev/fuse
- sudo chown root:$USER /etc/fuse.conf

# These are the latest Go versions, only run go vet and misspell on these
- os: linux
dist: trusty
sudo: required
go: 1.8
script:
- sudo -E apt-get -yq --no-install-suggests --no-install-recommends --force-yes install fuse
- sudo modprobe fuse
- sudo chmod 666 /dev/fuse
- sudo chown root:$USER /etc/fuse.conf
- go run build/ci.go install
- go run build/ci.go test -coverage -vet -misspell

- os: osx
go: 1.8
sudo: required
script:
- brew update
- brew install caskroom/cask/brew-cask
- brew cask install osxfuse
- go run build/ci.go install
- go run build/ci.go test -coverage -vet -misspell

Expand Down
14 changes: 14 additions & 0 deletions build/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,20 @@ func doInstall(cmdline []string) {
if flag.NArg() > 0 {
packages = flag.Args()
}

// Resolve ./... manually and remove vendor/bazil/fuse (fuse is not in windows)
out, err := goTool("list", "./...").CombinedOutput()
if err != nil {
log.Fatalf("package listing failed: %v\n%s", err, string(out))
}
packages = []string{}
for _, line := range strings.Split(string(out), "\n") {
if !strings.Contains(line, "vendor") {
packages = append(packages, strings.TrimSpace(line))
}
}


if *arch == "" || *arch == runtime.GOARCH {
goinstall := goTool("install", buildFlags(env)...)
goinstall.Args = append(goinstall.Args, "-v")
Expand Down
2 changes: 1 addition & 1 deletion cmd/swarm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func init() {
// Override flag defaults so bzzd can run alongside geth.
utils.ListenPortFlag.Value = 30399
utils.IPCPathFlag.Value = utils.DirectoryString{Value: "bzzd.ipc"}
utils.IPCApiFlag.Value = "admin, bzz, chequebook, debug, rpc, web3"
utils.IPCApiFlag.Value = "admin, bzz, chequebook, debug, rpc, swarmfs, web3"

// Set up the cli app.
app.Action = bzzd
Expand Down
29 changes: 29 additions & 0 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,12 @@ var Modules = map[string]string{
"personal": Personal_JS,
"rpc": RPC_JS,
"shh": Shh_JS,
"swarmfs": SWARMFS_JS,
"txpool": TxPool_JS,

}


const Chequebook_JS = `
web3._extend({
property: 'chequebook',
Expand Down Expand Up @@ -486,6 +489,32 @@ web3._extend({
]
});
`
const SWARMFS_JS = `
web3._extend({
property: 'swarmfs',
methods:
[
new web3._extend.Method({
name: 'mount',
call: 'swarmfs_mount',
params: 2,
inputFormatter: [null,null]
}),
new web3._extend.Method({
name: 'unmount',
call: 'swarmfs_unmount',
params: 1,
inputFormatter: [null]
}),
new web3._extend.Method({
name: 'listmounts',
call: 'swarmfs_listmounts',
params: 0,
inputFormatter: []
})
]
});
`

const TxPool_JS = `
web3._extend({
Expand Down
139 changes: 139 additions & 0 deletions swarm/api/fuse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

// +build !windows

package api

import (
"io"
"os"

"bazil.org/fuse"
"bazil.org/fuse/fs"
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/swarm/storage"
"golang.org/x/net/context"
)




// Data structures used for Fuse filesystem, serving directories and serving files to Fuse driver
type FS struct {
root *Dir
}

type Dir struct {
inode uint64
name string
path string
directories []*Dir
files []*File
}

type File struct {
inode uint64
name string
path string
key storage.Key
swarmApi *Api
fileSize uint64
reader storage.LazySectionReader
}


// Functions which satisfy the Fuse File System requests
func (filesystem *FS) Root() (fs.Node, error) {
return filesystem.root, nil
}

func (directory *Dir) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = directory.inode
//TODO: need to get permission as argument
a.Mode = os.ModeDir | 0500
a.Uid = uint32(os.Getuid())
a.Gid = uint32(os.Getegid())
return nil
}

func (directory *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
if directory.files != nil {
for _, n := range directory.files {
if n.name == name {
return n, nil
}
}
}
if directory.directories != nil {
for _, n := range directory.directories {
if n.name == name {
return n, nil
}
}
}
return nil, fuse.ENOENT
}

func (d *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
var children []fuse.Dirent
if d.files != nil {
for _, file := range d.files {
children = append(children, fuse.Dirent{Inode: file.inode, Type: fuse.DT_File, Name: file.name})
}
}
if d.directories != nil {
for _, dir := range d.directories {
children = append(children, fuse.Dirent{Inode: dir.inode, Type: fuse.DT_Dir, Name: dir.name})
}
}
return children, nil
}

func (file *File) Attr(ctx context.Context, a *fuse.Attr) error {

a.Inode = file.inode
//TODO: need to get permission as argument
a.Mode = 0500
a.Uid = uint32(os.Getuid())
a.Gid = uint32(os.Getegid())


reader := file.swarmApi.Retrieve(file.key)
quitC := make(chan bool)
size, err := reader.Size(quitC)
if err != nil {
log.Warn("Couldnt file size of file %s : %v", file.path, err)
a.Size = uint64(0)
}
a.Size = uint64(size)
file.fileSize = a.Size
return nil
}

var _ = fs.HandleReader(&File{})

func (file *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
buf := make([]byte, req.Size)
reader := file.swarmApi.Retrieve(file.key)
n, err := reader.ReadAt(buf, req.Offset)
if err == io.ErrUnexpectedEOF || err == io.EOF {
err = nil
}
resp.Data = buf[:n]
return err

}
48 changes: 48 additions & 0 deletions swarm/api/swarmfs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package api

import (
"time"
"sync"
)

const (
Swarmfs_Version = "0.1"
mountTimeout = time.Second * 5
maxFuseMounts = 5
)


type SwarmFS struct {
swarmApi *Api
activeMounts map[string]*MountInfo
activeLock *sync.RWMutex
}



func NewSwarmFS(api *Api) *SwarmFS {
swarmfs := &SwarmFS{
swarmApi: api,
activeLock: &sync.RWMutex{},
activeMounts: map[string]*MountInfo{},
}
return swarmfs
}


Loading