add --track-logs-interval flag (#2807)

* add --track-logs-interval flag

Signed-off-by: pznamensky <kompastver@gmail.com>

* address review nits: logsInterval plumbing and test coverage

- kubedog: move defaultLogsInterval next to TrackOptions in options.go,
  where the field it defaults lives
- kubedog: pass logsInterval through newProgressPrinter instead of a
  post-construction field assignment; zero falls back to the default
- kubedog: cover WithLogsInterval and the LogsInterval default in
  tracker tests
- config: document that defaultTrackLogsInterval is shared by sync and
  apply and mirrors kubedog's default
- config: add a negative-interval validation test case

Signed-off-by: yxxhero <aiopsclub@163.com>

---------

Signed-off-by: pznamensky <kompastver@gmail.com>
Signed-off-by: yxxhero <aiopsclub@163.com>
Co-authored-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
pznamensky
2026-09-30 08:30:21 +08:00
committed by GitHub
co-authored by yxxhero
parent 9263200ed7
commit 5ed585e223
17 changed files with 246 additions and 55 deletions
+12 -1
View File
@@ -3,6 +3,7 @@ package config
import (
"fmt"
"slices"
"time"
)
// ApplyOptoons is the options for the apply command
@@ -95,6 +96,8 @@ type ApplyOptions struct {
TrackLogs bool
// TrackFailedLogs streams logs only for pods that enter a failed state.
TrackFailedLogs bool
// TrackLogsInterval is the interval between kubedog log output updates.
TrackLogsInterval time.Duration
// HelmStuckGrace, when > 0, enables the helm-killer safety valve. See
// ReleaseSpec.HelmStuckGrace for details. Value is in seconds.
HelmStuckGrace int
@@ -109,7 +112,7 @@ type ApplyOptions struct {
// NewApply creates a new Apply
func NewApplyOptions() *ApplyOptions {
return &ApplyOptions{}
return &ApplyOptions{TrackLogsInterval: defaultTrackLogsInterval}
}
// ApplyImpl is impl for applyOptions
@@ -346,6 +349,11 @@ func (a *ApplyImpl) TrackFailedLogs() bool {
return a.ApplyOptions.TrackFailedLogs
}
// TrackLogsInterval returns the kubedog log output interval.
func (a *ApplyImpl) TrackLogsInterval() time.Duration {
return a.ApplyOptions.TrackLogsInterval
}
// HelmStuckGrace returns the helm-stuck-grace value (seconds, 0 = disabled).
func (a *ApplyImpl) HelmStuckGrace() int {
return a.ApplyOptions.HelmStuckGrace
@@ -371,5 +379,8 @@ func (a *ApplyImpl) ValidateConfig() error {
if a.ApplyOptions.TrackMode != "" && !slices.Contains(validTrackModes, a.ApplyOptions.TrackMode) {
return fmt.Errorf("--track-mode must be 'helm', 'helm-legacy', or 'kubedog', got: %s", a.ApplyOptions.TrackMode)
}
if a.ApplyOptions.TrackLogsInterval < time.Second {
return fmt.Errorf("--track-logs-interval must be at least 1s, got: %s", a.ApplyOptions.TrackLogsInterval)
}
return a.GlobalImpl.ValidateConfig()
}
+17 -1
View File
@@ -3,8 +3,14 @@ package config
import (
"fmt"
"slices"
"time"
)
// defaultTrackLogsInterval is the default --track-logs-interval shared by
// the sync and apply commands. It mirrors kubedog's defaultLogsInterval;
// keep the two in sync.
const defaultTrackLogsInterval = 10 * time.Second
// SyncOptions is the options for the build command
type SyncOptions struct {
// Set is the set flag
@@ -63,6 +69,8 @@ type SyncOptions struct {
TrackLogs bool
// TrackFailedLogs streams logs only for pods that enter a failed state.
TrackFailedLogs bool
// TrackLogsInterval is the interval between kubedog log output updates.
TrackLogsInterval time.Duration
// HelmStuckGrace, when > 0, enables the helm-killer safety valve. See
// ReleaseSpec.HelmStuckGrace for details. Value is in seconds.
HelmStuckGrace int
@@ -93,7 +101,7 @@ type SyncOptions struct {
// NewSyncOptions creates a new Apply
func NewSyncOptions() *SyncOptions {
return &SyncOptions{}
return &SyncOptions{TrackLogsInterval: defaultTrackLogsInterval}
}
// SyncImpl is impl for applyOptions
@@ -254,6 +262,11 @@ func (t *SyncImpl) TrackFailedLogs() bool {
return t.SyncOptions.TrackFailedLogs
}
// TrackLogsInterval returns the kubedog log output interval.
func (t *SyncImpl) TrackLogsInterval() time.Duration {
return t.SyncOptions.TrackLogsInterval
}
// HelmStuckGrace returns the helm-stuck-grace value (seconds, 0 = disabled).
func (t *SyncImpl) HelmStuckGrace() int {
return t.SyncOptions.HelmStuckGrace
@@ -349,5 +362,8 @@ func (t *SyncImpl) ValidateConfig() error {
if t.SyncOptions.TrackMode != "" && !slices.Contains(validTrackModes, t.SyncOptions.TrackMode) {
return fmt.Errorf("--track-mode must be 'helm', 'helm-legacy', or 'kubedog', got: %s", t.SyncOptions.TrackMode)
}
if t.SyncOptions.TrackLogsInterval < time.Second {
return fmt.Errorf("--track-logs-interval must be at least 1s, got: %s", t.SyncOptions.TrackLogsInterval)
}
return t.GlobalImpl.ValidateConfig()
}
+61
View File
@@ -0,0 +1,61 @@
package config
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestTrackLogsIntervalDefault(t *testing.T) {
require.Equal(t, 10*time.Second, NewApplyOptions().TrackLogsInterval)
require.Equal(t, 10*time.Second, NewSyncOptions().TrackLogsInterval)
}
func TestTrackLogsIntervalValidation(t *testing.T) {
commands := []struct {
name string
validate func(time.Duration) error
}{
{
name: "apply",
validate: func(interval time.Duration) error {
options := NewApplyOptions()
options.TrackLogsInterval = interval
return NewApplyImpl(NewGlobalImpl(&GlobalOptions{}), options).ValidateConfig()
},
},
{
name: "sync",
validate: func(interval time.Duration) error {
options := NewSyncOptions()
options.TrackLogsInterval = interval
return NewSyncImpl(NewGlobalImpl(&GlobalOptions{}), options).ValidateConfig()
},
},
}
for _, command := range commands {
t.Run(command.name, func(t *testing.T) {
for _, tt := range []struct {
name string
interval time.Duration
wantErr bool
}{
{name: "zero", interval: 0, wantErr: true},
{name: "negative", interval: -time.Second, wantErr: true},
{name: "below minimum", interval: 500 * time.Millisecond, wantErr: true},
{name: "minimum", interval: time.Second},
} {
t.Run(tt.name, func(t *testing.T) {
err := command.validate(tt.interval)
if tt.wantErr {
require.ErrorContains(t, err, "--track-logs-interval must be at least 1s")
} else {
require.NoError(t, err)
}
})
}
})
}
}