Beispiel #1
0
func setup_dir(t testing.TB, chunkStore chunks.Store, dirents []*wire.Dirent) *wire.Dirent {
	blob, err := blobs.Open(
		chunkStore,
		blobs.EmptyManifest("dir"),
	)
	if err != nil {
		t.Fatalf("unexpected blob open error: %v", err)
	}
	w := snap.NewWriter(blob)
	for _, de := range dirents {
		err := w.Add(de)
		if err != nil {
			t.Fatalf("unexpected add error: %v", err)
		}
	}
	manifest, err := blob.Save()
	if err != nil {
		t.Fatalf("unexpected save error: %v", err)
	}
	var de wire.Dirent
	de.Type.Dir = &wire.Dir{
		Manifest: wirecas.FromBlob(manifest),
	}
	return &de
}
Beispiel #2
0
func TestTwoLevels(t *testing.T) {
	tmp := tempdir.New(t)
	defer tmp.Cleanup()

	setup_fs := func() fs.FS {
		chunkStore := &mock.InMemory{}
		greeting := setup_greeting(t, chunkStore)
		dir1 := setup_dir(t, chunkStore, []*wire.Dirent{
			&wire.Dirent{
				Name: "hello",
				Type: wire.Type{
					File: &wire.File{
						Manifest: wirecas.FromBlob(greeting),
					},
				},
				// Space:   uint64(len(GREETING)),
				// Written: TIME_1,
			},
		})
		dir1.Name = "second"
		dir2 := setup_dir(t, chunkStore, []*wire.Dirent{dir1})

		filesys, err := newFS(chunkStore, dir2.Type.Dir)
		if err != nil {
			t.Fatalf("cannot serve snapshot as FUSE: %v", err)
		}
		return filesys
	}
	filesys := setup_fs()

	mnt, err := fstestutil.MountedT(t, filesys)
	if err != nil {
		t.Fatalf("Mount fail: %v\n", err)
	}
	defer mnt.Close()

	hello_path := path.Join(mnt.Dir, "second", "hello")
	f, err := os.Open(hello_path)
	if err != nil {
		t.Fatalf("hello open failed with %v", err)
	}
	buf, err := ioutil.ReadAll(f)
	if err != nil {
		t.Errorf("hello read failed with %v", err)
	}
	if string(buf) != GREETING {
		t.Errorf("hello read wrong content: %q", string(buf))
	}
	err = f.Close()
	if err != nil {
		t.Fatalf("hello close failed with %v", err)
	}
}
Beispiel #3
0
func (f *file) marshalInternal() (*wire.Dirent, error) {
	de := &wire.Dirent{
		Inode: f.inode,
	}
	manifest, err := f.blob.Save()
	if err != nil {
		return nil, err
	}
	de.File = &wire.File{
		Manifest: wirecas.FromBlob(manifest),
	}
	return de, nil
}
Beispiel #4
0
func setup_fs(t *testing.T) fs.FS {
	chunkStore := &mock.InMemory{}

	greeting := setup_greeting(t, chunkStore)
	dir := setup_dir(t, chunkStore, []*wire.Dirent{
		&wire.Dirent{
			Name: "hello",
			File: &wire.File{
				Manifest: wirecas.FromBlob(greeting),
			},
			// Space:   uint64(len(GREETING)),
			// Written: TIME_1,
		},
	})

	filesys, err := newFS(chunkStore, dir)
	if err != nil {
		t.Fatalf("cannot serve snapshot as FUSE: %v", err)
	}
	return filesys
}
Beispiel #5
0
// snapshot records a snapshot of the directory and stores it in wde
func (d *dir) snapshot(tx *bolt.Tx, out *wiresnap.Dir, intr fs.Intr) error {
	// NOT HOLDING THE LOCK, accessing database snapshot ONLY

	// TODO move bucket lookup to caller?
	bucket := d.fs.bucket(tx).Bucket(bucketDir)
	if bucket == nil {
		return errors.New("dir bucket missing")
	}

	manifest := blobs.EmptyManifest("dir")
	blob, err := blobs.Open(d.fs.chunkStore, manifest)
	if err != nil {
		return err
	}
	w := snap.NewWriter(blob)

	c := bucket.Cursor()
	prefix := pathToKey(d.inode, "")
	for k, v := c.Seek(prefix); k != nil; k, v = c.Next() {
		if !bytes.HasPrefix(k, prefix) {
			// past the end of the directory
			break
		}

		name := string(k[len(prefix):])
		de, err := d.unmarshalDirent(v)
		if err != nil {
			return err
		}
		sde := wiresnap.Dirent{
			Name: name,
		}
		switch {
		case de.Type.File != nil:
			// TODO d.reviveNode would do blobs.Open and that's a bit
			// too much work; rework the apis
			sde.Type.File = &wiresnap.File{
				Manifest: de.Type.File.Manifest,
			}
		case de.Type.Dir != nil:
			child, err := d.reviveDir(de, name)
			if err != nil {
				return err
			}
			sde.Type.Dir = &wiresnap.Dir{}
			err = child.snapshot(tx, sde.Type.Dir, intr)
			if err != nil {
				return err
			}
		default:
			return errors.New("TODO")
		}
		err = w.Add(&sde)
		if err != nil {
			return err
		}
	}

	manifest, err = blob.Save()
	if err != nil {
		return err
	}
	out.Manifest = wirecas.FromBlob(manifest)
	out.Align = w.Align()
	return nil
}