修复1.0.0版本出现的各种问题
This commit is contained in:
@@ -1 +1 @@
|
|||||||
{"compress":false,"storage_type":1,"storage":"/var/tmp","total_file_mem_limit":"80%","containered_sock_path":"/run/k3s/containerd/containerd.sock"}
|
{"compress":false,"storage_type":1,"storage":"/var/lib/coredump","total_file_mem_limit":"80%","containered_sock_path":"/run/k3s/containerd/containerd.sock"}
|
||||||
@@ -55,6 +55,12 @@ func isDiskSufficient(pipe_config types.Pipeconfig) (bool, error) {
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
func createCoreDumpDir(pipe_config *types.Pipeconfig, args types.Coredump_config) error {
|
func createCoreDumpDir(pipe_config *types.Pipeconfig, args types.Coredump_config) error {
|
||||||
|
if _, err := os.Stat(pipe_config.Storage); os.IsNotExist(err) {
|
||||||
|
// 目录不存在,创建目录
|
||||||
|
if err := os.MkdirAll(pipe_config.Storage, os.ModePerm); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
pipe_config.Storage = fmt.Sprintf("%s/%s_%s_%d_coredump", pipe_config.Storage, args.Initial_ns_pid, args.Process_ns_pid, args.Timestamp)
|
pipe_config.Storage = fmt.Sprintf("%s/%s_%s_%d_coredump", pipe_config.Storage, args.Initial_ns_pid, args.Process_ns_pid, args.Timestamp)
|
||||||
dirName := pipe_config.Storage
|
dirName := pipe_config.Storage
|
||||||
if _, err := os.Stat(dirName); os.IsNotExist(err) {
|
if _, err := os.Stat(dirName); os.IsNotExist(err) {
|
||||||
@@ -140,6 +146,26 @@ func writeCoreDumpToFile(config types.Coredump_config) error {
|
|||||||
io.Copy(file, reader)
|
io.Copy(file, reader)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func writeMiniDumpToFile(config types.Coredump_config) error {
|
||||||
|
filename := fmt.Sprintf("%s_%s_%d_minidump.info", config.Initial_ns_pid, config.Process_ns_pid, config.Timestamp)
|
||||||
|
file, err := os.Create(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
// 创建一个管道
|
||||||
|
reader, writer := io.Pipe()
|
||||||
|
// 将标准输入连接到管道的写入端
|
||||||
|
go func() {
|
||||||
|
defer writer.Close()
|
||||||
|
io.Copy(writer, os.Stdin)
|
||||||
|
}()
|
||||||
|
|
||||||
|
// 从管道的读取端将内容写入文件
|
||||||
|
io.Copy(file, reader)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func compress(config types.Coredump_config) error {
|
func compress(config types.Coredump_config) error {
|
||||||
// Create a new zip archive.
|
// Create a new zip archive.
|
||||||
filename := fmt.Sprintf("%s_%s_%d_coredump.info", config.Initial_ns_pid, config.Process_ns_pid, config.Timestamp)
|
filename := fmt.Sprintf("%s_%s_%d_coredump.info", config.Initial_ns_pid, config.Process_ns_pid, config.Timestamp)
|
||||||
@@ -158,7 +184,6 @@ func compress(config types.Coredump_config) error {
|
|||||||
Name: filename,
|
Name: filename,
|
||||||
Method: zip.Deflate,
|
Method: zip.Deflate,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the header to the zip file.
|
// Write the header to the zip file.
|
||||||
writer, err := zipwriter.CreateHeader(header)
|
writer, err := zipwriter.CreateHeader(header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -205,10 +230,14 @@ func main() {
|
|||||||
}
|
}
|
||||||
//判断硬盘使用率
|
//判断硬盘使用率
|
||||||
flag, err := isDiskSufficient(pipe_config)
|
flag, err := isDiskSufficient(pipe_config)
|
||||||
if err != nil && !flag {
|
if err != nil {
|
||||||
journal.Print(journal.PriErr, err.Error())
|
journal.Print(journal.PriErr, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !flag {
|
||||||
|
journal.Print(journal.PriErr, "Disk space exceeds limit")
|
||||||
|
return
|
||||||
|
}
|
||||||
//创建存储coredump内容文件夹
|
//创建存储coredump内容文件夹
|
||||||
err = createCoreDumpDir(&pipe_config, coredump_config)
|
err = createCoreDumpDir(&pipe_config, coredump_config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -3,19 +3,18 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"coredump-tools/types"
|
"coredump-tools/types"
|
||||||
"crypto/rand"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"github.com/google/uuid"
|
||||||
|
"golang.org/x/term"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/client-go/kubernetes"
|
"k8s.io/client-go/kubernetes"
|
||||||
@@ -34,7 +33,7 @@ func terminalSize() (width, height int, err error) {
|
|||||||
}
|
}
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
width, height, err = terminal.GetSize(int(file.Fd()))
|
width, height, err = term.GetSize(int(file.Fd()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, err
|
return 0, 0, err
|
||||||
}
|
}
|
||||||
@@ -42,51 +41,7 @@ func terminalSize() (width, height int, err error) {
|
|||||||
}
|
}
|
||||||
func debug(config types.Coredump_config, command string) error {
|
func debug(config types.Coredump_config, command string) error {
|
||||||
// 使用kubectl命令执行debug操作
|
// 使用kubectl命令执行debug操作
|
||||||
if config.Image_name != "" {
|
if config.Image_name != "NULL" {
|
||||||
// // 定义要运行的 kubectl 命令
|
|
||||||
// command := "kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name} {end}'"
|
|
||||||
|
|
||||||
// // 在 shell 中运行 kubectl 命令并读取输出
|
|
||||||
// cmd := exec.Command("bash", "-c", command)
|
|
||||||
// output, err := cmd.Output()
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // 将输出字符串按空格拆分为字符串切片
|
|
||||||
// nodes := strings.Split(strings.TrimSpace(string(output)), " ")
|
|
||||||
// if len(nodes) == 0 {
|
|
||||||
// return errors.New("the node list is empty")
|
|
||||||
// }
|
|
||||||
// if command == "gdb" {
|
|
||||||
// chmod := "cd" + filepath.Dir(config.Process_exe_path)
|
|
||||||
// cmd := exec.Command("kubectl", "debug", "node/"+nodes[0], "-it", "--image="+config.Image_id, "--image-pull-policy=Never", "--", "gdb", config.Process_exe_path, "/host"+config.Storage, "-ex", chmod)
|
|
||||||
// cmd.Stdin = os.Stdin
|
|
||||||
// cmd.Stdout = os.Stdout
|
|
||||||
// cmd.Stderr = os.Stderr
|
|
||||||
// fmt.Println(cmd.String())
|
|
||||||
// if err := cmd.Start(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// err := cmd.Wait()
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// cmd := exec.Command("kubectl", "debug", "node/"+config.Hostname, "-it", "--image="+config.Image_id, "--image-pull-policy=Never", "--", command)
|
|
||||||
// cmd.Stdin = os.Stdin
|
|
||||||
// cmd.Stdout = os.Stdout
|
|
||||||
// cmd.Stderr = os.Stderr
|
|
||||||
// fmt.Println(cmd.String())
|
|
||||||
// fmt.Println("exe=", config.Process_exe_path, "coredump=/host", config.Storage)
|
|
||||||
// if err := cmd.Start(); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// err := cmd.Wait()
|
|
||||||
// if err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
kubeconfig := os.Getenv("KUBECONFIG")
|
kubeconfig := os.Getenv("KUBECONFIG")
|
||||||
if kubeconfig == "" {
|
if kubeconfig == "" {
|
||||||
kubeconfig = os.Getenv("HOME") + "/.kube/config"
|
kubeconfig = os.Getenv("HOME") + "/.kube/config"
|
||||||
@@ -115,7 +70,7 @@ func debug(config types.Coredump_config, command string) error {
|
|||||||
fmt.Printf("Deleted Pod %q.\n", podName)
|
fmt.Printf("Deleted Pod %q.\n", podName)
|
||||||
return nil
|
return nil
|
||||||
} else { // 使用gdb命令进行命令行交互分析
|
} else { // 使用gdb命令进行命令行交互分析
|
||||||
cmd := exec.Command("gdb", config.Process_exe_path, config.Storage)
|
cmd := exec.Command("gdb", config.Process_exe_path, config.Storage, "-cd", filepath.Dir(config.Process_exe_path))
|
||||||
cmd.Stdin = os.Stdin
|
cmd.Stdin = os.Stdin
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
@@ -126,26 +81,11 @@ func debug(config types.Coredump_config, command string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func generateRandomString(length int) (string, error) {
|
|
||||||
const charset = "abcdefghijklmnopqrstuvwxyz0123456789"
|
|
||||||
bytes := make([]byte, length)
|
|
||||||
max := big.NewInt(int64(len(charset)))
|
|
||||||
for i := 0; i < length; i++ {
|
|
||||||
n, err := rand.Int(rand.Reader, max)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
bytes[i] = charset[n.Int64()]
|
|
||||||
}
|
|
||||||
return string(bytes), nil
|
|
||||||
}
|
|
||||||
func debugInpod(conf *rest.Config, clientset *kubernetes.Clientset, config types.Coredump_config, command string) (string, error) {
|
func debugInpod(conf *rest.Config, clientset *kubernetes.Clientset, config types.Coredump_config, command string) (string, error) {
|
||||||
// Define the Pod object
|
// Define the Pod object
|
||||||
randword, err := generateRandomString(5)
|
id := uuid.New()
|
||||||
if err != nil {
|
fmt.Println(id.String())
|
||||||
return "", err
|
podName := fmt.Sprintf("node-debug-%s", id.String())
|
||||||
}
|
|
||||||
podName := fmt.Sprintf("node-debug-%s-%d", randword, time.Now().Unix())
|
|
||||||
containerName := "debug"
|
containerName := "debug"
|
||||||
pod := &v1.Pod{
|
pod := &v1.Pod{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
@@ -167,6 +107,14 @@ func debugInpod(conf *rest.Config, clientset *kubernetes.Clientset, config types
|
|||||||
Name: "host-dir",
|
Name: "host-dir",
|
||||||
MountPath: "/host",
|
MountPath: "/host",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "lib-debuginfo-dir",
|
||||||
|
MountPath: "/usr/lib/debug",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "src-debuginfo-dir",
|
||||||
|
MountPath: "/usr/src/debug",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
SecurityContext: &v1.SecurityContext{
|
SecurityContext: &v1.SecurityContext{
|
||||||
Privileged: &[]bool{true}[0],
|
Privileged: &[]bool{true}[0],
|
||||||
@@ -182,6 +130,22 @@ func debugInpod(conf *rest.Config, clientset *kubernetes.Clientset, config types
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "lib-debuginfo-dir",
|
||||||
|
VolumeSource: v1.VolumeSource{
|
||||||
|
HostPath: &v1.HostPathVolumeSource{
|
||||||
|
Path: "/usr/lib/debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "src-debuginfo-dir",
|
||||||
|
VolumeSource: v1.VolumeSource{
|
||||||
|
HostPath: &v1.HostPathVolumeSource{
|
||||||
|
Path: "/usr/src/debug",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
RestartPolicy: v1.RestartPolicyNever,
|
RestartPolicy: v1.RestartPolicyNever,
|
||||||
},
|
},
|
||||||
@@ -214,12 +178,16 @@ func debugInpod(conf *rest.Config, clientset *kubernetes.Clientset, config types
|
|||||||
if !ready {
|
if !ready {
|
||||||
return podName, errors.New("create pod timeout")
|
return podName, errors.New("create pod timeout")
|
||||||
}
|
}
|
||||||
// Exec into the container
|
// Disable canonical mode and enable echo mode.
|
||||||
|
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
return podName, err
|
||||||
|
}
|
||||||
|
defer term.Restore(int(os.Stdin.Fd()), oldState)
|
||||||
// Create exec request
|
// Create exec request
|
||||||
var cmd []string
|
var cmd []string
|
||||||
if command == "gdb" {
|
if command == "gdb" {
|
||||||
chmod := "cd" + filepath.Dir(config.Process_exe_path)
|
cmd = []string{"gdb", config.Process_exe_path, "/host" + config.Storage, "-cd", filepath.Dir(config.Process_exe_path)}
|
||||||
cmd = []string{"gdb", config.Process_exe_path, "/host" + config.Storage, "-ex", chmod}
|
|
||||||
} else {
|
} else {
|
||||||
cmd = []string{command}
|
cmd = []string{command}
|
||||||
}
|
}
|
||||||
@@ -316,6 +284,11 @@ func Help() {
|
|||||||
fmt.Println(" Directory path")
|
fmt.Println(" Directory path")
|
||||||
fmt.Println(" -p string")
|
fmt.Println(" -p string")
|
||||||
fmt.Println(" Pid to matching")
|
fmt.Println(" Pid to matching")
|
||||||
|
fmt.Println("debug options:")
|
||||||
|
fmt.Println(" -dir string")
|
||||||
|
fmt.Println(" Directory path")
|
||||||
|
fmt.Println(" -p string")
|
||||||
|
fmt.Println(" Pid to matching")
|
||||||
fmt.Println(" -command string")
|
fmt.Println(" -command string")
|
||||||
fmt.Println(" exe command when attach to pod")
|
fmt.Println(" exe command when attach to pod")
|
||||||
}
|
}
|
||||||
@@ -331,7 +304,7 @@ func main() {
|
|||||||
debugCmd.StringVar(&dirPath, "dir", "", "Directory path")
|
debugCmd.StringVar(&dirPath, "dir", "", "Directory path")
|
||||||
debugCmd.StringVar(&command, "command", "", "")
|
debugCmd.StringVar(&command, "command", "", "")
|
||||||
if len(os.Args) == 1 {
|
if len(os.Args) == 1 {
|
||||||
helpCmd.Usage()
|
Help()
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
switch os.Args[1] {
|
switch os.Args[1] {
|
||||||
@@ -348,7 +321,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if listCmd.Parsed() {
|
if listCmd.Parsed() {
|
||||||
if dirPath == "" {
|
if dirPath == "" {
|
||||||
dirPath = "/var/tmp"
|
dirPath = "/var/lib/coredump"
|
||||||
}
|
}
|
||||||
WalkDirectory(dirPath)
|
WalkDirectory(dirPath)
|
||||||
list(pid)
|
list(pid)
|
||||||
@@ -356,7 +329,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
if debugCmd.Parsed() {
|
if debugCmd.Parsed() {
|
||||||
if dirPath == "" {
|
if dirPath == "" {
|
||||||
dirPath = "/var/tmp"
|
dirPath = "/var/lib/coredump"
|
||||||
}
|
}
|
||||||
if command == "" {
|
if command == "" {
|
||||||
command = "gdb"
|
command = "gdb"
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -5,6 +5,7 @@ go 1.20
|
|||||||
require (
|
require (
|
||||||
github.com/containerd/containerd v1.7.0
|
github.com/containerd/containerd v1.7.0
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0
|
github.com/coreos/go-systemd/v22 v22.5.0
|
||||||
|
github.com/google/uuid v1.3.0
|
||||||
golang.org/x/crypto v0.1.0
|
golang.org/x/crypto v0.1.0
|
||||||
k8s.io/api v0.26.2
|
k8s.io/api v0.26.2
|
||||||
k8s.io/apimachinery v0.26.2
|
k8s.io/apimachinery v0.26.2
|
||||||
@@ -36,7 +37,6 @@ require (
|
|||||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||||
github.com/google/go-cmp v0.5.9 // indirect
|
github.com/google/go-cmp v0.5.9 // indirect
|
||||||
github.com/google/gofuzz v1.2.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
github.com/google/uuid v1.3.0 // indirect
|
|
||||||
github.com/imdario/mergo v0.3.13 // indirect
|
github.com/imdario/mergo v0.3.13 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
|
|||||||
Reference in New Issue
Block a user