Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(instance): support snapshot based instance #3787

Merged
merged 5 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ EXAMPLES:
Create an instance with volumes from snapshots
scw instance server create image=ubuntu_focal root-volume=local:<snapshot_id> additional-volumes.0=block:<snapshot_id>

Create and start an instance from a snapshot
scw instance server create image=none root-volume=local:<snapshot_id>

Use an existing IP
ip=$(scw instance ip create | grep id | awk '{ print $2 }')
scw instance server create image=ubuntu_focal ip=$ip
Expand Down
5 changes: 5 additions & 0 deletions docs/commands/instance.md
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,11 @@ Create an instance with volumes from snapshots
scw instance server create image=ubuntu_focal root-volume=local:<snapshot_id> additional-volumes.0=block:<snapshot_id>
```

Create and start an instance from a snapshot
```
scw instance server create image=none root-volume=local:<snapshot_id>
```

Use an existing IP
```
ip=$(scw instance ip create | grep id | awk '{ print $2 }')
Expand Down
44 changes: 30 additions & 14 deletions internal/namespaces/instance/v1/custom_server_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,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 @@ -231,6 +235,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 @@ -250,22 +256,32 @@ 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" {
var err error
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 @@ -315,7 +331,7 @@ func instanceServerCreateRun(ctx context.Context, argsI interface{}) (i interfac
}

// Validate root volume type and size.
if getImageResponse != nil {
if args.Image != "none" && getImageResponse != nil {
if err := validateRootVolume(getImageResponse.Image.RootVolume.Size, volumes["0"]); err != nil {
return nil, err
}
Expand All @@ -324,7 +340,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
Loading