Skip to content

Commit 018dc90

Browse files
Mia-CrossLaure-di
authored andcommitted
fix(instance): delete sbs volumes on instance termination (scaleway#4848)
1 parent 5d02211 commit 018dc90

9 files changed

+8539
-5653
lines changed

internal/namespaces/instance/v1/custom_server_action.go

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ import (
55
"errors"
66
"fmt"
77
"reflect"
8+
"sort"
89
"strings"
910

1011
"github.com/scaleway/scaleway-cli/v2/core"
1112
"github.com/scaleway/scaleway-cli/v2/internal/interactive"
13+
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
1214
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
1315
"github.com/scaleway/scaleway-sdk-go/scw"
1416
)
@@ -394,6 +396,46 @@ func serverTerminateCommand() *core.Command {
394396
}
395397
_, _ = interactive.Printf("successfully detached volume %s\n", volumeName)
396398
}
399+
} else {
400+
successMessages := make(map[string]string)
401+
402+
for index, volume := range server.Server.Volumes {
403+
if volume.VolumeType != instance.VolumeServerVolumeTypeSbsVolume {
404+
continue
405+
}
406+
407+
_, err = api.DetachVolume(&instance.DetachVolumeRequest{
408+
VolumeID: volume.ID,
409+
Zone: volume.Zone,
410+
}, scw.WithContext(ctx))
411+
if err != nil {
412+
return nil, fmt.Errorf("failed to detach block volume %s: %w", volume.ID, err)
413+
}
414+
415+
blockAPI := block.NewAPI(client)
416+
terminalStatus := block.VolumeStatusAvailable
417+
418+
blockVolume, err := blockAPI.WaitForVolume(&block.WaitForVolumeRequest{
419+
VolumeID: volume.ID,
420+
Zone: volume.Zone,
421+
TerminalStatus: &terminalStatus,
422+
})
423+
if err != nil {
424+
return nil, fmt.Errorf("failed to wait for block volume %s: %w", volume.ID, err)
425+
}
426+
427+
err = blockAPI.DeleteVolume(&block.DeleteVolumeRequest{
428+
VolumeID: blockVolume.ID,
429+
Zone: blockVolume.Zone,
430+
}, scw.WithContext(ctx))
431+
if err != nil {
432+
return nil, fmt.Errorf("failed to delete block volume %s: %w", blockVolume.Name, err)
433+
}
434+
435+
successMessages[index] = fmt.Sprintf("successfully deleted block volume %q", blockVolume.Name)
436+
}
437+
438+
printSuccessMessagesInOrder(successMessages)
397439
}
398440

399441
if _, err := api.ServerAction(&instance.ServerActionRequest{
@@ -439,7 +481,8 @@ func shouldDeleteBlockVolumes(
439481
case withBlockPrompt:
440482
// Only prompt user if at least one block volume is attached to the instance
441483
for _, volume := range server.Server.Volumes {
442-
if volume.VolumeType != instance.VolumeServerVolumeTypeBSSD {
484+
if volume.VolumeType != instance.VolumeServerVolumeTypeBSSD &&
485+
volume.VolumeType != instance.VolumeServerVolumeTypeSbsVolume {
443486
continue
444487
}
445488

@@ -456,6 +499,19 @@ func shouldDeleteBlockVolumes(
456499
}
457500
}
458501

502+
// printSuccessMessagesInOrder prints volume deletion messages ordered by volume map key "0", "1", "2",...
503+
func printSuccessMessagesInOrder(messages map[string]string) {
504+
indexes := []string(nil)
505+
for index := range messages {
506+
indexes = append(indexes, index)
507+
}
508+
sort.Strings(indexes)
509+
510+
for _, index := range indexes {
511+
_, _ = interactive.Println(messages[index])
512+
}
513+
}
514+
459515
type instanceUniqueActionRequest struct {
460516
Zone scw.Zone
461517
ServerID string

internal/namespaces/instance/v1/custom_server_action_test.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
block "github.com/scaleway/scaleway-cli/v2/internal/namespaces/block/v1alpha1"
99
"github.com/scaleway/scaleway-cli/v2/internal/namespaces/instance/v1"
1010
"github.com/scaleway/scaleway-cli/v2/internal/testhelpers"
11+
blockSDK "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
1112
instanceSDK "github.com/scaleway/scaleway-sdk-go/api/instance/v1"
1213
"github.com/scaleway/scaleway-sdk-go/scw"
1314
"github.com/stretchr/testify/assert"
@@ -25,7 +26,7 @@ func Test_ServerTerminate(t *testing.T) {
2526
"Server",
2627
testServerCommand("image=ubuntu-jammy ip=new -w"),
2728
),
28-
Cmd: `scw instance server terminate {{ .Server.ID }}`,
29+
Cmd: `scw instance server terminate {{ .Server.ID }} with-block=true`,
2930
Check: core.TestCheckCombine(
3031
core.TestCheckGolden(),
3132
core.TestCheckExitCode(0),
@@ -56,7 +57,7 @@ func Test_ServerTerminate(t *testing.T) {
5657
"Server",
5758
testServerCommand("image=ubuntu-jammy ip=new -w"),
5859
),
59-
Cmd: `scw instance server terminate {{ .Server.ID }} with-ip=true`,
60+
Cmd: `scw instance server terminate {{ .Server.ID }} with-ip=true with-block=true`,
6061
Check: core.TestCheckCombine(
6162
core.TestCheckGolden(),
6263
core.TestCheckExitCode(0),
@@ -98,6 +99,10 @@ func Test_ServerTerminate(t *testing.T) {
9899
`scw block volume wait terminal-status=available {{ (index .Server.Volumes "1").ID }}`,
99100
),
100101
core.ExecAfterCmd(`scw block volume delete {{ (index .Server.Volumes "1").ID }}`),
102+
core.ExecAfterCmd(
103+
`scw block volume wait terminal-status=available {{ (index .Server.Volumes "0").ID }}`,
104+
),
105+
core.ExecAfterCmd(`scw block volume delete {{ (index .Server.Volumes "0").ID }}`),
101106
),
102107
DisableParallel: true,
103108
}))
@@ -114,16 +119,23 @@ func Test_ServerTerminate(t *testing.T) {
114119
core.TestCheckExitCode(0),
115120
func(t *testing.T, ctx *core.CheckFuncCtx) {
116121
t.Helper()
117-
api := instanceSDK.NewAPI(ctx.Client)
122+
api := blockSDK.NewAPI(ctx.Client)
118123
server := testhelpers.MapValue[*instance.ServerWithWarningsResponse](
119124
t,
120125
ctx.Meta,
121126
"Server",
122127
).Server
123-
volume := testhelpers.MapTValue(t, server.Volumes, "0")
128+
rootVolume := testhelpers.MapTValue(t, server.Volumes, "0")
129+
130+
_, err := api.GetVolume(&blockSDK.GetVolumeRequest{
131+
VolumeID: rootVolume.ID,
132+
Zone: server.Zone,
133+
})
134+
require.IsType(t, &scw.ResourceNotFoundError{}, err)
124135

125-
_, err := api.GetVolume(&instanceSDK.GetVolumeRequest{
126-
VolumeID: volume.ID,
136+
additionalVolume := testhelpers.MapTValue(t, server.Volumes, "1")
137+
_, err = api.GetVolume(&blockSDK.GetVolumeRequest{
138+
VolumeID: additionalVolume.ID,
127139
Zone: server.Zone,
128140
})
129141
require.IsType(t, &scw.ResourceNotFoundError{}, err)

0 commit comments

Comments
 (0)