Also wait for deletion events

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2020-04-29 15:26:11 +02:00
parent 5d61fc119a
commit 814259ae33
No known key found for this signature in database
GPG Key ID: 9858809D6F8F6E7E
5 changed files with 60 additions and 36 deletions

View File

@ -12,6 +12,11 @@ func (c *client) ComposeDown(ctx context.Context, projectName string, deleteClus
} }
fmt.Printf("Delete stack ") fmt.Printf("Delete stack ")
err = c.WaitStackCompletion(ctx, projectName)
if err != nil {
return err
}
if !deleteCluster { if !deleteCluster {
return nil return nil
} }

View File

@ -20,6 +20,7 @@ func TestDownDontDeleteCluster(t *testing.T) {
ctx := context.TODO() ctx := context.TODO()
recorder := m.EXPECT() recorder := m.EXPECT()
recorder.DeleteStack(ctx, "test_project").Return(nil).Times(1) recorder.DeleteStack(ctx, "test_project").Return(nil).Times(1)
recorder.WaitStackComplete(ctx, "test_project", gomock.Any()).Return(nil).Times(1)
c.ComposeDown(ctx, "test_project", false) c.ComposeDown(ctx, "test_project", false)
} }
@ -37,6 +38,7 @@ func TestDownDeleteCluster(t *testing.T) {
ctx := context.TODO() ctx := context.TODO()
recorder := m.EXPECT() recorder := m.EXPECT()
recorder.DeleteStack(ctx, "test_project").Return(nil).Times(1) recorder.DeleteStack(ctx, "test_project").Return(nil).Times(1)
recorder.WaitStackComplete(ctx, "test_project", gomock.Any()).Return(nil).Times(1)
recorder.DeleteCluster(ctx, "test_cluster").Return(nil).Times(1) recorder.DeleteCluster(ctx, "test_cluster").Return(nil).Times(1)
c.ComposeDown(ctx, "test_project", true) c.ComposeDown(ctx, "test_project", true)

View File

@ -3,13 +3,9 @@ package amazon
import ( import (
"context" "context"
"fmt" "fmt"
"sort"
"github.com/aws/aws-sdk-go/aws"
cf "github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/awslabs/goformation/v4/cloudformation" "github.com/awslabs/goformation/v4/cloudformation"
"github.com/docker/ecs-plugin/pkg/compose" "github.com/docker/ecs-plugin/pkg/compose"
"github.com/docker/ecs-plugin/pkg/console"
) )
func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error { func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error {
@ -38,42 +34,13 @@ func (c *client) ComposeUp(ctx context.Context, project *compose.Project) error
return err return err
} }
w := console.NewProgressWriter() return c.WaitStackCompletion(ctx, project.Name)
known := map[string]struct{}{}
err = c.api.WaitStackComplete(ctx, project.Name, func() error {
events, err := c.api.DescribeStackEvents(ctx, project.Name)
if err != nil {
return err
}
sort.Slice(events, func(i, j int) bool {
return events[i].Timestamp.Before(*events[j].Timestamp)
})
for _, event := range events {
if _, ok := known[*event.EventId]; ok {
continue
}
known[*event.EventId] = struct{}{}
resource := fmt.Sprintf("%s %q", aws.StringValue(event.ResourceType), aws.StringValue(event.LogicalResourceId))
w.ResourceEvent(resource, aws.StringValue(event.ResourceStatus), aws.StringValue(event.ResourceStatusReason))
}
return nil
})
if err != nil {
return err
}
// TODO monitor progress
return nil
} }
type upAPI interface { type upAPI interface {
waitAPI
ClusterExists(ctx context.Context, name string) (bool, error) ClusterExists(ctx context.Context, name string) (bool, error)
CreateCluster(ctx context.Context, name string) (string, error) CreateCluster(ctx context.Context, name string) (string, error)
StackExists(ctx context.Context, name string) (bool, error) StackExists(ctx context.Context, name string) (bool, error)
CreateStack(ctx context.Context, name string, template *cloudformation.Template) error CreateStack(ctx context.Context, name string, template *cloudformation.Template) error
WaitStackComplete(ctx context.Context, name string, fn func() error) error
DescribeStackEvents(ctx context.Context, stack string) ([]*cf.StackEvent, error)
} }

46
ecs/pkg/amazon/wait.go Normal file
View File

@ -0,0 +1,46 @@
package amazon
import (
"context"
"fmt"
"sort"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/cloudformation"
"github.com/docker/ecs-plugin/pkg/console"
)
func (c *client) WaitStackCompletion(ctx context.Context, name string) error {
w := console.NewProgressWriter()
known := map[string]struct{}{}
err := c.api.WaitStackComplete(ctx, name, func() error {
events, err := c.api.DescribeStackEvents(ctx, name)
if err != nil {
return err
}
sort.Slice(events, func(i, j int) bool {
return events[i].Timestamp.Before(*events[j].Timestamp)
})
for _, event := range events {
if _, ok := known[*event.EventId]; ok {
continue
}
known[*event.EventId] = struct{}{}
resource := fmt.Sprintf("%s %q", aws.StringValue(event.ResourceType), aws.StringValue(event.LogicalResourceId))
w.ResourceEvent(resource, aws.StringValue(event.ResourceStatus), aws.StringValue(event.ResourceStatusReason))
}
return nil
})
if err != nil {
return err
}
return nil
}
type waitAPI interface {
WaitStackComplete(ctx context.Context, name string, fn func() error) error
DescribeStackEvents(ctx context.Context, stack string) ([]*cloudformation.StackEvent, error)
}

View File

@ -21,7 +21,11 @@ type progress struct {
resources []*resource resources []*resource
} }
func NewProgressWriter() *progress { type ProgressWriter interface {
ResourceEvent(name string, status string, details string)
}
func NewProgressWriter() ProgressWriter {
return &progress{ return &progress{
console: ansiConsole{os.Stdout}, console: ansiConsole{os.Stdout},
} }