package collect import ( "bytes" "context" "path/filepath" "time" "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/replicatedhq/troubleshoot/pkg/k8sutil" kuberneteserrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" "k8s.io/klog/v2" ) type CollectSysctl struct { Collector *troubleshootv1beta2.Sysctl BundlePath string Namespace string ClientConfig *rest.Config Client kubernetes.Interface Context context.Context RBACErrors } func (c *CollectSysctl) Title() string { return getCollectorName(c) } func (c *CollectSysctl) IsExcluded() (bool, error) { return isExcluded(c.Collector.Exclude) } func (c *CollectSysctl) Collect(progressChan chan<- interface{}) (CollectorResult, error) { if c.Collector.Timeout != "" { timeout, err := time.ParseDuration(c.Collector.Timeout) if err != nil { return nil, errors.Wrap(err, "parse timeout") } if timeout == 0 { timeout = time.Minute } childCtx, cancel := context.WithTimeout(c.Context, timeout) defer cancel() c.Context = childCtx } if c.Collector.Namespace == "" { c.Collector.Namespace = c.Namespace } if c.Collector.Namespace == "" { kubeconfig := k8sutil.GetKubeconfig() namespace, _, _ := kubeconfig.Namespace() c.Collector.Namespace = namespace } runPodOptions := RunPodOptions{ Image: c.Collector.Image, ImagePullPolicy: c.Collector.ImagePullPolicy, Namespace: c.Collector.Namespace, HostNetwork: true, } command := ` find /proc/sys/net/ipv4 -type f | while read f; do v=$(cat $f 2>/dev/null); echo "$f = $v"; done find /proc/sys/net/bridge -type f | while read f; do v=$(cat $f 2>/dev/null); echo "$f = $v"; done find /proc/sys/vm -type f | while read f; do v=$(cat $f 2>/dev/null); echo "$f = $v"; done ` runPodOptions.Command = []string{"sh", "-c", command} if c.Collector.ImagePullSecret != nil { runPodOptions.ImagePullSecretName = c.Collector.ImagePullSecret.Name if c.Collector.ImagePullSecret.Data != nil { secretName, err := createSecret(c.Context, c.Client, c.Collector.Namespace, c.Collector.ImagePullSecret) if err != nil { return nil, errors.Wrap(err, "create image pull secret") } defer func() { err := c.Client.CoreV1().Secrets(c.Collector.Namespace).Delete(context.Background(), c.Collector.ImagePullSecret.Name, metav1.DeleteOptions{}) if err != nil && !kuberneteserrors.IsNotFound(err) { klog.Errorf("Failed to delete secret %s: %v", c.Collector.ImagePullSecret.Name, err) } }() runPodOptions.ImagePullSecretName = secretName } } results, err := RunPodsReadyNodes(c.Context, c.Client.CoreV1(), runPodOptions) if err != nil { return nil, err } output := NewResult() for k, v := range results { output.SaveResult(c.BundlePath, filepath.Join("sysctl", k), bytes.NewBuffer(v)) } return output, nil }