talos/pkg/cluster/crashdump.go
Noel Georgi 5112547d6b
chore: generate support zip for crashdump
Generate support zip on crashdump.

Signed-off-by: Noel Georgi <git@frezbo.dev>
2024-11-06 15:54:21 +05:30

110 lines
2.7 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package cluster
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"github.com/siderolabs/gen/xslices"
"github.com/siderolabs/go-talos-support/support"
"github.com/siderolabs/go-talos-support/support/bundle"
"github.com/siderolabs/go-talos-support/support/collectors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8s "k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/clientcmd"
"github.com/siderolabs/talos/pkg/machinery/client"
"github.com/siderolabs/talos/pkg/provision"
)
// Crashdump creates a support.zip for the cluster.
func Crashdump(ctx context.Context, cluster provision.Cluster, out io.Writer) {
statePath, err := cluster.StatePath()
if err != nil {
fmt.Fprintf(out, "error getting state path: %s\n", err)
return
}
supportZip := filepath.Join(statePath, "support.zip")
supportFile, err := os.Create(supportZip)
if err != nil {
fmt.Fprintf(out, "error creating crashdump file: %s\n", err)
return
}
defer supportFile.Close() //nolint:errcheck
c, err := client.New(ctx, client.WithDefaultConfig())
if err != nil {
fmt.Fprintf(out, "error creating crashdump: %s\n", err)
}
nodes := xslices.Map(cluster.Info().Nodes, func(nodeInfo provision.NodeInfo) string {
return nodeInfo.IPs[0].String()
})
controlplane := nodes[0]
opts := []bundle.Option{
bundle.WithArchiveOutput(supportFile),
bundle.WithTalosClient(c),
bundle.WithNodes(nodes...),
bundle.WithNumWorkers(1),
}
kubeclient, err := getKubernetesClient(ctx, c, controlplane)
if err == nil {
opts = append(opts, bundle.WithKubernetesClient(kubeclient))
}
options := bundle.NewOptions(opts...)
collectors, err := collectors.GetForOptions(ctx, options)
if err != nil {
fmt.Fprintf(out, "error creating crashdump collector options: %s\n", err)
}
if err := support.CreateSupportBundle(ctx, options, collectors...); err != nil {
fmt.Fprintf(out, "error creating crashdump: %s\n", err)
}
}
func getKubernetesClient(ctx context.Context, c *client.Client, endpoint string) (*k8s.Clientset, error) {
kubeconfig, err := c.Kubeconfig(client.WithNodes(ctx, endpoint))
if err != nil {
return nil, err
}
config, err := clientcmd.NewClientConfigFromBytes(kubeconfig)
if err != nil {
return nil, err
}
restconfig, err := config.ClientConfig()
if err != nil {
return nil, err
}
clientset, err := k8s.NewForConfig(restconfig)
if err != nil {
return nil, err
}
// just checking that k8s responds
_, err = clientset.CoreV1().Namespaces().Get(ctx, "kube-system", v1.GetOptions{})
if err != nil {
return nil, err
}
return clientset, nil
}