Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package stern for openSUSE:Factory checked in at 2024-05-24 19:53:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/stern (Old) and /work/SRC/openSUSE:Factory/.stern.new.24587 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "stern" Fri May 24 19:53:14 2024 rev:10 rq:1176690 version:1.30.0 Changes: -------- --- /work/SRC/openSUSE:Factory/stern/stern.changes 2024-05-03 10:47:41.388114197 +0200 +++ /work/SRC/openSUSE:Factory/.stern.new.24587/stern.changes 2024-05-24 19:53:35.398884720 +0200 @@ -1,0 +2,9 @@ +Fri May 24 07:48:53 UTC 2024 - [email protected] + +- Update to version 1.30.0: + * Update CHANGELOG for v1.30.0 (#307) + * Add support to configure colors for pods and containers (#306) + * Display different colors for different containers (#305) + * Support an array value in the config file (#303) + +------------------------------------------------------------------- Old: ---- stern-1.29.0.obscpio New: ---- stern-1.30.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ stern.spec ++++++ --- /var/tmp/diff_new_pack.Fvj219/_old 2024-05-24 19:53:36.954941659 +0200 +++ /var/tmp/diff_new_pack.Fvj219/_new 2024-05-24 19:53:36.958941805 +0200 @@ -19,7 +19,7 @@ %define __arch_install_post export NO_BRP_STRIP_DEBUG=true Name: stern -Version: 1.29.0 +Version: 1.30.0 Release: 0 Summary: Multi pod and container log tailing for Kubernetes License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.Fvj219/_old 2024-05-24 19:53:36.990942976 +0200 +++ /var/tmp/diff_new_pack.Fvj219/_new 2024-05-24 19:53:36.994943122 +0200 @@ -3,7 +3,7 @@ <param name="url">https://github.com/stern/stern</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v1.29.0</param> + <param name="revision">v1.30.0</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> <param name="changesgenerate">enable</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.Fvj219/_old 2024-05-24 19:53:37.018944000 +0200 +++ /var/tmp/diff_new_pack.Fvj219/_new 2024-05-24 19:53:37.022944147 +0200 @@ -3,6 +3,6 @@ <param name="url">https://github.com/wercker/stern</param> <param name="changesrevision">94f4ffb3b98a9dcd34aedf00f8a7e95b623b25d3</param></service><service name="tar_scm"> <param name="url">https://github.com/stern/stern</param> - <param name="changesrevision">dd6b763dba41842dd8ef942889d88adc5b1b38dc</param></service></servicedata> + <param name="changesrevision">72e2de21fdcae1af295dc8b10bba41398aa590af</param></service></servicedata> (No newline at EOF) ++++++ stern-1.29.0.obscpio -> stern-1.30.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/.gitignore new/stern-1.30.0/.gitignore --- old/stern-1.29.0/.gitignore 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/.gitignore 2024-05-23 16:27:07.000000000 +0200 @@ -1,3 +1,5 @@ /dist /hack/tools/bin vendor +.idea +.vscode diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/CHANGELOG.md new/stern-1.30.0/CHANGELOG.md --- old/stern-1.29.0/CHANGELOG.md 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/CHANGELOG.md 2024-05-23 16:27:07.000000000 +0200 @@ -1,3 +1,35 @@ +# v1.30.0 + +## :zap: Notable Changes + +### Add support for configuring colors for pods and containers +You can now configure highlight colors for pods and containers in [the config file](https://github.com/stern/stern/blob/master/README.md#config-file) using a comma-separated list of [SGR (Select Graphic Rendition) sequences](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters). See the ["Customize highlight colors" section](https://github.com/stern/stern/blob/master/README.md#customize-highlight-colors) for details. + +Example configuration: + +```yaml +# Green, Yellow, Blue, Magenta, Cyan, White +pod-colors: "32,33,34,35,36,37" + +# Colors with underline (4) +# If empty, the pod colors will be used as container colors +container-colors: "32;4,33;4,34;4,35;4,36;4,37;4" +``` + +### Display different colors for different containers +A new `--diff-container` flag allows displaying different colors for different containers. This is useful when you want to debug logs for multiple containers in the same pod. + +You can also enable this feature in [the config file](https://github.com/stern/stern/blob/master/README.md#config-file). + +```yaml +diff-container: true +``` + +### Changes +* Add support to configure colors for pods and containers ([#306](https://github.com/stern/stern/pull/306)) [f4b2edc](https://github.com/stern/stern/commit/f4b2edc) (Takashi Kusumi) +* Display different colors for different containers ([#305](https://github.com/stern/stern/pull/305)) [d1b5d74](https://github.com/stern/stern/commit/d1b5d74) (Se7en) +* Support an array value in the config file ([#303](https://github.com/stern/stern/pull/303)) [6afabde](https://github.com/stern/stern/commit/6afabde) (Takashi Kusumi) + # v1.29.0 ## :zap: Notable Changes diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/README.md new/stern-1.30.0/README.md --- old/stern-1.29.0/README.md 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/README.md 2024-05-23 16:27:07.000000000 +0200 @@ -76,8 +76,10 @@ `--completion` | | Output stern command-line completion code for the specified shell. Can be 'bash', 'zsh' or 'fish'. `--config` | `~/.config/stern/config.yaml` | Path to the stern config file `--container`, `-c` | `.*` | Container name when multiple containers in pod. (regular expression) + `--container-colors` | | Specifies the colors used to highlight container names. Use the same format as --pod-colors. Defaults to the values of --pod-colors if omitted, and must match its length. `--container-state` | `all` | Tail containers with state in running, waiting, terminated, or all. 'all' matches all container states. To specify multiple states, repeat this or set comma-separated value. `--context` | | The name of the kubeconfig context to use + `--diff-container`, `-d` | `false` | Display different colors for different containers. `--ephemeral-containers` | `true` | Include or exclude ephemeral containers. `--exclude`, `-e` | `[]` | Log lines to exclude. (regular expression) `--exclude-container`, `-E` | `[]` | Container name to exclude when multiple containers in pod. (regular expression) @@ -93,6 +95,7 @@ `--node` | | Node name to filter on. `--only-log-lines` | `false` | Print only log lines `--output`, `-o` | `default` | Specify predefined template. Currently support: [default, raw, json, extjson, ppextjson] + `--pod-colors` | | Specifies the colors used to highlight pod names. Provide colors as a comma-separated list using SGR (Select Graphic Rendition) sequences, e.g., "91,92,93,94,95,96". `--prompt`, `-p` | `false` | Toggle interactive prompt for selecting 'app.kubernetes.io/instance' label values. `--selector`, `-l` | | Selector (label query) to filter on. If present, default to ".*" for the pod-query. `--show-hidden-options` | `false` | Print a list of hidden options. @@ -196,6 +199,28 @@ The combination of `--max-log-requests 1` and `--no-follow` will be helpful if you want to show logs in order. +### Customize highlight colors +You can configure highlight colors for pods and containers in [the config file](#config-file) using a comma-separated list of [SGR (Select Graphic Rendition) sequences](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters), as shown below. If you omit `container-colors`, the pod colors will be used as container colors as well. + +```yaml +# Green, Yellow, Blue, Magenta, Cyan, White +pod-colors: "32,33,34,35,36,37" + +# Colors with underline (4) +# If empty, the pod colors will be used as container colors +container-colors: "32;4,33;4,34;4,35;4,36;4,37;4" +``` + +This format enables the use of various attributes, such as underline, background colors, 8-bit colors, and 24-bit colors, if your terminal supports them. + +The equivalent flags `--pod-colors` and `--container-colors` are also available. The following command applies [24-bit colors](https://en.wikipedia.org/wiki/ANSI_escape_code#24-bit) using the `--pod-colors` flag. + +```bash +# Monokai theme +podColors="38;2;255;97;136,38;2;169;220;118,38;2;255;216;102,38;2;120;220;232,38;2;171;157;242" +stern --pod-colors "$podColors" deploy/app +``` + ## Examples: Tail all logs from all namespaces ``` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/cmd.go new/stern-1.30.0/cmd/cmd.go --- old/stern-1.29.0/cmd/cmd.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/cmd/cmd.go 2024-05-23 16:27:07.000000000 +0200 @@ -86,6 +86,9 @@ configFilePath string showHiddenOptions bool stdin bool + diffContainer bool + podColors []string + containerColors []string client kubernetes.Interface clientConfig clientcmd.ClientConfig @@ -168,6 +171,9 @@ if err := o.setVerbosity(); err != nil { return err } + if err := o.setColorList(); err != nil { + return err + } config, err := o.sternConfig() if err != nil { @@ -318,6 +324,7 @@ OnlyLogLines: o.onlyLogLines, MaxLogRequests: maxLogRequests, Stdin: o.stdin, + DiffContainer: o.diffContainer, Out: o.Out, ErrOut: o.ErrOut, @@ -337,6 +344,13 @@ return nil } +func (o *options) setColorList() error { + if len(o.podColors) > 0 || len(o.containerColors) > 0 { + return stern.SetColorList(o.podColors, o.containerColors) + } + return nil +} + // overrideFlagSetDefaultFromConfig overrides the default value of the flagSets // from the config file func (o *options) overrideFlagSetDefaultFromConfig(fs *pflag.FlagSet) error { @@ -377,6 +391,20 @@ continue } + if valueSlice, ok := value.([]any); ok { + // the value is an array + if flagSlice, ok := flag.Value.(pflag.SliceValue); ok { + values := make([]string, len(valueSlice)) + for i, v := range valueSlice { + values[i] = fmt.Sprint(v) + } + if err := flagSlice.Replace(values); err != nil { + return fmt.Errorf("invalid value %q for %q in the config file: %v", value, name, err) + } + continue + } + } + if err := flag.Value.Set(fmt.Sprint(value)); err != nil { return fmt.Errorf("invalid value %q for %q in the config file: %v", value, name, err) } @@ -421,6 +449,9 @@ fs.BoolVarP(&o.version, "version", "v", o.version, "Print the version and exit.") fs.BoolVar(&o.showHiddenOptions, "show-hidden-options", o.showHiddenOptions, "Print a list of hidden options.") fs.BoolVar(&o.stdin, "stdin", o.stdin, "Parse logs from stdin. All Kubernetes related flags are ignored when it is set.") + fs.BoolVarP(&o.diffContainer, "diff-container", "d", o.diffContainer, "Display different colors for different containers.") + fs.StringSliceVar(&o.podColors, "pod-colors", o.podColors, "Specifies the colors used to highlight pod names. Provide colors as a comma-separated list using SGR (Select Graphic Rendition) sequences, e.g., \"91,92,93,94,95,96\".") + fs.StringSliceVar(&o.containerColors, "container-colors", o.containerColors, "Specifies the colors used to highlight container names. Use the same format as --pod-colors. Defaults to the values of --pod-colors if omitted, and must match its length.") fs.Lookup("timestamps").NoOptDefVal = "default" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/cmd_test.go new/stern-1.30.0/cmd/cmd_test.go --- old/stern-1.29.0/cmd/cmd_test.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/cmd/cmd_test.go 2024-05-23 16:27:07.000000000 +0200 @@ -920,3 +920,46 @@ }) } } + +func TestOptionsOverrideFlagSetDefaultFromConfigArray(t *testing.T) { + tests := []struct { + config string + want []string + }{ + { + config: "testdata/config-string.yaml", + want: []string{"hello-world"}, + }, + { + config: "testdata/config-array0.yaml", + want: []string{}, + }, + { + config: "testdata/config-array1.yaml", + want: []string{"abcd"}, + }, + { + config: "testdata/config-array2.yaml", + want: []string{"abcd", "efgh"}, + }, + } + + for _, tt := range tests { + tt := tt + t.Run(tt.config, func(t *testing.T) { + o := NewOptions(genericclioptions.NewTestIOStreamsDiscard()) + fs := pflag.NewFlagSet("", pflag.ExitOnError) + o.AddFlags(fs) + if err := fs.Parse([]string{"--config=" + tt.config}); err != nil { + t.Fatal(err) + } + if err := o.overrideFlagSetDefaultFromConfig(fs); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(tt.want, o.exclude) { + t.Errorf("expected %v, but got %v", tt.want, o.exclude) + } + }) + } + +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/testdata/config-array0.yaml new/stern-1.30.0/cmd/testdata/config-array0.yaml --- old/stern-1.29.0/cmd/testdata/config-array0.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/cmd/testdata/config-array0.yaml 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1 @@ +exclude: [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/testdata/config-array1.yaml new/stern-1.30.0/cmd/testdata/config-array1.yaml --- old/stern-1.29.0/cmd/testdata/config-array1.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/cmd/testdata/config-array1.yaml 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1 @@ +exclude: ["abcd"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/testdata/config-array2.yaml new/stern-1.30.0/cmd/testdata/config-array2.yaml --- old/stern-1.29.0/cmd/testdata/config-array2.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/cmd/testdata/config-array2.yaml 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1 @@ +exclude: ["abcd", "efgh"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/cmd/testdata/config-string.yaml new/stern-1.30.0/cmd/testdata/config-string.yaml --- old/stern-1.29.0/cmd/testdata/config-string.yaml 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/cmd/testdata/config-string.yaml 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1 @@ +exclude: "hello-world" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/color.go new/stern-1.30.0/stern/color.go --- old/stern-1.29.0/stern/color.go 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/stern/color.go 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1,74 @@ +package stern + +import ( + "errors" + "strconv" + "strings" + + "github.com/fatih/color" +) + +var colorList = [][2]*color.Color{ + {color.New(color.FgHiCyan), color.New(color.FgCyan)}, + {color.New(color.FgHiGreen), color.New(color.FgGreen)}, + {color.New(color.FgHiMagenta), color.New(color.FgMagenta)}, + {color.New(color.FgHiYellow), color.New(color.FgYellow)}, + {color.New(color.FgHiBlue), color.New(color.FgBlue)}, + {color.New(color.FgHiRed), color.New(color.FgRed)}, +} + +func SetColorList(podColors, containerColors []string) error { + colors, err := parseColors(podColors, containerColors) + if err != nil { + return err + } + colorList = colors + return nil +} + +func parseColors(podColors, containerColors []string) ([][2]*color.Color, error) { + if len(podColors) == 0 { + return nil, errors.New("pod-colors must not be empty") + } + if len(containerColors) == 0 { + // if containerColors is empty, use podColors as containerColors + return createColorPairs(podColors, podColors) + } + if len(containerColors) != len(podColors) { + return nil, errors.New("pod-colors and container-colors must have the same length") + } + return createColorPairs(podColors, containerColors) +} + +func createColorPairs(podColors, containerColors []string) ([][2]*color.Color, error) { + colorList := make([][2]*color.Color, 0, len(podColors)) + for i := 0; i < len(podColors); i++ { + podColor, err := sgrSequenceToColor(podColors[i]) + if err != nil { + return nil, err + } + containerColor, err := sgrSequenceToColor(containerColors[i]) + if err != nil { + return nil, err + } + colorList = append(colorList, [2]*color.Color{podColor, containerColor}) + } + return colorList, nil +} + +// sgrSequenceToColor converts a string representing SGR sequence +// separated by ";" into a *color.Color instance. +// For example, "31;4" means red foreground with underline. +// https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters +func sgrSequenceToColor(s string) (*color.Color, error) { + parts := strings.Split(s, ";") + attrs := make([]color.Attribute, 0, len(parts)) + for _, part := range parts { + attr, err := strconv.ParseInt(strings.TrimSpace(part), 10, 32) + if err != nil { + return nil, err + } + attrs = append(attrs, color.Attribute(attr)) + } + return color.New(attrs...), nil +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/color_test.go new/stern-1.30.0/stern/color_test.go --- old/stern-1.29.0/stern/color_test.go 1970-01-01 01:00:00.000000000 +0100 +++ new/stern-1.30.0/stern/color_test.go 2024-05-23 16:27:07.000000000 +0200 @@ -0,0 +1,106 @@ +package stern + +import ( + "testing" + + "github.com/fatih/color" +) + +func TestParseColors(t *testing.T) { + tests := []struct { + desc string + podColors []string + containerColors []string + want [][2]*color.Color + wantError bool + }{ + { + desc: "both pod and container colors are specified", + podColors: []string{"91", "92", "93"}, + containerColors: []string{"31", "32", "33"}, + want: [][2]*color.Color{ + {color.New(color.FgHiRed), color.New(color.FgRed)}, + {color.New(color.FgHiGreen), color.New(color.FgGreen)}, + {color.New(color.FgHiYellow), color.New(color.FgYellow)}, + }, + }, + { + desc: "only pod colors are specified", + podColors: []string{"91", "92", "93"}, + containerColors: []string{}, + want: [][2]*color.Color{ + {color.New(color.FgHiRed), color.New(color.FgHiRed)}, + {color.New(color.FgHiGreen), color.New(color.FgHiGreen)}, + {color.New(color.FgHiYellow), color.New(color.FgHiYellow)}, + }, + }, + { + desc: "multiple attributes", + podColors: []string{"4;91"}, + containerColors: []string{"38;2;255;97;136"}, + want: [][2]*color.Color{ + { + color.New(color.Underline, color.FgHiRed), + color.New(38, 2, 255, 97, 136), // 24-bit color + }, + }, + }, + { + desc: "spaces are ignored", + podColors: []string{" 91 ", "\t92\t"}, + containerColors: []string{}, + want: [][2]*color.Color{ + {color.New(color.FgHiRed), color.New(color.FgHiRed)}, + {color.New(color.FgHiGreen), color.New(color.FgHiGreen)}, + }, + }, + // error patterns + { + desc: "only container colors are specified", + podColors: []string{}, + containerColors: []string{"31", "32", "33"}, + wantError: true, + }, + { + desc: "both pod and container colors are empty", + podColors: []string{}, + containerColors: []string{}, + wantError: true, + }, + { + desc: "invalid color", + podColors: []string{"a"}, + containerColors: []string{""}, + wantError: true, + }, + } + for _, tt := range tests { + t.Run(tt.desc, func(t *testing.T) { + colorList, err := parseColors(tt.podColors, tt.containerColors) + + if tt.wantError { + if err == nil { + t.Error("expected err, but got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected err: %v", err) + } + + if len(tt.want) != len(colorList) { + t.Fatalf("expected colorList of size %d, but got %d", len(tt.want), len(colorList)) + } + + for i, wantPair := range tt.want { + gotPair := colorList[i] + if !wantPair[0].Equals(gotPair[0]) { + t.Errorf("colorList[%d][0]: expected %v, but got %v", i, wantPair[0], gotPair[0]) + } + if !wantPair[1].Equals(gotPair[1]) { + t.Errorf("colorList[%d][1]: expected %v, but got %v", i, wantPair[1], gotPair[1]) + } + } + }) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/config.go new/stern-1.30.0/stern/config.go --- old/stern-1.29.0/stern/config.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/stern/config.go 2024-05-23 16:27:07.000000000 +0200 @@ -51,6 +51,7 @@ OnlyLogLines bool MaxLogRequests int Stdin bool + DiffContainer bool Out io.Writer ErrOut io.Writer diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/stern.go new/stern-1.30.0/stern/stern.go --- old/stern-1.29.0/stern/stern.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/stern/stern.go 2024-05-23 16:27:07.000000000 +0200 @@ -65,7 +65,7 @@ } } newTail := func(t *Target) *Tail { - return NewTail(client.CoreV1(), t.Node, t.Namespace, t.Pod, t.Container, config.Template, config.Out, config.ErrOut, newTailOptions()) + return NewTail(client.CoreV1(), t.Node, t.Namespace, t.Pod, t.Container, config.Template, config.Out, config.ErrOut, newTailOptions(), config.DiffContainer) } if config.Stdin { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/tail.go new/stern-1.30.0/stern/tail.go --- old/stern-1.29.0/stern/tail.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/stern/tail.go 2024-05-23 16:27:07.000000000 +0200 @@ -67,8 +67,8 @@ } // NewTail returns a new tail for a Kubernetes container inside a pod -func NewTail(clientset corev1client.CoreV1Interface, nodeName, namespace, podName, containerName string, tmpl *template.Template, out, errOut io.Writer, options *TailOptions) *Tail { - podColor, containerColor := determineColor(podName) +func NewTail(clientset corev1client.CoreV1Interface, nodeName, namespace, podName, containerName string, tmpl *template.Template, out, errOut io.Writer, options *TailOptions, diffContainer bool) *Tail { + podColor, containerColor := determineColor(podName, containerName, diffContainer) return &Tail{ clientset: clientset, @@ -87,22 +87,18 @@ } } -var colorList = [][2]*color.Color{ - {color.New(color.FgHiCyan), color.New(color.FgCyan)}, - {color.New(color.FgHiGreen), color.New(color.FgGreen)}, - {color.New(color.FgHiMagenta), color.New(color.FgMagenta)}, - {color.New(color.FgHiYellow), color.New(color.FgYellow)}, - {color.New(color.FgHiBlue), color.New(color.FgBlue)}, - {color.New(color.FgHiRed), color.New(color.FgRed)}, +func determineColor(podName, containerName string, diffContainer bool) (podColor, containerColor *color.Color) { + colors := colorList[colorIndex(podName)] + if diffContainer { + return colors[0], colorList[colorIndex(containerName)][1] + } + return colors[0], colors[1] } -func determineColor(podName string) (podColor, containerColor *color.Color) { +func colorIndex(name string) uint32 { hash := fnv.New32() - _, _ = hash.Write([]byte(podName)) - idx := hash.Sum32() % uint32(len(colorList)) - - colors := colorList[idx] - return colors[0], colors[1] + _, _ = hash.Write([]byte(name)) + return hash.Sum32() % uint32(len(colorList)) } // Start starts tailing diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/stern-1.29.0/stern/tail_test.go new/stern-1.30.0/stern/tail_test.go --- old/stern-1.29.0/stern/tail_test.go 2024-05-02 11:25:24.000000000 +0200 +++ new/stern-1.30.0/stern/tail_test.go 2024-05-23 16:27:07.000000000 +0200 @@ -13,8 +13,10 @@ func TestDetermineColor(t *testing.T) { podName := "stern" - podColor1, containerColor1 := determineColor(podName) - podColor2, containerColor2 := determineColor(podName) + containerName := "foo" + diffContainer := false + podColor1, containerColor1 := determineColor(podName, containerName, diffContainer) + podColor2, containerColor2 := determineColor(podName, containerName, diffContainer) if podColor1 != podColor2 { t.Errorf("expected color for pod to be the same between invocations but was %v and %v", @@ -26,6 +28,24 @@ } } +func TestDetermineColorDiffContainer(t *testing.T) { + podName := "stern" + containerName1 := "foo" + containerName2 := "bar" + diffContainer := true + podColor1, containerColor1 := determineColor(podName, containerName1, diffContainer) + podColor2, containerColor2 := determineColor(podName, containerName2, diffContainer) + + if podColor1 != podColor2 { + t.Errorf("expected color for pod to be the same between invocations but was %v and %v", + podColor1, podColor2) + } + if containerColor1 == containerColor2 { + t.Errorf("expected color for container to be different between invocations but was the same: %v", + containerColor1) + } +} + func TestConsumeStreamTail(t *testing.T) { logLines := `2023-02-13T21:20:30.000000001Z line 1 2023-02-13T21:20:30.000000002Z line 2 @@ -83,7 +103,7 @@ for i, tt := range tests { t.Run(tt.name, func(t *testing.T) { out := new(bytes.Buffer) - tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", tmpl, out, io.Discard, &TailOptions{}) + tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", tmpl, out, io.Discard, &TailOptions{}, false) tail.resumeRequest = tt.resumeReq if err := tail.ConsumeRequest(context.TODO(), &responseWrapperMock{data: bytes.NewBufferString(logLines)}); err != nil { t.Fatalf("%d: unexpected err %v", i, err) @@ -142,7 +162,7 @@ clientset := fake.NewSimpleClientset() for i, tt := range tests { errOut := new(bytes.Buffer) - tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", nil, io.Discard, errOut, tt.options) + tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", nil, io.Discard, errOut, tt.options, false) tail.printStarting() if !bytes.Equal(tt.expected, errOut.Bytes()) { @@ -184,7 +204,7 @@ clientset := fake.NewSimpleClientset() for i, tt := range tests { errOut := new(bytes.Buffer) - tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", nil, io.Discard, errOut, tt.options) + tail := NewTail(clientset.CoreV1(), "my-node", "my-namespace", "my-pod", "my-container", nil, io.Discard, errOut, tt.options, false) tail.printStopping() if !bytes.Equal(tt.expected, errOut.Bytes()) { ++++++ stern.obsinfo ++++++ --- /var/tmp/diff_new_pack.Fvj219/_old 2024-05-24 19:53:37.142948538 +0200 +++ /var/tmp/diff_new_pack.Fvj219/_new 2024-05-24 19:53:37.146948684 +0200 @@ -1,5 +1,5 @@ name: stern -version: 1.29.0 -mtime: 1714641924 -commit: dd6b763dba41842dd8ef942889d88adc5b1b38dc +version: 1.30.0 +mtime: 1716474427 +commit: 72e2de21fdcae1af295dc8b10bba41398aa590af ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/stern/vendor.tar.gz /work/SRC/openSUSE:Factory/.stern.new.24587/vendor.tar.gz differ: char 5, line 1
