diff --git a/internal/dao/pod.go b/internal/dao/pod.go index 1de4ed59..b1942e05 100644 --- a/internal/dao/pod.go +++ b/internal/dao/pod.go @@ -32,8 +32,9 @@ var ( ) const ( - logRetryCount = 20 - logRetryWait = 1 * time.Second + logRetryCount = 20 + logRetryWait = 1 * time.Second + defaultLogContainerAnnotation = "kubectl.kubernetes.io/default-logs-container" ) // Pod represents a pod resource. @@ -195,6 +196,13 @@ func (p *Pod) TailLogs(ctx context.Context, c LogChan, opts LogOptions) error { opts.SingleContainer = true return tailLogs(ctx, p, c, opts) } + + if defaultContainer, ok := getDefaultLogContainer(po); ok { + opts.SingleContainer = true + opts.Container = defaultContainer + return tailLogs(ctx, p, c, opts) + } + if len(po.Spec.InitContainers)+len(po.Spec.Containers) == 1 { opts.SingleContainer = true } @@ -491,3 +499,17 @@ func (p *Pod) isControlled(path string) (string, bool, error) { } return "", false, nil } + +func getDefaultLogContainer(po v1.Pod) (string, bool) { + defaultContainer, ok := po.GetAnnotations()[defaultLogContainerAnnotation] + if ok { + for _, container := range po.Spec.Containers { + if container.Name == defaultContainer { + return defaultContainer, true + } + } + log.Warn().Msg(defaultContainer + " container not found. " + defaultLogContainerAnnotation + " annotation will be ignored") + } + + return "", false +} diff --git a/internal/dao/pod_test.go b/internal/dao/pod_test.go new file mode 100644 index 00000000..a340dbfd --- /dev/null +++ b/internal/dao/pod_test.go @@ -0,0 +1,44 @@ +package dao + +import ( + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGetDefaultLogContainer(t *testing.T) { + type args struct { + imageSpecs ImageSpecs + } + uu := map[string]struct { + po v1.Pod + wantContainer string + wantOk bool + }{ + "no_annotation": { + po: v1.Pod{}, + wantContainer: "", + wantOk: false, + }, + "container_not_present": { + po: v1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}}}, + wantContainer: "", + wantOk: false, + }, + "container_found": { + po: v1.Pod{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{"kubectl.kubernetes.io/default-logs-container": "container1"}}, Spec: v1.PodSpec{Containers: []v1.Container{{Name: "container1"}}}}, + wantContainer: "container1", + wantOk: true, + }, + } + for k := range uu { + u := uu[k] + t.Run(k, func(t *testing.T) { + container, ok := getDefaultLogContainer(u.po) + assert.Equal(t, u.wantContainer, container) + assert.Equal(t, u.wantOk, ok) + }) + } +}