Skip to content

Commit 4bb75b5

Browse files
add output flag for advise
1 parent af3aecb commit 4bb75b5

File tree

4 files changed

+48
-9
lines changed

4 files changed

+48
-9
lines changed

cmd/src/scout_advise.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,14 @@ func init() {
2323
Make recommendations for all pods in a kubernetes deployment of Sourcegraph.
2424
$ src scout advise
2525
26-
Make recommendations for all containers in a Docker deployment of Sourcegraph.
27-
$ src scout advise
28-
2926
Make recommendations for specific pod:
3027
$ src scout advise --pod <podname>
3128
32-
Make recommendations for specific container:
33-
$ src scout advise --container <containername>
34-
3529
Add namespace if using namespace in a Kubernetes cluster
3630
$ src scout advise --namespace <namespace>
31+
32+
Output advice to file
33+
$ src scout advise --o path/to/file
3734
`
3835

3936
flagSet := flag.NewFlagSet("advise", flag.ExitOnError)
@@ -48,6 +45,7 @@ func init() {
4845
namespace = flagSet.String("namespace", "", "(optional) specify the kubernetes namespace to use")
4946
pod = flagSet.String("pod", "", "(optional) specify a single pod")
5047
container = flagSet.String("container", "", "(optional) specify a single container")
48+
output = flagSet.String("o", "", "(optional) output advice to file")
5149
docker = flagSet.Bool("docker", false, "(optional) using docker deployment")
5250
)
5351

@@ -89,6 +87,9 @@ func init() {
8987
if *pod != "" {
9088
options = append(options, advise.WithPod(*pod))
9189
}
90+
if *output != "" {
91+
options = append(options, advise.WithOutput(*output))
92+
}
9293
if *container != "" || *docker {
9394
if *container != "" {
9495
options = append(options, advise.WithContainer(*container))

internal/scout/advise/advise.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,9 @@ func WithContainer(containerName string) Option {
2828
config.Container = containerName
2929
}
3030
}
31+
32+
func WithOutput(pathToFile string) Option {
33+
return func(config *scout.Config) {
34+
config.Output = pathToFile
35+
}
36+
}

internal/scout/advise/k8s.go

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package advise
33
import (
44
"context"
55
"fmt"
6+
"os"
67

78
"github.com/sourcegraph/sourcegraph/lib/errors"
89
"github.com/sourcegraph/src-cli/internal/scout"
@@ -24,6 +25,7 @@ func K8s(
2425
Namespace: "default",
2526
Pod: "",
2627
Container: "",
28+
Output: "",
2729
Spy: false,
2830
Docker: false,
2931
RestConfig: restConfig,
@@ -64,6 +66,11 @@ func K8s(
6466
return nil
6567
}
6668

69+
// Advise generates resource allocation advice for a Kubernetes pod.
70+
// The function fetches usage metrics for each container in the pod. It then
71+
// checks the usage percentages against thresholds to determine if more or less
72+
// of a resource is needed. Advice is generated and either printed to the console
73+
// or output to a file depending on the cfg.Output field.
6774
func Advise(ctx context.Context, cfg *scout.Config, pod v1.Pod) error {
6875
var advice []string
6976
usageMetrics, err := getUsageMetrics(ctx, cfg, pod)
@@ -83,15 +90,39 @@ func Advise(ctx context.Context, cfg *scout.Config, pod v1.Pod) error {
8390
advice = append(advice, storageAdvice)
8491
}
8592

86-
fmt.Println(scout.EmojiFingerPointRight, pod.Name)
87-
for _, msg := range advice {
88-
fmt.Println(msg)
93+
if cfg.Output != "" {
94+
outputToFile(ctx, cfg, pod, advice)
95+
} else {
96+
for _, msg := range advice {
97+
fmt.Println(msg)
98+
}
8999
}
90100
}
91101

92102
return nil
93103
}
94104

105+
// outputToFile writes resource allocation advice for a Kubernetes pod to a file.
106+
func outputToFile(ctx context.Context, cfg *scout.Config, pod v1.Pod, advice []string) error {
107+
file, err := os.OpenFile(cfg.Output, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
108+
if err != nil {
109+
return errors.Wrap(err, "failed to open file")
110+
}
111+
defer file.Close()
112+
113+
if _, err := file.WriteString(fmt.Sprintf("- %s\n", pod.Name)); err != nil {
114+
return errors.Wrap(err, "failed to write pod name to file")
115+
}
116+
117+
for _, msg := range advice {
118+
if _, err := file.WriteString(fmt.Sprintf("%s\n", msg)); err != nil {
119+
return errors.Wrap(err, "failed to write container advice to file")
120+
}
121+
}
122+
return nil
123+
}
124+
125+
// getUsageMetrics generates resource usage statistics for containers in a Kubernetes pod.
95126
func getUsageMetrics(ctx context.Context, cfg *scout.Config, pod v1.Pod) ([]scout.UsageStats, error) {
96127
var usages []scout.UsageStats
97128
var usage scout.UsageStats

internal/scout/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type Config struct {
1212
Namespace string
1313
Pod string
1414
Container string
15+
Output string
1516
Spy bool
1617
Docker bool
1718
RestConfig *rest.Config

0 commit comments

Comments
 (0)