Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2efbf19c62 |
@@ -411,7 +411,6 @@ func ListZFSHoldsAndBookmarks(ctx context.Context, fsfilter zfs.DatasetFilter) (
|
|||||||
for _, fs := range fss {
|
for _, fs := range fss {
|
||||||
err := listZFSHoldsAndBookmarksImplFS(ctx, out, fs)
|
err := listZFSHoldsAndBookmarksImplFS(ctx, out, fs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME if _, ok := err.(*zfs.DatasetDoesNotExist); ok { noop }
|
|
||||||
return nil, errors.Wrapf(err, "list holds and bookmarks on %q", fs.ToString())
|
return nil, errors.Wrapf(err, "list holds and bookmarks on %q", fs.ToString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -421,8 +420,7 @@ func ListZFSHoldsAndBookmarks(ctx context.Context, fsfilter zfs.DatasetFilter) (
|
|||||||
func listZFSHoldsAndBookmarksImplFS(ctx context.Context, out *ListHoldsAndBookmarksOutput, fs *zfs.DatasetPath) error {
|
func listZFSHoldsAndBookmarksImplFS(ctx context.Context, out *ListHoldsAndBookmarksOutput, fs *zfs.DatasetPath) error {
|
||||||
fsvs, err := zfs.ZFSListFilesystemVersions(fs, nil)
|
fsvs, err := zfs.ZFSListFilesystemVersions(fs, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// FIXME if _, ok := err.(*zfs.DatasetDoesNotExist); ok { noop }
|
return errors.Wrapf(err, "list filesystem versions of %q", fs)
|
||||||
return errors.Wrapf(err, "list filesystem versions of %q", fs.ToString())
|
|
||||||
}
|
}
|
||||||
for _, v := range fsvs {
|
for _, v := range fsvs {
|
||||||
switch v.Type {
|
switch v.Type {
|
||||||
@@ -431,12 +429,7 @@ func listZFSHoldsAndBookmarksImplFS(ctx context.Context, out *ListHoldsAndBookma
|
|||||||
case zfs.Snapshot:
|
case zfs.Snapshot:
|
||||||
holds, err := zfs.ZFSHolds(ctx, fs.ToString(), v.Name)
|
holds, err := zfs.ZFSHolds(ctx, fs.ToString(), v.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if _, ok := err.(*zfs.DatasetDoesNotExist); ok {
|
return errors.Wrapf(err, "get holds of %q", v.ToAbsPath(fs))
|
||||||
holds = []string{}
|
|
||||||
// fallthrough
|
|
||||||
} else {
|
|
||||||
return errors.Wrapf(err, "get holds of %q", v.ToAbsPath(fs))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for _, tag := range holds {
|
for _, tag := range holds {
|
||||||
listZFSHoldsAndBookmarksImplSnapshotTryParseHold(ctx, out, fs, v, tag)
|
listZFSHoldsAndBookmarksImplSnapshotTryParseHold(ctx, out, fs, v, tag)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package tests
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
"github.com/zrepl/zrepl/platformtest"
|
"github.com/zrepl/zrepl/platformtest"
|
||||||
"github.com/zrepl/zrepl/zfs"
|
"github.com/zrepl/zrepl/zfs"
|
||||||
)
|
)
|
||||||
@@ -14,28 +13,35 @@ func IdempotentHold(ctx *platformtest.Context) {
|
|||||||
DESTROYROOT
|
DESTROYROOT
|
||||||
CREATEROOT
|
CREATEROOT
|
||||||
+ "foo bar"
|
+ "foo bar"
|
||||||
+ "foo bar@1 2"
|
+ "foo bar@1"
|
||||||
|
`)
|
||||||
|
defer platformtest.Run(ctx, platformtest.PanicErr, ctx.RootDataset, `
|
||||||
|
R zfs release zrepl_platformtest "${ROOTDS}/foo bar@1"
|
||||||
|
- "foo bar@1"
|
||||||
|
- "foo bar"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
fs := fmt.Sprintf("%s/foo bar", ctx.RootDataset)
|
fs := fmt.Sprintf("%s/foo bar", ctx.RootDataset)
|
||||||
snap := sendArgVersion(fs, "@1 2")
|
v1 := sendArgVersion(fs, "@1")
|
||||||
|
|
||||||
tag := "zrepl_platformtest"
|
tag := "zrepl_platformtest"
|
||||||
err := zfs.ZFSHold(ctx, fs, snap, tag)
|
err := zfs.ZFSHold(ctx, fs, v1, tag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// existing holds
|
err = zfs.ZFSHold(ctx, fs, v1, tag)
|
||||||
holds, err := zfs.ZFSHolds(ctx, fs, "1 2")
|
if err != nil {
|
||||||
require.NoError(ctx, err)
|
panic(err)
|
||||||
require.Equal(ctx, []string{tag}, holds)
|
}
|
||||||
|
|
||||||
|
vnonexistent := zfs.ZFSSendArgVersion{
|
||||||
|
RelName: "@nonexistent",
|
||||||
|
GUID: 0xbadf00d,
|
||||||
|
}
|
||||||
|
err = zfs.ZFSHold(ctx, fs, vnonexistent, tag)
|
||||||
|
if err == nil {
|
||||||
|
panic("still expecting error for nonexistent snapshot")
|
||||||
|
}
|
||||||
|
|
||||||
holds, err = zfs.ZFSHolds(ctx, fs, "non existent")
|
|
||||||
ctx.Logf("holds=%v", holds)
|
|
||||||
ctx.Logf("errT=%T", err)
|
|
||||||
ctx.Logf("err=%s", err)
|
|
||||||
notExist, ok := err.(*zfs.DatasetDoesNotExist)
|
|
||||||
require.True(ctx, ok)
|
|
||||||
require.Equal(ctx, fs+"@non existent", notExist.Path)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package tests
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/zrepl/zrepl/platformtest"
|
|
||||||
"github.com/zrepl/zrepl/zfs"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ListHolds(ctx *platformtest.Context) {
|
|
||||||
|
|
||||||
platformtest.Run(ctx, platformtest.PanicErr, ctx.RootDataset, `
|
|
||||||
DESTROYROOT
|
|
||||||
CREATEROOT
|
|
||||||
+ "foo bar"
|
|
||||||
+ "foo bar@1"
|
|
||||||
`)
|
|
||||||
defer platformtest.Run(ctx, platformtest.PanicErr, ctx.RootDataset, `
|
|
||||||
R zfs release zrepl_platformtest "${ROOTDS}/foo bar@1"
|
|
||||||
- "foo bar@1"
|
|
||||||
- "foo bar"
|
|
||||||
`)
|
|
||||||
|
|
||||||
fs := fmt.Sprintf("%s/foo bar", ctx.RootDataset)
|
|
||||||
v1 := sendArgVersion(fs, "@1")
|
|
||||||
|
|
||||||
tag := "zrepl_platformtest"
|
|
||||||
err := zfs.ZFSHold(ctx, fs, v1, tag)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = zfs.ZFSHold(ctx, fs, v1, tag)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
vnonexistent := zfs.ZFSSendArgVersion{
|
|
||||||
RelName: "@nonexistent",
|
|
||||||
GUID: 0xbadf00d,
|
|
||||||
}
|
|
||||||
err = zfs.ZFSHold(ctx, fs, vnonexistent, tag)
|
|
||||||
if err == nil {
|
|
||||||
panic("still expecting error for nonexistent snapshot")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -31,5 +31,4 @@ var Cases = []Case{
|
|||||||
SendArgsValidationEncryptedSendOfUnencryptedDatasetForbidden,
|
SendArgsValidationEncryptedSendOfUnencryptedDatasetForbidden,
|
||||||
SendArgsValidationResumeTokenEncryptionMismatchForbidden,
|
SendArgsValidationResumeTokenEncryptionMismatchForbidden,
|
||||||
SendArgsValidationResumeTokenDifferentFilesystemForbidden,
|
SendArgsValidationResumeTokenDifferentFilesystemForbidden,
|
||||||
ListHolds,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ success:
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the snapshot does not exist, the returned error is of type *DatasetDoesNotExist
|
|
||||||
func ZFSHolds(ctx context.Context, fs, snap string) ([]string, error) {
|
func ZFSHolds(ctx context.Context, fs, snap string) ([]string, error) {
|
||||||
if err := validateZFSFilesystem(fs); err != nil {
|
if err := validateZFSFilesystem(fs); err != nil {
|
||||||
return nil, errors.Wrap(err, "`fs` is not a valid filesystem path")
|
return nil, errors.Wrap(err, "`fs` is not a valid filesystem path")
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ type FilesystemPlaceholderState struct {
|
|||||||
// For nonexistent FS, err == nil and state.FSExists == false
|
// For nonexistent FS, err == nil and state.FSExists == false
|
||||||
func ZFSGetFilesystemPlaceholderState(p *DatasetPath) (state *FilesystemPlaceholderState, err error) {
|
func ZFSGetFilesystemPlaceholderState(p *DatasetPath) (state *FilesystemPlaceholderState, err error) {
|
||||||
state = &FilesystemPlaceholderState{FS: p.ToString()}
|
state = &FilesystemPlaceholderState{FS: p.ToString()}
|
||||||
state.FS = p.ToString()
|
|
||||||
props, err := zfsGet(p.ToString(), []string{PlaceholderPropertyName}, sourceLocal)
|
props, err := zfsGet(p.ToString(), []string{PlaceholderPropertyName}, sourceLocal)
|
||||||
var _ error = (*DatasetDoesNotExist)(nil) // weak assertion on zfsGet's interface
|
var _ error = (*DatasetDoesNotExist)(nil) // weak assertion on zfsGet's interface
|
||||||
if _, ok := err.(*DatasetDoesNotExist); ok {
|
if _, ok := err.(*DatasetDoesNotExist); ok {
|
||||||
|
|||||||
Reference in New Issue
Block a user