Skip to content

Commit bf761bf

Browse files
tormath1remyleone
andauthored
feat(instance): support snapshot based instance (#3787)
Signed-off-by: Mathieu Tortuyaux <[email protected]> Co-authored-by: Rémy Léone <[email protected]>
1 parent 6790095 commit bf761bf

File tree

3 files changed

+38
-14
lines changed

3 files changed

+38
-14
lines changed

cmd/scw/testdata/test-all-usage-instance-server-create-usage.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ EXAMPLES:
2121
Create an instance with volumes from snapshots
2222
scw instance server create image=ubuntu_focal root-volume=local:<snapshot_id> additional-volumes.0=block:<snapshot_id>
2323

24+
Create and start an instance from a snapshot
25+
scw instance server create image=none root-volume=local:<snapshot_id>
26+
2427
Use an existing IP
2528
ip=$(scw instance ip create | grep id | awk '{ print $2 }')
2629
scw instance server create image=ubuntu_focal ip=$ip

docs/commands/instance.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,6 +1754,11 @@ Create an instance with volumes from snapshots
17541754
scw instance server create image=ubuntu_focal root-volume=local:<snapshot_id> additional-volumes.0=block:<snapshot_id>
17551755
```
17561756

1757+
Create and start an instance from a snapshot
1758+
```
1759+
scw instance server create image=none root-volume=local:<snapshot_id>
1760+
```
1761+
17571762
Use an existing IP
17581763
```
17591764
ip=$(scw instance ip create | grep id | awk '{ print $2 }')

internal/namespaces/instance/v1/custom_server_create.go

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ func serverCreateCommand() *core.Command {
168168
Short: "Create an instance with volumes from snapshots",
169169
ArgsJSON: `{"image":"ubuntu_focal","root_volume":"local:<snapshot_id>","additional_volumes":["block:<snapshot_id>"]}`,
170170
},
171+
{
172+
Short: "Create and start an instance from a snapshot",
173+
ArgsJSON: `{"image":"none","root_volume":"local:<snapshot_id>"}`,
174+
},
171175
{
172176
Short: "Use an existing IP",
173177
Raw: `ip=$(scw instance ip create | grep id | awk '{ print $2 }')
@@ -231,6 +235,8 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
231235
// - An image label
232236
//
233237
switch {
238+
case args.Image == "none":
239+
break
234240
case !validation.IsUUID(args.Image):
235241
// For retro-compatibility, we replace dashes with underscores
236242
imageLabel := strings.Replace(args.Image, "-", "_", -1)
@@ -250,22 +256,32 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
250256
serverReq.Image = args.Image
251257
}
252258

253-
getImageResponse, err := apiInstance.GetImage(&instance.GetImageRequest{
254-
Zone: args.Zone,
255-
ImageID: serverReq.Image,
256-
})
257-
if err != nil {
258-
logger.Warningf("cannot get image %s: %s", serverReq.Image, err)
259-
}
259+
var (
260+
getImageResponse *instance.GetImageResponse
261+
serverType *instance.ServerType
262+
)
263+
if args.Image != "none" {
264+
var err error
265+
getImageResponse, err = apiInstance.GetImage(&instance.GetImageRequest{
266+
Zone: args.Zone,
267+
ImageID: serverReq.Image,
268+
})
269+
if err != nil {
270+
logger.Warningf("cannot get image %s: %s", serverReq.Image, err)
271+
}
260272

261-
serverType := getServerType(apiInstance, serverReq.Zone, serverReq.CommercialType)
273+
serverType = getServerType(apiInstance, serverReq.Zone, serverReq.CommercialType)
262274

263-
if serverType != nil && getImageResponse != nil {
264-
if err := validateImageServerTypeCompatibility(getImageResponse.Image, serverType, serverReq.CommercialType); err != nil {
265-
return nil, err
275+
if serverType != nil && getImageResponse != nil {
276+
if err := validateImageServerTypeCompatibility(getImageResponse.Image, serverType, serverReq.CommercialType); err != nil {
277+
return nil, err
278+
}
279+
} else {
280+
logger.Warningf("skipping image server-type compatibility validation")
266281
}
267282
} else {
268-
logger.Warningf("skipping image server-type compatibility validation")
283+
getImageResponse = nil
284+
serverType = nil
269285
}
270286

271287
//
@@ -315,7 +331,7 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
315331
}
316332

317333
// Validate root volume type and size.
318-
if getImageResponse != nil {
334+
if args.Image != "none" && getImageResponse != nil {
319335
if err := validateRootVolume(getImageResponse.Image.RootVolume.Size, volumes["0"]); err != nil {
320336
return nil, err
321337
}
@@ -324,7 +340,7 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
324340
}
325341

326342
// Validate total local volume sizes.
327-
if serverType != nil && getImageResponse != nil {
343+
if args.Image != "none" && serverType != nil && getImageResponse != nil {
328344
if err := validateLocalVolumeSizes(volumes, serverType, serverReq.CommercialType, getImageResponse.Image.RootVolume.Size); err != nil {
329345
return nil, err
330346
}

0 commit comments

Comments
 (0)