Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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 @@ -4,18 +4,18 @@ USAGE:
scw [global-flags] instance image create [flags] [arg=value ...]

ARGS:
[name=<generated>] Name of the image
snapshot-id UUID of the snapshot
arch Architecture of the image (x86_64 | arm)
[default-bootscript] Default bootscript of the image
[extra-volumes.{key}.id] UUID of the volume
[extra-volumes.{key}.name] Name of the volume
[extra-volumes.{key}.size] Disk size of the volume
[extra-volumes.{key}.volume-type] Type of the volume (l_ssd | b_ssd)
[extra-volumes.{key}.organization] Organization ID of the volume
[public] True to create a public image
[organization] Organization ID to use. If none is passed will use default organization ID from the config
[zone] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)
[name=<generated>] Name of the image
root-volume UUID of the snapshot
arch Architecture of the image (x86_64 | arm)
[default-bootscript] Default bootscript of the image
[additional-volumes.{key}.id] UUID of the volume
[additional-volumes.{key}.name] Name of the volume
[additional-volumes.{key}.size] Disk size of the volume
[additional-volumes.{key}.volume-type] Type of the volume (l_ssd | b_ssd)
[additional-volumes.{key}.organization] Organization ID of the volume
[public] True to create a public image
[organization] Organization ID to use. If none is passed will use default organization ID from the config
[zone] Zone to target. If none is passed will use default zone from the config (fr-par-1 | nl-ams-1)

FLAGS:
-h, --help help for create
Expand Down
2 changes: 1 addition & 1 deletion internal/namespaces/instance/v1/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func GetCommands() *core.Commands {
//
human.RegisterMarshalerFunc(instance.CreateImageResponse{}, marshallNestedField("Image"))

cmds.MustFind("instance", "image", "list").Override(imageListBuilder)
cmds.MustFind("instance", "image", "create").Override(imageCreateBuilder)
cmds.MustFind("instance", "image", "list").Override(imageListBuilder)

//
// Snapshot
Expand Down
70 changes: 45 additions & 25 deletions internal/namespaces/instance/v1/custom_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package instance
import (
"context"
"reflect"
"strconv"
"time"

"github.com/scaleway/scaleway-cli/internal/core"
Expand All @@ -14,6 +15,49 @@ import (
// Builders
//

// imageCreateBuilder overrides 'instance image create' to
// - rename extra-volumes arguments into additional-volumes
// - rename the argument 'root-volume' into 'snapshot-id'
func imageCreateBuilder(c *core.Command) *core.Command {
Comment thread
QuentinBrosse marked this conversation as resolved.

type customCreateImageRequest struct {
*instance.CreateImageRequest
AdditionalVolumes map[string]*instance.VolumeTemplate
SnapshotID string
}

c.ArgSpecs.GetByName("extra-volumes.{key}.id").Name = "additional-volumes.{key}.id"
c.ArgSpecs.GetByName("extra-volumes.{key}.name").Name = "additional-volumes.{key}.name"
c.ArgSpecs.GetByName("extra-volumes.{key}.size").Name = "additional-volumes.{key}.size"
c.ArgSpecs.GetByName("extra-volumes.{key}.volume-type").Name = "additional-volumes.{key}.volume-type"
c.ArgSpecs.GetByName("extra-volumes.{key}.organization").Name = "additional-volumes.{key}.organization"

c.ArgSpecs.GetByName("root-volume").Name = "snapshot-id"

c.ArgsType = reflect.TypeOf(customCreateImageRequest{})

originalRun := c.Run

c.Run = func(ctx context.Context, argsI interface{}) (i interface{}, e error) {
args := argsI.(*customCreateImageRequest)

request := args.CreateImageRequest
request.RootVolume = args.SnapshotID
request.ExtraVolumes = make(map[string]*instance.VolumeTemplate)

// Extra volumes need to start at volumeIndex 1.
volumeIndex := 1
for _, volume := range args.AdditionalVolumes {
request.ExtraVolumes[strconv.Itoa(volumeIndex)] = volume
volumeIndex++
}

return originalRun(ctx, request)
}

return c
}

// imageListBuilder list the images for a given organization.
// A call to GetServer(..) with the ID contained in Image.FromServer retrieves more information about the server.
func imageListBuilder(c *core.Command) *core.Command {
Expand All @@ -31,6 +75,7 @@ func imageListBuilder(c *core.Command) *core.Command {
Public bool
RootVolume *instance.VolumeSummary
State instance.ImageState

// Replace Image.FromServer
ServerID string
ServerName string
Expand Down Expand Up @@ -86,28 +131,3 @@ func imageListBuilder(c *core.Command) *core.Command {

return c
}

// imageCreateBuilder overrides 'instance image create' to rename the argument 'root-volume' into 'snapshot-id'.
func imageCreateBuilder(c *core.Command) *core.Command {
type CreateImageRequestCustom struct {
*instance.CreateImageRequest
SnapshotID string
}

c.ArgSpecs.GetByName("root-volume").Name = "snapshot-id"

c.ArgsType = reflect.TypeOf(CreateImageRequestCustom{})

oldRun := c.Run

c.Run = func(ctx context.Context, args interface{}) (i interface{}, e error) {
requestCustom := args.(*CreateImageRequestCustom)

request := requestCustom.CreateImageRequest
request.RootVolume = requestCustom.SnapshotID

return oldRun(ctx, request)
}

return c
}
17 changes: 8 additions & 9 deletions internal/namespaces/instance/v1/custom_image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,26 @@ import (
)

func Test_ImageCreate(t *testing.T) {
Comment thread
QuentinBrosse marked this conversation as resolved.
t.Run("simple", core.Test(&core.TestConfig{
Commands: GetCommands(),

t.Run("Create simple image", core.Test(&core.TestConfig{
BeforeFunc: core.BeforeFuncCombine(
createServer("Server"),
func(ctx *core.BeforeFuncCtx) error {
ctx.Meta["SnapshotResponse"] = ctx.ExecuteCmd(`scw instance snapshot create volume-id={{ (index .Server.Volumes "0").ID }}`)
return nil
},
core.ExecStoreBeforeCmd("Snapshot", `scw instance snapshot create volume-id={{ (index .Server.Volumes "0").ID }}`),
),
Cmd: "scw instance image create snapshot-id={{ .SnapshotResponse.Snapshot.ID }} arch=x86_64",
Commands: GetCommands(),
Cmd: "scw instance image create snapshot-id={{ .Snapshot.Snapshot.ID }} arch=x86_64",
Check: core.TestCheckCombine(
core.TestCheckGolden(),
core.TestCheckExitCode(0),
),
AfterFunc: core.AfterFuncCombine(
deleteServer("Server"),
func(ctx *core.AfterFuncCtx) error {
ctx.ExecuteCmd("scw instance image delete image-id=" + ctx.CmdResult.(*instance.CreateImageResponse).Image.ID)
ctx.ExecuteCmd("scw instance snapshot delete snapshot-id={{ .SnapshotResponse.Snapshot.ID }}")
return nil
},
deleteServer("Server"),
deleteSnapshot("Snapshot"),
),
}))

Comment thread
QuentinBrosse marked this conversation as resolved.
Outdated
}
9 changes: 9 additions & 0 deletions internal/namespaces/instance/v1/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,12 @@ func createSecurityGroup(metaKey string) core.BeforeFunc {
func deleteSecurityGroup(metaKey string) core.AfterFunc {
return core.ExecAfterCmd("scw instance security-group delete security-group-id={{ ." + metaKey + ".ID }}")
}

//
// Snapshot
//

// deleteSnapshot deletes a snapshot previously registered in the context Meta at metaKey.
func deleteSnapshot(metaKey string) core.AfterFunc {
return core.ExecAfterCmd("scw instance snapshot delete snapshot-id={{ ." + metaKey + ".Snapshot.ID }}")
}
Loading