Skip to content

Commit

Permalink
Merge branch 'master' of github.com:exoscale/cli into pej/sc-60922/to…
Browse files Browse the repository at this point in the history
…oling-support-for-multiple-ssh-keys

Signed-off-by: Pierre-Emmanuel Jacquier <[email protected]>
  • Loading branch information
pierre-emmanuelJ committed Jul 22, 2024
2 parents 451f91d + f262802 commit 016057c
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 33 deletions.
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
# Changelog

## Unreleased
## 1.78.4

### Improvements

- Compute Instance delete: Remove multiple entities by their IDs/Names #619

### Bug Fixes

- output template: use text/template #617

### Improvements

- egoscale/v3: use separate module v3.1.0 #621

## 1.78.3

### Improvements
Expand Down
6 changes: 3 additions & 3 deletions bucket/exoscale-cli.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"version": "1.78.3",
"version": "1.78.4",
"architecture": {
"64bit": {
"url": "https://github.com/exoscale/cli/releases/download/v1.78.3/exoscale-cli_1.78.3_windows_amd64.zip",
"url": "https://github.com/exoscale/cli/releases/download/v1.78.4/exoscale-cli_1.78.4_windows_amd64.zip",
"bin": [
"exo.exe"
],
"hash": "1f7835d226fad75095ae847395d7c0a92d72fece5f6168ec4774369007346df0"
"hash": "0b0f0357641fb62006504e0a8068393bf986be0f27b8b5ecc5fa3e7eff23acff"
}
},
"homepage": "https://github.com/exoscale/cli",
Expand Down
71 changes: 52 additions & 19 deletions cmd/instance_delete.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
package cmd

import (
"errors"
"fmt"
"os"
"path"
"strings"

"github.com/spf13/cobra"

"github.com/exoscale/cli/pkg/account"
"github.com/exoscale/cli/pkg/globalstate"
exoapi "github.com/exoscale/egoscale/v2/api"
v3 "github.com/exoscale/egoscale/v3"
)

type instanceDeleteCmd struct {
cliCommandSettings `cli-cmd:"-"`

_ bool `cli-cmd:"delete"`

Instance string `cli-arg:"#" cli-usage:"NAME|ID"`
Instances []string `cli-arg:"#" cli-usage:"NAME|ID"`

Force bool `cli-short:"f" cli-usage:"don't prompt for confirmation"`
Zone string `cli-short:"z" cli-usage:"instance zone"`
Expand All @@ -36,33 +35,67 @@ func (c *instanceDeleteCmd) cmdPreRun(cmd *cobra.Command, args []string) error {
}

func (c *instanceDeleteCmd) cmdRun(_ *cobra.Command, _ []string) error {
ctx := exoapi.WithEndpoint(gContext, exoapi.NewReqEndpoint(account.CurrentAccount.Environment, c.Zone))
ctx := gContext
client, err := switchClientZoneV3(
ctx,
globalstate.EgoscaleV3Client,
v3.ZoneName(c.Zone),
)
if err != nil {
return err
}

instance, err := globalstate.EgoscaleClient.FindInstance(ctx, c.Zone, c.Instance)
instances, err := client.ListInstances(ctx)
if err != nil {
if errors.Is(err, exoapi.ErrNotFound) {
return fmt.Errorf("resource not found in zone %q", c.Zone)
}
return err
}

if !c.Force {
if !askQuestion(fmt.Sprintf("Are you sure you want to delete instance %q?", c.Instance)) {
return nil
instanceToDelete := []v3.UUID{}
for _, i := range c.Instances {
instance, err := instances.FindListInstancesResponseInstances(i)
if err != nil {
if !c.Force {
return err
}
fmt.Fprintf(os.Stderr, "warning: %s not found.\n", i)

continue
}

if !c.Force {
if !askQuestion(fmt.Sprintf("Are you sure you want to delete instance %q?", i)) {
return nil
}
}

instanceToDelete = append(instanceToDelete, instance.ID)
}

var fns []func() error
for _, i := range instanceToDelete {
fns = append(fns, func() error {
op, err := client.DeleteInstance(ctx, i)
if err != nil {
return err
}
_, err = client.Wait(ctx, op, v3.OperationStateSuccess)
return err
})
}

decorateAsyncOperation(fmt.Sprintf("Deleting instance %q...", c.Instance), func() {
err = globalstate.EgoscaleClient.DeleteInstance(ctx, c.Zone, instance)
})
err = decorateAsyncOperations(fmt.Sprintf("Deleting instance %q...", strings.Join(c.Instances, ", ")), fns...)
if err != nil {
return err
}

instanceDir := path.Join(globalstate.ConfigFolder, "instances", *instance.ID)
if _, err := os.Stat(instanceDir); !os.IsNotExist(err) {
if err := os.RemoveAll(instanceDir); err != nil {
return fmt.Errorf("error deleting instance directory: %w", err)
// Cleaning up resources created in create instance
// https://github.com/exoscale/cli/blob/master/cmd/instance_create.go#L220
for _, i := range instanceToDelete {
instanceDir := path.Join(globalstate.ConfigFolder, "instances", i.String())
if _, err := os.Stat(instanceDir); !os.IsNotExist(err) {
if err := os.RemoveAll(instanceDir); err != nil {
return fmt.Errorf("error deleting instance directory: %w", err)
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/limits.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ Supported output template annotations: %s`,
limitSKSClusters: "SKS clusters",
limitSOSBuckets: "SOS buckets",
limitBlockStorageVolumes: "Block Storage Volumes",
limitBlockStorage: "Block Storage cumulative size",
limitBlockStorageMaxSize: "Max Size of Block Storage Volumes",
limitBlockStorage: "Block Storage cumulative size (GiB)",
limitBlockStorageMaxSize: "Max size of a Block Storage Volume (GiB)",
}

out := LimitsOutput{}
Expand Down
50 changes: 50 additions & 0 deletions cmd/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strconv"
"time"

"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"
"github.com/vbauerster/mpb/v4"
"github.com/vbauerster/mpb/v4/decor"
Expand Down Expand Up @@ -46,6 +47,7 @@ func printOutput(o output.Outputter, err error) error {
// decorateAsyncOperation is a cosmetic helper intended for wrapping long
// asynchronous operations, outputting progress feedback to the user's
// terminal.
// TODO remove this one once all has been migrated to decorateAsyncOperations.
func decorateAsyncOperation(message string, fn func()) {
p := mpb.New(
mpb.WithOutput(os.Stderr),
Expand Down Expand Up @@ -75,6 +77,54 @@ func decorateAsyncOperation(message string, fn func()) {
p.Wait()
}

func decorateAsyncOperations(message string, fns ...func() error) error {
if len(fns) == 0 {
return nil
}

p := mpb.New(
mpb.WithOutput(os.Stderr),
mpb.WithWidth(1),
mpb.ContainerOptOn(mpb.WithOutput(nil), func() bool { return globalstate.Quiet }),
)

spinner := p.AddSpinner(
int64(len(fns)),
mpb.SpinnerOnLeft,
mpb.AppendDecorators(
decor.Name(message, decor.WC{W: len(message) + 1, C: decor.DidentRight}),
decor.Elapsed(decor.ET_STYLE_GO),
),
mpb.BarOnComplete("✔"),
)

errs := &multierror.Error{}
done := make(chan struct{})
defer close(done)

for i := 0; i < len(fns); i += 10 {
batchSize := min(10, len(fns)-i)
for j := 0; j < batchSize; j++ {
fnIndex := i + j
go func(doneCh chan struct{}, fn func() error) {
if err := fn(); err != nil {
errs = multierror.Append(errs, err)
}
doneCh <- struct{}{}
}(done, fns[fnIndex])
}

for j := 0; j < batchSize; j++ {
<-done
spinner.Increment(1)
}
}

p.Wait()

return errs.ErrorOrNil()
}

func init() {
RootCmd.AddCommand(&cobra.Command{
Use: "output",
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ require (
github.com/aws/aws-sdk-go-v2/service/s3 v1.2.0
github.com/aws/smithy-go v1.1.0
github.com/dustin/go-humanize v1.0.1
github.com/exoscale/egoscale v0.102.5-0.20240712161721-275fc20694fd
github.com/exoscale/egoscale/v3 v3.1.1-0.20240712161721-275fc20694fd
github.com/exoscale/egoscale v0.102.4
github.com/exoscale/egoscale/v3 v3.1.0
github.com/exoscale/openapi-cli-generator v1.1.0
github.com/fatih/camelcase v1.0.0
github.com/google/uuid v1.4.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
github.com/exoscale/egoscale v0.102.5-0.20240712161721-275fc20694fd h1:2rQ9GatI7MzMwfx1hX0i5znmjk8F9XCyJX/DTz9UCjE=
github.com/exoscale/egoscale v0.102.5-0.20240712161721-275fc20694fd/go.mod h1:xKtCzfF+1O6sKtMb7QANYrTher0EFhkmw8LQLu7Scm0=
github.com/exoscale/egoscale/v3 v3.1.1-0.20240712161721-275fc20694fd h1:RhnSciyRNzsa2qdAr7k8S7diePF8bx6Nyg/nmTQXMjI=
github.com/exoscale/egoscale/v3 v3.1.1-0.20240712161721-275fc20694fd/go.mod h1:lPsza7G+giSxdzvzaHSEcjEAYz/YTiu2bEEha9KVAc4=
github.com/exoscale/egoscale v0.102.4 h1:GBKsZMIOzwBfSu+4ZmWka3Ejf2JLiaBDHp4CQUgvp2E=
github.com/exoscale/egoscale v0.102.4/go.mod h1:ROSmPtle0wvf91iLZb09++N/9BH2Jo9XxIpAEumvocA=
github.com/exoscale/egoscale/v3 v3.1.0 h1:8MSA0j4TZbUiE6iIzTmoY0URa3RoGGuHhX5oamCql4o=
github.com/exoscale/egoscale/v3 v3.1.0/go.mod h1:lPsza7G+giSxdzvzaHSEcjEAYz/YTiu2bEEha9KVAc4=
github.com/exoscale/openapi-cli-generator v1.1.0 h1:fYjmPqHR5vxlOBrbvde7eo7bISNQIFxsGn4A5/acwKA=
github.com/exoscale/openapi-cli-generator v1.1.0/go.mod h1:TZBnbT7f3hJ5ImyUphJwRM+X5xF/zCQZ6o8a42gQeTs=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
Expand Down
4 changes: 2 additions & 2 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,13 @@ github.com/dlclark/regexp2/syntax
# github.com/dustin/go-humanize v1.0.1
## explicit; go 1.16
github.com/dustin/go-humanize
# github.com/exoscale/egoscale v0.102.5-0.20240712161721-275fc20694fd
# github.com/exoscale/egoscale v0.102.4
## explicit; go 1.22
github.com/exoscale/egoscale/v2
github.com/exoscale/egoscale/v2/api
github.com/exoscale/egoscale/v2/oapi
github.com/exoscale/egoscale/version
# github.com/exoscale/egoscale/v3 v3.1.1-0.20240712161721-275fc20694fd
# github.com/exoscale/egoscale/v3 v3.1.0
## explicit; go 1.22
github.com/exoscale/egoscale/v3
github.com/exoscale/egoscale/v3/credentials
Expand Down

0 comments on commit 016057c

Please sign in to comment.