func TestRollback(t *testing.T) { zpoolTest(t, func() { f, err := zfs.CreateFilesystem("test/snapshot-test", nil) ok(t, err) filesystems, err := zfs.Filesystems("") ok(t, err) for _, filesystem := range filesystems { equals(t, zfs.DatasetFilesystem, filesystem.Type) } s1, err := f.Snapshot("test", false) ok(t, err) _, err = f.Snapshot("test2", false) ok(t, err) s3, err := f.Snapshot("test3", false) ok(t, err) err = s3.Rollback(false) ok(t, err) err = s1.Rollback(false) assert(t, err != nil, "should error when rolling back beyond most recent without destroyMoreRecent = true") err = s1.Rollback(true) ok(t, err) ok(t, s1.Destroy(zfs.DestroyDefault)) ok(t, f.Destroy(zfs.DestroyDefault)) }) }
func TestSendSnapshot(t *testing.T) { zpoolTest(t, func() { f, err := zfs.CreateFilesystem("test/snapshot-test", nil) ok(t, err) filesystems, err := zfs.Filesystems("") ok(t, err) for _, filesystem := range filesystems { equals(t, zfs.DatasetFilesystem, filesystem.Type) } s, err := f.Snapshot("test", false) ok(t, err) file, _ := ioutil.TempFile("/tmp/", "zfs-") defer file.Close() err = file.Truncate(pow2(30)) ok(t, err) defer os.Remove(file.Name()) err = s.SendSnapshot(file) ok(t, err) ok(t, s.Destroy(zfs.DestroyDefault)) ok(t, f.Destroy(zfs.DestroyDefault)) }) }
func TestClone(t *testing.T) { zpoolTest(t, func() { f, err := zfs.CreateFilesystem("test/snapshot-test", nil) ok(t, err) filesystems, err := zfs.Filesystems("") ok(t, err) for _, filesystem := range filesystems { equals(t, zfs.DatasetFilesystem, filesystem.Type) } s, err := f.Snapshot("test", false) ok(t, err) equals(t, zfs.DatasetSnapshot, s.Type) equals(t, "test/snapshot-test@test", s.Name) c, err := s.Clone("test/clone-test", nil) ok(t, err) equals(t, zfs.DatasetFilesystem, c.Type) ok(t, c.Destroy(zfs.DestroyDefault)) ok(t, s.Destroy(zfs.DestroyDefault)) ok(t, f.Destroy(zfs.DestroyDefault)) }) }
func TestFilesystems(t *testing.T) { zpoolTest(t, func() { f, err := zfs.CreateFilesystem("test/filesystem-test", nil) ok(t, err) filesystems, err := zfs.Filesystems("") ok(t, err) for _, filesystem := range filesystems { equals(t, zfs.DatasetFilesystem, filesystem.Type) } ok(t, f.Destroy(zfs.DestroyDefault)) }) }
func TestCreateFilesystemWithProperties(t *testing.T) { zpoolTest(t, func() { props := map[string]string{ "compression": "lz4", } f, err := zfs.CreateFilesystem("test/filesystem-test", props) ok(t, err) equals(t, "lz4", f.Compression) filesystems, err := zfs.Filesystems("") ok(t, err) for _, filesystem := range filesystems { equals(t, zfs.DatasetFilesystem, filesystem.Type) } ok(t, f.Destroy(zfs.DestroyDefault)) }) }
// Init returns a new ZFS driver. // It takes base mount path and an array of options which are represented as key value pairs. // Each option is in the for key=value. 'zfs.fsname' is expected to be a valid key in the options. func Init(base string, opt []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) { var err error if _, err := exec.LookPath("zfs"); err != nil { logrus.Debugf("[zfs] zfs command is not available: %v", err) return nil, graphdriver.ErrPrerequisites } file, err := os.OpenFile("/dev/zfs", os.O_RDWR, 600) if err != nil { logrus.Debugf("[zfs] cannot open /dev/zfs: %v", err) return nil, graphdriver.ErrPrerequisites } defer file.Close() options, err := parseOptions(opt) if err != nil { return nil, err } options.mountPath = base rootdir := path.Dir(base) if options.fsName == "" { err = checkRootdirFs(rootdir) if err != nil { return nil, err } } if options.fsName == "" { options.fsName, err = lookupZfsDataset(rootdir) if err != nil { return nil, err } } zfs.SetLogger(new(Logger)) filesystems, err := zfs.Filesystems(options.fsName) if err != nil { return nil, fmt.Errorf("Cannot find root filesystem %s: %v", options.fsName, err) } filesystemsCache := make(map[string]bool, len(filesystems)) var rootDataset *zfs.Dataset for _, fs := range filesystems { if fs.Name == options.fsName { rootDataset = fs } filesystemsCache[fs.Name] = true } if rootDataset == nil { return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName) } rootUID, rootGID, err := idtools.GetRootUIDGID(uidMaps, gidMaps) if err != nil { return nil, fmt.Errorf("Failed to get root uid/guid: %v", err) } if err := idtools.MkdirAllAs(base, 0700, rootUID, rootGID); err != nil { return nil, fmt.Errorf("Failed to create '%s': %v", base, err) } if err := mount.MakePrivate(base); err != nil { return nil, err } d := &Driver{ dataset: rootDataset, options: options, filesystemsCache: filesystemsCache, uidMaps: uidMaps, gidMaps: gidMaps, ctr: graphdriver.NewRefCounter(graphdriver.NewDefaultChecker()), } return graphdriver.NewNaiveDiffDriver(d, uidMaps, gidMaps), nil }
// Init returns a new ZFS driver. // It takes base mount path and a array of options which are represented as key value pairs. // Each option is in the for key=value. 'zfs.fsname' is expected to be a valid key in the options. func Init(base string, opt []string) (graphdriver.Driver, error) { var err error if _, err := exec.LookPath("zfs"); err != nil { logrus.Debugf("[zfs] zfs command is not available: %v", err) return nil, graphdriver.ErrPrerequisites } file, err := os.OpenFile("/dev/zfs", os.O_RDWR, 600) if err != nil { logrus.Debugf("[zfs] cannot open /dev/zfs: %v", err) return nil, graphdriver.ErrPrerequisites } defer file.Close() options, err := parseOptions(opt) if err != nil { return nil, err } options.mountPath = base rootdir := path.Dir(base) if options.fsName == "" { err = checkRootdirFs(rootdir) if err != nil { return nil, err } } if options.fsName == "" { options.fsName, err = lookupZfsDataset(rootdir) if err != nil { return nil, err } } zfs.SetLogger(new(Logger)) filesystems, err := zfs.Filesystems(options.fsName) if err != nil { return nil, fmt.Errorf("Cannot find root filesystem %s: %v", options.fsName, err) } filesystemsCache := make(map[string]bool, len(filesystems)) var rootDataset *zfs.Dataset for _, fs := range filesystems { if fs.Name == options.fsName { rootDataset = fs } filesystemsCache[fs.Name] = true } if rootDataset == nil { return nil, fmt.Errorf("BUG: zfs get all -t filesystem -rHp '%s' should contain '%s'", options.fsName, options.fsName) } d := &Driver{ dataset: rootDataset, options: options, filesystemsCache: filesystemsCache, } return graphdriver.NaiveDiffDriver(d), nil }