Skip to content

Commit

Permalink
fix(instance): support snapshot based instance
Browse files Browse the repository at this point in the history
This PR allow users to create an instance from a snapshot directly
without creating an image.
It's already supported by the APIs.

Signed-off-by: Mathieu Tortuyaux <mtortuyaux@microsoft.com>
  • Loading branch information
tormath1 committed Apr 23, 2024
1 parent a0407a5 commit bdc9f1a
Showing 1 changed file with 29 additions and 14 deletions.
43 changes: 29 additions & 14 deletions internal/namespaces/instance/v1/custom_server_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ func serverCreateCommand() *core.Command {
Short: "Create an instance with volumes from snapshots",
ArgsJSON: `{"image":"ubuntu_focal","root_volume":"local:<snapshot_id>","additional_volumes":["block:<snapshot_id>"]}`,
},
{
Short: "Create and start an instance from a snapshot",
ArgsJSON: `{"image":"none","root_volume":"local:<snapshot_id>"}`,
},
{
Short: "Use an existing IP",
Raw: `ip=$(scw instance ip create | grep id | awk '{ print $2 }')
Expand Down Expand Up @@ -212,6 +216,8 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
// - An image label
//
switch {
case args.Image == "none":
break
case !validation.IsUUID(args.Image):
// For retro-compatibility, we replace dashes with underscores
imageLabel := strings.Replace(args.Image, "-", "_", -1)
Expand All @@ -231,22 +237,31 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
serverReq.Image = args.Image
}

getImageResponse, err := apiInstance.GetImage(&instance.GetImageRequest{
Zone: args.Zone,
ImageID: serverReq.Image,
})
if err != nil {
logger.Warningf("cannot get image %s: %s", serverReq.Image, err)
}
var (
getImageResponse *instance.GetImageResponse
serverType *instance.ServerType
)
if args.Image != "none" {
getImageResponse, err := apiInstance.GetImage(&instance.GetImageRequest{
Zone: args.Zone,
ImageID: serverReq.Image,
})
if err != nil {
logger.Warningf("cannot get image %s: %s", serverReq.Image, err)
}

serverType := getServerType(apiInstance, serverReq.Zone, serverReq.CommercialType)
serverType := getServerType(apiInstance, serverReq.Zone, serverReq.CommercialType)

if serverType != nil && getImageResponse != nil {
if err := validateImageServerTypeCompatibility(getImageResponse.Image, serverType, serverReq.CommercialType); err != nil {
return nil, err
if serverType != nil && getImageResponse != nil {
if err := validateImageServerTypeCompatibility(getImageResponse.Image, serverType, serverReq.CommercialType); err != nil {
return nil, err
}
} else {
logger.Warningf("skipping image server-type compatibility validation")
}
} else {
logger.Warningf("skipping image server-type compatibility validation")
getImageResponse = nil
serverType = nil
}

//
Expand Down Expand Up @@ -296,7 +311,7 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
}

// Validate root volume type and size.
if getImageResponse != nil {
if serverReq.Image != "none" && getImageResponse != nil {
if err := validateRootVolume(getImageResponse.Image.RootVolume.Size, volumes["0"]); err != nil {
return nil, err
}
Expand All @@ -305,7 +320,7 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
}

// Validate total local volume sizes.
if serverType != nil && getImageResponse != nil {
if args.Image != "none" && serverType != nil && getImageResponse != nil {
if err := validateLocalVolumeSizes(volumes, serverType, serverReq.CommercialType, getImageResponse.Image.RootVolume.Size); err != nil {
return nil, err
}
Expand Down

0 comments on commit bdc9f1a

Please sign in to comment.