Skip to content
Open
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
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,35 @@
### Linux

```shell
$ sudo apt-get install fuse
sudo apt-get install fuse
```

### MacOSX

```shell
$ brew cask install osxfuse
brew cask install osxfuse

```

## Build

```shell
$ go get
$ go build -o lot-fuse main.go
go get
go build -o lot-fuse main.go
```

## Usage

```shell
$ export LOTPATH=/tmp/mountpoint
$ export LOTBIN=$LOTPATH/bin
$ export PATH=$PATH:$LOTBIN
$ mkdir -p $LOTBIN
export LOTPATH=/tmp/mountpoint
export LOTBIN=$LOTPATH/bin
export PATH=$PATH:$LOTBIN
mkdir -p $LOTBIN
```

```shell
$ umount $LOTBIN ; go build -o lot-fuse main2.go && ./lot-fuse -fuse.debug $LOTBIN
umount $LOTBIN
./lot-fuse -fuse.debug $LOTBIN
```

## References
Expand Down
177 changes: 132 additions & 45 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,70 +1,157 @@
// Copyright 2016 the Go-FUSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This program is the analogon of libfuse's hello.c, a a program that
// exposes a single file "file.txt" in the root directory.
// Hellofs implements a simple "hello world" file system.
// https://github.com/ipfs/go-ipfs/blob/master/fuse/readonly/readonly_unix.go
package main

import (
"context"
"flag"
"fmt"
"log"
"os"
"syscall"
"fmt"
"os"
// "io/ioutil"
"io"
"net/http"

"github.com/hanwen/go-fuse/fs"
"github.com/hanwen/go-fuse/fuse"
fuseversion "github.com/jbenet/go-fuse-version"
"bazil.org/fuse"
"bazil.org/fuse/fs"
// fuseversion "github.com/jbenet/go-fuse-version"
_ "bazil.org/fuse/fs/fstestutil"
)

type HelloRoot struct {
fs.Inode
func usage() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
fmt.Fprintf(os.Stderr, " %s <mountpoint>\n", os.Args[0])
flag.PrintDefaults()
}

func (r *HelloRoot) OnAdd(ctx context.Context) {
ch := r.NewPersistentInode(
ctx, &fs.MemRegularFile{
Data: []byte("file.txt"),
Attr: fuse.Attr{
Mode: 0644,
},
}, fs.StableAttr{Ino: 2})
r.AddChild("file.txt", ch, false)
}
func main() {
flag.Usage = usage
flag.Parse()

func (r *HelloRoot) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
out.Mode = 0755
return 0
}
if flag.NArg() != 1 {
usage()
os.Exit(2)
}

mountpoint := flag.Arg(0)

var _ = (fs.NodeGetattrer)((*HelloRoot)(nil))
var _ = (fs.NodeOnAdder)((*HelloRoot)(nil))
c, err := fuse.Mount(
mountpoint,
fuse.FSName("helloworld"),
fuse.Subtype("hellofs"),
)

// sysv, err := fuseversion.LocalFuseSystems()
// if err != nil {
// fmt.Fprintf(os.Stderr, "%s\n", err)
// os.Exit(1)
// }

// for _, s := range sysv {
// fmt.Printf("Fuse Version %s, %s, %s\n", s.FuseVersion, s.AgentVersion, s.AgentName)
// }

func main() {
sysv, err := fuseversion.LocalFuseSystems()
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
os.Exit(1)
log.Fatal(err)
}
defer c.Close()

for _, s := range sysv {
fmt.Printf("Fuse Version %s, %s, %s\n", s.FuseVersion, s.AgentVersion, s.AgentName)
err = fs.Serve(c, FS{})
if err != nil {
log.Fatal(err)
}
}

debug := flag.Bool("debug", false, "print debug data")
flag.Parse()
if len(flag.Args()) < 1 {
log.Fatal("Usage:\n hello MOUNTPOINT")
// FS implements the hello world file system.
type FS struct{}

func (FS) Root() (fs.Node, error) {
return Dir{}, nil
}

// Dir implements both Node and Handle for the root directory.
type Dir struct{}

func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 1
a.Mode = os.ModeDir | 0o555
return nil
}

func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
if name == "hello" {
return NewVirtualFile("https://gist.githubusercontent.com/rubeniskov/e8aeec1bebf46696a9b9557e1a1bf936/raw/3fd978bcb6e89274409e5f9eb8ad1e436939c40f/semver-patcher.py"), nil
}
opts := &fs.Options{}
opts.Debug = *debug
return nil, syscall.ENOENT
}

var dirDirs = []fuse.Dirent{
{Inode: 2, Name: "hello", Type: fuse.DT_File},
}

func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
return dirDirs, nil
}

// File implements both Node and Handle for the hello file.




// func (File) ReadAll(ctx context.Context) ([]byte, error) {
// resp, err := http.Get("https://gist.githubusercontent.com/rubeniskov/e8aeec1bebf46696a9b9557e1a1bf936/raw/3fd978bcb6e89274409e5f9eb8ad1e436939c40f/semver-patcher.py")
// if err != nil {
// log.Fatal(err)
// }
// defer resp.Body.Close()
// body, err := ioutil.ReadAll(resp.Body)

// if err != nil {
// log.Fatal(err)
// }

// fmt.Printf("%s", body)

// return body, nil
// }

fmt.Printf("Mounting directory %s\n", flag.Arg(0))
server, err := fs.Mount(flag.Arg(0), &HelloRoot{}, opts)


type VirtualFile struct{
size int64
body io.Reader
}


func NewVirtualFile(locator string) *VirtualFile {
hresp, err := http.Get(locator)
if err != nil {
log.Fatalf("Mount fail: %v\n", err)
log.Fatal(err)
}
return &VirtualFile{
hresp.ContentLength,
hresp.Body,
}
}

func (vf *VirtualFile) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 2
a.Mode = 0o555
a.Size = uint64(vf.size)
return nil
}

func (vf *VirtualFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
// Data has a capacity of Size
buf := resp.Data[:int(req.Size)]
n, err := io.ReadFull(vf.body, buf)
resp.Data = buf[:n]
switch err {
case nil, io.EOF, io.ErrUnexpectedEOF:
default:
return err
}
server.Wait()
resp.Data = resp.Data[:n]
return nil // may be non-nil / not succeeded
}
Loading