mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-11 05:29:30 +00:00
Merge branch '3.x' into galera-log-explainer
This commit is contained in:
@@ -22,7 +22,7 @@ pkgs = $(shell find . -type d -name "pt-*" -exec basename {} \;)
|
||||
# VERSION ?=$(shell git describe --abbrev=0) doesn't always work here, need to use git log
|
||||
VERSION ?=$(shell git log --no-walk --tags --pretty="%H %d" --decorate=short | head -n1 | awk -F'[, $(CP)]' '{ print $$4; }')
|
||||
BUILD=$(BUILD_DATE)
|
||||
GOVERSION=$(shell go version | cut --delimiter=" " -f3)
|
||||
GOVERSION=$(shell go version | cut -d " " -f3)
|
||||
GOUTILSDIR ?= $(GOPATH)/bin
|
||||
FILES = $(shell find . -type f -name '*.go' -not -path "./vendor/*")
|
||||
PREFIX=$(shell pwd)
|
||||
@@ -127,24 +127,36 @@ env-down: env ## Clean-up MongoDB docker containers cluster
|
||||
docker-compose down -v
|
||||
rm .env
|
||||
|
||||
linux-amd64: ## Build Mongo tools for linux-amd64.
|
||||
linux-amd64: ## Build Go tools for linux-amd64.
|
||||
@echo "Building linux/amd64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=linux GOARCH=amd64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
linux-386: ## Build Mongo tools for linux-386
|
||||
linux-386: ## Build Go tools for linux-386
|
||||
@echo "Building linux/386 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=linux GOARCH=386 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
darwin-amd64: ## Build Mongo tools for darwin-amd64 (MacOS)
|
||||
darwin-amd64: ## Build Go tools for darwin-amd64 (MacOS)
|
||||
@echo "Building darwin/amd64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=darwin GOARCH=amd64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
darwin-arm64: ## Build Go tools for darwin-arm64 (MacOS)
|
||||
@echo "Building darwin/arm64 binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),GOOS=darwin GOARCH=arm64 go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
build:
|
||||
@echo "Building binaries in ${BIN_DIR} as version ${VERSION}"
|
||||
@cd ${TOP_DIR} && go get ./...
|
||||
@$(foreach pkg,$(pkgs),rm -f ${BIN_DIR}/$(pkg) 2> /dev/null;)
|
||||
@$(foreach pkg,$(pkgs),go build -ldflags ${LDFLAGS} -o ${BIN_DIR}/$(pkg) ./$(pkg);)
|
||||
|
||||
style: ## Check code style
|
||||
@echo ">> checking code style"
|
||||
@! gofmt -d $(shell find . -path ./vendor -prune -o -name '*.go' -print) | grep '^'
|
||||
|
@@ -129,14 +129,14 @@ func TestOverrideConfig(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDefaultFiles(t *testing.T) {
|
||||
user, _ := user.Current()
|
||||
current, _ := user.Current()
|
||||
toolname := "pt-testing"
|
||||
|
||||
want := []string{
|
||||
"/etc/percona-toolkit/percona-toolkit.conf",
|
||||
fmt.Sprintf("/etc/percona-toolkit/%s.conf", toolname),
|
||||
fmt.Sprintf("%s/.percona-toolkit.conf", user.HomeDir),
|
||||
fmt.Sprintf("%s/.%s.conf", user.HomeDir, toolname),
|
||||
fmt.Sprintf("%s/.percona-toolkit.conf", current.HomeDir),
|
||||
fmt.Sprintf("%s/.%s.conf", current.HomeDir, toolname),
|
||||
}
|
||||
|
||||
got, err := DefaultConfigFiles(toolname)
|
||||
|
@@ -37,7 +37,7 @@ type Security struct {
|
||||
KeyFile string `bson:"keyFile"`
|
||||
ClusterAuthMode string `bson:"clusterAuthMode"`
|
||||
Authorization string `bson:"authorization"`
|
||||
JavascriptEnabled bool `bson:javascriptEnabled"`
|
||||
JavascriptEnabled bool `bson:"javascriptEnabled"`
|
||||
Sasl struct {
|
||||
HostName string `bson:"hostName"`
|
||||
ServiceName string `bson:"serverName"`
|
||||
|
@@ -30,10 +30,10 @@ type ServerStatus struct {
|
||||
}
|
||||
|
||||
type StorageEngine struct {
|
||||
Name string `bson:"name"`
|
||||
SupportCommittedREads bool `bson:supportsCommittedReads"`
|
||||
ReadOnly bool `bson:"readOnly"`
|
||||
Persistent bool `bson:"persistent"`
|
||||
Name string `bson:"name"`
|
||||
SupportsCommittedReads bool `bson:"supportsCommittedReads"`
|
||||
ReadOnly bool `bson:"readOnly"`
|
||||
Persistent bool `bson:"persistent"`
|
||||
}
|
||||
|
||||
// WiredTiger stores information related to the WiredTiger storage engine.
|
||||
|
@@ -20,16 +20,17 @@ import (
|
||||
|
||||
// Dumper struct is for dumping cluster
|
||||
type Dumper struct {
|
||||
cmd string
|
||||
kubeconfig string
|
||||
resources []string
|
||||
filePaths []string
|
||||
namespace string
|
||||
location string
|
||||
errors string
|
||||
mode int64
|
||||
crType string
|
||||
forwardport string
|
||||
cmd string
|
||||
kubeconfig string
|
||||
resources []string
|
||||
filePaths []string
|
||||
fileContainer string
|
||||
namespace string
|
||||
location string
|
||||
errors string
|
||||
mode int64
|
||||
crType string
|
||||
forwardport string
|
||||
}
|
||||
|
||||
var resourcesRe = regexp.MustCompile(`(\w+)\.(\w+).percona\.com`)
|
||||
@@ -124,6 +125,7 @@ func New(location, namespace, resource string, kubeconfig string, forwardport st
|
||||
"var/lib/mysql/mysqld.post.processing.log",
|
||||
"var/lib/mysql/auto.cnf",
|
||||
)
|
||||
d.fileContainer = "logs"
|
||||
}
|
||||
d.resources = resources
|
||||
d.crType = resource
|
||||
@@ -272,7 +274,7 @@ func (d *Dumper) DumpCluster() error {
|
||||
// get individual Logs
|
||||
location = filepath.Join(d.location, ns.Name, pod.Name)
|
||||
for _, path := range d.filePaths {
|
||||
err = d.getIndividualFiles(resourceType(d.crType), ns.Name, pod.Name, path, location, tw)
|
||||
err = d.getIndividualFiles(ns.Name, pod.Name, path, location, tw)
|
||||
if err != nil {
|
||||
d.logError(err.Error(), "get file "+path+" for pod "+pod.Name)
|
||||
log.Printf("Error: get %s file: %v", path, err)
|
||||
@@ -370,13 +372,15 @@ type crSecrets struct {
|
||||
} `json:"spec"`
|
||||
}
|
||||
|
||||
// TODO: check if resource parameter is really needed
|
||||
func (d *Dumper) getIndividualFiles(resource, namespace string, podName, path, location string, tw *tar.Writer) error {
|
||||
args := []string{"-n", namespace, "cp", podName + ":" + path, "/dev/stdout"}
|
||||
func (d *Dumper) getIndividualFiles(namespace string, podName, path, location string, tw *tar.Writer) error {
|
||||
if len(d.fileContainer) == 0 {
|
||||
return errors.Errorf("Logs container name is not specified for resource %s in namespace %s", resourceType(d.crType), d.namespace)
|
||||
}
|
||||
args := []string{"-n", namespace, "-c", d.fileContainer, "cp", podName + ":" + path, "/dev/stdout"}
|
||||
output, err := d.runCmd(args...)
|
||||
if err != nil {
|
||||
d.logError(err.Error(), args...)
|
||||
log.Printf("Error: get path %s for resource %s in namespace %s: %v", path, resource, d.namespace, err)
|
||||
log.Printf("Error: get path %s for resource %s in namespace %s: %v", path, resourceType(d.crType), d.namespace, err)
|
||||
return addToArchive(location, d.mode, []byte(err.Error()), tw)
|
||||
}
|
||||
|
||||
|
20
src/go/pt-k8s-debug-collector/dumper/dumper_test.go
Normal file
20
src/go/pt-k8s-debug-collector/dumper/dumper_test.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package dumper
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
/*
|
||||
Unit test for non-existing logs container name error handling
|
||||
*/
|
||||
|
||||
func TestGetIndividualFilesError(t *testing.T) {
|
||||
d := New("", "", "psmdb", "", "")
|
||||
|
||||
err := d.getIndividualFiles("", "", "", "", nil)
|
||||
|
||||
assert.Error(t, err)
|
||||
assert.ErrorContains(t, err, "Logs container name is not specified")
|
||||
}
|
@@ -412,15 +412,15 @@ type multiSorter struct {
|
||||
less []lessFunc
|
||||
}
|
||||
|
||||
// Sort sorts the argument slice according to the less functions passed to OrderedBy.
|
||||
// Sort sorts the argument slice according to the less functions passed to orderedBy.
|
||||
func (ms *multiSorter) Sort(queries []stats.QueryStats) {
|
||||
ms.queries = queries
|
||||
sort.Sort(ms)
|
||||
}
|
||||
|
||||
// OrderedBy returns a Sorter that sorts using the less functions, in order.
|
||||
// orderedBy returns a Sorter that sorts using the less functions, in order.
|
||||
// Call its Sort method to sort the data.
|
||||
func OrderedBy(less ...lessFunc) *multiSorter {
|
||||
func orderedBy(less ...lessFunc) *multiSorter {
|
||||
return &multiSorter{
|
||||
less: less,
|
||||
}
|
||||
@@ -520,7 +520,7 @@ func sortQueries(queries []stats.QueryStats, orderby []string) []stats.QueryStat
|
||||
sortFuncs = append(sortFuncs, f)
|
||||
}
|
||||
|
||||
OrderedBy(sortFuncs...).Sort(queries)
|
||||
orderedBy(sortFuncs...).Sort(queries)
|
||||
return queries
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user