|
|
@@ -23,6 +23,7 @@ import (
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
+ "strings"
|
|
|
|
|
|
"github.com/compose-spec/compose-go/types"
|
|
|
"github.com/distribution/reference"
|
|
|
@@ -68,22 +69,30 @@ func (s *composeService) push(ctx context.Context, project *types.Project, optio
|
|
|
continue
|
|
|
}
|
|
|
service := service
|
|
|
- eg.Go(func() error {
|
|
|
- err := s.pushServiceImage(ctx, service, info, s.configFile(), w, options.Quiet)
|
|
|
- if err != nil {
|
|
|
- if !options.IgnoreFailures {
|
|
|
- return err
|
|
|
+ tags := []string{service.Image}
|
|
|
+ if service.Build != nil {
|
|
|
+ tags = append(tags, service.Build.Tags...)
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, tag := range tags {
|
|
|
+ tag := tag
|
|
|
+ eg.Go(func() error {
|
|
|
+ err := s.pushServiceImage(ctx, tag, info, s.configFile(), w, options.Quiet)
|
|
|
+ if err != nil {
|
|
|
+ if !options.IgnoreFailures {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ w.TailMsgf("Pushing %s: %s", service.Name, err.Error())
|
|
|
}
|
|
|
- w.TailMsgf("Pushing %s: %s", service.Name, err.Error())
|
|
|
- }
|
|
|
- return nil
|
|
|
- })
|
|
|
+ return nil
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
return eg.Wait()
|
|
|
}
|
|
|
|
|
|
-func (s *composeService) pushServiceImage(ctx context.Context, service types.ServiceConfig, info moby.Info, configFile driver.Auth, w progress.Writer, quietPush bool) error {
|
|
|
- ref, err := reference.ParseNormalizedNamed(service.Image)
|
|
|
+func (s *composeService) pushServiceImage(ctx context.Context, tag string, info moby.Info, configFile driver.Auth, w progress.Writer, quietPush bool) error {
|
|
|
+ ref, err := reference.ParseNormalizedNamed(tag)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
@@ -107,7 +116,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, service types.Ser
|
|
|
return err
|
|
|
}
|
|
|
|
|
|
- stream, err := s.apiClient().ImagePush(ctx, service.Image, moby.ImagePushOptions{
|
|
|
+ stream, err := s.apiClient().ImagePush(ctx, tag, moby.ImagePushOptions{
|
|
|
RegistryAuth: base64.URLEncoding.EncodeToString(buf),
|
|
|
})
|
|
|
if err != nil {
|
|
|
@@ -127,9 +136,10 @@ func (s *composeService) pushServiceImage(ctx context.Context, service types.Ser
|
|
|
}
|
|
|
|
|
|
if !quietPush {
|
|
|
- toPushProgressEvent(service.Name, jm, w)
|
|
|
+ toPushProgressEvent(tag, jm, w)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
@@ -145,7 +155,7 @@ func toPushProgressEvent(prefix string, jm jsonmessage.JSONMessage, w progress.W
|
|
|
current int64
|
|
|
percent int
|
|
|
)
|
|
|
- if jm.Status == "Pushed" || jm.Status == "Already exists" {
|
|
|
+ if isDone(jm) {
|
|
|
status = progress.Done
|
|
|
percent = 100
|
|
|
}
|
|
|
@@ -174,3 +184,13 @@ func toPushProgressEvent(prefix string, jm jsonmessage.JSONMessage, w progress.W
|
|
|
StatusText: text,
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
+func isDone(msg jsonmessage.JSONMessage) bool {
|
|
|
+ // TODO there should be a better way to detect push is done than such a status message check
|
|
|
+ switch strings.ToLower(msg.Status) {
|
|
|
+ case "pushed", "layer already exists":
|
|
|
+ return true
|
|
|
+ default:
|
|
|
+ return false
|
|
|
+ }
|
|
|
+}
|