예제 #1
0
파일: local.go 프로젝트: ar-jan/restic
// Open opens the local backend as specified by config.
func Open(dir string) (*Local, error) {
	// test if all necessary dirs are there
	for _, d := range paths(dir) {
		if _, err := fs.Stat(d); err != nil {
			return nil, errors.Wrap(err, "Open")
		}
	}

	return &Local{p: dir}, nil
}
예제 #2
0
파일: local.go 프로젝트: ar-jan/restic
// Save stores data in the backend at the handle.
func (b *Local) Save(h restic.Handle, p []byte) (err error) {
	debug.Log("Save %v, length %v", h, len(p))
	if err := h.Valid(); err != nil {
		return err
	}

	tmpfile, err := writeToTempfile(filepath.Join(b.p, backend.Paths.Temp), p)
	debug.Log("saved %v (%d bytes) to %v", h, len(p), tmpfile)
	if err != nil {
		return err
	}

	filename := filename(b.p, h.Type, h.Name)

	// test if new path already exists
	if _, err := fs.Stat(filename); err == nil {
		return errors.Errorf("Rename(): file %v already exists", filename)
	}

	// create directories if necessary, ignore errors
	if h.Type == restic.DataFile {
		err = fs.MkdirAll(filepath.Dir(filename), backend.Modes.Dir)
		if err != nil {
			return errors.Wrap(err, "MkdirAll")
		}
	}

	err = fs.Rename(tmpfile, filename)
	debug.Log("save %v: rename %v -> %v: %v",
		h, filepath.Base(tmpfile), filepath.Base(filename), err)

	if err != nil {
		return errors.Wrap(err, "Rename")
	}

	// set mode to read-only
	fi, err := fs.Stat(filename)
	if err != nil {
		return errors.Wrap(err, "Stat")
	}

	return setNewFileMode(filename, fi)
}
예제 #3
0
파일: local.go 프로젝트: ar-jan/restic
// Test returns true if a blob of the given type and name exists in the backend.
func (b *Local) Test(t restic.FileType, name string) (bool, error) {
	debug.Log("Test %v %v", t, name)
	_, err := fs.Stat(filename(b.p, t, name))
	if err != nil {
		if os.IsNotExist(errors.Cause(err)) {
			return false, nil
		}
		return false, errors.Wrap(err, "Stat")
	}

	return true, nil
}
예제 #4
0
파일: local.go 프로젝트: ar-jan/restic
// Stat returns information about a blob.
func (b *Local) Stat(h restic.Handle) (restic.FileInfo, error) {
	debug.Log("Stat %v", h)
	if err := h.Valid(); err != nil {
		return restic.FileInfo{}, err
	}

	fi, err := fs.Stat(filename(b.p, h.Type, h.Name))
	if err != nil {
		return restic.FileInfo{}, errors.Wrap(err, "Stat")
	}

	return restic.FileInfo{Size: fi.Size()}, nil
}
예제 #5
0
func mount(opts MountOptions, gopts GlobalOptions, mountpoint string) error {
	debug.Log("start mount")
	defer debug.Log("finish mount")

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	err = repo.LoadIndex()
	if err != nil {
		return err
	}

	if _, err := resticfs.Stat(mountpoint); os.IsNotExist(errors.Cause(err)) {
		Verbosef("Mountpoint %s doesn't exist, creating it\n", mountpoint)
		err = resticfs.Mkdir(mountpoint, os.ModeDir|0700)
		if err != nil {
			return err
		}
	}
	c, err := systemFuse.Mount(
		mountpoint,
		systemFuse.ReadOnly(),
		systemFuse.FSName("restic"),
	)
	if err != nil {
		return err
	}

	Printf("Now serving the repository at %s\n", mountpoint)
	Printf("Don't forget to umount after quitting!\n")

	root := fs.Tree{}
	root.Add("snapshots", fuse.NewSnapshotsDir(repo, opts.OwnerRoot))

	debug.Log("serving mount at %v", mountpoint)
	err = fs.Serve(c, &root)
	if err != nil {
		return err
	}

	<-c.Ready
	return c.MountError
}