From 7ddd8e5e9714b60897531546e5c55b2d3007a6ef Mon Sep 17 00:00:00 2001 From: Guillame Tardif Date: Fri, 27 Nov 2020 17:39:22 +0100 Subject: [PATCH 1/3] =?UTF-8?q?Helper=20methods=20to=20create=20progress?= =?UTF-8?q?=20events,=20more=20homogeneous=20display=20for=20=E2=80=9Ccrea?= =?UTF-8?q?ting=E2=80=9D,=20=E2=80=9CCreated=E2=80=9D,=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guillame Tardif --- aci/aci.go | 24 +++---------- aci/volumes.go | 40 +++++++-------------- ecs/down.go | 14 ++++---- ecs/wait.go | 6 +--- local/compose.go | 63 +++++++--------------------------- local/convergence.go | 39 +++++---------------- progress/event.go | 82 ++++++++++++++++++++++++++++++++++++++++++++ progress/writer.go | 30 ---------------- 8 files changed, 129 insertions(+), 169 deletions(-) create mode 100644 progress/event.go diff --git a/aci/aci.go b/aci/aci.go index 1857c2c54..bc8c19b55 100644 --- a/aci/aci.go +++ b/aci/aci.go @@ -107,11 +107,7 @@ func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContex } groupDisplay := "Group " + *groupDefinition.Name - w.Event(progress.Event{ - ID: groupDisplay, - Status: progress.Working, - StatusText: "Waiting", - }) + w.Event(progress.CreatingEvent(groupDisplay)) future, err := containerGroupsClient.CreateOrUpdate( ctx, @@ -123,18 +119,10 @@ func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContex return err } - w.Event(progress.Event{ - ID: groupDisplay, - Status: progress.Done, - StatusText: "Created", - }) + w.Event(progress.CreatedEvent(groupDisplay)) for _, c := range *groupDefinition.Containers { if c.Name != nil && *c.Name != convert.ComposeDNSSidecarName { - w.Event(progress.Event{ - ID: *c.Name, - Status: progress.Working, - StatusText: "Waiting", - }) + w.Event(progress.CreatingEvent(*c.Name)) } } @@ -145,11 +133,7 @@ func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContex for _, c := range *groupDefinition.Containers { if c.Name != nil && *c.Name != convert.ComposeDNSSidecarName { - w.Event(progress.Event{ - ID: *c.Name, - Status: progress.Done, - StatusText: "Done", - }) + w.Event(progress.CreatedEvent(*c.Name)) } } diff --git a/aci/volumes.go b/aci/volumes.go index d323dc1b3..a09583fd3 100644 --- a/aci/volumes.go +++ b/aci/volumes.go @@ -84,14 +84,14 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int return volumes.Volume{}, errors.New("could not read Azure VolumeCreateOptions struct from generic parameter") } w := progress.ContextWriter(ctx) - w.Event(event(opts.Account, progress.Working, "Validating")) + w.Event(progress.NewEvent(opts.Account, progress.Working, "Validating")) accountClient, err := login.NewStorageAccountsClient(cs.aciContext.SubscriptionID) if err != nil { return volumes.Volume{}, err } account, err := accountClient.GetProperties(ctx, cs.aciContext.ResourceGroup, opts.Account, "") if err == nil { - w.Event(event(opts.Account, progress.Done, "Use existing")) + w.Event(progress.NewEvent(opts.Account, progress.Done, "Use existing")) } else if !account.HasHTTPStatus(http.StatusNotFound) { return volumes.Volume{}, err } else { @@ -107,25 +107,25 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int } parameters := defaultStorageAccountParams(cs.aciContext) - w.Event(event(opts.Account, progress.Working, "Creating")) + w.Event(progress.CreatingEvent(opts.Account)) future, err := accountClient.Create(ctx, cs.aciContext.ResourceGroup, opts.Account, parameters) if err != nil { - w.Event(errorEvent(opts.Account)) + w.Event(progress.ErrorEvent(opts.Account, "Error")) return volumes.Volume{}, err } if err := future.WaitForCompletionRef(ctx, accountClient.Client); err != nil { - w.Event(errorEvent(opts.Account)) + w.Event(progress.ErrorEvent(opts.Account, "Error")) return volumes.Volume{}, err } account, err = future.Result(accountClient) if err != nil { - w.Event(errorEvent(opts.Account)) + w.Event(progress.ErrorEvent(opts.Account, "Error")) return volumes.Volume{}, err } - w.Event(event(opts.Account, progress.Done, "Created")) + w.Event(progress.CreatedEvent(opts.Account)) } - w.Event(event(name, progress.Working, "Creating")) + w.Event(progress.CreatingEvent(name)) fileShareClient, err := login.NewFileShareClient(cs.aciContext.SubscriptionID) if err != nil { return volumes.Volume{}, err @@ -133,38 +133,22 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int fileShare, err := fileShareClient.Get(ctx, cs.aciContext.ResourceGroup, *account.Name, name, "") if err == nil { - w.Event(errorEvent(name)) + w.Event(progress.ErrorEvent(name, "Error")) return volumes.Volume{}, errors.Wrapf(errdefs.ErrAlreadyExists, "Azure fileshare %q already exists", name) } if !fileShare.HasHTTPStatus(http.StatusNotFound) { - w.Event(errorEvent(name)) + w.Event(progress.ErrorEvent(name, "Error")) return volumes.Volume{}, err } fileShare, err = fileShareClient.Create(ctx, cs.aciContext.ResourceGroup, *account.Name, name, storage.FileShare{}) if err != nil { - w.Event(errorEvent(name)) + w.Event(progress.ErrorEvent(name, "Error")) return volumes.Volume{}, err } - w.Event(event(name, progress.Done, "Created")) + w.Event(progress.CreatedEvent(name)) return toVolume(*account.Name, *fileShare.Name), nil } -func event(resource string, status progress.EventStatus, text string) progress.Event { - return progress.Event{ - ID: resource, - Status: status, - StatusText: text, - } -} - -func errorEvent(resource string) progress.Event { - return progress.Event{ - ID: resource, - Status: progress.Error, - StatusText: "Error", - } -} - func checkVolumeUsage(ctx context.Context, aciContext store.AciContext, id string) error { containerGroups, err := getACIContainerGroups(ctx, aciContext.SubscriptionID, aciContext.ResourceGroup) if err != nil { diff --git a/ecs/down.go b/ecs/down.go index 79dc726d4..8d1223249 100644 --- a/ecs/down.go +++ b/ecs/down.go @@ -65,11 +65,13 @@ func (b *ecsAPIService) previousStackEvents(ctx context.Context, project string) func doDelete(ctx context.Context, delete func(ctx context.Context, arn string) error) func(r stackResource) error { return func(r stackResource) error { w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: r.LogicalID, - Status: progress.Working, - StatusText: "DeleteInProgress", - }) - return delete(ctx, r.ARN) + w.Event(progress.RemovingEvent(r.LogicalID)) + err := delete(ctx, r.ARN) + if err != nil { + w.Event(progress.ErrorEvent(r.LogicalID, "Error")) + return err + } + w.Event(progress.RemovedEvent(r.LogicalID)) + return nil } } diff --git a/ecs/wait.go b/ecs/wait.go index 600c1fb8b..af62f902a 100644 --- a/ecs/wait.go +++ b/ecs/wait.go @@ -116,11 +116,7 @@ func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, op } stackErr = err operation = stackDelete - w.Event(progress.Event{ - ID: name, - Status: progress.Error, - StatusText: err.Error(), - }) + w.Event(progress.ErrorEvent(name, err.Error())) } } diff --git a/local/compose.go b/local/compose.go index 4651492f6..43cc509a3 100644 --- a/local/compose.go +++ b/local/compose.go @@ -117,29 +117,17 @@ func (s *composeService) Down(ctx context.Context, projectName string) error { for _, c := range list { container := c eg.Go(func() error { - w.Event(progress.Event{ - ID: getContainerName(container), - Text: "Stopping", - Status: progress.Working, - }) + w.Event(progress.NewEvent(getContainerName(container), progress.Working, "Stopping")) err := s.apiClient.ContainerStop(ctx, container.ID, nil) if err != nil { return err } - w.Event(progress.Event{ - ID: getContainerName(container), - Text: "Removing", - Status: progress.Working, - }) + w.Event(progress.RemovingEvent(getContainerName(container))) err = s.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{}) if err != nil { return err } - w.Event(progress.Event{ - ID: getContainerName(container), - Text: "Removed", - Status: progress.Done, - }) + w.Event(progress.RemovedEvent(getContainerName(container))) return nil }) } @@ -591,20 +579,13 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi } createOpts.IPAM.Config = append(createOpts.IPAM.Config, config) } + networkEventName := fmt.Sprintf("Network %q", n.Name) w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Network %q", n.Name), - Status: progress.Working, - StatusText: "Create", - }) + w.Event(progress.CreatingEvent(networkEventName)) if _, err := s.apiClient.NetworkCreate(ctx, n.Name, createOpts); err != nil { return errors.Wrapf(err, "failed to create network %s", n.Name) } - w.Event(progress.Event{ - ID: fmt.Sprintf("Network %q", n.Name), - Status: progress.Done, - StatusText: "Created", - }) + w.Event(progress.CreatedEvent(networkEventName)) return nil } return err @@ -614,27 +595,16 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi func (s *composeService) ensureNetworkDown(ctx context.Context, networkID string, networkName string) error { w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Network %q", networkName), - Status: progress.Working, - StatusText: "Delete", - }) + eventName := fmt.Sprintf("Network %q", networkName) + w.Event(progress.RemovingEvent(eventName)) if err := s.apiClient.NetworkRemove(ctx, networkID); err != nil { msg := fmt.Sprintf("failed to create network %s", networkID) - w.Event(progress.Event{ - ID: fmt.Sprintf("Network %q", networkName), - Status: progress.Error, - StatusText: "Error: " + msg, - }) + w.Event(progress.ErrorEvent(eventName, "Error: "+msg)) return errors.Wrapf(err, msg) } - w.Event(progress.Event{ - ID: fmt.Sprintf("Network %q", networkName), - Status: progress.Done, - StatusText: "Deleted", - }) + w.Event(progress.RemovedEvent(eventName)) return nil } @@ -643,12 +613,9 @@ func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeCo _, err := s.apiClient.VolumeInspect(ctx, volume.Name) if err != nil { if errdefs.IsNotFound(err) { + eventName := fmt.Sprintf("Volume %q", volume.Name) w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Volume %q", volume.Name), - Status: progress.Working, - StatusText: "Create", - }) + w.Event(progress.CreatingEvent(eventName)) // TODO we miss support for driver_opts and labels _, err := s.apiClient.VolumeCreate(ctx, mobyvolume.VolumeCreateBody{ Labels: volume.Labels, @@ -656,11 +623,7 @@ func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeCo Driver: volume.Driver, DriverOpts: volume.DriverOpts, }) - w.Event(progress.Event{ - ID: fmt.Sprintf("Volume %q", volume.Name), - Status: progress.Done, - StatusText: "Created", - }) + w.Event(progress.CreatedEvent(eventName)) if err != nil { return err } diff --git a/local/convergence.go b/local/convergence.go index 6ebcd5e90..9e3532219 100644 --- a/local/convergence.go +++ b/local/convergence.go @@ -163,31 +163,21 @@ func getScale(config types.ServiceConfig) int { } func (s *composeService) createContainer(ctx context.Context, project *types.Project, service types.ServiceConfig, name string, number int) error { + eventName := fmt.Sprintf("Service %q", service.Name) w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Working, - StatusText: "Create", - }) + w.Event(progress.CreatingEvent(eventName)) err := s.runContainer(ctx, project, service, name, number, nil) if err != nil { return err } - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Done, - StatusText: "Created", - }) + w.Event(progress.CreatedEvent(eventName)) return nil } func (s *composeService) recreateContainer(ctx context.Context, project *types.Project, service types.ServiceConfig, container moby.Container) error { w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Working, - StatusText: "Recreate", - }) + eventName := fmt.Sprintf("Service %q", service.Name) + w.Event(progress.NewEvent(eventName, progress.Working, "Recreate")) err := s.apiClient.ContainerStop(ctx, container.ID, nil) if err != nil { return err @@ -210,11 +200,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P if err != nil { return err } - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Done, - StatusText: "Recreated", - }) + w.Event(progress.NewEvent(eventName, progress.Done, "Recreated")) setDependentLifecycle(project, service.Name, forceRecreate) return nil } @@ -234,20 +220,13 @@ func setDependentLifecycle(project *types.Project, service string, strategy stri func (s *composeService) restartContainer(ctx context.Context, service types.ServiceConfig, container moby.Container) error { w := progress.ContextWriter(ctx) - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Working, - StatusText: "Restart", - }) + eventName := fmt.Sprintf("Service %q", service.Name) + w.Event(progress.NewEvent(eventName, progress.Working, "Restart")) err := s.apiClient.ContainerStart(ctx, container.ID, moby.ContainerStartOptions{}) if err != nil { return err } - w.Event(progress.Event{ - ID: fmt.Sprintf("Service %q", service.Name), - Status: progress.Done, - StatusText: "Restarted", - }) + w.Event(progress.NewEvent(eventName, progress.Done, "Restarted")) return nil } diff --git a/progress/event.go b/progress/event.go new file mode 100644 index 000000000..739dd21d0 --- /dev/null +++ b/progress/event.go @@ -0,0 +1,82 @@ +/* + Copyright 2020 Docker Compose CLI authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package progress + +import "time" + +// EventStatus indicates the status of an action +type EventStatus int + +const ( + // Working means that the current task is working + Working EventStatus = iota + // Done means that the current task is done + Done + // Error means that the current task has errored + Error +) + +// Event represents a progress event. +type Event struct { + ID string + Text string + Status EventStatus + StatusText string + + startTime time.Time + endTime time.Time + spinner *spinner +} + +// ErrorEvent creates a new Error Event +func ErrorEvent(ID string, msg string) Event { + return NewEvent(ID, Error, msg) +} + +// CreatingEvent creates a new Create in progress Event +func CreatingEvent(ID string) Event { + return NewEvent(ID, Working, "Creating...") +} + +// CreatedEvent creates a new Created (done) Event +func CreatedEvent(ID string) Event { + return NewEvent(ID, Done, "Created") +} + +// CreatingEvent creates a new Create in progress Event +func RemovingEvent(ID string) Event { + return NewEvent(ID, Working, "Removing...") +} + +// CreatedEvent creates a new Created (done) Event +func RemovedEvent(ID string) Event { + return NewEvent(ID, Done, "Removed") +} + +// NewEvent new event +func NewEvent(ID string, status EventStatus, statusText string) Event { + return Event{ + ID: ID, + Status: status, + StatusText: statusText, + } +} + +func (e *Event) stop() { + e.endTime = time.Now() + e.spinner.Stop() +} diff --git a/progress/writer.go b/progress/writer.go index dd75a18de..656c125d3 100644 --- a/progress/writer.go +++ b/progress/writer.go @@ -20,42 +20,12 @@ import ( "context" "os" "sync" - "time" "github.com/containerd/console" "github.com/moby/term" "golang.org/x/sync/errgroup" ) -// EventStatus indicates the status of an action -type EventStatus int - -const ( - // Working means that the current task is working - Working EventStatus = iota - // Done means that the current task is done - Done - // Error means that the current task has errored - Error -) - -// Event represents a progress event. -type Event struct { - ID string - Text string - Status EventStatus - StatusText string - - startTime time.Time - endTime time.Time - spinner *spinner -} - -func (e *Event) stop() { - e.endTime = time.Now() - e.spinner.Stop() -} - // Writer can write multiple progress events type Writer interface { Start(context.Context) error From 4d1f265c6287cc11229dbb548391b7fa685f6129 Mon Sep 17 00:00:00 2001 From: Guillame Tardif Date: Fri, 27 Nov 2020 18:18:14 +0100 Subject: [PATCH 2/3] Adding error progress indication when errors Signed-off-by: Guillame Tardif --- aci/aci.go | 1 + aci/volumes.go | 16 ++++++++++------ ecs/down.go | 2 +- ecs/wait.go | 8 ++------ local/compose.go | 11 +++++++---- progress/event.go | 13 +++++++++---- 6 files changed, 30 insertions(+), 21 deletions(-) diff --git a/aci/aci.go b/aci/aci.go index bc8c19b55..d576d2249 100644 --- a/aci/aci.go +++ b/aci/aci.go @@ -116,6 +116,7 @@ func createOrUpdateACIContainers(ctx context.Context, aciContext store.AciContex groupDefinition, ) if err != nil { + w.Event(progress.ErrorEvent(groupDisplay)) return err } diff --git a/aci/volumes.go b/aci/volumes.go index a09583fd3..2c012b534 100644 --- a/aci/volumes.go +++ b/aci/volumes.go @@ -87,12 +87,14 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int w.Event(progress.NewEvent(opts.Account, progress.Working, "Validating")) accountClient, err := login.NewStorageAccountsClient(cs.aciContext.SubscriptionID) if err != nil { + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } account, err := accountClient.GetProperties(ctx, cs.aciContext.ResourceGroup, opts.Account, "") if err == nil { w.Event(progress.NewEvent(opts.Account, progress.Done, "Use existing")) } else if !account.HasHTTPStatus(http.StatusNotFound) { + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } else { result, err := accountClient.CheckNameAvailability(ctx, storage.AccountCheckNameAvailabilityParameters{ @@ -100,9 +102,11 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int Type: to.StringPtr("Microsoft.Storage/storageAccounts"), }) if err != nil { + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } if !*result.NameAvailable { + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, errors.New("error: " + *result.Message) } parameters := defaultStorageAccountParams(cs.aciContext) @@ -111,16 +115,16 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int future, err := accountClient.Create(ctx, cs.aciContext.ResourceGroup, opts.Account, parameters) if err != nil { - w.Event(progress.ErrorEvent(opts.Account, "Error")) + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } if err := future.WaitForCompletionRef(ctx, accountClient.Client); err != nil { - w.Event(progress.ErrorEvent(opts.Account, "Error")) + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } account, err = future.Result(accountClient) if err != nil { - w.Event(progress.ErrorEvent(opts.Account, "Error")) + w.Event(progress.ErrorEvent(opts.Account)) return volumes.Volume{}, err } w.Event(progress.CreatedEvent(opts.Account)) @@ -133,16 +137,16 @@ func (cs *aciVolumeService) Create(ctx context.Context, name string, options int fileShare, err := fileShareClient.Get(ctx, cs.aciContext.ResourceGroup, *account.Name, name, "") if err == nil { - w.Event(progress.ErrorEvent(name, "Error")) + w.Event(progress.ErrorEvent(name)) return volumes.Volume{}, errors.Wrapf(errdefs.ErrAlreadyExists, "Azure fileshare %q already exists", name) } if !fileShare.HasHTTPStatus(http.StatusNotFound) { - w.Event(progress.ErrorEvent(name, "Error")) + w.Event(progress.ErrorEvent(name)) return volumes.Volume{}, err } fileShare, err = fileShareClient.Create(ctx, cs.aciContext.ResourceGroup, *account.Name, name, storage.FileShare{}) if err != nil { - w.Event(progress.ErrorEvent(name, "Error")) + w.Event(progress.ErrorEvent(name)) return volumes.Volume{}, err } w.Event(progress.CreatedEvent(name)) diff --git a/ecs/down.go b/ecs/down.go index 8d1223249..bd1c434f5 100644 --- a/ecs/down.go +++ b/ecs/down.go @@ -68,7 +68,7 @@ func doDelete(ctx context.Context, delete func(ctx context.Context, arn string) w.Event(progress.RemovingEvent(r.LogicalID)) err := delete(ctx, r.ARN) if err != nil { - w.Event(progress.ErrorEvent(r.LogicalID, "Error")) + w.Event(progress.ErrorEvent(r.LogicalID)) return err } w.Event(progress.RemovedEvent(r.LogicalID)) diff --git a/ecs/wait.go b/ecs/wait.go index af62f902a..183c59546 100644 --- a/ecs/wait.go +++ b/ecs/wait.go @@ -101,11 +101,7 @@ func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, op } } } - w.Event(progress.Event{ - ID: resource, - Status: progressStatus, - StatusText: fmt.Sprintf("%s %s", toCamelCase(status), reason), - }) + w.Event(progress.NewEvent(resource, progressStatus, fmt.Sprintf("%s %s", toCamelCase(status), reason))) } if operation != stackCreate || stackErr != nil { continue @@ -116,7 +112,7 @@ func (b *ecsAPIService) WaitStackCompletion(ctx context.Context, name string, op } stackErr = err operation = stackDelete - w.Event(progress.ErrorEvent(name, err.Error())) + w.Event(progress.ErrorMessageEvent(name, err.Error())) } } diff --git a/local/compose.go b/local/compose.go index 43cc509a3..c550d5080 100644 --- a/local/compose.go +++ b/local/compose.go @@ -120,11 +120,13 @@ func (s *composeService) Down(ctx context.Context, projectName string) error { w.Event(progress.NewEvent(getContainerName(container), progress.Working, "Stopping")) err := s.apiClient.ContainerStop(ctx, container.ID, nil) if err != nil { + w.Event(progress.ErrorMessageEvent(getContainerName(container), "Error while Stopping")) return err } w.Event(progress.RemovingEvent(getContainerName(container))) err = s.apiClient.ContainerRemove(ctx, container.ID, moby.ContainerRemoveOptions{}) if err != nil { + w.Event(progress.ErrorMessageEvent(getContainerName(container), "Error while Removing")) return err } w.Event(progress.RemovedEvent(getContainerName(container))) @@ -583,6 +585,7 @@ func (s *composeService) ensureNetwork(ctx context.Context, n types.NetworkConfi w := progress.ContextWriter(ctx) w.Event(progress.CreatingEvent(networkEventName)) if _, err := s.apiClient.NetworkCreate(ctx, n.Name, createOpts); err != nil { + w.Event(progress.ErrorEvent(networkEventName)) return errors.Wrapf(err, "failed to create network %s", n.Name) } w.Event(progress.CreatedEvent(networkEventName)) @@ -599,9 +602,8 @@ func (s *composeService) ensureNetworkDown(ctx context.Context, networkID string w.Event(progress.RemovingEvent(eventName)) if err := s.apiClient.NetworkRemove(ctx, networkID); err != nil { - msg := fmt.Sprintf("failed to create network %s", networkID) - w.Event(progress.ErrorEvent(eventName, "Error: "+msg)) - return errors.Wrapf(err, msg) + w.Event(progress.ErrorEvent(eventName)) + return errors.Wrapf(err, fmt.Sprintf("failed to create network %s", networkID)) } w.Event(progress.RemovedEvent(eventName)) @@ -623,10 +625,11 @@ func (s *composeService) ensureVolume(ctx context.Context, volume types.VolumeCo Driver: volume.Driver, DriverOpts: volume.DriverOpts, }) - w.Event(progress.CreatedEvent(eventName)) if err != nil { + w.Event(progress.ErrorEvent(eventName)) return err } + w.Event(progress.CreatedEvent(eventName)) } return err } diff --git a/progress/event.go b/progress/event.go index 739dd21d0..828ca7156 100644 --- a/progress/event.go +++ b/progress/event.go @@ -42,11 +42,16 @@ type Event struct { spinner *spinner } -// ErrorEvent creates a new Error Event -func ErrorEvent(ID string, msg string) Event { +// ErrorMessageEvent creates a new Error Event with message +func ErrorMessageEvent(ID string, msg string) Event { return NewEvent(ID, Error, msg) } +// ErrorEvent creates a new Error Event +func ErrorEvent(ID string) Event { + return NewEvent(ID, Error, "Error") +} + // CreatingEvent creates a new Create in progress Event func CreatingEvent(ID string) Event { return NewEvent(ID, Working, "Creating...") @@ -57,12 +62,12 @@ func CreatedEvent(ID string) Event { return NewEvent(ID, Done, "Created") } -// CreatingEvent creates a new Create in progress Event +// RemovingEvent creates a new Removing in progress Event func RemovingEvent(ID string) Event { return NewEvent(ID, Working, "Removing...") } -// CreatedEvent creates a new Created (done) Event +// RemovedEvent creates a new removed (done) Event func RemovedEvent(ID string) Event { return NewEvent(ID, Done, "Removed") } From fd54682109f37b89132210d064c9a70e794db2c1 Mon Sep 17 00:00:00 2001 From: Guillame Tardif Date: Fri, 27 Nov 2020 18:21:22 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Display=20=E2=80=9CCreating=E2=80=9D,=20not?= =?UTF-8?q?=20=E2=80=9CCreating...=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Guillame Tardif --- progress/event.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/progress/event.go b/progress/event.go index 828ca7156..3d72efeb5 100644 --- a/progress/event.go +++ b/progress/event.go @@ -54,7 +54,7 @@ func ErrorEvent(ID string) Event { // CreatingEvent creates a new Create in progress Event func CreatingEvent(ID string) Event { - return NewEvent(ID, Working, "Creating...") + return NewEvent(ID, Working, "Creating") } // CreatedEvent creates a new Created (done) Event @@ -64,7 +64,7 @@ func CreatedEvent(ID string) Event { // RemovingEvent creates a new Removing in progress Event func RemovingEvent(ID string) Event { - return NewEvent(ID, Working, "Removing...") + return NewEvent(ID, Working, "Removing") } // RemovedEvent creates a new removed (done) Event