mirror of
https://github.com/docker/compose.git
synced 2025-07-16 18:24:26 +02:00
Merge pull request #1433 from docker/container_name_without_project
This commit is contained in:
commit
b6df84f56a
@ -314,22 +314,21 @@ type Stack struct {
|
|||||||
|
|
||||||
// LogConsumer is a callback to process log messages from services
|
// LogConsumer is a callback to process log messages from services
|
||||||
type LogConsumer interface {
|
type LogConsumer interface {
|
||||||
Log(name, service, container, message string)
|
Log(service, container, message string)
|
||||||
Status(name, container, msg string)
|
Status(container, msg string)
|
||||||
Register(name string, source string)
|
Register(container string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ContainerEventListener is a callback to process ContainerEvent from services
|
// ContainerEventListener is a callback to process ContainerEvent from services
|
||||||
type ContainerEventListener func(event ContainerEvent)
|
type ContainerEventListener func(event ContainerEvent)
|
||||||
|
|
||||||
// ContainerEvent notify an event has been collected on Source container implementing Service
|
// ContainerEvent notify an event has been collected on source container implementing Service
|
||||||
type ContainerEvent struct {
|
type ContainerEvent struct {
|
||||||
Type int
|
Type int
|
||||||
Source string
|
Container string
|
||||||
Service string
|
Service string
|
||||||
Name string
|
Line string
|
||||||
Line string
|
ExitCode int
|
||||||
ExitCode int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -399,11 +399,11 @@ func (p printer) run(ctx context.Context, cascadeStop bool, exitCodeFrom string,
|
|||||||
case compose.UserCancel:
|
case compose.UserCancel:
|
||||||
aborting = true
|
aborting = true
|
||||||
case compose.ContainerEventAttach:
|
case compose.ContainerEventAttach:
|
||||||
consumer.Register(event.Name, event.Source)
|
consumer.Register(event.Container)
|
||||||
count++
|
count++
|
||||||
case compose.ContainerEventExit:
|
case compose.ContainerEventExit:
|
||||||
if !aborting {
|
if !aborting {
|
||||||
consumer.Status(event.Name, event.Source, fmt.Sprintf("exited with code %d", event.ExitCode))
|
consumer.Status(event.Container, fmt.Sprintf("exited with code %d", event.ExitCode))
|
||||||
}
|
}
|
||||||
if cascadeStop {
|
if cascadeStop {
|
||||||
if !aborting {
|
if !aborting {
|
||||||
@ -426,7 +426,7 @@ func (p printer) run(ctx context.Context, cascadeStop bool, exitCodeFrom string,
|
|||||||
}
|
}
|
||||||
case compose.ContainerEventLog:
|
case compose.ContainerEventLog:
|
||||||
if !aborting {
|
if !aborting {
|
||||||
consumer.Log(event.Name, event.Service, event.Source, event.Line)
|
consumer.Log(event.Container, event.Service, event.Line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,11 @@ func NewLogConsumer(ctx context.Context, w io.Writer, color bool, prefix bool) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logConsumer) Register(name string, id string) {
|
func (l *logConsumer) Register(name string) {
|
||||||
l.register(name, id)
|
l.register(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logConsumer) register(name string, id string) *presenter {
|
func (l *logConsumer) register(name string) *presenter {
|
||||||
cf := monochrome
|
cf := monochrome
|
||||||
if l.color {
|
if l.color {
|
||||||
cf = nextColor()
|
cf = nextColor()
|
||||||
@ -51,7 +51,7 @@ func (l *logConsumer) register(name string, id string) *presenter {
|
|||||||
colors: cf,
|
colors: cf,
|
||||||
name: name,
|
name: name,
|
||||||
}
|
}
|
||||||
l.presenters[id] = p
|
l.presenters[name] = p
|
||||||
if l.prefix {
|
if l.prefix {
|
||||||
l.computeWidth()
|
l.computeWidth()
|
||||||
for _, p := range l.presenters {
|
for _, p := range l.presenters {
|
||||||
@ -62,25 +62,25 @@ func (l *logConsumer) register(name string, id string) *presenter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Log formats a log message as received from name/container
|
// Log formats a log message as received from name/container
|
||||||
func (l *logConsumer) Log(name, service, container, message string) {
|
func (l *logConsumer) Log(container, service, message string) {
|
||||||
if l.ctx.Err() != nil {
|
if l.ctx.Err() != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p, ok := l.presenters[container]
|
p, ok := l.presenters[container]
|
||||||
if !ok { // should have been registered, but ¯\_(ツ)_/¯
|
if !ok { // should have been registered, but ¯\_(ツ)_/¯
|
||||||
p = l.register(name, container)
|
p = l.register(container)
|
||||||
}
|
}
|
||||||
for _, line := range strings.Split(message, "\n") {
|
for _, line := range strings.Split(message, "\n") {
|
||||||
fmt.Fprintf(l.writer, "%s %s\n", p.prefix, line) // nolint:errcheck
|
fmt.Fprintf(l.writer, "%s %s\n", p.prefix, line) // nolint:errcheck
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *logConsumer) Status(name, id, msg string) {
|
func (l *logConsumer) Status(container, msg string) {
|
||||||
p, ok := l.presenters[id]
|
p, ok := l.presenters[container]
|
||||||
if !ok {
|
if !ok {
|
||||||
p = l.register(name, id)
|
p = l.register(container)
|
||||||
}
|
}
|
||||||
s := p.colors(fmt.Sprintf("%s %s\n", name, msg))
|
s := p.colors(fmt.Sprintf("%s %s\n", container, msg))
|
||||||
l.writer.Write([]byte(s)) // nolint:errcheck
|
l.writer.Write([]byte(s)) // nolint:errcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ type API interface {
|
|||||||
InspectSecret(ctx context.Context, id string) (secrets.Secret, error)
|
InspectSecret(ctx context.Context, id string) (secrets.Secret, error)
|
||||||
ListSecrets(ctx context.Context) ([]secrets.Secret, error)
|
ListSecrets(ctx context.Context) ([]secrets.Secret, error)
|
||||||
DeleteSecret(ctx context.Context, id string, recover bool) error
|
DeleteSecret(ctx context.Context, id string, recover bool) error
|
||||||
GetLogs(ctx context.Context, name string, consumer func(name string, service string, container string, message string), follow bool) error
|
GetLogs(ctx context.Context, name string, consumer func(container string, service string, message string), follow bool) error
|
||||||
DescribeService(ctx context.Context, cluster string, arn string) (compose.ServiceStatus, error)
|
DescribeService(ctx context.Context, cluster string, arn string) (compose.ServiceStatus, error)
|
||||||
DescribeServiceTasks(ctx context.Context, cluster string, project string, service string) ([]compose.ContainerSummary, error)
|
DescribeServiceTasks(ctx context.Context, cluster string, project string, service string) ([]compose.ContainerSummary, error)
|
||||||
getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error)
|
getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/docker/compose-cli/ecs (interfaces: API)
|
// Container: github.com/docker/compose-cli/ecs (interfaces: API)
|
||||||
|
|
||||||
// Package ecs is a generated GoMock package.
|
// Package ecs is a generated GoMock package.
|
||||||
package ecs
|
package ecs
|
||||||
@ -285,7 +285,7 @@ func (mr *MockAPIMockRecorder) GetLoadBalancerURL(arg0, arg1 interface{}) *gomoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetLogs mocks base method
|
// GetLogs mocks base method
|
||||||
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 func(string, string, string, string), arg3 bool) error {
|
func (m *MockAPI) GetLogs(arg0 context.Context, arg1 string, arg2 func(string, string, string), arg3 bool) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "GetLogs", arg0, arg1, arg2, arg3)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
|
@ -805,7 +805,7 @@ func (s sdk) DeleteSecret(ctx context.Context, id string, recover bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s sdk) GetLogs(ctx context.Context, name string, consumer func(name string, service string, container string, message string), follow bool) error {
|
func (s sdk) GetLogs(ctx context.Context, name string, consumer func(container string, service string, message string), follow bool) error {
|
||||||
logGroup := fmt.Sprintf("/docker-compose/%s", name)
|
logGroup := fmt.Sprintf("/docker-compose/%s", name)
|
||||||
var startTime int64
|
var startTime int64
|
||||||
for {
|
for {
|
||||||
@ -832,7 +832,7 @@ func (s sdk) GetLogs(ctx context.Context, name string, consumer func(name string
|
|||||||
|
|
||||||
for _, event := range events.Events {
|
for _, event := range events.Events {
|
||||||
p := strings.Split(aws.StringValue(event.LogStreamName), "/")
|
p := strings.Split(aws.StringValue(event.LogStreamName), "/")
|
||||||
consumer(p[1], p[1], p[2], aws.StringValue(event.Message))
|
consumer(p[1], p[2], aws.StringValue(event.Message))
|
||||||
startTime = *event.IngestionTime
|
startTime = *event.IngestionTime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,8 @@ func (kc *KubeClient) GetLogs(ctx context.Context, projectName string, consumer
|
|||||||
for _, pod := range pods.Items {
|
for _, pod := range pods.Items {
|
||||||
request := kc.client.CoreV1().Pods(kc.namespace).GetLogs(pod.Name, &corev1.PodLogOptions{Follow: follow})
|
request := kc.client.CoreV1().Pods(kc.namespace).GetLogs(pod.Name, &corev1.PodLogOptions{Follow: follow})
|
||||||
service := pod.Labels[compose.ServiceTag]
|
service := pod.Labels[compose.ServiceTag]
|
||||||
w := utils.GetWriter(pod.Name, service, string(pod.UID), func(event compose.ContainerEvent) {
|
w := utils.GetWriter(pod.Name, service, func(event compose.ContainerEvent) {
|
||||||
consumer.Log(event.Name, event.Service, event.Source, event.Line)
|
consumer.Log(event.Container, event.Service, event.Line)
|
||||||
})
|
})
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
|
@ -41,7 +41,7 @@ func (s *composeService) attach(ctx context.Context, project *types.Project, lis
|
|||||||
|
|
||||||
var names []string
|
var names []string
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
names = append(names, getCanonicalContainerName(c))
|
names = append(names, getContainerNameWithoutProject(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Attaching to %s\n", strings.Join(names, ", "))
|
fmt.Printf("Attaching to %s\n", strings.Join(names, ", "))
|
||||||
@ -95,7 +95,7 @@ func (s *composeService) attach(ctx context.Context, project *types.Project, lis
|
|||||||
|
|
||||||
func (s *composeService) attachContainer(ctx context.Context, container moby.Container, listener compose.ContainerEventListener, project *types.Project) error {
|
func (s *composeService) attachContainer(ctx context.Context, container moby.Container, listener compose.ContainerEventListener, project *types.Project) error {
|
||||||
serviceName := container.Labels[serviceLabel]
|
serviceName := container.Labels[serviceLabel]
|
||||||
w := utils.GetWriter(getContainerNameWithoutProject(container), serviceName, container.ID, listener)
|
w := utils.GetWriter(getContainerNameWithoutProject(container), serviceName, listener)
|
||||||
|
|
||||||
service, err := project.GetService(serviceName)
|
service, err := project.GetService(serviceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -103,10 +103,9 @@ func (s *composeService) attachContainer(ctx context.Context, container moby.Con
|
|||||||
}
|
}
|
||||||
|
|
||||||
listener(compose.ContainerEvent{
|
listener(compose.ContainerEvent{
|
||||||
Type: compose.ContainerEventAttach,
|
Type: compose.ContainerEventAttach,
|
||||||
Source: container.ID,
|
Container: getContainerNameWithoutProject(container),
|
||||||
Name: getContainerNameWithoutProject(container),
|
Service: container.Labels[serviceLabel],
|
||||||
Service: container.Labels[serviceLabel],
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return s.attachContainerStreams(ctx, container.ID, service.Tty, nil, w)
|
return s.attachContainerStreams(ctx, container.ID, service.Tty, nil, w)
|
||||||
|
@ -76,8 +76,8 @@ func (s *composeService) Logs(ctx context.Context, projectName string, consumer
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
name := getContainerNameWithoutProject(c)
|
name := getContainerNameWithoutProject(c)
|
||||||
w := utils.GetWriter(name, service, c.ID, func(event compose.ContainerEvent) {
|
w := utils.GetWriter(name, service, func(event compose.ContainerEvent) {
|
||||||
consumer.Log(name, event.Service, event.Name, event.Line)
|
consumer.Log(name, service, event.Line)
|
||||||
})
|
})
|
||||||
if container.Config.Tty {
|
if container.Config.Tty {
|
||||||
_, err = io.Copy(w, r)
|
_, err = io.Copy(w, r)
|
||||||
|
@ -59,15 +59,14 @@ func (s *composeService) Start(ctx context.Context, project *types.Project, opti
|
|||||||
|
|
||||||
func (s *composeService) waitContainer(ctx context.Context, c moby.Container, listener compose.ContainerEventListener) {
|
func (s *composeService) waitContainer(ctx context.Context, c moby.Container, listener compose.ContainerEventListener) {
|
||||||
statusC, errC := s.apiClient.ContainerWait(ctx, c.ID, container.WaitConditionNotRunning)
|
statusC, errC := s.apiClient.ContainerWait(ctx, c.ID, container.WaitConditionNotRunning)
|
||||||
name := getCanonicalContainerName(c)
|
name := getContainerNameWithoutProject(c)
|
||||||
select {
|
select {
|
||||||
case status := <-statusC:
|
case status := <-statusC:
|
||||||
listener(compose.ContainerEvent{
|
listener(compose.ContainerEvent{
|
||||||
Type: compose.ContainerEventExit,
|
Type: compose.ContainerEventExit,
|
||||||
Source: c.ID,
|
Container: name,
|
||||||
Name: name,
|
Service: c.Labels[serviceLabel],
|
||||||
Service: c.Labels[serviceLabel],
|
ExitCode: int(status.StatusCode),
|
||||||
ExitCode: int(status.StatusCode),
|
|
||||||
})
|
})
|
||||||
case err := <-errC:
|
case err := <-errC:
|
||||||
logrus.Warnf("Unexpected API error for %s : %s", name, err.Error())
|
logrus.Warnf("Unexpected API error for %s : %s", name, err.Error())
|
||||||
|
@ -140,7 +140,7 @@ func TestAttachRestart(t *testing.T) {
|
|||||||
res := c.RunDockerOrExitError("compose", "--ansi=never", "--project-directory", "fixtures/attach-restart", "up")
|
res := c.RunDockerOrExitError("compose", "--ansi=never", "--project-directory", "fixtures/attach-restart", "up")
|
||||||
output := res.Stdout()
|
output := res.Stdout()
|
||||||
|
|
||||||
exitRegex := regexp.MustCompile("attach-restart_another_1 exited with code 1")
|
exitRegex := regexp.MustCompile("another_1 exited with code 1")
|
||||||
assert.Equal(t, len(exitRegex.FindAllStringIndex(output, -1)), 3, res.Combined())
|
assert.Equal(t, len(exitRegex.FindAllStringIndex(output, -1)), 3, res.Combined())
|
||||||
|
|
||||||
execRegex := regexp.MustCompile(`another_1 \| world`)
|
execRegex := regexp.MustCompile(`another_1 \| world`)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/docker/docker/client (interfaces: APIClient)
|
// Container: github.com/docker/docker/client (interfaces: APIClient)
|
||||||
|
|
||||||
// Package mocks is a generated GoMock package.
|
// Package mocks is a generated GoMock package.
|
||||||
package mocks
|
package mocks
|
||||||
|
@ -43,29 +43,28 @@ type allowListLogConsumer struct {
|
|||||||
delegate compose.LogConsumer
|
delegate compose.LogConsumer
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *allowListLogConsumer) Log(name, service, container, message string) {
|
func (a *allowListLogConsumer) Log(container, service, message string) {
|
||||||
if a.allowList[service] {
|
if a.allowList[service] {
|
||||||
a.delegate.Log(name, service, container, message)
|
a.delegate.Log(container, service, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *allowListLogConsumer) Status(name, container, message string) {
|
func (a *allowListLogConsumer) Status(container, message string) {
|
||||||
if a.allowList[name] {
|
if a.allowList[container] {
|
||||||
a.delegate.Status(name, container, message)
|
a.delegate.Status(container, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *allowListLogConsumer) Register(name string, source string) {
|
func (a *allowListLogConsumer) Register(name string) {
|
||||||
if a.allowList[name] {
|
if a.allowList[name] {
|
||||||
a.delegate.Register(name, source)
|
a.delegate.Register(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWriter creates a io.Writer that will actually split by line and format by LogConsumer
|
// GetWriter creates a io.Writer that will actually split by line and format by LogConsumer
|
||||||
func GetWriter(name, service, container string, events compose.ContainerEventListener) io.Writer {
|
func GetWriter(container, service string, events compose.ContainerEventListener) io.Writer {
|
||||||
return &splitBuffer{
|
return &splitBuffer{
|
||||||
buffer: bytes.Buffer{},
|
buffer: bytes.Buffer{},
|
||||||
name: name,
|
|
||||||
service: service,
|
service: service,
|
||||||
container: container,
|
container: container,
|
||||||
consumer: events,
|
consumer: events,
|
||||||
@ -74,7 +73,6 @@ func GetWriter(name, service, container string, events compose.ContainerEventLis
|
|||||||
|
|
||||||
type splitBuffer struct {
|
type splitBuffer struct {
|
||||||
buffer bytes.Buffer
|
buffer bytes.Buffer
|
||||||
name string
|
|
||||||
service string
|
service string
|
||||||
container string
|
container string
|
||||||
consumer compose.ContainerEventListener
|
consumer compose.ContainerEventListener
|
||||||
@ -94,11 +92,10 @@ func (s *splitBuffer) Write(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
line := s.buffer.Next(index + 1)
|
line := s.buffer.Next(index + 1)
|
||||||
s.consumer(compose.ContainerEvent{
|
s.consumer(compose.ContainerEvent{
|
||||||
Type: compose.ContainerEventLog,
|
Type: compose.ContainerEventLog,
|
||||||
Name: s.name,
|
Service: s.service,
|
||||||
Service: s.service,
|
Container: s.container,
|
||||||
Source: s.container,
|
Line: string(line[:len(line)-1]),
|
||||||
Line: string(line[:len(line)-1]),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return n, nil
|
return n, nil
|
||||||
|
@ -26,7 +26,7 @@ import (
|
|||||||
|
|
||||||
func TestSplitWriter(t *testing.T) {
|
func TestSplitWriter(t *testing.T) {
|
||||||
var lines []string
|
var lines []string
|
||||||
w := GetWriter("name", "service", "container", func(event compose.ContainerEvent) {
|
w := GetWriter("container", "service", func(event compose.ContainerEvent) {
|
||||||
lines = append(lines, event.Line)
|
lines = append(lines, event.Line)
|
||||||
})
|
})
|
||||||
w.Write([]byte("h")) //nolint: errcheck
|
w.Write([]byte("h")) //nolint: errcheck
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Code generated by MockGen. DO NOT EDIT.
|
// Code generated by MockGen. DO NOT EDIT.
|
||||||
// Source: github.com/docker/compose-cli/prompt (interfaces: UI)
|
// Container: github.com/docker/compose-cli/prompt (interfaces: UI)
|
||||||
|
|
||||||
// Package prompt is a generated GoMock package.
|
// Package prompt is a generated GoMock package.
|
||||||
package prompt
|
package prompt
|
||||||
|
Loading…
x
Reference in New Issue
Block a user