-
Notifications
You must be signed in to change notification settings - Fork 152
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(block): add snapshot wait command (#4455)
- Loading branch information
Showing
19 changed files
with
1,338 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
cmd/scw/testdata/test-all-usage-block-snapshot-wait-usage.golden
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
🎲🎲🎲 EXIT CODE: 0 🎲🎲🎲 | ||
🟥🟥🟥 STDERR️️ 🟥🟥🟥️ | ||
Wait for snapshot to reach a stable state. This is similar to using --wait flag on other action commands, but without requiring a new action on the snapshot. | ||
|
||
USAGE: | ||
scw block snapshot wait <snapshot-id ...> [arg=value ...] | ||
|
||
EXAMPLES: | ||
Wait for a snapshot to be available | ||
scw block snapshot wait 11111111-1111-1111-1111-111111111111 terminal-status=available | ||
|
||
ARGS: | ||
[timeout=5m0s] Timeout of the wait | ||
snapshot-id ID of the snapshot affected by the action. | ||
[terminal-status] Expected terminal status, will wait until this status is reached. (unknown_status | creating | available | error | deleting | deleted | in_use | locked | exporting) | ||
[zone=fr-par-1] Zone to target. If none is passed will use default zone from the config (fr-par-1 | fr-par-2 | fr-par-3 | nl-ams-1 | nl-ams-2 | nl-ams-3 | pl-waw-1 | pl-waw-2 | pl-waw-3) | ||
|
||
FLAGS: | ||
-h, --help help for wait | ||
|
||
GLOBAL FLAGS: | ||
-c, --config string The path to the config file | ||
-D, --debug Enable debug mode | ||
-o, --output string Output format: json or human, see 'scw help output' for more info (default "human") | ||
-p, --profile string The config profile to use |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package block | ||
|
||
import ( | ||
"context" | ||
"reflect" | ||
"time" | ||
|
||
"github.com/scaleway/scaleway-cli/v2/core" | ||
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" | ||
"github.com/scaleway/scaleway-sdk-go/api/instance/v1" | ||
"github.com/scaleway/scaleway-sdk-go/scw" | ||
) | ||
|
||
const ( | ||
snapshotActionTimeout = 5 * time.Minute | ||
) | ||
|
||
type snapshotWaitRequest struct { | ||
Zone scw.Zone | ||
SnapshotID string | ||
Timeout time.Duration | ||
|
||
TerminalStatus *block.SnapshotStatus | ||
} | ||
|
||
func snapshotWaitCommand() *core.Command { | ||
snapshotsStatuses := block.SnapshotStatus("").Values() | ||
snapshotsStatusStrings := make([]string, len(snapshotsStatuses)) | ||
for k, v := range snapshotsStatuses { | ||
snapshotsStatusStrings[k] = v.String() | ||
} | ||
|
||
return &core.Command{ | ||
Short: `Wait for snapshot to reach a stable state`, | ||
Long: `Wait for snapshot to reach a stable state. This is similar to using --wait flag on other action commands, but without requiring a new action on the snapshot.`, | ||
Namespace: "block", | ||
Resource: "snapshot", | ||
Verb: "wait", | ||
Groups: []string{"workflow"}, | ||
ArgsType: reflect.TypeOf(snapshotWaitRequest{}), | ||
Run: func(ctx context.Context, argsI interface{}) (i interface{}, err error) { | ||
args := argsI.(*snapshotWaitRequest) | ||
|
||
return block.NewAPI(core.ExtractClient(ctx)).WaitForSnapshot(&block.WaitForSnapshotRequest{ | ||
Zone: args.Zone, | ||
SnapshotID: args.SnapshotID, | ||
Timeout: scw.TimeDurationPtr(args.Timeout), | ||
RetryInterval: core.DefaultRetryInterval, | ||
|
||
TerminalStatus: args.TerminalStatus, | ||
}) | ||
}, | ||
ArgSpecs: core.ArgSpecs{ | ||
core.WaitTimeoutArgSpec(snapshotActionTimeout), | ||
{ | ||
Name: "snapshot-id", | ||
Short: `ID of the snapshot affected by the action.`, | ||
Required: true, | ||
Positional: true, | ||
}, | ||
{ | ||
Name: "terminal-status", | ||
Short: `Expected terminal status, will wait until this status is reached.`, | ||
EnumValues: snapshotsStatusStrings, | ||
}, | ||
core.ZoneArgSpec((*instance.API)(nil).Zones()...), | ||
}, | ||
Examples: []*core.Example{ | ||
{ | ||
Short: "Wait for a snapshot to be available", | ||
ArgsJSON: `{"snapshot_id": "11111111-1111-1111-1111-111111111111", "terminal_status": "available"}`, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func blockSnapshotCreateBuilder(c *core.Command) *core.Command { | ||
c.WaitFunc = func(ctx context.Context, _, respI interface{}) (interface{}, error) { | ||
resp := respI.(*block.Snapshot) | ||
|
||
return block.NewAPI(core.ExtractClient(ctx)).WaitForSnapshot(&block.WaitForSnapshotRequest{ | ||
SnapshotID: resp.ID, | ||
Zone: resp.Zone, | ||
}) | ||
} | ||
|
||
return c | ||
} |
49 changes: 49 additions & 0 deletions
49
internal/namespaces/block/v1alpha1/custom_snapshot_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package block_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/scaleway/scaleway-cli/v2/core" | ||
block "github.com/scaleway/scaleway-cli/v2/internal/namespaces/block/v1alpha1" | ||
"github.com/scaleway/scaleway-cli/v2/internal/testhelpers" | ||
blockSDK "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_SnapshotWait(t *testing.T) { | ||
t.Run("Wait command", core.Test(&core.TestConfig{ | ||
Commands: block.GetCommands(), | ||
BeforeFunc: core.BeforeFuncCombine( | ||
core.ExecStoreBeforeCmd("Volume", "scw block volume create perf-iops=5000 from-empty.size=20GB -w"), | ||
core.ExecStoreBeforeCmd("Snapshot", "scw block snapshot create volume-id={{ .Volume.ID }}"), | ||
), | ||
Cmd: "scw block snapshot wait {{ .Snapshot.ID }}", | ||
Check: core.TestCheckCombine( | ||
core.TestCheckGolden(), | ||
core.TestCheckExitCode(0), | ||
), | ||
AfterFunc: core.AfterFuncCombine( | ||
deleteSnapshot("Snapshot"), | ||
deleteVolume("Volume"), | ||
), | ||
})) | ||
|
||
t.Run("Wait flag", core.Test(&core.TestConfig{ | ||
Commands: block.GetCommands(), | ||
BeforeFunc: core.ExecStoreBeforeCmd("Volume", "scw block volume create perf-iops=5000 from-empty.size=20GB -w"), | ||
Cmd: "scw block snapshot create volume-id={{ .Volume.ID }} -w", | ||
Check: core.TestCheckCombine( | ||
func(t *testing.T, ctx *core.CheckFuncCtx) { | ||
t.Helper() | ||
snap := testhelpers.Value[*blockSDK.Snapshot](t, ctx.Result) | ||
require.Equal(t, blockSDK.SnapshotStatusAvailable, snap.Status) | ||
}, | ||
core.TestCheckGolden(), | ||
core.TestCheckExitCode(0), | ||
), | ||
AfterFunc: core.AfterFuncCombine( | ||
deleteSnapshot("CmdResult"), | ||
deleteVolume("Volume"), | ||
), | ||
})) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package block_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/scaleway/scaleway-cli/v2/core" | ||
block "github.com/scaleway/scaleway-cli/v2/internal/namespaces/block/v1alpha1" | ||
"github.com/scaleway/scaleway-cli/v2/internal/testhelpers" | ||
blockSDK "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_VolumeWait(t *testing.T) { | ||
t.Run("Wait command", core.Test(&core.TestConfig{ | ||
Commands: block.GetCommands(), | ||
BeforeFunc: core.BeforeFuncCombine( | ||
core.ExecStoreBeforeCmd("Volume", "scw block volume create perf-iops=5000 from-empty.size=20GB"), | ||
), | ||
Cmd: "scw block volume wait {{ .Volume.ID }}", | ||
Check: core.TestCheckCombine( | ||
core.TestCheckGolden(), | ||
core.TestCheckExitCode(0), | ||
), | ||
AfterFunc: deleteVolume("Volume"), | ||
})) | ||
|
||
t.Run("Wait flag", core.Test(&core.TestConfig{ | ||
Commands: block.GetCommands(), | ||
Cmd: "scw block volume create perf-iops=5000 from-empty.size=20GB -w", | ||
Check: core.TestCheckCombine( | ||
func(t *testing.T, ctx *core.CheckFuncCtx) { | ||
t.Helper() | ||
vol := testhelpers.Value[*blockSDK.Volume](t, ctx.Result) | ||
require.Equal(t, blockSDK.VolumeStatusAvailable, vol.Status) | ||
}, | ||
core.TestCheckGolden(), | ||
core.TestCheckExitCode(0), | ||
), | ||
AfterFunc: deleteVolume("CmdResult"), | ||
})) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package block_test | ||
|
||
import "github.com/scaleway/scaleway-cli/v2/core" | ||
|
||
// deleteVolume deletes a volume. | ||
// metaKey must be the key in meta where the volume state is stored. | ||
func deleteVolume(metaKey string) core.AfterFunc { | ||
return core.ExecAfterCmd("scw block volume delete {{." + metaKey + ".ID}}") | ||
} | ||
|
||
// deleteSnapshot deletes a snapshot. | ||
// metaKey must be the key in meta where the volume state is stored. | ||
func deleteSnapshot(metaKey string) core.AfterFunc { | ||
return core.ExecAfterCmd("scw block snapshot delete {{." + metaKey + ".ID}}") | ||
} |
Oops, something went wrong.