Skip to content

Commit c345fba

Browse files
Codelaxremyleone
andauthored
feat(instance): handle sbs volumes in server backup (scaleway#4248)
Co-authored-by: Rémy Léone <[email protected]>
1 parent 180a2ae commit c345fba

File tree

5 files changed

+2150
-13
lines changed

5 files changed

+2150
-13
lines changed

internal/namespaces/instance/v1/custom_image.go

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/fatih/color"
1111
"github.com/scaleway/scaleway-cli/v2/core"
1212
"github.com/scaleway/scaleway-cli/v2/internal/human"
13+
block "github.com/scaleway/scaleway-sdk-go/api/block/v1alpha1"
1314
"github.com/scaleway/scaleway-sdk-go/api/instance/v1"
1415
"github.com/scaleway/scaleway-sdk-go/scw"
1516
)
@@ -246,6 +247,7 @@ func imageDeleteBuilder(c *core.Command) *core.Command {
246247
args := argsI.(*customDeleteImageRequest)
247248

248249
api := instance.NewAPI(core.ExtractClient(ctx))
250+
blockAPI := block.NewAPI(core.ExtractClient(ctx))
249251

250252
// If we want to delete snapshot we must GET image before we delete it
251253
image := (*instance.Image)(nil)
@@ -266,21 +268,49 @@ func imageDeleteBuilder(c *core.Command) *core.Command {
266268
return nil, err
267269
}
268270

271+
type UnknownSnapshot struct {
272+
ID string
273+
Type instance.VolumeVolumeType
274+
}
275+
269276
// Once the image is deleted we can delete snapshots.
270277
if args.WithSnapshots {
271-
snapshotIDs := []string{
272-
image.RootVolume.ID,
278+
snapshots := []UnknownSnapshot{
279+
{
280+
ID: image.RootVolume.ID,
281+
Type: image.RootVolume.VolumeType,
282+
},
273283
}
274-
for _, snapshot := range image.ExtraVolumes {
275-
snapshotIDs = append(snapshotIDs, snapshot.ID)
276-
}
277-
for _, snapshotID := range snapshotIDs {
278-
err := api.DeleteSnapshot(&instance.DeleteSnapshotRequest{
279-
Zone: args.Zone,
280-
SnapshotID: snapshotID,
284+
for _, extraVolume := range image.ExtraVolumes {
285+
snapshots = append(snapshots, UnknownSnapshot{
286+
ID: extraVolume.ID,
287+
Type: extraVolume.VolumeType,
281288
})
282-
if err != nil {
283-
return nil, err
289+
}
290+
for _, snapshot := range snapshots {
291+
if snapshot.Type == instance.VolumeVolumeTypeSbsSnapshot {
292+
_, err := blockAPI.WaitForSnapshot(&block.WaitForSnapshotRequest{
293+
SnapshotID: snapshot.ID,
294+
Zone: args.Zone,
295+
})
296+
if err != nil {
297+
return nil, err
298+
}
299+
err = blockAPI.DeleteSnapshot(&block.DeleteSnapshotRequest{
300+
Zone: args.Zone,
301+
SnapshotID: snapshot.ID,
302+
})
303+
if err != nil {
304+
return nil, err
305+
}
306+
} else {
307+
err := api.DeleteSnapshot(&instance.DeleteSnapshotRequest{
308+
Zone: args.Zone,
309+
SnapshotID: snapshot.ID,
310+
})
311+
if err != nil {
312+
return nil, err
313+
}
284314
}
285315
}
286316
}

internal/namespaces/instance/v1/custom_server_action.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,14 @@ Once your image is ready you will be able to create a new server based on this i
177177
VolumeType: instance.SnapshotVolumeTypeUnified,
178178
}
179179
} else {
180-
template = &instance.ServerActionRequestVolumeBackupTemplate{
181-
VolumeType: instance.SnapshotVolumeType(v.VolumeType),
180+
if v.VolumeType == instance.VolumeServerVolumeTypeSbsVolume {
181+
template = &instance.ServerActionRequestVolumeBackupTemplate{
182+
VolumeType: instance.SnapshotVolumeType("sbs_snapshot"),
183+
}
184+
} else {
185+
template = &instance.ServerActionRequestVolumeBackupTemplate{
186+
VolumeType: instance.SnapshotVolumeType(v.VolumeType),
187+
}
182188
}
183189
}
184190
req.Volumes[v.ID] = template

internal/namespaces/instance/v1/custom_server_action_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,20 @@ func Test_ServerBackup(t *testing.T) {
114114
core.ExecAfterCmd("scw instance server delete {{ .Server.ID }} with-ip=true with-volumes=local"),
115115
),
116116
}))
117+
118+
t.Run("With SBS volumes", core.Test(&core.TestConfig{
119+
Commands: instance.GetCommands(),
120+
BeforeFunc: core.ExecStoreBeforeCmd("Server", testServerCommand("root-volume=sbs:20G stopped=true image=ubuntu-jammy")),
121+
Cmd: `scw instance server backup {{ .Server.ID }} name=backup`,
122+
Check: core.TestCheckCombine(
123+
core.TestCheckGolden(),
124+
core.TestCheckExitCode(0),
125+
),
126+
AfterFunc: core.AfterFuncCombine(
127+
core.ExecAfterCmd("scw instance image delete {{ .CmdResult.Image.ID }} with-snapshots=true"),
128+
core.ExecAfterCmd("scw instance server delete {{ .Server.ID }} with-ip=true with-volumes=local"),
129+
),
130+
}))
117131
}
118132

119133
func Test_ServerAction(t *testing.T) {

0 commit comments

Comments
 (0)