Skip to content

Commit ec98863

Browse files
author
Quentin Perez
committed
Fix #258
1 parent 52cb149 commit ec98863

File tree

6 files changed

+112
-31
lines changed

6 files changed

+112
-31
lines changed

pkg/api/api.go

Lines changed: 74 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,7 +1255,7 @@ func (s *ScalewayAPI) PutVolume(volumeID string, definition ScalewayVolumePutDef
12551255
return err
12561256
}
12571257

1258-
// ResolveServer attempts the find a matching Identifier for the input string
1258+
// ResolveServer attempts to find a matching Identifier for the input string
12591259
func (s *ScalewayAPI) ResolveServer(needle string) (ScalewayResolverResults, error) {
12601260
servers := s.Cache.LookUpServers(needle, true)
12611261
if len(servers) == 0 {
@@ -1267,7 +1267,19 @@ func (s *ScalewayAPI) ResolveServer(needle string) (ScalewayResolverResults, err
12671267
return servers, nil
12681268
}
12691269

1270-
// ResolveSnapshot attempts the find a matching Identifier for the input string
1270+
// ResolveVolume attempts to find a matching Identifier for the input string
1271+
func (s *ScalewayAPI) ResolveVolume(needle string) (ScalewayResolverResults, error) {
1272+
volumes := s.Cache.LookUpVolumes(needle, true)
1273+
if len(volumes) == 0 {
1274+
if _, err := s.GetVolumes(); err != nil {
1275+
return nil, err
1276+
}
1277+
volumes = s.Cache.LookUpVolumes(needle, true)
1278+
}
1279+
return volumes, nil
1280+
}
1281+
1282+
// ResolveSnapshot attempts to find a matching Identifier for the input string
12711283
func (s *ScalewayAPI) ResolveSnapshot(needle string) (ScalewayResolverResults, error) {
12721284
snapshots := s.Cache.LookUpSnapshots(needle, true)
12731285
if len(snapshots) == 0 {
@@ -1279,7 +1291,7 @@ func (s *ScalewayAPI) ResolveSnapshot(needle string) (ScalewayResolverResults, e
12791291
return snapshots, nil
12801292
}
12811293

1282-
// ResolveImage attempts the find a matching Identifier for the input string
1294+
// ResolveImage attempts to find a matching Identifier for the input string
12831295
func (s *ScalewayAPI) ResolveImage(needle string) (ScalewayResolverResults, error) {
12841296
images := s.Cache.LookUpImages(needle, true)
12851297
if len(images) == 0 {
@@ -1291,7 +1303,7 @@ func (s *ScalewayAPI) ResolveImage(needle string) (ScalewayResolverResults, erro
12911303
return images, nil
12921304
}
12931305

1294-
// ResolveBootscript attempts the find a matching Identifier for the input string
1306+
// ResolveBootscript attempts to find a matching Identifier for the input string
12951307
func (s *ScalewayAPI) ResolveBootscript(needle string) (ScalewayResolverResults, error) {
12961308
bootscripts := s.Cache.LookUpBootscripts(needle, true)
12971309
if len(bootscripts) == 0 {
@@ -1372,6 +1384,40 @@ func (s *ScalewayAPI) DeleteImage(imageID string) error {
13721384
return nil
13731385
}
13741386

1387+
// DeleteSnapshot deletes a snapshot
1388+
func (s *ScalewayAPI) DeleteSnapshot(snapshotID string) error {
1389+
defer s.Cache.RemoveSnapshot(snapshotID)
1390+
resp, err := s.DeleteResponse(fmt.Sprintf("snapshots/%s", snapshotID))
1391+
if resp != nil {
1392+
defer resp.Body.Close()
1393+
}
1394+
if err != nil {
1395+
return err
1396+
}
1397+
1398+
if _, err := s.handleHTTPError([]int{204}, resp); err != nil {
1399+
return err
1400+
}
1401+
return nil
1402+
}
1403+
1404+
// DeleteVolume deletes a volume
1405+
func (s *ScalewayAPI) DeleteVolume(volumeID string) error {
1406+
defer s.Cache.RemoveVolume(volumeID)
1407+
resp, err := s.DeleteResponse(fmt.Sprintf("volumes/%s", volumeID))
1408+
if resp != nil {
1409+
defer resp.Body.Close()
1410+
}
1411+
if err != nil {
1412+
return err
1413+
}
1414+
1415+
if _, err := s.handleHTTPError([]int{204}, resp); err != nil {
1416+
return err
1417+
}
1418+
return nil
1419+
}
1420+
13751421
// GetSnapshots gets the list of snapshots from the ScalewayAPI
13761422
func (s *ScalewayAPI) GetSnapshots() (*[]ScalewaySnapshot, error) {
13771423
query := url.Values{}
@@ -1825,7 +1871,7 @@ func (s *ScalewayAPI) GetDashboard() (*ScalewayDashboard, error) {
18251871
return &dashboard.Dashboard, nil
18261872
}
18271873

1828-
// GetServerID returns exactly one server matching or dies
1874+
// GetServerID returns exactly one server matching
18291875
func (s *ScalewayAPI) GetServerID(needle string) (string, error) {
18301876
// Parses optional type prefix, i.e: "server:name" -> "name"
18311877
_, needle = parseNeedle(needle)
@@ -1858,7 +1904,25 @@ func showResolverResults(needle string, results ScalewayResolverResults) error {
18581904
return fmt.Errorf("Too many candidates for %s (%d)", needle, len(results))
18591905
}
18601906

1861-
// GetSnapshotID returns exactly one snapshot matching or dies
1907+
// GetVolumeID returns exactly one volume matching
1908+
func (s *ScalewayAPI) GetVolumeID(needle string) (string, error) {
1909+
// Parses optional type prefix, i.e: "volume:name" -> "name"
1910+
_, needle = parseNeedle(needle)
1911+
1912+
volumes, err := s.ResolveVolume(needle)
1913+
if err != nil {
1914+
return "", fmt.Errorf("Unable to resolve volume %s: %s", needle, err)
1915+
}
1916+
if len(volumes) == 1 {
1917+
return volumes[0].Identifier, nil
1918+
}
1919+
if len(volumes) == 0 {
1920+
return "", fmt.Errorf("No such volume: %s", needle)
1921+
}
1922+
return "", showResolverResults(needle, volumes)
1923+
}
1924+
1925+
// GetSnapshotID returns exactly one snapshot matching
18621926
func (s *ScalewayAPI) GetSnapshotID(needle string) (string, error) {
18631927
// Parses optional type prefix, i.e: "snapshot:name" -> "name"
18641928
_, needle = parseNeedle(needle)
@@ -1876,8 +1940,8 @@ func (s *ScalewayAPI) GetSnapshotID(needle string) (string, error) {
18761940
return "", showResolverResults(needle, snapshots)
18771941
}
18781942

1879-
// GetImageID returns exactly one image matching or dies
1880-
func (s *ScalewayAPI) GetImageID(needle string, exitIfMissing bool) (*ScalewayImageIdentifier, error) {
1943+
// GetImageID returns exactly one image matching
1944+
func (s *ScalewayAPI) GetImageID(needle string) (*ScalewayImageIdentifier, error) {
18811945
// Parses optional type prefix, i.e: "image:name" -> "name"
18821946
_, needle = parseNeedle(needle)
18831947

@@ -1895,10 +1959,7 @@ func (s *ScalewayAPI) GetImageID(needle string, exitIfMissing bool) (*ScalewayIm
18951959
}, nil
18961960
}
18971961
if len(images) == 0 {
1898-
if exitIfMissing {
1899-
return nil, fmt.Errorf("No such image: %s", needle)
1900-
}
1901-
return nil, nil
1962+
return nil, fmt.Errorf("No such image: %s", needle)
19021963
}
19031964
return nil, showResolverResults(needle, images)
19041965
}
@@ -2255,7 +2316,7 @@ func (s *ScalewayAPI) GetQuotas() (*ScalewayGetQuotas, error) {
22552316
return &quotas, nil
22562317
}
22572318

2258-
// GetBootscriptID returns exactly one bootscript matching or dies
2319+
// GetBootscriptID returns exactly one bootscript matching
22592320
func (s *ScalewayAPI) GetBootscriptID(needle, arch string) (string, error) {
22602321
// Parses optional type prefix, i.e: "bootscript:name" -> "name"
22612322
_, needle = parseNeedle(needle)

pkg/api/helpers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ func CreateServer(api *ScalewayAPI, c *ConfigCreateServer) (string, error) {
367367
// Use an existing image
368368
// FIXME: handle snapshots
369369
inheritingVolume = true
370-
imageIdentifier, err = api.GetImageID(c.ImageName, false)
370+
imageIdentifier, err = api.GetImageID(c.ImageName)
371371
if err != nil {
372372
return "", err
373373
}

pkg/cli/cmd_rmi.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import "github.com/scaleway/scaleway-cli/pkg/commands"
88

99
var cmdRmi = &Command{
1010
Exec: runRmi,
11-
UsageLine: "rmi [OPTIONS] IMAGE [IMAGE...]",
12-
Description: "Remove one or more images",
13-
Help: "Remove one or more images.",
11+
UsageLine: "rmi [OPTIONS] IDENTIFIER [IDENTIFIER...]",
12+
Description: "Remove one or more image(s)/volume(s)/snapshot(s)",
13+
Help: "Remove one or more image(s)/volume(s)/snapshot(s)",
1414
Examples: `
1515
$ scw rmi myimage
16+
$ scw rmi mysnapshot
17+
$ scw rmi myvolume
1618
$ scw rmi $(scw images -q)
1719
`,
1820
}
@@ -33,7 +35,7 @@ func runRmi(cmd *Command, rawArgs []string) error {
3335
}
3436

3537
args := commands.RmiArgs{
36-
Images: rawArgs,
38+
Identifier: rawArgs,
3739
}
3840
ctx := cmd.GetContext(rawArgs)
3941
return commands.RunRmi(ctx, args)

pkg/commands/history.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type HistoryArgs struct {
2222

2323
// RunHistory is the handler for 'scw history'
2424
func RunHistory(ctx CommandContext, args HistoryArgs) error {
25-
imageID, err := ctx.API.GetImageID(args.Image, true)
25+
imageID, err := ctx.API.GetImageID(args.Image)
2626
if err != nil {
2727
return err
2828
}

pkg/commands/ps.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ func RunPs(ctx CommandContext, args PsArgs) error {
8282
goto skipServer
8383
}
8484
case "image":
85-
imageID, err := ctx.API.GetImageID(value, true)
85+
imageID, err := ctx.API.GetImageID(value)
8686
if err != nil {
8787
goto skipServer
8888
}

pkg/commands/rmi.go

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,44 @@ import (
1212

1313
// RmiArgs are flags for the `RunRmi` function
1414
type RmiArgs struct {
15-
Images []string
15+
Identifier []string // images/volumes/snapshots
1616
}
1717

1818
// RunRmi is the handler for 'scw rmi'
1919
func RunRmi(ctx CommandContext, args RmiArgs) error {
2020
hasError := false
21-
for _, needle := range args.Images {
22-
image, err := ctx.API.GetImageID(needle, true)
23-
if err != nil {
24-
return err
21+
for _, needle := range args.Identifier {
22+
if image, err := ctx.API.GetImageID(needle); err == nil {
23+
if err = ctx.API.DeleteImage(image.Identifier); err != nil {
24+
logrus.Errorf("failed to delete image %s: %s", image.Identifier, err)
25+
hasError = true
26+
} else {
27+
fmt.Fprintln(ctx.Stdout, needle)
28+
}
29+
continue
2530
}
26-
if err = ctx.API.DeleteImage(image.Identifier); err != nil {
27-
logrus.Errorf("failed to delete image %s: %s", image.Identifier, err)
28-
hasError = true
29-
} else {
30-
fmt.Fprintln(ctx.Stdout, needle)
31+
if snapshotID, err := ctx.API.GetSnapshotID(needle); err == nil {
32+
if err = ctx.API.DeleteSnapshot(snapshotID); err != nil {
33+
logrus.Errorf("failed to delete snapshot %s: %s", snapshotID, err)
34+
hasError = true
35+
} else {
36+
fmt.Fprintln(ctx.Stdout, needle)
37+
}
38+
continue
3139
}
40+
if volumeID, err := ctx.API.GetVolumeID(needle); err == nil {
41+
if err = ctx.API.DeleteVolume(volumeID); err != nil {
42+
logrus.Errorf("failed to delete volume %s: %s", volumeID, err)
43+
hasError = true
44+
} else {
45+
fmt.Fprintln(ctx.Stdout, needle)
46+
}
47+
continue
48+
}
49+
hasError = true
3250
}
3351
if hasError {
34-
return fmt.Errorf("at least 1 image failed to be removed")
52+
return fmt.Errorf("at least 1 image/snapshot/volume failed to be removed")
3553
}
3654
return nil
3755
}

0 commit comments

Comments
 (0)