Example #1
0
func main() {
	flag.Usage = Usage
	flag.Parse()

	if flag.NArg() != 1 {
		Usage()
		os.Exit(2)
	}
	mountpoint := flag.Arg(0)

	c, err := fuse.Mount(
		mountpoint,
		fuse.FSName("helloworld"),
		fuse.Subtype("hellofs"),
		fuse.LocalVolume(),
		fuse.VolumeName("Hello world!"),
	)
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	err = fs.Serve(c, FS{})
	if err != nil {
		log.Fatal(err)
	}

	// check if the mount process has an error to report
	<-c.Ready
	if err := c.MountError; err != nil {
		log.Fatal(err)
	}
}
Example #2
0
// MountedFunc mounts a filesystem at a temporary directory. The
// filesystem used is constructed by calling a function, to allow
// storing fuse.Conn and fs.Server in the FS.
//
// It also waits until the filesystem is known to be visible (OS X
// workaround).
//
// After successful return, caller must clean up by calling Close.
func MountedFunc(fn func(*Mount) fs.FS, conf *fs.Config, options ...fuse.MountOption) (*Mount, error) {
	dir, err := ioutil.TempDir("", "fusetest")
	if err != nil {
		return nil, err
	}
	c, err := fuse.Mount(dir, options...)
	if err != nil {
		return nil, err
	}
	server := fs.New(c, conf)
	done := make(chan struct{})
	serveErr := make(chan error, 1)
	mnt := &Mount{
		Dir:    dir,
		Conn:   c,
		Server: server,
		Error:  serveErr,
		done:   done,
	}
	filesys := fn(mnt)
	go func() {
		defer close(done)
		serveErr <- server.Serve(filesys)
	}()

	select {
	case <-mnt.Conn.Ready:
		if err := mnt.Conn.MountError; err != nil {
			return nil, err
		}
		return mnt, nil
	case err = <-mnt.Error:
		// Serve quit early
		if err != nil {
			return nil, err
		}
		return nil, errors.New("Serve exited early")
	}
}
Example #3
0
//
// Main function.
//  - Exposes remote FS structure locally using FUSE (bazil-fuse)
//  - Gets files from remote on-demand
//  - TODO:
//	- Check-in files to remote
//	- Version control
//
func Revelo(Name string, accType string, cacheDir string, mntDir string) error {

	GlobalData.metaName = Name + ".meta"
	acc, err := initAccess(accType, mntDir)
	if err != nil {
		log.Errorf("Revelo: Invalid Access type: %v", accType)
		return err
	}

	remoteDir, err := acc.Init()
	if err != nil {
		log.WithFields(log.Fields{"Acc": acc, "Error": err}).Error("Revelo: Cannot init access")
		return err
	}

	GlobalData.cacheDir = cacheDir
	GlobalData.mntDir = mntDir

	log.WithFields(log.Fields{
		"Access":    acc,
		"CacheDir":  cacheDir,
		"mntDir":    mntDir,
		"RemoteDir": remoteDir,
	}).Info("Revelo - Init done...")

	_, err = os.Stat(cacheDir + "/" + GlobalData.metaName)

	// If some error happened here, we might fail in open later.
	// Its better not to GetFile in that case.

	// Get meta from <name>.meta file
	metaPresent := ((err == nil) || !os.IsNotExist(err))
	if metaPresent == false {
		var metaName string
		if remoteDir == "" {
			metaName = GlobalData.metaName
		} else {
			metaName = remoteDir + "/" + GlobalData.metaName
		}
		err = acc.GetFile(metaName, cacheDir+"/"+GlobalData.metaName)
		if err != nil {
			log.WithFields(log.Fields{
				"Remote":  metaName,
				"Local":   cacheDir + "/" + GlobalData.metaName,
				"AccData": acc,
			}).Error("Revelo: Cannot get meta file")
			return err
		}
	} else {
		log.Info("Revelo: Meta file present, using it...")
	}

	metaFile, err := os.Open(cacheDir + "/" + GlobalData.metaName)
	if err != nil {
		log.WithFields(log.Fields{
			"Meta File": cacheDir + "/" + GlobalData.metaName,
			"Error":     err,
		}).Error("Cannot open meta file")
		return err
	}
	defer metaFile.Close()

	st, _ := metaFile.Stat() //XXX This should not fail
	metaData := make([]byte, st.Size()+1)
	n, err := metaFile.Read(metaData)
	if err != nil || n == 0 {
		log.WithFields(log.Fields{
			"Meta File":  cacheDir + "/" + GlobalData.metaName,
			"Read bytes": n,
			"Error":      err,
		}).Error("Revelo: Cannot read meta file, error or empty")
		return syscall.EINVAL
	}

	// Unmarshal the meta data
	metaData = metaData[:n]
	meta := new(horcrux.Meta)
	err = json.Unmarshal(metaData, meta)
	if err != nil {
		log.WithFields(log.Fields{
			"Meta Data": string(metaData),
			"Error":     err,
		}).Error("Revelo: Cannot unmarshal meta data")
		return err
	}

	// Create dirTree
	GlobalData.Root, err = dirTree.Create(meta)
	GlobalData.Config = meta.Config
	GlobalData.CurrVer = meta.CurrVer
	GlobalData.NumFiles = meta.NumFiles

	// Mount local
	fuseConn, err := fuse.Mount(mntDir,
		fuse.FSName("Horcrux"),
		fuse.Subtype("Horcrux-"+acc.Name()),
		fuse.MaxReadahead(128*(1<<10)),
		fuse.AllowOther()) //XXX : Revisit AllowOther
	if err != nil {
		log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Mount Failed")
		return err
	}
	defer fuseConn.Close()

	GlobalData.fuseConn = fuseConn

	log.Debugf("Mount OK: %v", GlobalData.CurrVer)

	horcruxFS := &FS{Acc: &acc, RData: &GlobalData, remoteDir: remoteDir, cacheDir: cacheDir}

	err = fs.Serve(fuseConn, horcruxFS)
	if err != nil {
		log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Cannot fs.Serve")
		return err
	}

	<-fuseConn.Ready

	if err := fuseConn.MountError; err != nil {
		log.WithFields(log.Fields{"Conn": fuseConn, "Error": err}).Error("Mount Failed")
		return err
	}

	log.Info("Revelo Done...")
	return nil
}